From 9a95049393ea98ef6222bf217ab44dd127c3f960 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 22 Jan 2024 17:21:52 +0100 Subject: -show-defineables and -export-defineables --- src/check_builtin.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/check_builtin.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 7e3bcb7ee..b2afa3d0c 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1777,7 +1777,7 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o } String name = arg->Ident.token.string; - + operand->type = def.type; operand->mode = def.mode; @@ -1793,6 +1793,15 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o operand->value = found->Constant.value; } } + + Defineable defineable = {}; + defineable.name = name; + defineable.default_value = def.value; + defineable.pos = arg->Ident.token.pos; + + MUTEX_GUARD(&c->info->defineables_mutex); + array_add(&c->info->defineables, defineable); + } else { error(call, "Unknown directive call: #%.*s", LIT(name)); } -- cgit v1.2.3 From b818a7713175d882a7f8b345cee59bd19b0d1d47 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Thu, 25 Jan 2024 02:16:30 +0100 Subject: check if -define is actually used --- src/check_builtin.cpp | 15 +++++++++++++-- src/checker.hpp | 1 + src/main.cpp | 33 ++++++++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 7 deletions(-) (limited to 'src/check_builtin.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index b2afa3d0c..a74082fb2 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1756,6 +1756,17 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o operand->mode = Addressing_Constant; operand->value = exact_value_bool(is_defined); + // If the arg is a selector expression we don't add it, `-define` only allows identifiers. + if (arg->kind == Ast_Ident) { + Defineable defineable = {}; + defineable.name = arg->Ident.token.string; + defineable.default_value = exact_value_bool(false); + defineable.pos = arg->Ident.token.pos; + + MUTEX_GUARD(&c->info->defineables_mutex); + array_add(&c->info->defineables, defineable); + } + } else if (name == "config") { if (ce->args.count != 2) { error(call, "'#config' expects 2 argument, got %td", ce->args.count); @@ -1777,7 +1788,7 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o } String name = arg->Ident.token.string; - + operand->type = def.type; operand->mode = def.mode; @@ -1794,7 +1805,7 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o } } - Defineable defineable = {}; + Defineable defineable = {}; defineable.name = name; defineable.default_value = def.value; defineable.pos = arg->Ident.token.pos; diff --git a/src/checker.hpp b/src/checker.hpp index fc37f5769..9db5757e3 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -381,6 +381,7 @@ struct Defineable { ExactValue default_value; TokenPos pos; + // These strings are only computed from previous fields when defineables are being shown or exported. String default_value_str; String pos_str; }; diff --git a/src/main.cpp b/src/main.cpp index a3e87fb6a..eac1b7ed9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -822,9 +822,9 @@ gb_internal bool parse_build_flags(Array args) { } case BuildFlag_ShowDefineables: { GB_ASSERT(value.kind == ExactValue_Invalid); - build_context.show_defineables = true; - break; - } + build_context.show_defineables = true; + break; + } case BuildFlag_ExportDefineables: { GB_ASSERT(value.kind == ExactValue_String); @@ -1577,6 +1577,28 @@ gb_internal void timings_export_all(Timings *t, Checker *c, bool timings_are_fin gb_printf("Done.\n"); } +gb_internal void check_defines(BuildContext *bc, Checker *c) { + for (auto const &entry : bc->defined_values) { + String name = make_string_c(entry.key); + ExactValue value = entry.value; + GB_ASSERT(value.kind != ExactValue_Invalid); + + bool found = false; + for_array(i, c->info.defineables) { + Defineable *def = &c->info.defineables[i]; + if (def->name == name) { + found = true; + break; + } + } + + if (!found) { + warning(nullptr, "given -define:%s is unused in the project", name); + error_line("\tSuggestion: use the -show-defineables flag for an overview of the possible defines\n"); + } + } +} + gb_internal void temp_alloc_defineable_strings(Checker *c) { for_array(i, c->info.defineables) { Defineable *def = &c->info.defineables[i]; @@ -2059,11 +2081,11 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(0, ""); print_usage_line(1, "-show-defineables"); - print_usage_line(2, "Shows an overview of all the #config usages in the project."); + print_usage_line(2, "Shows an overview of all the #config/#defined usages in the project."); print_usage_line(0, ""); print_usage_line(1, "-export-defineables:"); - print_usage_line(2, "Exports an overview of all the #config usages in CSV format to the given file path."); + print_usage_line(2, "Exports an overview of all the #config/#defined usages in CSV format to the given file path."); print_usage_line(2, "Example: -export-defineables:defineables.csv"); print_usage_line(0, ""); } @@ -3063,6 +3085,7 @@ int main(int arg_count, char const **arg_ptr) { defer (destroy_checker(checker)); check_parsed_files(checker); + check_defines(&build_context, checker); if (any_errors()) { print_all_errors(); return 1; -- cgit v1.2.3 From 315695b4f8b3437fb63cfc99c976b76be4cee173 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Fri, 7 Jun 2024 14:48:11 +0200 Subject: collect and show docs of defineables --- src/check_builtin.cpp | 8 ++++++- src/checker.hpp | 7 +++--- src/main.cpp | 62 ++++++++++++++++++++++++++++----------------------- 3 files changed, 45 insertions(+), 32 deletions(-) (limited to 'src/check_builtin.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index a74082fb2..54708b5ae 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1759,6 +1759,7 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o // If the arg is a selector expression we don't add it, `-define` only allows identifiers. if (arg->kind == Ast_Ident) { Defineable defineable = {}; + defineable.docs = nullptr; defineable.name = arg->Ident.token.string; defineable.default_value = exact_value_bool(false); defineable.pos = arg->Ident.token.pos; @@ -1769,7 +1770,7 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o } else if (name == "config") { if (ce->args.count != 2) { - error(call, "'#config' expects 2 argument, got %td", ce->args.count); + error(call, "'#config' expects 2 arguments, got %td", ce->args.count); return false; } Ast *arg = unparen_expr(ce->args[0]); @@ -1806,10 +1807,15 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o } Defineable defineable = {}; + defineable.docs = nullptr; defineable.name = name; defineable.default_value = def.value; defineable.pos = arg->Ident.token.pos; + if (c->decl) { + defineable.docs = c->decl->docs; + } + MUTEX_GUARD(&c->info->defineables_mutex); array_add(&c->info->defineables, defineable); diff --git a/src/checker.hpp b/src/checker.hpp index 9db5757e3..1a8cef29a 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -377,9 +377,10 @@ struct GenTypesData { }; struct Defineable { - String name; - ExactValue default_value; - TokenPos pos; + String name; + ExactValue default_value; + TokenPos pos; + CommentGroup *docs; // These strings are only computed from previous fields when defineables are being shown or exported. String default_value_str; diff --git a/src/main.cpp b/src/main.cpp index 793030f3f..530681d03 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1593,7 +1593,8 @@ gb_internal void check_defines(BuildContext *bc, Checker *c) { } if (!found) { - warning(nullptr, "given -define:%s is unused in the project", name); + ERROR_BLOCK(); + warning(nullptr, "given -define:%.*s is unused in the project", LIT(name)); error_line("\tSuggestion: use the -show-defineables flag for an overview of the possible defines\n"); } } @@ -1639,44 +1640,49 @@ gb_internal void export_defineables(Checker *c, String path) { } defer (gb_file_close(&f)); - gb_fprintf(&f, "Defineable,Default Value,Location\n"); + gbString docs = gb_string_make(heap_allocator(), ""); + defer (gb_string_free(docs)); + + gb_fprintf(&f, "Defineable,Default Value,Docs,Location\n"); for_array(i, c->info.defineables) { Defineable *def = &c->info.defineables[i]; - gb_fprintf(&f,"%.*s,%.*s,%.*s\n", LIT(def->name), LIT(def->default_value_str), LIT(def->pos_str)); + + gb_string_clear(docs); + if (def->docs) { + docs = gb_string_appendc(docs, "\""); + for (Token const &token : def->docs->list) { + for (isize i = 0; i < token.string.len; i++) { + u8 c = token.string.text[i]; + if (c == '"') { + docs = gb_string_appendc(docs, "\"\""); + } else { + docs = gb_string_append_length(docs, &c, 1); + } + } + } + docs = gb_string_appendc(docs, "\""); + } + + gb_fprintf(&f,"%.*s,%.*s,%s,%.*s\n", LIT(def->name), LIT(def->default_value_str), docs, LIT(def->pos_str)); } } gb_internal void show_defineables(Checker *c) { - isize max_name_len = gb_strlen("Defineable"); - isize max_default_len = gb_strlen("Default Value"); - isize max_pos_len = gb_strlen("Location"); - for_array(i, c->info.defineables) { Defineable *def = &c->info.defineables[i]; - if (def->name.len > max_name_len) { - max_name_len = def->name.len; + if (has_ansi_terminal_colours()) { + gb_printf("\x1b[0;90m"); } - - if (def->default_value_str.len > max_default_len) { - max_default_len = def->default_value_str.len; + printf("%.*s\n", LIT(def->pos_str)); + if (def->docs) { + for (Token const &token : def->docs->list) { + gb_printf("%.*s\n", LIT(token.string)); + } } - - if (def->pos_str.len > max_pos_len) { - max_pos_len = def->pos_str.len; + if (has_ansi_terminal_colours()) { + gb_printf("\x1b[0m"); } - } - - printf("%-*s - %-*s - %-*s\n", - cast(int)max_name_len, "Defineable", - cast(int)max_default_len, "Default Value", - cast(int)max_pos_len, "Location"); - - for_array(i, c->info.defineables) { - Defineable *def = &c->info.defineables[i]; - printf("%-*.*s - %-*.*s - %-*.*s\n", - cast(int)max_name_len, LIT(def->name), - cast(int)max_default_len, LIT(def->default_value_str), - cast(int)max_pos_len, LIT(def->pos_str)); + gb_printf("%.*s :: %.*s\n\n", LIT(def->name), LIT(def->default_value_str)); } } -- cgit v1.2.3