changeset 226:7c2c2239ec9c

Make unicorns grok errors and warnings. Added unicorn formatted error and warning output and also a framework to handle errors which know which character position in the line they occurred in.
author William Astle <lost@l-w.ca>
date Sun, 15 Jul 2012 21:19:43 -0600
parents 823560a8c251
children 721a5ea5e36a
files lwasm/lwasm.c lwasm/lwasm.h lwasm/main.c lwasm/unicorns.c
diffstat 4 files changed, 92 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/lwasm.c	Sun Jul 15 21:19:04 2012 -0600
+++ b/lwasm/lwasm.c	Sun Jul 15 21:19:43 2012 -0600
@@ -199,50 +199,92 @@
 	return NULL;
 }
 
-void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...)
+void lwasm_register_error_real(asmstate_t *as, line_t *l, char *iptr, const char *msg, va_list args)
 {
 	lwasm_error_t *e;
-	va_list args;
 	char errbuff[1024];
 
 	if (!l)
 		return;
 
-	va_start(args, msg);
-	
 	e = lw_alloc(sizeof(lwasm_error_t));
 	
 	e -> next = l -> err;
 	l -> err = e;
+	e -> charpos = -1;
+	
+	if (iptr)
+		e -> charpos = iptr - l -> ltext + 1;
 	
 	as -> errorcount++;
 	
 	(void)vsnprintf(errbuff, 1024, msg, args);
 	e -> mess = lw_strdup(errbuff);
+}
+
+void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...)
+{
+	va_list args;
+	
+	va_start(args, msg);
+	
+	lwasm_register_error_real(as, l, NULL, msg, args);
 	
 	va_end(args);
 }
 
-void lwasm_register_warning(asmstate_t *as, line_t *l, const char *msg, ...)
+void lwasm_register_error_n(asmstate_t *as, line_t *l, char *iptr, const char *msg, ...)
+{
+	va_list args;
+	
+	va_start(args, msg);
+	
+	lwasm_register_error_real(as, l, iptr, msg, args);
+	
+	va_end(args);
+}
+
+void lwasm_register_warning_real(asmstate_t *as, line_t *l, char *iptr, const char *msg, va_list args)
 {
 	lwasm_error_t *e;
-	va_list args;
 	char errbuff[1024];
 	
 	if (!l)
 		return;
 
-	va_start(args, msg);
-	
 	e = lw_alloc(sizeof(lwasm_error_t));
 	
 	e -> next = l -> warn;
 	l -> warn = e;
 	
+	e -> charpos = -1;
+	if (iptr)
+		e -> charpos = iptr - l -> ltext + 1;
+	
 	as -> warningcount++;
 	
 	(void)vsnprintf(errbuff, 1024, msg, args);
 	e -> mess = lw_strdup(errbuff);
+}
+
+void lwasm_register_warning(asmstate_t *as, line_t *l, const char *msg, ...)
+{
+	va_list args;
+	
+	va_start(args, msg);
+	
+	lwasm_register_warning_real(as, l, NULL, msg, args);
+	
+	va_end(args);
+}
+
+void lwasm_register_warning_n(asmstate_t *as, line_t *l, char *iptr, const char *msg, ...)
+{
+	va_list args;
+	
+	va_start(args, msg);
+	
+	lwasm_register_warning_real(as, l, iptr, msg, args);
 	
 	va_end(args);
 }
--- a/lwasm/lwasm.h	Sun Jul 15 21:19:04 2012 -0600
+++ b/lwasm/lwasm.h	Sun Jul 15 21:19:43 2012 -0600
@@ -123,6 +123,7 @@
 struct lwasm_error_s
 {
 	char *mess;							// actual error message
+	int charpos;						// character position on line where parsing stopped
 	lwasm_error_t *next;				// ptr to next error
 };
 
@@ -322,6 +323,10 @@
 
 extern void lwasm_register_error(asmstate_t *as, line_t *cl, const char *msg, ...);
 extern void lwasm_register_warning(asmstate_t *as, line_t *cl, const char *msg, ...);
+
+extern void lwasm_register_error_n(asmstate_t *as, line_t *cl, char *iptr, const char *msg, ...);
+extern void lwasm_register_warning_n(asmstate_t *as, line_t *cl, char *iptr, const char *msg, ...);
+
 extern int lwasm_next_context(asmstate_t *as);
 extern void lwasm_emit(line_t *cl, int byte);
 extern void lwasm_emitop(line_t *cl, int opc);
--- a/lwasm/main.c	Sun Jul 15 21:19:04 2012 -0600
+++ b/lwasm/main.c	Sun Jul 15 21:19:43 2012 -0600
@@ -291,8 +291,10 @@
 				// stop processing immediately
 				break;
 			}
-			lwasm_do_unicorns(&asmstate);
-			lwasm_show_errors(&asmstate);
+			if (asmstate.flags & FLAG_UNICORNS)
+				lwasm_do_unicorns(&asmstate);
+			else
+				lwasm_show_errors(&asmstate);
 			exit(1);
 		}
 	}
--- a/lwasm/unicorns.c	Sun Jul 15 21:19:04 2012 -0600
+++ b/lwasm/unicorns.c	Sun Jul 15 21:19:43 2012 -0600
@@ -46,12 +46,25 @@
 	}
 }
 
+static void show_unicorn_error(FILE *fp, line_t *l, lwasm_error_t *ee, const char *tag)
+{
+	fprintf(fp, "%s: lineno=%d,filename=", tag, l -> lineno);
+	print_urlencoding(fp, l -> linespec);
+	fputs(",message=", fp);
+	print_urlencoding(fp, ee -> mess);
+	if (ee -> charpos > 0)
+		fprintf(fp, ",col=%d", ee -> charpos);
+	fputc('\n', fp);
+}
+
 void lwasm_do_unicorns(asmstate_t *as)
 {
 	struct ifl *ifl;
 	macrotab_t *me;
 	structtab_t *se;
 	int i;
+	line_t *l;
+	lwasm_error_t *ee;
 			
 	/* output file list */	
 	for (ifl = ifl_head; ifl; ifl = ifl -> next)
@@ -86,5 +99,24 @@
 		print_urlencoding(stdout, se -> definedat -> linespec);
 		fputc('\n', stdout);
 	}
-	
+
+	/* output error and warning lists */
+	for (l = as -> line_head; l; l = l -> next)
+	{
+		if (l -> err)
+		{
+			for (ee = l -> err; ee; ee = ee -> next)
+			{
+				show_unicorn_error(stdout, l, ee, "ERROR");
+			}
+		}
+		
+		if (l -> warn)
+		{
+			for (ee = l -> warn; ee; ee = ee -> next)
+			{
+				show_unicorn_error(stdout, l, ee, "WARNING");
+			}
+		}
+	}
 }