summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2015-06-03 11:54:06 +0200
committerJohn MacFarlane <jgm@berkeley.edu>2015-06-03 11:56:05 +0200
commit65056eabe93702620d64449761c980b0ab3292ff (patch)
treed185e7bd3067903cb80e2c188b55b02459f900a1
parentee82af08672810bc03769b2fb5a5767627d30d36 (diff)
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.
-rw-r--r--src/blocks.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/blocks.c b/src/blocks.c
index 8ae452e..bb8acd2 100644
--- 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;