diff --git a/preprocess.c b/preprocess.c index f877dd2..b286482 100644 --- a/preprocess.c +++ b/preprocess.c @@ -68,6 +68,7 @@ struct Hideset { static HashMap macros; static CondIncl *cond_incl; static HashMap pragma_once; +static int include_next_idx; static Token *preprocess2(Token *tok); static Macro *find_macro(Token *tok); @@ -696,11 +697,21 @@ char *search_include_paths(char *filename) { if (!file_exists(path)) continue; hashmap_put(&cache, filename, path); + include_next_idx = i + 1; return path; } return NULL; } +static char *search_include_next(char *filename) { + for (; include_next_idx < include_paths.len; include_next_idx++) { + char *path = format("%s/%s", include_paths.data[include_next_idx], filename); + if (file_exists(path)) + return path; + } + return NULL; +} + // Read an #include argument. static char *read_include_filename(Token **rest, Token *tok, bool *is_dquote) { // Pattern 1: #include "foo.h" @@ -863,6 +874,14 @@ static Token *preprocess2(Token *tok) { continue; } + if (equal(tok, "include_next")) { + bool ignore; + char *filename = read_include_filename(&tok, tok->next, &ignore); + char *path = search_include_next(filename); + tok = include_file(tok, path ? path : filename, start->next->next); + continue; + } + if (equal(tok, "define")) { read_macro_definition(&tok, tok->next); continue; diff --git a/test/driver.sh b/test/driver.sh index f6ed8f0..b076371 100755 --- a/test/driver.sh +++ b/test/driver.sh @@ -265,4 +265,13 @@ echo 'int foo(); int bar=3; int main() { foo(); }' > $tmp/main.c $chibicc -o $tmp/foo $tmp/main.c $tmp/foo.so check -fPIC +# #include_next +mkdir -p $tmp/next1 $tmp/next2 $tmp/next3 +echo '#include "file1.h"' > $tmp/file.c +echo '#include_next "file1.h"' > $tmp/next1/file1.h +echo '#include_next "file2.h"' > $tmp/next2/file1.h +echo 'foo' > $tmp/next3/file2.h +$chibicc -I$tmp/next1 -I$tmp/next2 -I$tmp/next3 -E $tmp/file.c | grep -q foo +check '#include_next' + echo OK