cmark

My personal build of CMark ✏️

Commit
65056eabe93702620d64449761c980b0ab3292ff
Parent
ee82af08672810bc03769b2fb5a5767627d30d36
Author
John MacFarlane <jgm@berkeley.edu>
Date

Revised "add newline to end if missing" for performance.

From btrask's alternate code in the comment on https://github.com/jgm/cmark/pull/18.

Note: this gives a 1-2% performance boot in our benchmark, probably enough to make it worth while.

Diffstat

1 file changed, 18 insertions, 5 deletions

Status File Name N° Changes Insertions Deletions
Modified src/blocks.c 23 18 5
diff --git a/src/blocks.c b/src/blocks.c
@@ -557,18 +557,31 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, size_t bytes)
 	bool indented;
 	cmark_chunk input;
 	bool maybe_lazy;
+	int trim = 0;
+	bool cr = false;
+	bool lf = false;
 
 	utf8proc_detab(parser->curline, buffer, bytes);
 
 	// Add a newline to the end if not present:
 	// TODO this breaks abstraction:
-	if (parser->curline->size && parser->curline->ptr[parser->curline->size - 1] == '\n') {
-		cmark_strbuf_truncate(parser->curline, parser->curline->size - 1);
+	if (parser->curline->size > trim &&
+	    parser->curline->ptr[parser->curline->size - 1 - trim] == '\n') {
+		trim += 1;
+		lf = true;
 	}
-	if (parser->curline->size && parser->curline->ptr[parser->curline->size - 1] == '\r') {
-		cmark_strbuf_truncate(parser->curline, parser->curline->size - 1);
+	if (parser->curline->size > trim &&
+	    parser->curline->ptr[parser->curline->size - 1 - trim] == '\r') {
+		trim += 1;
+		cr = true;
 	}
-	cmark_strbuf_putc(parser->curline, '\n');
+	if (cr) {
+		cmark_strbuf_truncate(parser->curline, parser->curline->size - trim);
+	}
+	if (cr || !lf) {
+		cmark_strbuf_putc(parser->curline, '\n');
+	}
+
 	input.data = parser->curline->ptr;
 	input.len = parser->curline->size;