diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | flake.nix | 9 | ||||
| -rw-r--r-- | justfile | 5 | ||||
| -rw-r--r-- | src/cli.c | 16 | ||||
| -rw-r--r-- | src/cli.h | 2 | ||||
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/preprocess.c | 21 | ||||
| -rw-r--r-- | src/preprocess.h | 2 | ||||
| -rw-r--r-- | tests/helpers.sh | 10 |
9 files changed, 55 insertions, 14 deletions
@@ -30,6 +30,6 @@ $(BUILD_ROOT_DIR)/$(TARGET): $(OBJECTS) # TODO: provide release build? $(BUILD_DIR)/%.o: src/%.c - $(CC) -c -Wall -MMD -g -O0 --std=c23 -o $@ $< + $(CC) -c $(CFLAGS) -Wall -MMD -g -O0 --std=c23 -o $@ $< -include $(BUILD_DIR)/*.d @@ -53,6 +53,15 @@ # Disable some kinds of hardening to disable GCC optimization. # cf. https://nixos.wiki/wiki/C#Hardening_flags hardeningDisable = [ "fortify" ]; + shellHook = '' + export CFLAGS="$( + gcc -E -Wp,-v -xc /dev/null 2>&1 | + sed -n '/#include <...>/,/End of search list/p' | + sed '1d;$d' | + awk '{ print "-I"$1; }' | + xargs + )" + ''; }; formatter = treefmt.config.build.wrapper; @@ -3,15 +3,18 @@ build N="1": set -e if [[ {{N}} = 1 ]]; then cc=gcc + cflags= target=ducc elif [[ {{N}} = 2 ]]; then cc=./build/ducc + cflags="${CFLAGS:-}" target=ducc{{N}} else cc="./build/ducc$(({{N}} - 1))" + cflags="${CFLAGS:-}" target=ducc{{N}} fi - CC="$cc" TARGET="$target" make + CC="$cc" CFLAGS="$cflags" TARGET="$target" make build-upto-5-gen: just build 1 @@ -14,6 +14,8 @@ CliArgs* parse_cli_args(int argc, char** argv) { bool opt_c = false; bool opt_E = false; bool opt_MMD = false; + StrArray include_dirs; + strings_init(&include_dirs); for (int i = 1; i < argc; ++i) { if (argv[i][0] != '-') { @@ -29,6 +31,19 @@ CliArgs* parse_cli_args(int argc, char** argv) { // ignore } else if (c == 'M' && argv[i][2] == '\0') { // ignore -M + } else if (c == 'I') { + const char* dir = NULL; + if (argv[i][2] != '\0') { + // -Ipath format + dir = argv[i] + 2; + } else if (argc > i + 1) { + // -I path format + dir = argv[i + 1]; + ++i; + } else { + fatal_error("-I requires directory"); + } + strings_push(&include_dirs, dir); } else if (c == 'o') { if (argc <= i + 1) { fatal_error("-o requires filename"); @@ -63,6 +78,7 @@ CliArgs* parse_cli_args(int argc, char** argv) { a->totally_deligate_to_gcc = false; a->gcc_command = NULL; a->generate_deps = opt_MMD; + a->include_dirs = include_dirs; if (!a->only_compile && str_ends_with(a->input_filename, ".o")) { a->totally_deligate_to_gcc = true; @@ -1,6 +1,7 @@ #ifndef DUCC_CLI_H #define DUCC_CLI_H +#include "common.h" #include "std.h" typedef struct { @@ -12,6 +13,7 @@ typedef struct { bool generate_deps; bool totally_deligate_to_gcc; const char* gcc_command; + StrArray include_dirs; } CliArgs; CliArgs* parse_cli_args(int argc, char** argv); @@ -22,7 +22,7 @@ int main(int argc, char** argv) { StrArray included_files; strings_init(&included_files); - TokenArray* pp_tokens = preprocess(source, &included_files); + TokenArray* pp_tokens = preprocess(source, &included_files, &cli_args->include_dirs); if (cli_args->preprocess_only) { FILE* output_file = cli_args->output_filename ? fopen(cli_args->output_filename, "w") : stdout; diff --git a/src/preprocess.c b/src/preprocess.c index 5e029f2..00b01dd 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -562,7 +562,8 @@ typedef struct { StrArray* included_files; } Preprocessor; -static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files); +static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files, + StrArray* user_include_dirs); static Preprocessor* preprocessor_new(TokenArray* pp_tokens, int include_depth, MacroArray* macros, StrArray* included_files) { @@ -744,7 +745,7 @@ static void expand_include_directive(Preprocessor* pp, const char* include_name, } TokenArray* include_pp_tokens = - do_preprocess(include_source, pp->include_depth + 1, pp->macros, pp->included_files); + do_preprocess(include_source, pp->include_depth + 1, pp->macros, pp->included_files, NULL); tokens_pop(include_pp_tokens); // pop EOF token pp->pos = insert_pp_tokens(pp, pp->pos, include_pp_tokens); } @@ -1541,23 +1542,33 @@ static char* get_ducc_include_path() { return buf; } -static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files) { +static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files, + StrArray* user_include_dirs) { TokenArray* pp_tokens = pp_tokenize(src); Preprocessor* pp = preprocessor_new(pp_tokens, depth, macros, included_files); + + // Ducc's built-in headers has highest priority. add_include_path(pp, get_ducc_include_path()); + + if (user_include_dirs) { + for (size_t i = 0; i < user_include_dirs->len; ++i) { + add_include_path(pp, user_include_dirs->data[i]); + } + } add_include_path(pp, "/usr/local/include"); add_include_path(pp, "/usr/include/x86_64-linux-gnu"); add_include_path(pp, "/usr/include"); + preprocess_preprocessing_file(pp); remove_pp_directives(pp); return pp->pp_tokens; } -TokenArray* preprocess(InFile* src, StrArray* included_files) { +TokenArray* preprocess(InFile* src, StrArray* included_files, StrArray* user_include_dirs) { MacroArray* macros = macros_new(); add_predefined_macros(macros); strings_push(included_files, src->loc.filename); - return do_preprocess(src, 0, macros, included_files); + return do_preprocess(src, 0, macros, included_files, user_include_dirs); } void print_token_to_file(FILE* out, TokenArray* pp_tokens) { diff --git a/src/preprocess.h b/src/preprocess.h index 5449857..e78776f 100644 --- a/src/preprocess.h +++ b/src/preprocess.h @@ -6,7 +6,7 @@ #include "io.h" #include "token.h" -TokenArray* preprocess(InFile* src, StrArray* included_files); +TokenArray* preprocess(InFile* src, StrArray* included_files, StrArray* user_include_dirs); void print_token_to_file(FILE* output_file, TokenArray* pp_tokens); #endif diff --git a/tests/helpers.sh b/tests/helpers.sh index a69e213..adc9511 100644 --- a/tests/helpers.sh +++ b/tests/helpers.sh @@ -1,7 +1,7 @@ function test_exit_code() { cat > main.c - "$ducc" -o a.out main.c + "$ducc" "${CFLAGS:-}" -o a.out main.c set +e ./a.out exit_code=$? @@ -18,7 +18,7 @@ function test_exit_code() { function test_diff() { cat > main.c - "$ducc" -o a.out main.c + "$ducc" "${CFLAGS:-}" -o a.out main.c if [[ ! -f input ]]; then touch input fi @@ -37,7 +37,7 @@ function test_compile_error() { cat > main.c set +e - "$ducc" main.c > /dev/null 2> output + "$ducc" "${CFLAGS:-}" main.c > /dev/null 2> output exit_code=$? set -e @@ -52,14 +52,14 @@ function test_compile_error() { function test_cpp() { cat > main.c - "$ducc" -E main.c > output + "$ducc" "${CFLAGS:-}" -E main.c > output diff -u -Z expected output } function test_example() { filename="../../../examples/$1.c" - "$ducc" -o a.out "$filename" + "$ducc" "${CFLAGS:-}" -o a.out "$filename" if [[ ! -f input ]]; then touch input fi |
