aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-01-08 02:44:13 +0900
committernsfisis <nsfisis@gmail.com>2026-01-08 02:44:13 +0900
commit09b9a73c2d8abcd8d459a0e412fa4bef5f4ded95 (patch)
treee4070e7a1eb78e8e0bd2ca9d2dd49dda6a7f5d5f
parentca88e6a04cae4eea7b1a3ae849f4a0cc44fecb95 (diff)
downloadducc-09b9a73c2d8abcd8d459a0e412fa4bef5f4ded95.tar.gz
ducc-09b9a73c2d8abcd8d459a0e412fa4bef5f4ded95.tar.zst
ducc-09b9a73c2d8abcd8d459a0e412fa4bef5f4ded95.zip
fix: infinite loop when tokenizing "#include HEADER_MACRO"
-rw-r--r--src/tokenize.c10
-rw-r--r--tests/include_errors.sh11
2 files changed, 21 insertions, 0 deletions
diff --git a/src/tokenize.c b/src/tokenize.c
index 1e7a8df..26c6e13 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -361,6 +361,16 @@ static void do_tokenize_all(Lexer* l) {
} else if (c == '\n') {
infile_next_char(l->src);
tok->kind = TokenKind_newline;
+
+ // Reset expect_header_name at the end of line. It handles cases like:
+ //
+ // #ifdef ADDITIONAL_HEADER
+ // #include ADDITIONAL_HEADER
+ // #endif
+ //
+ // Even if ADDITIONAL_HEADER is undefined, this include directive line is tokenized. If the flag were not
+ // reset, the next occurrence of '<' or '"' would be recognized as part of a header name.
+ l->expect_header_name = false;
} else if (isspace(c)) {
while (isspace((c = infile_peek_char(l->src)))) {
if (c == '\n')
diff --git a/tests/include_errors.sh b/tests/include_errors.sh
index 3ac546f..e0f856e 100644
--- a/tests/include_errors.sh
+++ b/tests/include_errors.sh
@@ -50,3 +50,14 @@ test_compile_error <<'EOF'
#include <hoge.h>
EOF
+cat <<'EOF' > expected
+42
+EOF
+
+test_exit_code 0 <<'EOF'
+#ifdef FOO
+#include FOO
+#endif
+
+int main() { 1 < 2; }
+EOF