From a1dd6213c85dfa6f36f74fd00ade09ed9fa3e467 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 25 Sep 2020 23:18:32 +0900 Subject: [PATCH] Add -I option --- Makefile | 4 ++-- chibicc.h | 1 + main.c | 14 +++++++++++++- preprocess.c | 19 ++++++++++++++++--- self.py | 2 ++ test/driver.sh | 6 ++++++ 6 files changed, 40 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index a87a1fc..9993e00 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ chibicc: $(OBJS) $(OBJS): chibicc.h test/%.exe: chibicc test/%.c - ./chibicc -c -o test/$*.o test/$*.c + ./chibicc -Itest -c -o test/$*.o test/$*.c $(CC) -o $@ test/$*.o -xc test/common test: $(TESTS) @@ -35,7 +35,7 @@ stage2/%.o: chibicc self.py %.c stage2/test/%.exe: stage2/chibicc test/%.c mkdir -p stage2/test - ./stage2/chibicc -c -o stage2/test/$*.o test/$*.c + ./stage2/chibicc -Itest -c -o stage2/test/$*.o test/$*.c $(CC) -o $@ stage2/test/$*.o -xc test/common test-stage2: $(TESTS:test/%=stage2/test/%) diff --git a/chibicc.h b/chibicc.h index 9cd1ed2..4a09b19 100644 --- a/chibicc.h +++ b/chibicc.h @@ -348,4 +348,5 @@ int align_to(int n, int align); bool file_exists(char *path); +extern StringArray include_paths; extern char *base_file; diff --git a/main.c b/main.c index 4c520c5..4abfeca 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,7 @@ #include "chibicc.h" +StringArray include_paths; + static bool opt_E; static bool opt_S; static bool opt_c; @@ -19,7 +21,12 @@ static void usage(int status) { } static bool take_arg(char *arg) { - return !strcmp(arg, "-o"); + char *x[] = {"-o", "-I"}; + + for (int i = 0; i < sizeof(x) / sizeof(*x); i++) + if (!strcmp(arg, x[i])) + return true; + return false; } static void parse_args(int argc, char **argv) { @@ -69,6 +76,11 @@ static void parse_args(int argc, char **argv) { continue; } + if (!strncmp(argv[i], "-I", 2)) { + strarray_push(&include_paths, argv[i] + 2); + continue; + } + if (!strcmp(argv[i], "-cc1-input")) { base_file = argv[++i]; continue; diff --git a/preprocess.c b/preprocess.c index ca06ed9..487e5b4 100644 --- a/preprocess.c +++ b/preprocess.c @@ -596,6 +596,19 @@ static bool expand_macro(Token **rest, Token *tok) { return true; } +static char *search_include_paths(char *filename) { + if (filename[0] == '/') + return filename; + + // Search a file from the include paths. + for (int i = 0; i < include_paths.len; i++) { + char *path = format("%s/%s", include_paths.data[i], 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" @@ -669,7 +682,7 @@ static Token *preprocess2(Token *tok) { bool is_dquote; char *filename = read_include_filename(&tok, tok->next, &is_dquote); - if (filename[0] != '/') { + if (filename[0] != '/' && is_dquote) { char *path = format("%s/%s", dirname(strdup(start->file->name)), filename); if (file_exists(path)) { tok = include_file(tok, path, start->next->next); @@ -677,8 +690,8 @@ static Token *preprocess2(Token *tok) { } } - // TODO: Search a file from the include paths. - tok = include_file(tok, filename, start->next->next); + char *path = search_include_paths(filename); + tok = include_file(tok, path ? path : filename, start->next->next); continue; } diff --git a/self.py b/self.py index 32e0580..88af153 100755 --- a/self.py +++ b/self.py @@ -95,6 +95,8 @@ FILE *open_memstream(char **ptr, size_t *sizeloc); char *dirname(char *path); char *strncpy(char *dest, char *src, long n); int stat(char *pathname, struct stat *statbuf); +int stat(char *pathname, struct stat *statbuf); +char *dirname(char *path); """) for path in sys.argv[1:]: diff --git a/test/driver.sh b/test/driver.sh index 2358af8..80bc0db 100755 --- a/test/driver.sh +++ b/test/driver.sh @@ -85,4 +85,10 @@ echo "#include \"$tmp/out1\"" | $chibicc -E -o $tmp/out2 - cat $tmp/out2 | grep -q foo check '-E and -o' +# -I +mkdir $tmp/dir +echo foo > $tmp/dir/i-option-test +echo "#include \"i-option-test\"" | $chibicc -I$tmp/dir -E - | grep -q foo +check -I + echo OK -- GitLab