diff lwasm/lwasm.c @ 370:8764142b3192

Convert internal error/warning handling framework to a new unified system Replace the ad hoc error and warning handling with a new system that codifies the errors with specific codes. This makes it possible in the future for error numbers to be used for testing and other purposes. It also makes sure the error strings themselves are consistent. Thanks to Erik G <erik@6809.org> for the patch.
author William Astle <lost@l-w.ca>
date Mon, 22 Jun 2015 18:49:38 -0600
parents 433dbc18fb41
children 8e25147c2aa8
line wrap: on
line diff
--- a/lwasm/lwasm.c	Mon Jun 22 18:38:30 2015 -0600
+++ b/lwasm/lwasm.c	Mon Jun 22 18:49:38 2015 -0600
@@ -33,8 +33,6 @@
 #include "lwasm.h"
 #include "instab.h"
 
-void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...);
-
 int lwasm_expr_exportable(asmstate_t *as, lw_expr_t expr)
 {
 	return 0;
@@ -48,7 +46,7 @@
 void lwasm_dividezero(void *priv)
 {
 	asmstate_t *as = (asmstate_t *)priv;
-	lwasm_register_error(as, as -> cl, "Division by zero");
+	lwasm_register_error(as, as -> cl, E_DIV0);
 }
 
 lw_expr_t lwasm_evaluate_var(char *var, void *priv)
@@ -100,7 +98,7 @@
 nomatch:
 	if (as -> badsymerr)
 	{
-		lwasm_register_error(as, as -> cl, "Undefined symbol %s", var);
+		lwasm_register_error2(as, as -> cl, E_SYMBOL_UNDEFINED, "%s", var);
 	}
 	return NULL;
 }
@@ -206,93 +204,120 @@
 	return NULL;
 }
 
-void lwasm_register_error_real(asmstate_t *as, line_t *l, char *iptr, const char *msg, va_list args)
+const char* lwasm_lookup_error(lwasm_errorcode_t error_code)
+{
+	switch (error_code)
+	{
+		case E_6309_INVALID:			return "Illegal use of 6309 instruction in 6809 mode";
+		case E_6809_INVALID:			return "Illegal use of 6809 instruction in 6309 mode";
+		case E_ALIGNMENT_INVALID:		return "Invalid alignment";
+		case E_BITNUMBER_INVALID:		return "Invalid bit number";
+		case E_BITNUMBER_UNRESOLVED:	return "Bit number must be fully resolved";
+		case E_BYTE_OVERFLOW:			return "Byte overflow";
+		case E_CONDITION_P1:			return "Conditions must be constant on pass 1";
+		case E_DIRECTIVE_OS9_ONLY:		return "Directive only valid for OS9 target";
+		case E_DIV0:					return "Division by zero";
+		case E_EXEC_ADDRESS:			return "Exec address not constant!";
+		case E_EXPRESSION_BAD:			return "Bad expression";
+		case E_EXPRESSION_NOT_CONST:	return "Expression must be constant";
+		case E_EXPRESSION_NOT_RESOLVED: return "Expression not fully resolved";
+		case E_FILE_OPEN:				return "Cannot open file";
+		case E_FILENAME_MISSING:		return "Missing filename";
+		case E_FILL_INVALID:			return "Invalid fill length";
+		case E_IMMEDIATE_INVALID:		return "Immediate mode not allowed";
+		case E_IMMEDIATE_UNRESOLVED:	return "Immediate byte must be fully resolved";
+		case E_INSTRUCTION_FAILED:		return "Instruction failed to resolve.";
+		case E_INSTRUCTION_SECTION:		return "Instruction generating output outside of a section";
+		case E_LINE_ADDRESS:			return "Cannot resolve line address";
+		case E_LINED_ADDRESS:			return "Cannot resolve line data address";
+		case E_OBJTARGET_ONLY:			return "Only supported for object target";
+		case E_OPCODE_BAD:				return "Bad opcode";
+		case E_OPERAND_BAD:				return "Bad operand";
+		case E_PADDING_BAD:				return "Bad padding";
+		case E_PRAGMA_UNRECOGNIZED:		return "Unrecognized pragma string";
+		case E_REGISTER_BAD:			return "Bad register";
+		case E_SETDP_INVALID:			return "SETDP not permitted for object target";
+		case E_SETDP_NOT_CONST:			return "SETDP must be constant on pass 1";
+		case E_STRING_BAD:				return "Bad string condition";
+		case E_SYMBOL_BAD:				return "Bad symbol";
+		case E_SYMBOL_MISSING:			return "Missing symbol";
+		case E_SYMBOL_UNDEFINED_EXPORT: return "Undefined exported symbol";
+		case E_MACRO_DUPE:				return "Duplicate macro definition";
+		case E_MACRO_ENDM:				return "ENDM without MACRO";
+		case E_MACRO_NONAME:			return "Missing macro name";
+		case E_MACRO_RECURSE:			return "Attempt to define a macro inside a macro";
+		case E_MODULE_IN:				return "Already in a module!";
+		case E_MODULE_NOTIN:			return "Not in a module!";
+		case E_NEGATIVE_BLOCKSIZE:		return "Negative block sizes make no sense!";
+		case E_NEGATIVE_RESERVATION:	return "Negative reservation sizes make no sense!";
+		case E_NW_8:					return "n,W cannot be 8 bit";
+		case E_SECTION_END:				return "ENDSECTION without SECTION";
+		case E_SECTION_EXTDEP:			return "EXTDEP must be within a section";
+		case E_SECTION_FLAG:			return "Unrecognized section flag";
+		case E_SECTION_NAME:			return "Need section name";
+		case E_SECTION_TARGET:			return "Cannot use sections unless using the object target";
+		case E_STRUCT_DUPE:				return "Duplicate structure definition";
+		case E_STRUCT_NONAME:			return "Cannot declare a structure without a symbol name.";
+		case E_STRUCT_NOSYMBOL:			return "Structure definition with no effect - no symbol";
+		case E_STRUCT_RECURSE:			return "Attempt to define a structure inside a structure";
+		case E_SYMBOL_DUPE:				return "Multiply defined symbol";
+		case E_UNKNOWN_OPERATION:		return "Unknown operation";
+
+		case W_ENDSTRUCT_WITHOUT:		return "ENDSTRUCT without STRUCT";
+		case W_DUPLICATE_SECTION:		return "Section flags can only be specified the first time; ignoring duplicate definition";
+		case W_NOT_SUPPORTED:			return "Not supported";
+
+		default:						return "Error";
+	}
+}
+
+void lwasm_register_error_real(asmstate_t *as, line_t *l, lwasm_errorcode_t err, const char *msg)
 {
 	lwasm_error_t *e;
-	char errbuff[1024];
 
 	if (!l)
 		return;
 
 	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);
+	if (err >= 1000)
+	{
+		e->next = l->warn;
+		l->warn = e;
+		as->warningcount++;
+	}
+	else
+	{
+		e->next = l->err;
+		l->err = e;
+		as->errorcount++;
+	}
 	
-	va_end(args);
-}
+	e -> charpos = -1;
 
-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);
+	e -> mess = lw_strdup(msg);
 }
 
-void lwasm_register_warning_real(asmstate_t *as, line_t *l, char *iptr, const char *msg, va_list args)
+void lwasm_register_error(asmstate_t *as, line_t *l, lwasm_errorcode_t err)
 {
-	lwasm_error_t *e;
-	char errbuff[1024];
-	
-	if (!l)
-		return;
-
-	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);
+	lwasm_register_error_real(as, l, err, lwasm_lookup_error(err));
 }
 
-void lwasm_register_warning(asmstate_t *as, line_t *l, const char *msg, ...)
+void lwasm_register_error2(asmstate_t *as, line_t *l, lwasm_errorcode_t err, const char* fmt, ...)
 {
+	char errbuff[1024];
+	char f[128];
+
+	sprintf(f, "%s %s", lwasm_lookup_error(err), fmt);
+
 	va_list args;
-	
-	va_start(args, msg);
-	
-	lwasm_register_warning_real(as, l, NULL, msg, args);
-	
-	va_end(args);
-}
+
+	va_start(args, fmt);
 
-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);
-	
+	(void) vsnprintf(errbuff, 1024, f, args);
+
+	lwasm_register_error_real(as, l, err, errbuff);
+
 	va_end(args);
 }
 
@@ -308,7 +333,7 @@
 {
 	if (cl -> as -> output_format == OUTPUT_OBJ && cl -> csect == NULL)
 	{
-		lwasm_register_error(cl -> as, cl, "Instruction generating output outside of a section");
+		lwasm_register_error(cl -> as, cl, E_INSTRUCTION_SECTION);
 		return;
 	}
 	if (cl -> outputl < 0)
@@ -817,7 +842,7 @@
 
 			if (l -> csect == NULL)
 			{
-				lwasm_register_error(l -> as, l, "Instruction generating output outside of a section");
+				lwasm_register_error(l -> as, l, E_INSTRUCTION_SECTION);
 				return -1;
 			}
 			
@@ -871,7 +896,7 @@
 				lwasm_emit(l, 0);
 			return 0;
 		}
-		lwasm_register_error(l -> as, l, "Expression not fully resolved");
+		lwasm_register_error(l->as, l, E_EXPRESSION_NOT_RESOLVED);
 		return -1;
 	}
 	
@@ -994,7 +1019,7 @@
 	
 	if (!e)
 	{
-		lwasm_register_error(as, as -> cl, "Bad expression");
+		lwasm_register_error(as, as -> cl, E_EXPRESSION_BAD);
 		return NULL;
 	}
 
@@ -1026,7 +1051,7 @@
 	if (!lw_expr_istype(e, lw_expr_type_int))
 	{
 		debug_message(as, 250, "Non-constant expression");
-		lwasm_register_error(as, as -> cl, "Conditions must be constant on pass 1");
+		lwasm_register_error(as, as -> cl, E_CONDITION_P1);
 		return NULL;
 	}
 	debug_message(as, 250, "Returning expression");