# HG changeset patch # User William Astle # Date 1342408783 21600 # Node ID 7c2c2239ec9c0ee013fe90b7776399dcc0f32f56 # Parent 823560a8c2510e9c88b9ec805a23b245ba4dd945 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. diff -r 823560a8c251 -r 7c2c2239ec9c lwasm/lwasm.c --- 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); } diff -r 823560a8c251 -r 7c2c2239ec9c lwasm/lwasm.h --- 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); diff -r 823560a8c251 -r 7c2c2239ec9c lwasm/main.c --- 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); } } diff -r 823560a8c251 -r 7c2c2239ec9c lwasm/unicorns.c --- 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"); + } + } + } }