diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-01-14 23:15:45 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-01-17 00:27:28 +0900 |
| commit | 98fb9ed53b6f6c7b792a751ed1f448af5c680877 (patch) | |
| tree | c7f1ea9976ee8e9126e936c551622ce95bb8a6b1 | |
| parent | f0351da192b8f32bdf9323b3796521cbc390c749 (diff) | |
| download | ducc-98fb9ed53b6f6c7b792a751ed1f448af5c680877.tar.gz ducc-98fb9ed53b6f6c7b792a751ed1f448af5c680877.tar.zst ducc-98fb9ed53b6f6c7b792a751ed1f448af5c680877.zip | |
feat: support -MD flag
| -rw-r--r-- | src/cli.c | 6 | ||||
| -rw-r--r-- | src/cli.h | 3 | ||||
| -rw-r--r-- | src/main.c | 6 | ||||
| -rw-r--r-- | src/preprocess.c | 57 | ||||
| -rw-r--r-- | src/preprocess.h | 3 |
5 files changed, 60 insertions, 15 deletions
@@ -15,6 +15,7 @@ CliArgs* parse_cli_args(int argc, char** argv) { bool opt_c = false; bool opt_E = false; bool opt_wasm = false; + bool opt_MD = false; bool opt_MMD = false; StrArray include_dirs; strings_init(&include_dirs); @@ -75,6 +76,8 @@ CliArgs* parse_cli_args(int argc, char** argv) { opt_c = true; } else if (c == 'E') { opt_E = true; + } else if (strcmp(argv[i], "-MD") == 0) { + opt_MD = true; } else if (strcmp(argv[i], "-MMD") == 0) { opt_MMD = true; } else if (strcmp(argv[i], "--version") == 0) { @@ -101,7 +104,8 @@ CliArgs* parse_cli_args(int argc, char** argv) { a->totally_deligate_to_gcc = false; a->wasm = opt_wasm; a->gcc_command = NULL; - a->generate_deps = opt_MMD; + a->generate_system_deps = opt_MD; + a->generate_user_deps = opt_MD || opt_MMD; a->include_dirs = include_dirs; a->defines = defines; @@ -9,7 +9,8 @@ typedef struct { bool output_assembly; bool only_compile; bool preprocess_only; - bool generate_deps; + bool generate_system_deps; + bool generate_user_deps; bool totally_deligate_to_gcc; bool wasm; const char* gcc_command; @@ -21,7 +21,8 @@ int main(int argc, char** argv) { StrArray included_files; strings_init(&included_files); - TokenArray* pp_tokens = preprocess(source, &included_files, &cli_args->include_dirs, &cli_args->defines); + TokenArray* pp_tokens = preprocess(source, &included_files, &cli_args->include_dirs, &cli_args->defines, + cli_args->generate_system_deps, cli_args->generate_user_deps); if (cli_args->preprocess_only) { FILE* output_file = cli_args->output_filename ? fopen(cli_args->output_filename, "w") : stdout; @@ -70,7 +71,8 @@ int main(int argc, char** argv) { } } - if (cli_args->generate_deps && cli_args->only_compile && cli_args->output_filename) { + if ((cli_args->generate_system_deps || cli_args->generate_user_deps) && cli_args->only_compile && + cli_args->output_filename) { const char* dep_filename = replace_extension(cli_args->output_filename, ".d"); FILE* dep_file = fopen(dep_filename, "w"); diff --git a/src/preprocess.c b/src/preprocess.c index 869b069..70a7d13 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -36,6 +36,25 @@ typedef struct { TokenArray replacements; } Macro; +void macro_build_json(JsonBuilder* builder, Macro* macro) { + jsonbuilder_object_start(builder); + + jsonbuilder_object_member_start(builder, "kind"); + jsonbuilder_string(builder, macro_kind_stringify(macro->kind)); + jsonbuilder_object_member_end(builder); + jsonbuilder_object_member_start(builder, "name"); + jsonbuilder_string(builder, macro->name); + jsonbuilder_object_member_end(builder); + jsonbuilder_object_member_start(builder, "parameters"); + tokens_build_json(builder, ¯o->parameters); + jsonbuilder_object_member_end(builder); + jsonbuilder_object_member_start(builder, "replacements"); + tokens_build_json(builder, ¯o->replacements); + jsonbuilder_object_member_end(builder); + + jsonbuilder_object_end(builder); +} + static int macro_find_param(Macro* macro, Token* tok) { if (tok->kind != TokenKind_ident) return -1; @@ -150,6 +169,16 @@ static void add_user_defines(MacroArray* macros, StrArray* user_defines) { } } +void macros_build_json(JsonBuilder* builder, MacroArray* macros) { + jsonbuilder_array_start(builder); + for (size_t i = 0; i < macros->len; ++i) { + jsonbuilder_array_element_start(builder); + macro_build_json(builder, ¯os->data[i]); + jsonbuilder_array_element_end(builder); + } + jsonbuilder_array_end(builder); +} + typedef struct { TokenArray tokens; } MacroArg; @@ -215,13 +244,15 @@ typedef struct { int include_depth; StrArray include_paths; StrArray* included_files; + bool generate_system_deps; + bool generate_user_deps; } Preprocessor; static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files, - StrArray* user_include_dirs); + StrArray* user_include_dirs, bool generate_system_deps, bool generate_user_deps); static Preprocessor* preprocessor_new(TokenArray* pp_tokens, int include_depth, MacroArray* macros, - StrArray* included_files) { + StrArray* included_files, bool generate_system_deps, bool generate_user_deps) { if (include_depth >= 32) { fatal_error("include depth limit exceeded"); } @@ -232,6 +263,8 @@ static Preprocessor* preprocessor_new(TokenArray* pp_tokens, int include_depth, pp->include_depth = include_depth; strings_init(&pp->include_paths); pp->included_files = included_files; + pp->generate_system_deps = generate_system_deps; + pp->generate_user_deps = generate_user_deps; return pp; } @@ -416,8 +449,8 @@ static void expand_include_directive(Preprocessor* pp, const char* include_name, original_include_name_tok->loc.line, token_stringify(original_include_name_tok)); } - TokenArray* include_pp_tokens = - do_preprocess(include_source, pp->include_depth + 1, pp->macros, pp->included_files, NULL); + TokenArray* include_pp_tokens = do_preprocess(include_source, pp->include_depth + 1, pp->macros, pp->included_files, + NULL, pp->generate_system_deps, pp->generate_user_deps); tokens_pop(include_pp_tokens); // pop EOF token pp->pos = insert_pp_tokens(pp, pp->pos, include_pp_tokens); } @@ -599,7 +632,8 @@ static int expand_macro(Preprocessor* pp, bool skip_newline, MacroExpansionConte static void expand_macro_arg(Preprocessor* pp, MacroArg* arg, bool skip_newline, MacroExpansionContext* ctx) { tokens_push_new(&arg->tokens)->kind = TokenKind_eof; - Preprocessor* pp2 = preprocessor_new(&arg->tokens, pp->include_depth, pp->macros, pp->included_files); + Preprocessor* pp2 = preprocessor_new(&arg->tokens, pp->include_depth, pp->macros, pp->included_files, + pp->generate_system_deps, pp->generate_user_deps); size_t arg_token_count = arg->tokens.len; size_t processed_token_count = 0; @@ -1060,7 +1094,8 @@ static void preprocess_include_directive(Preprocessor* pp) { token_stringify(include_name)); } - if (include_name->value.string[0] == '"') { + if ((pp->generate_system_deps && include_name->value.string[0] == '<') || + (pp->generate_user_deps && include_name->value.string[0] == '"')) { bool already_included = false; for (size_t i = 0; i < pp->included_files->len; ++i) { if (strcmp(pp->included_files->data[i], include_name_resolved) == 0) { @@ -1372,9 +1407,10 @@ static char* get_ducc_include_path() { } static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files, - StrArray* user_include_dirs) { + StrArray* user_include_dirs, bool generate_system_deps, bool generate_user_deps) { TokenArray* pp_tokens = tokenize(src); - Preprocessor* pp = preprocessor_new(pp_tokens, depth, macros, included_files); + Preprocessor* pp = + preprocessor_new(pp_tokens, depth, macros, included_files, generate_system_deps, generate_user_deps); // Ducc's built-in headers has highest priority. add_include_path(pp, get_ducc_include_path()); @@ -1393,12 +1429,13 @@ static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, Str return pp->pp_tokens; } -TokenArray* preprocess(InFile* src, StrArray* included_files, StrArray* user_include_dirs, StrArray* user_defines) { +TokenArray* preprocess(InFile* src, StrArray* included_files, StrArray* user_include_dirs, StrArray* user_defines, + bool generate_system_deps, bool generate_user_deps) { MacroArray* macros = macros_new(); add_predefined_macros(macros); add_user_defines(macros, user_defines); strings_push(included_files, src->loc.filename); - return do_preprocess(src, 0, macros, included_files, user_include_dirs); + return do_preprocess(src, 0, macros, included_files, user_include_dirs, generate_system_deps, generate_user_deps); } void concat_adjacent_string_literals(TokenArray* pp_tokens) { diff --git a/src/preprocess.h b/src/preprocess.h index 0365a57..5f46b51 100644 --- a/src/preprocess.h +++ b/src/preprocess.h @@ -5,7 +5,8 @@ #include "io.h" #include "token.h" -TokenArray* preprocess(InFile* src, StrArray* included_files, StrArray* user_include_dirs, StrArray* user_defines); +TokenArray* preprocess(InFile* src, StrArray* included_files, StrArray* user_include_dirs, StrArray* user_defines, + bool generate_system_deps, bool generate_user_deps); void concat_adjacent_string_literals(TokenArray* pp_tokens); void print_token_to_file(FILE* output_file, TokenArray* pp_tokens); |
