G

G Programming Language
git clone http://git.omkov.net/G
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2022-05-07 04:17:55
Commit12630d46f80fa6ee292736da348bb8d1afdb2f7d
Parent163d55f61c21e198d889f0e7c12dfb0f65f21968

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");