aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-01-14 23:15:45 +0900
committernsfisis <nsfisis@gmail.com>2026-01-17 00:27:28 +0900
commit98fb9ed53b6f6c7b792a751ed1f448af5c680877 (patch)
treec7f1ea9976ee8e9126e936c551622ce95bb8a6b1
parentf0351da192b8f32bdf9323b3796521cbc390c749 (diff)
downloadducc-98fb9ed53b6f6c7b792a751ed1f448af5c680877.tar.gz
ducc-98fb9ed53b6f6c7b792a751ed1f448af5c680877.tar.zst
ducc-98fb9ed53b6f6c7b792a751ed1f448af5c680877.zip
feat: support -MD flag
-rw-r--r--src/cli.c6
-rw-r--r--src/cli.h3
-rw-r--r--src/main.c6
-rw-r--r--src/preprocess.c57
-rw-r--r--src/preprocess.h3
5 files changed, 60 insertions, 15 deletions
diff --git a/src/cli.c b/src/cli.c
index 17bfdc6..b14bf08 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -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;
diff --git a/src/cli.h b/src/cli.h
index 6758323..f4a610a 100644
--- a/src/cli.h
+++ b/src/cli.h
@@ -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;
diff --git a/src/main.c b/src/main.c
index 54fe87a..51e2200 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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, &macro->parameters);
+ jsonbuilder_object_member_end(builder);
+ jsonbuilder_object_member_start(builder, "replacements");
+ tokens_build_json(builder, &macro->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, &macros->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);