aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-08-19 07:51:50 +0900
committernsfisis <nsfisis@gmail.com>2025-08-19 07:51:50 +0900
commiteb22f9bbc2f2596c2c690960852e29eaed04ea09 (patch)
tree123f5c29f5bc8550196e39ec43ffaa148f1b3774
parentf17425f819558ab506cb5aea29d5f4f2837ab0c1 (diff)
downloadducc-eb22f9bbc2f2596c2c690960852e29eaed04ea09.tar.gz
ducc-eb22f9bbc2f2596c2c690960852e29eaed04ea09.tar.zst
ducc-eb22f9bbc2f2596c2c690960852e29eaed04ea09.zip
feat: skip a pair of backslash and new-line
-rw-r--r--io.c18
-rw-r--r--tests/096.sh41
2 files changed, 59 insertions, 0 deletions
diff --git a/io.c b/io.c
index c6e94d1..dcfbd08 100644
--- a/io.c
+++ b/io.c
@@ -57,6 +57,24 @@ BOOL infile_eof(InFile* f) {
char infile_peek_char(InFile* f) {
char c = f->buf[f->pos];
+
+ // Skip a pair of backslash and new-line.
+ if (c == '\\') {
+ char c2 = f->buf[f->pos + 1];
+ // C23: 5.1.1.2
+ // A source file that is not empty shall end in a new-line character,
+ // which shall not be immediately preceded by a backslash character
+ // before any such splicing takes place.
+ 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;
+ return infile_peek_char(f);
+ }
+ }
+
// Normalize new-line.
// TODO: crlf
if (c == '\r')
diff --git a/tests/096.sh b/tests/096.sh
new file mode 100644
index 0000000..8bd6848
--- /dev/null
+++ b/tests/096.sh
@@ -0,0 +1,41 @@
+set -e
+
+cat <<'EOF' > expected
+10 20
+100 300 500
+EOF
+
+bash ../../test_diff.sh <<'EOF'
+int printf();
+in\
+t ma\
+in() {
+ int x = 1\
+0;
+
+ int y = 2\
+\
+\
+0;
+
+#def\
+ine X 100
+#define Y 100 + \
+200
+#define Z /*
+*/ 500
+ // comment \
+ x *= 100, y *= 200;
+ /* comment *\
+/
+
+ printf("%d %d\n", x, y);
+ printf("%d %d %d\n", X, Y, Z);
+}
+EOF
+
+cat <<'EOF' > expected
+main.c:1: <new-line> expected, but got <eof>
+EOF
+
+echo -n 'int main() {}\' | bash ../../test_compile_error.sh