# HG changeset patch # User lost@starbug # Date 1271981946 21600 # Node ID 90de73ba0cac699dac966647b236fa675125f954 # Parent 9c24d9d485b981df9b00403da77787069fa8eb40 Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string diff -r 9c24d9d485b9 -r 90de73ba0cac lwasm/debug.c --- a/lwasm/debug.c Wed Apr 21 23:29:18 2010 -0600 +++ b/lwasm/debug.c Thu Apr 22 18:19:06 2010 -0600 @@ -32,7 +32,7 @@ Various debug utilities */ -void dump_state(asmstate_t *as, FILE *fp) +void dump_state(asmstate_t *as) { line_t *cl; exportlist_t *ex; @@ -41,40 +41,51 @@ struct line_expr_s *le; lwasm_error_t *e; - fprintf(fp, "Lines:\n"); + debug_message(as, 100, "Lines:"); for (cl = as -> line_head; cl; cl = cl -> next) { - fprintf(fp, "%p ", cl); - if (cl -> insn >= 0) - { - fprintf(fp, "INSN %d (%s) ", cl -> insn, instab[cl -> insn].opcode); - fprintf(fp, "LEN %d ", cl -> len); - } - fprintf(fp, "\n ADDR:"); - lw_expr_print(cl -> addr, fp); + debug_message(as, 100, "%p INSN %d (%s) LEN %d", cl, cl -> insn, (cl -> insn >= 0) ? instab[cl -> insn].opcode : "", cl -> len); + debug_message(as, 100, " ADDR: %s", lw_expr_print(cl -> addr)); + for (le = cl -> exprs; le; le = le -> next) { - fprintf(fp, "\n EXPR %d:", le -> id); - lw_expr_print(le -> expr, fp); + debug_message(as, 100, " EXPR %d: %s", le -> id, lw_expr_print(le -> expr)); } if (cl -> outputl > 0) { int i; - fprintf(fp, "\n OUTPUT:"); for (i = 0; i < cl -> outputl; i++) { - fprintf(fp, "%02X", cl -> output[i]); + debug_message(as, 100, " OBYTE %02X: %02X", i, cl -> output[i]); } } for (e = cl -> err; e; e = e -> next) { - fprintf(fp, "\n ERR: %s", e -> mess); + debug_message(as, 100, " ERR: %s", e -> mess); } for (e = cl -> warn; e; e = e -> next) { - fprintf(fp, "\n WARN: %s", e -> mess); + debug_message(as, 100, " WARN: %s", e -> mess); } - fprintf(fp, "\n"); } } + +void debug_message(asmstate_t *as, int level, const char *fmt, ...) +{ + va_list args; + + if (as -> debug_level < level) + return; + + if (as -> debug_file == NULL) + as -> debug_file = stderr; + + va_start(args, fmt); + + fprintf(as -> debug_file, "DEBUG %03d: ", level); + vfprintf(as -> debug_file, fmt, args); + fputc('\n', as -> debug_file); + + va_end(args); +} diff -r 9c24d9d485b9 -r 90de73ba0cac lwasm/lwasm.h --- a/lwasm/lwasm.h Wed Apr 21 23:29:18 2010 -0600 +++ b/lwasm/lwasm.h Thu Apr 22 18:19:06 2010 -0600 @@ -185,6 +185,7 @@ int output_format; // output format int target; // assembly target int debug_level; // level of debugging requested + FILE *debug_file; // FILE * to output debug messages to int flags; // assembly flags int pragmas; // pragmas currently in effect int errorcount; // number of errors encountered @@ -250,6 +251,10 @@ extern int lwasm_reduce_expr(asmstate_t *as, lw_expr_t expr); +extern void debug_message(asmstate_t *as, int level, const char *fmt, ...); +extern void dump_state(asmstate_t *as); + + #endif #define OPLEN(op) (((op)>0xFF)?2:1) diff -r 9c24d9d485b9 -r 90de73ba0cac lwasm/main.c --- a/lwasm/main.c Wed Apr 21 23:29:18 2010 -0600 +++ b/lwasm/main.c Thu Apr 22 18:19:06 2010 -0600 @@ -43,7 +43,7 @@ static struct argp_option options[] = { { "output", 'o', "FILE", 0, "Output to FILE"}, - { "debug", 'd', 0, 0, "Set debug mode"}, + { "debug", 'd', "LEVEL", OPTION_ARG_OPTIONAL, "Set debug mode"}, { "format", 'f', "TYPE", 0, "Select output format: decb, raw, obj, os9"}, { "list", 'l', "FILE", OPTION_ARG_OPTIONAL, "Generate list [to FILE]"}, { "decb", 'b', 0, 0, "Generate DECB .bin format output, equivalent of --format=decb"}, @@ -75,7 +75,10 @@ break; case 'd': - as -> debug_level++; + if (!arg) + as -> debug_level = 50; + else + as -> debug_level = atoi(arg); break; case 'l': @@ -190,7 +193,6 @@ { NULL, NULL } }; -extern void dump_state(asmstate_t *as, FILE *fp); int main(int argc, char **argv) { @@ -221,10 +223,10 @@ for (passnum = 0; passlist[passnum].fn; passnum++) { - fprintf(stderr, "Doing pass %d (%s)\n", passnum, passlist[passnum].passname); + debug_message(&asmstate, 50, "Doing pass %d (%s)\n", passnum, passlist[passnum].passname); (passlist[passnum].fn)(&asmstate); - fprintf(stderr, "After pass %d (%s):\n", passnum, passlist[passnum].passname); - dump_state(&asmstate, stderr); + debug_message(&asmstate, 50, "After pass %d (%s)\n", passnum, passlist[passnum].passname); + dump_state(&asmstate); if (asmstate.errorcount > 0) { diff -r 9c24d9d485b9 -r 90de73ba0cac lwasm/pass1.c --- a/lwasm/pass1.c Wed Apr 21 23:29:18 2010 -0600 +++ b/lwasm/pass1.c Thu Apr 22 18:19:06 2010 -0600 @@ -76,7 +76,7 @@ lw_free(line); continue; } - printf("%s\n", line); + debug_message(as, 75, "Read line: %s", line); cl = lw_alloc(sizeof(line_t)); memset(cl, 0, sizeof(line_t)); @@ -252,9 +252,7 @@ { if (cl -> sym && cl -> symset == 0) { - printf("Register symbol %s:", cl -> sym); - lw_expr_print(cl -> addr, stderr); - printf("\n"); + debug_message(as, 50, "Register symbol %s: %s", cl -> sym, lw_expr_print(cl -> addr)); // register symbol at line address if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none)) @@ -263,9 +261,7 @@ // lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym); } } - - lw_expr_print(cl -> addr, stderr); - printf("\n"); + debug_message(as, 40, "Line address: %s", lw_expr_print(cl -> addr)); } nextline: diff -r 9c24d9d485b9 -r 90de73ba0cac lwlib/lw_expr.c --- a/lwlib/lw_expr.c Wed Apr 21 23:29:18 2010 -0600 +++ b/lwlib/lw_expr.c Thu Apr 22 18:19:06 2010 -0600 @@ -193,99 +193,121 @@ return r; } -void lw_expr_print(lw_expr_t E, FILE *fp) +void lw_expr_print_aux(lw_expr_t E, char **obuf, int *buflen, int *bufloc) { struct lw_expr_opers *o; int c = 0; - + char buf[256]; + for (o = E -> operands; o; o = o -> next) { c++; - lw_expr_print(o -> p, fp); + lw_expr_print_aux(o -> p, obuf, buflen, bufloc); } switch (E -> type) { case lw_expr_type_int: if (E -> value < 0) - fprintf(fp, "-%#x ", -(E -> value)); + snprintf(buf, 256, "-%#x ", -(E -> value)); else - fprintf(fp, "%#x ", E -> value); + snprintf(buf, 256, "%#x ", E -> value); break; case lw_expr_type_var: - fprintf(fp, "V(%s) ", (char *)(E -> value2)); + snprintf(buf, 256, "V(%s) ", (char *)(E -> value2)); break; case lw_expr_type_special: - fprintf(fp, "S(%d,%p) ", E -> value, E -> value2); + snprintf(buf, 256, "S(%d,%p) ", E -> value, E -> value2); break; case lw_expr_type_oper: - fprintf(fp, "[%d]", c); + snprintf(buf, 256, "[%d]", c); switch (E -> value) { case lw_expr_oper_plus: - fprintf(fp, "+ "); + strcat(buf, "+ "); break; case lw_expr_oper_minus: - fprintf(fp, "- "); + strcat(buf, "- "); break; case lw_expr_oper_times: - fprintf(fp, "* "); + strcat(buf, "* "); break; case lw_expr_oper_divide: - fprintf(fp, "/ "); + strcat(buf, "/ "); break; case lw_expr_oper_mod: - fprintf(fp, "%% "); + strcat(buf, "% "); break; case lw_expr_oper_intdiv: - fprintf(fp, "\\ "); + strcat(buf, "\\ "); break; case lw_expr_oper_bwand: - fprintf(fp, "BWAND "); + strcat(buf, "BWAND "); break; case lw_expr_oper_bwor: - fprintf(fp, "BWOR "); + strcat(buf, "BWOR "); break; case lw_expr_oper_bwxor: - fprintf(fp, "BWXOR "); + strcat(buf, "BWXOR "); break; case lw_expr_oper_and: - fprintf(fp, "AND "); + strcat(buf, "AND "); break; case lw_expr_oper_or: - fprintf(fp, "OR "); + strcat(buf, "OR "); break; case lw_expr_oper_neg: - fprintf(fp, "NEG "); + strcat(buf, "NEG "); break; case lw_expr_oper_com: - fprintf(fp, "COM "); + strcat(buf, "COM "); break; default: - fprintf(fp, "OPER "); + strcat(buf, "OPER "); break; } break; default: - fprintf(fp, "ERR "); + snprintf(buf, 256, "ERR "); break; } + + c = strlen(buf); + if (*bufloc + c >= *buflen) + { + *buflen += 128; + *obuf = lw_realloc(*obuf, *buflen); + } + strcpy(*obuf + *bufloc, buf); + *bufloc += c; +} + +char *lw_expr_print(lw_expr_t E) +{ + static char *obuf = NULL; + static int obufsize = 0; + + int obufloc = 0; + + lw_expr_print_aux(E, &obuf, &obufsize, &obufloc); + + return obuf; } /* @@ -394,12 +416,6 @@ int lw_expr_simplify_isliketerm(lw_expr_t e1, lw_expr_t e2) { - fprintf(stderr, "isliketerm in: "); - lw_expr_print(e1, stderr); - fprintf(stderr, "; "); - lw_expr_print(e2, stderr); - fprintf(stderr, "\n"); - // first term is a "times" if (e1 -> type == lw_expr_type_oper && e1 -> value == lw_expr_oper_times) { diff -r 9c24d9d485b9 -r 90de73ba0cac lwlib/lw_expr.h --- a/lwlib/lw_expr.h Wed Apr 21 23:29:18 2010 -0600 +++ b/lwlib/lw_expr.h Thu Apr 22 18:19:06 2010 -0600 @@ -82,7 +82,7 @@ extern lw_expr_t lw_expr_copy(lw_expr_t E); extern void lw_expr_add_operand(lw_expr_t E, lw_expr_t O); extern lw_expr_t lw_expr_build(int exprtype, ...); -extern void lw_expr_print(lw_expr_t E, FILE *fp); +extern char *lw_expr_print(lw_expr_t E); extern int lw_expr_compare(lw_expr_t E1, lw_expr_t E2); extern void lw_expr_simplify(lw_expr_t E, void *priv);