aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-09-09 00:12:22 +0900
committernsfisis <nsfisis@gmail.com>2025-09-09 00:12:22 +0900
commitb447618c33683b947c1fb26f1e7cd9033e20e5cb (patch)
treec62d4d9bc5c119ae94022e0a3f8e8d0a085b0190
parent32b15c9dbfec14417bb0a4e04c0eaa8a8028fd42 (diff)
downloadducc-b447618c33683b947c1fb26f1e7cd9033e20e5cb.tar.gz
ducc-b447618c33683b947c1fb26f1e7cd9033e20e5cb.tar.zst
ducc-b447618c33683b947c1fb26f1e7cd9033e20e5cb.zip
feat: support CRLF and CR
-rw-r--r--src/io.c27
-rw-r--r--tests/121.sh16
2 files changed, 38 insertions, 5 deletions
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: <new-line> expected, but got <eof>", 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