Author | Jakob Wakeling <[email protected]> |
Date | 2022-05-07 04:17:55 |
Commit | 12630d46f80fa6ee292736da348bb8d1afdb2f7d |
Parent | 163d55f61c21e198d889f0e7c12dfb0f65f21968 |
Add warning level configuration
Diffstat
M | src/log.c | | | 24 | ++++++++++++++++++++---- |
M | src/log.h | | | 5 | ++++- |
M | src/main.c | | | 27 | ++++++++++++++++++++++++++- |
3 files changed, 50 insertions, 6 deletions
diff --git a/src/log.c b/src/log.c index 4b16278..059a378 100644 --- a/src/log.c +++ b/src/log.c @@ -1,17 +1,32 @@ // log.c // Log source file for G -// Copyright (C) 2021, Jakob Wakeling +// Copyright (C) 2022, Jakob Wakeling // All rights reserved. #include "log.h" +#include "util/error.h" #include "util/util.h" #include <stdarg.h> #include <stdio.h> +#include <stdlib.h> -/* Log a compiler note (0), warning (1), or error (2). */ -void note(const char *file, UINT ln, UINT cl, u32 level, const char *format, ...) { - fprintf(stderr, "%s:%zu:%zu: ", file, ln + 1, cl + 1); - fprintf(stderr, "%s", level == 0 ? "note: " : level == 1 ? "warning: " : "error: "); +bool log_waerr = false; +sint log_level = 4, log_limit = 8; + +static sint log_count = 0; + +/* Log a compiler fatal (-1), error (0), warning (1-3), or note (4). */ +void note(const char *file, UINT ln, UINT cl, sint level, const char *format, ...) { + if (file) { fprintf(stderr, "%s:%zu:%zu: ", file, ln + 1, cl + 1); } + + if (level <= -1) { fprintf(stderr, "fatal: "); } + else if (level == 0) { fprintf(stderr, "error: "); } + else if (level <= 3) { fprintf(stderr, "warning: "); } + else if (level >= 4) { fprintf(stderr, "note: "); } + va_list va; va_start(va, format); vfprintf(stderr, format, va); va_end(va); + fputc('\n', stderr); if (level == -1) { exit(1); } + + if (level == 0 && (log_count += 1) == log_limit) { error(1, "fatal: error limit reached"); } } diff --git a/src/log.h b/src/log.h index 38e82cd..e469f35 100644 --- a/src/log.h +++ b/src/log.h @@ -8,6 +8,9 @@ #include "util/util.h" -extern void note(const char *file, UINT ln, UINT cl, u32 level, const char *format, ...); +extern bool log_waerr; +extern sint log_level, log_limit; + +extern void note(const char *file, UINT ln, UINT cl, sint level, const char *format, ...); #endif // G_LOG_H_1RPM5P9E diff --git a/src/main.c b/src/main.c index cc2e7c4..42e698c 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #include "analyse.h" #include "init.h" #include "llvm.h" +#include "log.h" #include "parse.h" #include "util/error.h" #include "util/optget.h" @@ -32,6 +33,10 @@ static bool Eflag = false, pflag = false, Pflag = false; static void compile(const char *file, char *src, UINT len); static void compile_file(const char *file); +static void opt_f(const char *arg); +static void opt_O(const char *arg); +static void opt_W(const char *arg); + static void hlp(void); static void ver(void); @@ -39,14 +44,17 @@ int main(int ac, char *av[]) { A0 = av[0]; /* DEBUG */ if (ac == 1) { ac = (sizeof (aw) / sizeof (*aw)) - 1; av = aw; } - struct opt opt = OPTGET_INIT; opt.str = "bBcEpP"; opt.lops = lops; + struct opt opt = OPTGET_INIT; opt.str = "bBcEf:O:pPW:"; opt.lops = lops; for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) { case 'b': { bflag = true; } break; /* Output LLVM IR files */ case 'B': { Bflag = true; } break; /* Output LLVM bitcode files */ case 'c': { cflag = true; } break; /* Output object files */ case 'E': { Eflag = true; } break; /* Output lexer tokens */ + case 'f': { opt_f(opt.arg); } break; /* Configure formatting */ + case 'O': { opt_O(opt.arg); } break; /* Configure optimisation */ case 'p': { pflag = true; } break; /* Output parser AST */ case 'P': { Pflag = true; } break; /* Output analyser AST */ + case 'W': { opt_W(opt.arg); } break; /* Configure warnings and errors */ case 256: { hlp(); } return 0; case 257: { ver(); } return 0; default: {} return 1; @@ -87,6 +95,23 @@ static void compile_file(const char *file) { compile(file, fb, fl); free(fb); return; } +/* Configure formatting */ +static void opt_f(const char *arg) {} + +/* Configure optimisation */ +static void opt_O(const char *arg) {} + +/* Configure warnings and errors */ +static void opt_W(const char *arg) { + if (strcmp(arg, "0") == 0) { log_level = 0; } + else if (strcmp(arg, "1") == 0) { log_level = 1; } + else if (strcmp(arg, "2") == 0) { log_level = 2; } + else if (strcmp(arg, "3") == 0) { log_level = 3; } + else if (strcmp(arg, "4") == 0) { log_level = 4; } + else if (strcmp(arg, "error") == 0) { log_waerr = true; } + else { note(NULL, 0, 0, 1, "-W%s: unknown warning option", arg); } +} + /* Print help information. */ static void hlp(void) { puts("G - G Programming Language\n");