From 4636eeb4bf93b260e5c5cbecfb18c8c9b2a6976d Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 17 May 2025 16:31:37 -0400 Subject: Add --version flag for executables and more documentation. --- src/compile.c | 5 +++-- src/compile.h | 2 +- src/stdlib/stdlib.c | 12 ++++++++---- src/stdlib/stdlib.h | 6 +++--- src/tomo.c | 33 +++++++++++---------------------- 5 files changed, 26 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/compile.c b/src/compile.c index 410ee364..cd6aef72 100644 --- a/src/compile.c +++ b/src/compile.c @@ -4015,7 +4015,7 @@ static CORD get_flag_options(type_t *t, CORD separator) } } -CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type) +CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type, const char *version) { DeclareMatch(fn_info, fn_type, FunctionType); @@ -4084,7 +4084,8 @@ CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type) code = CORD_all(code, ";\n"); } - code = CORD_all(code, "tomo_parse_args(argc, argv, ", usage_code, ", ", help_code); + CORD version_code = CORD_quoted(version); + code = CORD_all(code, "tomo_parse_args(argc, argv, ", usage_code, ", ", help_code, ", ", version_code); for (arg_t *arg = fn_info->args; arg; arg = arg->next) { code = CORD_all(code, ",\n{", CORD_quoted(CORD_replace(arg->name, "_", "-")), ", ", (arg->default_val || arg->type->tag == OptionalType) ? "false" : "true", ", ", diff --git a/src/compile.h b/src/compile.h index ae9e510b..f4452288 100644 --- a/src/compile.h +++ b/src/compile.h @@ -20,6 +20,6 @@ CORD compile_statement(env_t *env, ast_t *ast); CORD compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast); CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *ast); CORD compile_type_info(type_t *t); -CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type); +CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type, const char *version); // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c index 6a855c66..6dfc735b 100644 --- a/src/stdlib/stdlib.c +++ b/src/stdlib/stdlib.c @@ -232,7 +232,7 @@ static Table_t parse_table(const TypeInfo_t *table, int n, char *args[]) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstack-protector" #endif -public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, int spec_len, cli_arg_t spec[spec_len]) +public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, const char *version, int spec_len, cli_arg_t spec[spec_len]) { bool populated_args[spec_len]; bool used_args[argc]; @@ -310,7 +310,11 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, } if (streq(argv[i], "--help")) { - say(help, true); + print(help); + exit(0); + } + if (streq(argv[i], "--version")) { + print(version); exit(0); } print_err("Unrecognized argument: ", argv[i], "\n", usage); @@ -361,7 +365,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, } if (*f == 'h') { - say(help, true); + print(help); exit(0); } print_err("Unrecognized flag: ", flag, "\n", usage); @@ -554,7 +558,7 @@ public void say(Text_t text, bool newline) public _Noreturn void tomo_exit(Text_t text, int32_t status) { if (text.length > 0) - say(text, true); + print(text); _exit(status); } diff --git a/src/stdlib/stdlib.h b/src/stdlib/stdlib.h index 04c504fe..2dd3c5b7 100644 --- a/src/stdlib/stdlib.h +++ b/src/stdlib/stdlib.h @@ -25,9 +25,9 @@ typedef struct { } cli_arg_t; void tomo_init(void); -void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, int spec_len, cli_arg_t spec[spec_len]); -#define tomo_parse_args(argc, argv, usage, help, ...) \ - _tomo_parse_args(argc, argv, usage, help, sizeof((cli_arg_t[]){__VA_ARGS__})/sizeof(cli_arg_t), (cli_arg_t[]){__VA_ARGS__}) +void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, const char *version, int spec_len, cli_arg_t spec[spec_len]); +#define tomo_parse_args(argc, argv, usage, help, version, ...) \ + _tomo_parse_args(argc, argv, usage, help, version, sizeof((cli_arg_t[]){__VA_ARGS__})/sizeof(cli_arg_t), (cli_arg_t[]){__VA_ARGS__}) #define fail(...) ({ \ fflush(stdout); \ diff --git a/src/tomo.c b/src/tomo.c index 3fcd0ade..24a407a4 100644 --- a/src/tomo.c +++ b/src/tomo.c @@ -62,7 +62,6 @@ static OptionalList_t files = NONE_LIST, uninstall = NONE_LIST, libraries = NONE_LIST; static OptionalBool_t verbose = false, - show_version = false, quiet = false, show_parse_tree = false, stop_at_transpile = false, @@ -183,12 +182,11 @@ int main(int argc, char *argv[]) ); Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage); tomo_parse_args( - argc, argv, usage, help, + argc, argv, usage, help, TOMO_VERSION, {"files", true, List$info(&Path$info), &files}, {"args", true, List$info(&Text$info), &args}, {"verbose", false, &Bool$info, &verbose}, {"v", false, &Bool$info, &verbose}, - {"version", false, &Bool$info, &show_version}, {"parse", false, &Bool$info, &show_parse_tree}, {"p", false, &Bool$info, &show_parse_tree}, {"quiet", false, &Bool$info, &quiet}, @@ -215,14 +213,6 @@ int main(int argc, char *argv[]) {"m", false, &Bool$info, &source_mapping}, ); - if (show_version) { - if (verbose) - print("Tomo version: ", TOMO_VERSION, " (", GIT_VERSION, ")"); - else - print("Tomo version: ", TOMO_VERSION); - return 0; - } - bool is_gcc = (system(String(cc, " -v 2>&1 | grep -q 'gcc version'")) == 0); if (is_gcc) { cflags = Texts(cflags, Text(" -fsanitize=signed-integer-overflow -fno-sanitize-recover" @@ -371,25 +361,23 @@ Path_t build_file(Path_t path, const char *extension) return Path$child(build_dir, Texts(Path$base_name(path), Text$from_str(extension))); } -static Text_t get_version_suffix(Path_t lib_dir) +static const char *get_version(Path_t lib_dir) { Path_t changes_file = Path$child(lib_dir, Text("CHANGES.md")); OptionalText_t changes = Path$read(changes_file); if (changes.length <= 0) { - print_err("I couldn't find a valid CHANGES.md for the library in ", lib_dir, "\n" - "In order to install a library, it has to have a version defined in CHANGES.md\n" - "\n" - "Example CHANGES.md:\n" - "\n" - "# Version History\n" - "## v0.1\n" - "First version"); + return "v0.0"; } const char *changes_str = Text$as_c_string(Texts(Text("\n"), changes)); const char *version_line = strstr(changes_str, "\n## "); if (version_line == NULL) print_err("CHANGES.md in ", lib_dir, " does not have any valid versions starting with '## '"); - return Texts(Text("_"), Text$from_strn(version_line + 4, strcspn(version_line + 4, "\r\n"))); + return String(string_slice(version_line + 4, strcspn(version_line + 4, "\r\n"))); +} + +static Text_t get_version_suffix(Path_t lib_dir) +{ + return Texts(Text("_"), Text$from_str(get_version(lib_dir))); } void build_library(Path_t lib_dir) @@ -721,6 +709,7 @@ void transpile_code(env_t *base_env, Path_t path) CORD_put(c_code, c_file); + const char *version = get_version(Path$parent(path)); binding_t *main_binding = get_binding(module_env, "main"); if (main_binding && main_binding->type->tag == FunctionType) { type_t *ret = Match(main_binding->type, FunctionType)->ret; @@ -735,7 +724,7 @@ void transpile_code(env_t *base_env, Path_t path) "tomo_init();\n", namespace_name(module_env, module_env->namespace, "$initialize"), "();\n" "\n", - compile_cli_arg_call(module_env, main_binding->code, main_binding->type), + compile_cli_arg_call(module_env, main_binding->code, main_binding->type, version), "return 0;\n" "}\n"), c_file); } -- cgit v1.2.3