From 81e3b64ecda857458b8e0762bdf6156cdaa1cb74 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 8 Sep 2022 16:35:25 +0100 Subject: [PATCH] Add `ODIN_BUILD_PROJECT_NAME` and `//+build-project-name` This allows for condition inclusion of files, similar to `+build` or `ODIN_BUILD`, but relies on the directory name of the project to be the same as specified Example: odin build foo/bar/baz ODIN_BUILD_PROJECT_NAME == "baz" //+build_project_name baz --- src/build_settings.cpp | 7 ++++++ src/checker.cpp | 1 + src/parser.cpp | 51 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 998c40208..b877b8cb7 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -225,6 +225,7 @@ struct BuildContext { String ODIN_VENDOR; // compiler vendor String ODIN_VERSION; // compiler version String ODIN_ROOT; // Odin ROOT + String ODIN_BUILD_PROJECT_NAME; // Odin main/initial package's directory name bool ODIN_DEBUG; // Odin in debug mode bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) @@ -1537,6 +1538,12 @@ bool init_build_paths(String init_filename) { enable_target_feature({}, bc->target_features_string); } + { + String build_project_name = last_path_element(bc->build_paths[BuildPath_Main_Package].basename); + GB_ASSERT(build_project_name.len > 0); + bc->ODIN_BUILD_PROJECT_NAME = build_project_name; + } + return true; } diff --git a/src/checker.cpp b/src/checker.cpp index a7470a4c9..16e480786 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -938,6 +938,7 @@ void init_universal(void) { add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); + add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME); { GlobalEnumValue values[TargetOs_COUNT] = { diff --git a/src/parser.cpp b/src/parser.cpp index 9a5531289..70a87d2a5 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5506,6 +5506,51 @@ isize calc_decl_count(Ast *decl) { return count; } +bool parse_build_project_directory_tag(Token token_for_pos, String s) { + String const prefix = str_lit("+build-project-name"); + GB_ASSERT(string_starts_with(s, prefix)); + s = string_trim_whitespace(substring(s, prefix.len, s.len)); + if (s.len == 0) { + return true; + } + + bool any_correct = false; + + while (s.len > 0) { + bool this_kind_correct = true; + + do { + String p = string_trim_whitespace(build_tag_get_token(s, &s)); + if (p.len == 0) break; + if (p == ",") break; + + bool is_notted = false; + if (p[0] == '!') { + is_notted = true; + p = substring(p, 1, p.len); + if (p.len == 0) { + syntax_error(token_for_pos, "Expected a build-project-name after '!'"); + break; + } + } + + if (p.len == 0) { + continue; + } + + if (is_notted) { + this_kind_correct = this_kind_correct && (p != build_context.ODIN_BUILD_PROJECT_NAME); + } else { + this_kind_correct = this_kind_correct && (p == build_context.ODIN_BUILD_PROJECT_NAME); + } + } while (s.len > 0); + + any_correct = any_correct || this_kind_correct; + } + + return any_correct; +} + bool parse_file(Parser *p, AstFile *f) { if (f->tokens.count == 0) { return true; @@ -5561,7 +5606,11 @@ bool parse_file(Parser *p, AstFile *f) { if (string_starts_with(str, str_lit("//"))) { String lc = string_trim_whitespace(substring(str, 2, str.len)); if (lc.len > 0 && lc[0] == '+') { - if (string_starts_with(lc, str_lit("+build"))) { + if (string_starts_with(lc, str_lit("+build-project-name"))) { + if (!parse_build_project_directory_tag(tok, lc)) { + return false; + } + } else if (string_starts_with(lc, str_lit("+build"))) { if (!parse_build_tag(tok, lc)) { return false; }