diff --git a/Makefile b/Makefile index fdf4f8d1a..3e3971660 100644 --- a/Makefile +++ b/Makefile @@ -31,11 +31,11 @@ $(C2C): output/bootstrap/bootstrap $(C2C_DEPS) @rm -rf output/bootstrap/cgen @mv -f output/c2c/* output/bootstrap @echo "---- running c2c (no plugins$(C2FLAGS)) ----" - @output/bootstrap/c2c $(C2FLAGS) --noplugins --fast c2c $(PLUGINS) + @output/bootstrap/c2c $(C2FLAGS) --noplugins --fast --quiet c2c $(PLUGINS) @mv -f output/c2c/c2c output/c2c/c2c_fast @./install_plugins.sh @echo "---- running c2c (optimized with plugins$(C2FLAGS)) ----" - @output/c2c/c2c_fast $(C2FLAGS) + @output/c2c/c2c_fast $(C2FLAGS) --quiet @./install_plugins.sh output/bootstrap/bootstrap: @@ -48,43 +48,43 @@ ubsan:; @$(MAKE) -B UBSAN=1 debug:; @$(MAKE) -B DEBUG=1 output/tester/tester: tools/tester/*.c2 $(C2C_DEPS) $(C2C) - @$(C2C) tester + @$(C2C) tester --quiet test-bootstrap: $(C2C) - @$(C2C) c2c -o c2c_bootstrap --bootstrap + @$(C2C) c2c -o c2c_bootstrap --bootstrap --quiet rebuild-bootstrap: $(C2C) @echo "generating bootstrap files for various systems/architectures" - $(C2C) c2c -b bootstrap/build-linux-x86_64.yaml --no-build --bootstrap + $(C2C) c2c -b bootstrap/build-linux-x86_64.yaml --no-build --bootstrap --quiet mv -f output/linux-x86_64/c2c/cgen/build.c bootstrap/bootstrap.c - $(C2C) c2c -b bootstrap/build-darwin-x86_64.yaml --no-build --bootstrap + $(C2C) c2c -b bootstrap/build-darwin-x86_64.yaml --no-build --bootstrap --quiet ( diff bootstrap/bootstrap.c output/darwin-x86_64/c2c/cgen/build.c > bootstrap/bootstrap-darwin-x86_64.patch ; true ) - $(C2C) c2c -b bootstrap/build-darwin-arm64.yaml --no-build --bootstrap + $(C2C) c2c -b bootstrap/build-darwin-arm64.yaml --no-build --bootstrap --quiet ( diff bootstrap/bootstrap.c output/darwin-arm64/c2c/cgen/build.c > bootstrap/bootstrap-darwin-arm64.patch ; true ) - $(C2C) c2c -b bootstrap/build-freebsd-amd64.yaml --no-build --bootstrap + $(C2C) c2c -b bootstrap/build-freebsd-amd64.yaml --no-build --bootstrap --quiet ( diff bootstrap/bootstrap.c output/freebsd-amd64/c2c/cgen/build.c > bootstrap/bootstrap-freebsd-amd64.patch ; true ) - $(C2C) c2c -b bootstrap/build-openbsd-amd64.yaml --no-build --bootstrap + $(C2C) c2c -b bootstrap/build-openbsd-amd64.yaml --no-build --bootstrap --quiet ( diff bootstrap/bootstrap.c output/openbsd-amd64/c2c/cgen/build.c > bootstrap/bootstrap-openbsd-amd64.patch ; true ) test: output/tester/tester @echo "---- running tests ----" - @output/tester/tester -t test + @output/tester/tester -q test testv: output/tester/tester @echo "---- running verbose tests ----" @output/tester/tester -v test output/c2c_trace/c2c_trace: $(C2C_DEPS) - $(C2C) c2c --trace-calls -o c2c_trace --fast + $(C2C) c2c --trace-calls -o c2c_trace --fast --quiet trace_calls: $(C2C) output/c2c_trace/c2c_trace - C2_TRACE="min=10;min2=1;mode=3;name=*;fd=2" output/c2c_trace/c2c_trace c2c -o c2c_calls --test 2> output/c2c/calls + C2_TRACE="min=10;min2=1;mode=3;name=*;fd=2" output/c2c_trace/c2c_trace c2c -o c2c_calls --quiet --test 2> output/c2c/calls trace: trace_calls cat output/c2c/calls alloc_trace: $(C2C) output/c2c_trace/c2c_trace - C2_TRACE="min=10;min2=1;mode=3;name=stdlib.malloc,stdlib.calloc,stdlib.realloc;fd=2" output/c2c_trace/c2c_trace c2c -o c2c_alloc --test 2> output/c2c/calls + C2_TRACE="min=10;min2=1;mode=3;name=stdlib.malloc,stdlib.calloc,stdlib.realloc;fd=2" output/c2c_trace/c2c_trace --quiet c2c -o c2c_alloc --test 2> output/c2c/calls cat output/c2c/calls errors: diff --git a/common/console.c2 b/common/console.c2 index 37ce1df96..83b6eccde 100644 --- a/common/console.c2 +++ b/common/console.c2 @@ -20,33 +20,55 @@ import color local; import stdarg local; import stdio local; -bool use_color = false; -bool show_debug = false; -bool show_timing = false; +public type Config struct @(opaque) { + // TODO: add color customisation + bool use_color; + bool quiet_mode; + bool show_debug; + bool show_timing; +} + +Config config; const u32 BUF_SIZE = 4096; -public fn void init() { - use_color = color.useColor(); +public fn void init(const Config *c = nil) { + if (c) { + setConfig(c); + } else { + config.use_color = color.useColor(); + } +} + +public fn void setQuiet(bool enable) { + config.quiet_mode = enable; } public fn void setDebug(bool enable) { - show_debug = enable; + config.show_debug = enable; } public fn void setTiming(bool enable) { - show_timing = enable; + config.show_timing = enable; +} + +public fn Config* getConfig() { + return &config; +} + +public fn void setConfig(const Config* c) @(unused) { + config = *c; } public fn void debug(const char* format @(printf_format), ...) { - if (!show_debug) return; + if (!config.show_debug) return; char[BUF_SIZE] buf; va_list args; va_start(args, format); vsnprintf(buf, elemsof(buf), format, args); va_end(args); - if (use_color) { + if (config.use_color) { printf("%s%s%s\n", color.Blue.str(), buf, color.Normal.str()); } else { printf("%s\n", buf); @@ -54,6 +76,8 @@ public fn void debug(const char* format @(printf_format), ...) { } public fn void log(const char* format @(printf_format), ...) { + if (config.quiet_mode) return; + char[BUF_SIZE] buf; va_list args; va_start(args, format); @@ -68,7 +92,7 @@ public fn void warn(const char* format @(printf_format), ...) { va_start(args, format); vsnprintf(buf, elemsof(buf), format, args); va_end(args); - if (use_color) { + if (config.use_color) { fprintf(stderr, "%swarning: %s%s\n", color.Yellow.str(), buf, color.Normal.str()); } else { fprintf(stderr, "warning: %s\n", buf); @@ -81,7 +105,7 @@ public fn void error(const char* format @(printf_format), ...) { va_start(args, format); vsnprintf(buf, elemsof(buf), format, args); va_end(args); - if (use_color) { + if (config.use_color) { fprintf(stderr, "%serror: %s%s\n", color.Red.str(), buf, color.Normal.str()); } else { fprintf(stderr, "error: %s\n", buf); @@ -94,7 +118,7 @@ public fn void error_diag(const char* loc, const char* format @(printf_format), va_start(args, format); vsnprintf(buf, elemsof(buf), format, args); va_end(args); - if (use_color) { + if (config.use_color) { fprintf(stderr, "%s%s: error: %s%s\n", color.Red.str(), loc, buf, color.Normal.str()); } else { fprintf(stderr, "%s: error: %s\n", loc, buf); @@ -102,8 +126,9 @@ public fn void error_diag(const char* loc, const char* format @(printf_format), } public fn void log_time(const char* item, u64 duration) { - if (!show_timing) return; - if (use_color) { + if (!config.show_timing) return; + + if (config.use_color) { printf("%s%s took %d usec%s\n", color.Blue.str(), item, duration, color.Normal.str()); } else { printf("%s took %d usec\n", item, duration); diff --git a/compiler/main.c2 b/compiler/main.c2 index f252123f5..efdc20260 100644 --- a/compiler/main.c2 +++ b/compiler/main.c2 @@ -48,6 +48,7 @@ type Options struct { bool print_timing; bool show_targets; bool show_plugins; + bool quiet_mode; bool no_plugins; bool use_ir_backend; bool trace_calls; @@ -213,6 +214,7 @@ const char[] Usage_help = " --showplugins print available plugins\n" " --target [triple] cross compile for a specified architecture\n" " --targets show available targets in recipe\n" + " -q --quiet prevent compiler logging messages\n" " --test test mode (do not check for main() function)\n" " --trace-calls generate code that traces function calls\n" " --version print version\n"; @@ -288,6 +290,9 @@ fn void parse_long_opt(ArgumentParser *ap, const char* arg, compiler.Options* co case "noplugins": opts.no_plugins = true; break; + case "quiet": + opts.quiet_mode = true; + break; case "showlibs": comp_opts.show_libs = true; break; @@ -386,6 +391,9 @@ fn void parse_arguments(ArgumentParser *ap, compiler.Options* comp_opts, Options case 'o': opts.output_name = argarg; break; + case 'q': + opts.quiet_mode = true; + break; case 'r': comp_opts.print_reports += 1; break; @@ -485,6 +493,7 @@ fn void Context.handle_args(Context* c, i32 argc, char** argv) { console.setTiming(c.opts.print_timing); console.setDebug(c.opts.log_verbose); + console.setQuiet(c.opts.quiet_mode); const char[] notFound = "c2c: error: cannot find project root directory\n" " c2c requires a %s file in the project root,\n" @@ -547,7 +556,7 @@ fn void Context.handle_args(Context* c, i32 argc, char** argv) { auto_found_buildfile = true; } - c.plugins = plugin_mgr.create(c.auxPool, c.opts.print_timing, c.opts.log_verbose, c.opts.no_plugins); + c.plugins = plugin_mgr.create(c.auxPool, console.getConfig(), c.opts.no_plugins); bool have_plugin_dir = false; if (c.opts.build_file) { diff --git a/compiler/plugin_mgr.c2 b/compiler/plugin_mgr.c2 index 817de80bf..e5b98a949 100644 --- a/compiler/plugin_mgr.c2 +++ b/compiler/plugin_mgr.c2 @@ -46,8 +46,7 @@ type Plugin struct { public type Mgr struct @(opaque) { string_pool.Pool* auxPool; - bool console_timing; - bool console_debug; + console.Config* console_config; bool no_plugins; Plugin* plugins; @@ -58,11 +57,10 @@ public type Mgr struct @(opaque) { char[256] error_msg; } -public fn Mgr* create(string_pool.Pool* auxPool, bool console_timing, bool console_debug, bool no_plugins) { +public fn Mgr* create(string_pool.Pool* auxPool, console.Config* console_config, bool no_plugins) { Mgr* m = stdlib.calloc(1, sizeof(Mgr)); m.auxPool = auxPool; - m.console_timing = console_timing; - m.console_debug = console_debug; + m.console_config = console_config; m.no_plugins = no_plugins; m.paths.init(auxPool); return m; @@ -170,7 +168,7 @@ fn bool Mgr.loadPlugin(Mgr* m, u32 name, u32 options, bool is_global) { } p.functions = handle_symbol; console.debug("plugins: loading %s", fullname); - p.arg = p.functions.load(m.auxPool.idx2str(options), m.console_timing, m.console_debug); + p.arg = p.functions.load(m.auxPool.idx2str(options), m.console_config); if (!p.arg) { dlclose(p.handle); stdio.snprintf(m.error_msg, elemsof(m.error_msg), "plugin %s failed to load", fullname); diff --git a/examples/Makefile b/examples/Makefile index b0a3e5db0..58d45d1f5 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,6 @@ all: - c2c + @echo "---- building examples ----" + @../output/c2c/c2c --quiet errors: @( grep -n 'error:' `find . -name build.log` | sed -E 's/build.log:[0-9]+://' ; true ) diff --git a/install_plugins.sh b/install_plugins.sh index afd814de7..83630959d 100755 --- a/install_plugins.sh +++ b/install_plugins.sh @@ -1,6 +1,6 @@ #!/bin/sh -echo "Installing C2C plugins in $C2_PLUGINDIR" +echo "---- installing c2c plugins in $C2_PLUGINDIR" if [ $(uname -s) = 'Darwin' ] ; then LIB_EXT='.dylib' diff --git a/plugins/deps_generator_plugin.c2 b/plugins/deps_generator_plugin.c2 index b04eb2f82..de5028313 100644 --- a/plugins/deps_generator_plugin.c2 +++ b/plugins/deps_generator_plugin.c2 @@ -36,11 +36,9 @@ type Plugin struct { plugin_info.Info* info; } -fn void* load(const char* options, bool show_timing, bool show_debug) { +fn void* load(const char* options, console.Config* config) { Plugin* p = calloc(1, sizeof(Plugin)); - console.init(); - console.setTiming(show_timing); - console.setDebug(show_debug); + console.init(config); // TODO handle options return p; } diff --git a/plugins/git_version_plugin.c2 b/plugins/git_version_plugin.c2 index 039dc3278..ff572f8d9 100644 --- a/plugins/git_version_plugin.c2 +++ b/plugins/git_version_plugin.c2 @@ -38,11 +38,9 @@ type Plugin struct { char[128] version; } -fn void* load(const char* options, bool show_timing, bool show_debug) { +fn void* load(const char* options, console.Config* config) { Plugin* p = calloc(1, sizeof(Plugin)); - console.init(); - console.setTiming(show_timing); - console.setDebug(show_debug); + console.init(config); // TODO handle options strcpy(p.version, "unknown"); diff --git a/plugins/plugin_info.c2 b/plugins/plugin_info.c2 index 627952a4c..81a797f04 100644 --- a/plugins/plugin_info.c2 +++ b/plugins/plugin_info.c2 @@ -20,6 +20,7 @@ import ast_builder; import ast_context; import build_target; import component; +import console; import diagnostics; import file_utils; import source_mgr; @@ -67,7 +68,7 @@ public fn bool Info.registerAttr(Info* info, post analysis generate files outside project (refs, deps) */ public type Plugin struct @(unused) { - fn void*(const char* options, bool console_timing, bool console_debug) load; + fn void*(const char* options, console.Config* config) load; fn void(void* arg) unload; fn void(void* arg, plugin_info.Info* info) init; fn void(void* arg) post_parse; diff --git a/plugins/refs_generator_plugin.c2 b/plugins/refs_generator_plugin.c2 index fbc9e19bf..b9e05dcf4 100644 --- a/plugins/refs_generator_plugin.c2 +++ b/plugins/refs_generator_plugin.c2 @@ -37,11 +37,9 @@ type Plugin struct { plugin_info.Info* info; } -fn void* load(const char* options, bool show_timing, bool show_debug) { +fn void* load(const char* options, console.Config* config) { Plugin* p = calloc(1, sizeof(Plugin)); - console.init(); - console.setTiming(show_timing); - console.setDebug(show_debug); + console.init(config); // TODO handle options return p; } diff --git a/plugins/shell_cmd_plugin.c2 b/plugins/shell_cmd_plugin.c2 index 5380dcb27..a8b9e3b5b 100644 --- a/plugins/shell_cmd_plugin.c2 +++ b/plugins/shell_cmd_plugin.c2 @@ -50,11 +50,9 @@ type Plugin struct { const char* config_file; // no ownership } -fn void* load(const char* options, bool show_timing, bool show_debug) { +fn void* load(const char* options, console.Config* config) { Plugin* p = calloc(1, sizeof(Plugin)); - console.init(); - console.setTiming(show_timing); - console.setDebug(show_debug); + console.init(config); assert(options); p.config_file = options; // options should point to a YAML file diff --git a/plugins/unit_test_plugin.c2 b/plugins/unit_test_plugin.c2 index 9037b50cb..3a214ce95 100644 --- a/plugins/unit_test_plugin.c2 +++ b/plugins/unit_test_plugin.c2 @@ -47,14 +47,12 @@ type Plugin struct { bool teardown; } -fn void* load(const char* options, bool show_timing, bool show_debug) { +fn void* load(const char* options, console.Config* config) { Plugin* p = calloc(1, sizeof(Plugin)); p.decls.init(); p.tests.init(); - console.init(); - console.setTiming(show_timing); - console.setDebug(show_debug); + console.init(config); return p; } diff --git a/tools/tester/tester.c2 b/tools/tester/tester.c2 index 3ecc4a586..f87a75054 100644 --- a/tools/tester/tester.c2 +++ b/tools/tester/tester.c2 @@ -288,8 +288,8 @@ fn void usage(const char* name) { printf("Usage: %s target ...\n", name); printf(" -j[#] use multi-threading (optional # of threads)\n"); printf(" -n no multi-threading\n"); + printf(" -q quiet mode, only errors shown\n"); printf(" -s only run skipped tests\n"); - printf(" -t terse output, only errors shown\n"); printf(" -v verbose output\n"); printf(" targets can be single files or full directories\n"); exit(EXIT_FAILURE); @@ -320,7 +320,7 @@ public fn i32 main(i32 argc, char** argv) { case "-s": runSkipped = true; break; - case "-t": + case "-q": verboseLevel -= 1; break; case "-v":