From b447618c33683b947c1fb26f1e7cd9033e20e5cb Mon Sep 17 00:00:00 2001 From: nsfisis Date: Tue, 9 Sep 2025 00:12:22 +0900 Subject: feat: support CRLF and CR --- src/io.c | 27 ++++++++++++++++++++++----- tests/121.sh | 16 ++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 tests/121.sh diff --git a/src/io.c b/src/io.c index 1d03e62..6b52318 100644 --- a/src/io.c +++ b/src/io.c @@ -65,16 +65,23 @@ char infile_peek_char(InFile* f) { if (c2 == '\0') { fatal_error("%s:%d: expected, but got ", f->loc.filename, f->loc.line); } - // TODO: crlf - if (c2 == '\r' || c2 == '\n') { - f->pos += 2; + // Handle line continuation. + if (c2 == '\r') { + if (f->buf[f->pos + 2] == '\n') { + f->pos += 3; // Backslash + CRLF + } else { + f->pos += 2; // Backslash + CR + } + ++f->loc.line; + return infile_peek_char(f); + } else if (c2 == '\n') { + f->pos += 2; // Backslash + LF ++f->loc.line; return infile_peek_char(f); } } // Normalize new-line. - // TODO: crlf if (c == '\r') c = '\n'; return c; @@ -82,7 +89,17 @@ char infile_peek_char(InFile* f) { char infile_next_char(InFile* f) { char c = infile_peek_char(f); - ++f->pos; + + if (f->buf[f->pos] == '\r') { + ++f->pos; + if (f->buf[f->pos] == '\n') { + ++f->pos; // CRLF + } + c = '\n'; + } else { + ++f->pos; + } + if (c == '\n') ++f->loc.line; return c; diff --git a/tests/121.sh b/tests/121.sh new file mode 100644 index 0000000..a5ecdb6 --- /dev/null +++ b/tests/121.sh @@ -0,0 +1,16 @@ +cat <<'EOF' > expected +Hello World +Line continues +EOF + +# CRLF +printf 'int printf(const char*, ...);\r\nint main() {\r\n printf("Hello World\\n");\r\n printf("Line con\\\r\ntinues\\n");\r\n return 0;\r\n}\r\n' > main_crlf.c +test_diff < main_crlf.c + +# CR +printf 'int printf(const char*, ...);\rint main() {\r printf("Hello World\\n");\r printf("Line con\\\rtinues\\n");\r return 0;\r}\r' > main_cr.c +test_diff < main_cr.c + +# Mixed +printf 'int printf(const char*, ...);\nint main() {\r\n printf("Hello World\\n");\r printf("Line con\\\r\ntinues\\n");\n return 0;\r\n}\r\n' > main_mixed.c +test_diff < main_mixed.c -- cgit v1.2.3-70-g09d2