changeset 372:90de73ba0cac

Created a useful debug framework and adjusted lw_expr_print() to return a "static" dynamic string
author lost@starbug
date Thu, 22 Apr 2010 18:19:06 -0600
parents 9c24d9d485b9
children 8f9d72cfb897
files lwasm/debug.c lwasm/lwasm.h lwasm/main.c lwasm/pass1.c lwlib/lw_expr.c lwlib/lw_expr.h
diffstat 6 files changed, 90 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- 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 : "<none>", 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);
+}
--- 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)
--- 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)
 		{
--- 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:
--- 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)
 	{
--- 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);