comparison 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
comparison
equal deleted inserted replaced
369:682524a1f32f 370:8764142b3192
31 #include <lw_string.h> 31 #include <lw_string.h>
32 32
33 #include "lwasm.h" 33 #include "lwasm.h"
34 #include "instab.h" 34 #include "instab.h"
35 35
36 void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...);
37
38 int lwasm_expr_exportable(asmstate_t *as, lw_expr_t expr) 36 int lwasm_expr_exportable(asmstate_t *as, lw_expr_t expr)
39 { 37 {
40 return 0; 38 return 0;
41 } 39 }
42 40
46 } 44 }
47 45
48 void lwasm_dividezero(void *priv) 46 void lwasm_dividezero(void *priv)
49 { 47 {
50 asmstate_t *as = (asmstate_t *)priv; 48 asmstate_t *as = (asmstate_t *)priv;
51 lwasm_register_error(as, as -> cl, "Division by zero"); 49 lwasm_register_error(as, as -> cl, E_DIV0);
52 } 50 }
53 51
54 lw_expr_t lwasm_evaluate_var(char *var, void *priv) 52 lw_expr_t lwasm_evaluate_var(char *var, void *priv)
55 { 53 {
56 asmstate_t *as = (asmstate_t *)priv; 54 asmstate_t *as = (asmstate_t *)priv;
98 return e; 96 return e;
99 97
100 nomatch: 98 nomatch:
101 if (as -> badsymerr) 99 if (as -> badsymerr)
102 { 100 {
103 lwasm_register_error(as, as -> cl, "Undefined symbol %s", var); 101 lwasm_register_error2(as, as -> cl, E_SYMBOL_UNDEFINED, "%s", var);
104 } 102 }
105 return NULL; 103 return NULL;
106 } 104 }
107 105
108 lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv) 106 lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv)
204 } 202 }
205 } 203 }
206 return NULL; 204 return NULL;
207 } 205 }
208 206
209 void lwasm_register_error_real(asmstate_t *as, line_t *l, char *iptr, const char *msg, va_list args) 207 const char* lwasm_lookup_error(lwasm_errorcode_t error_code)
208 {
209 switch (error_code)
210 {
211 case E_6309_INVALID: return "Illegal use of 6309 instruction in 6809 mode";
212 case E_6809_INVALID: return "Illegal use of 6809 instruction in 6309 mode";
213 case E_ALIGNMENT_INVALID: return "Invalid alignment";
214 case E_BITNUMBER_INVALID: return "Invalid bit number";
215 case E_BITNUMBER_UNRESOLVED: return "Bit number must be fully resolved";
216 case E_BYTE_OVERFLOW: return "Byte overflow";
217 case E_CONDITION_P1: return "Conditions must be constant on pass 1";
218 case E_DIRECTIVE_OS9_ONLY: return "Directive only valid for OS9 target";
219 case E_DIV0: return "Division by zero";
220 case E_EXEC_ADDRESS: return "Exec address not constant!";
221 case E_EXPRESSION_BAD: return "Bad expression";
222 case E_EXPRESSION_NOT_CONST: return "Expression must be constant";
223 case E_EXPRESSION_NOT_RESOLVED: return "Expression not fully resolved";
224 case E_FILE_OPEN: return "Cannot open file";
225 case E_FILENAME_MISSING: return "Missing filename";
226 case E_FILL_INVALID: return "Invalid fill length";
227 case E_IMMEDIATE_INVALID: return "Immediate mode not allowed";
228 case E_IMMEDIATE_UNRESOLVED: return "Immediate byte must be fully resolved";
229 case E_INSTRUCTION_FAILED: return "Instruction failed to resolve.";
230 case E_INSTRUCTION_SECTION: return "Instruction generating output outside of a section";
231 case E_LINE_ADDRESS: return "Cannot resolve line address";
232 case E_LINED_ADDRESS: return "Cannot resolve line data address";
233 case E_OBJTARGET_ONLY: return "Only supported for object target";
234 case E_OPCODE_BAD: return "Bad opcode";
235 case E_OPERAND_BAD: return "Bad operand";
236 case E_PADDING_BAD: return "Bad padding";
237 case E_PRAGMA_UNRECOGNIZED: return "Unrecognized pragma string";
238 case E_REGISTER_BAD: return "Bad register";
239 case E_SETDP_INVALID: return "SETDP not permitted for object target";
240 case E_SETDP_NOT_CONST: return "SETDP must be constant on pass 1";
241 case E_STRING_BAD: return "Bad string condition";
242 case E_SYMBOL_BAD: return "Bad symbol";
243 case E_SYMBOL_MISSING: return "Missing symbol";
244 case E_SYMBOL_UNDEFINED_EXPORT: return "Undefined exported symbol";
245 case E_MACRO_DUPE: return "Duplicate macro definition";
246 case E_MACRO_ENDM: return "ENDM without MACRO";
247 case E_MACRO_NONAME: return "Missing macro name";
248 case E_MACRO_RECURSE: return "Attempt to define a macro inside a macro";
249 case E_MODULE_IN: return "Already in a module!";
250 case E_MODULE_NOTIN: return "Not in a module!";
251 case E_NEGATIVE_BLOCKSIZE: return "Negative block sizes make no sense!";
252 case E_NEGATIVE_RESERVATION: return "Negative reservation sizes make no sense!";
253 case E_NW_8: return "n,W cannot be 8 bit";
254 case E_SECTION_END: return "ENDSECTION without SECTION";
255 case E_SECTION_EXTDEP: return "EXTDEP must be within a section";
256 case E_SECTION_FLAG: return "Unrecognized section flag";
257 case E_SECTION_NAME: return "Need section name";
258 case E_SECTION_TARGET: return "Cannot use sections unless using the object target";
259 case E_STRUCT_DUPE: return "Duplicate structure definition";
260 case E_STRUCT_NONAME: return "Cannot declare a structure without a symbol name.";
261 case E_STRUCT_NOSYMBOL: return "Structure definition with no effect - no symbol";
262 case E_STRUCT_RECURSE: return "Attempt to define a structure inside a structure";
263 case E_SYMBOL_DUPE: return "Multiply defined symbol";
264 case E_UNKNOWN_OPERATION: return "Unknown operation";
265
266 case W_ENDSTRUCT_WITHOUT: return "ENDSTRUCT without STRUCT";
267 case W_DUPLICATE_SECTION: return "Section flags can only be specified the first time; ignoring duplicate definition";
268 case W_NOT_SUPPORTED: return "Not supported";
269
270 default: return "Error";
271 }
272 }
273
274 void lwasm_register_error_real(asmstate_t *as, line_t *l, lwasm_errorcode_t err, const char *msg)
210 { 275 {
211 lwasm_error_t *e; 276 lwasm_error_t *e;
212 char errbuff[1024];
213 277
214 if (!l) 278 if (!l)
215 return; 279 return;
216 280
217 e = lw_alloc(sizeof(lwasm_error_t)); 281 e = lw_alloc(sizeof(lwasm_error_t));
218 282
219 e -> next = l -> err; 283 if (err >= 1000)
220 l -> err = e; 284 {
285 e->next = l->warn;
286 l->warn = e;
287 as->warningcount++;
288 }
289 else
290 {
291 e->next = l->err;
292 l->err = e;
293 as->errorcount++;
294 }
295
221 e -> charpos = -1; 296 e -> charpos = -1;
222 297
223 if (iptr) 298 e -> mess = lw_strdup(msg);
224 e -> charpos = iptr - l -> ltext + 1; 299 }
225 300
226 as -> errorcount++; 301 void lwasm_register_error(asmstate_t *as, line_t *l, lwasm_errorcode_t err)
227 302 {
228 (void)vsnprintf(errbuff, 1024, msg, args); 303 lwasm_register_error_real(as, l, err, lwasm_lookup_error(err));
229 e -> mess = lw_strdup(errbuff); 304 }
230 } 305
231 306 void lwasm_register_error2(asmstate_t *as, line_t *l, lwasm_errorcode_t err, const char* fmt, ...)
232 void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...) 307 {
233 { 308 char errbuff[1024];
309 char f[128];
310
311 sprintf(f, "%s %s", lwasm_lookup_error(err), fmt);
312
234 va_list args; 313 va_list args;
235 314
236 va_start(args, msg); 315 va_start(args, fmt);
237 316
238 lwasm_register_error_real(as, l, NULL, msg, args); 317 (void) vsnprintf(errbuff, 1024, f, args);
239 318
240 va_end(args); 319 lwasm_register_error_real(as, l, err, errbuff);
241 } 320
242
243 void lwasm_register_error_n(asmstate_t *as, line_t *l, char *iptr, const char *msg, ...)
244 {
245 va_list args;
246
247 va_start(args, msg);
248
249 lwasm_register_error_real(as, l, iptr, msg, args);
250
251 va_end(args);
252 }
253
254 void lwasm_register_warning_real(asmstate_t *as, line_t *l, char *iptr, const char *msg, va_list args)
255 {
256 lwasm_error_t *e;
257 char errbuff[1024];
258
259 if (!l)
260 return;
261
262 e = lw_alloc(sizeof(lwasm_error_t));
263
264 e -> next = l -> warn;
265 l -> warn = e;
266
267 e -> charpos = -1;
268 if (iptr)
269 e -> charpos = iptr - l -> ltext + 1;
270
271 as -> warningcount++;
272
273 (void)vsnprintf(errbuff, 1024, msg, args);
274 e -> mess = lw_strdup(errbuff);
275 }
276
277 void lwasm_register_warning(asmstate_t *as, line_t *l, const char *msg, ...)
278 {
279 va_list args;
280
281 va_start(args, msg);
282
283 lwasm_register_warning_real(as, l, NULL, msg, args);
284
285 va_end(args);
286 }
287
288 void lwasm_register_warning_n(asmstate_t *as, line_t *l, char *iptr, const char *msg, ...)
289 {
290 va_list args;
291
292 va_start(args, msg);
293
294 lwasm_register_warning_real(as, l, iptr, msg, args);
295
296 va_end(args); 321 va_end(args);
297 } 322 }
298 323
299 int lwasm_next_context(asmstate_t *as) 324 int lwasm_next_context(asmstate_t *as)
300 { 325 {
306 331
307 void lwasm_emit(line_t *cl, int byte) 332 void lwasm_emit(line_t *cl, int byte)
308 { 333 {
309 if (cl -> as -> output_format == OUTPUT_OBJ && cl -> csect == NULL) 334 if (cl -> as -> output_format == OUTPUT_OBJ && cl -> csect == NULL)
310 { 335 {
311 lwasm_register_error(cl -> as, cl, "Instruction generating output outside of a section"); 336 lwasm_register_error(cl -> as, cl, E_INSTRUCTION_SECTION);
312 return; 337 return;
313 } 338 }
314 if (cl -> outputl < 0) 339 if (cl -> outputl < 0)
315 cl -> outputl = 0; 340 cl -> outputl = 0;
316 341
815 reloctab_t *re; 840 reloctab_t *re;
816 lw_expr_t te; 841 lw_expr_t te;
817 842
818 if (l -> csect == NULL) 843 if (l -> csect == NULL)
819 { 844 {
820 lwasm_register_error(l -> as, l, "Instruction generating output outside of a section"); 845 lwasm_register_error(l -> as, l, E_INSTRUCTION_SECTION);
821 return -1; 846 return -1;
822 } 847 }
823 848
824 if (size == 4) 849 if (size == 4)
825 { 850 {
869 } 894 }
870 for (v = 0; v < size; v++) 895 for (v = 0; v < size; v++)
871 lwasm_emit(l, 0); 896 lwasm_emit(l, 0);
872 return 0; 897 return 0;
873 } 898 }
874 lwasm_register_error(l -> as, l, "Expression not fully resolved"); 899 lwasm_register_error(l->as, l, E_EXPRESSION_NOT_RESOLVED);
875 return -1; 900 return -1;
876 } 901 }
877 902
878 switch (size) 903 switch (size)
879 { 904 {
992 e = lwasm_parse_expr(as, p); 1017 e = lwasm_parse_expr(as, p);
993 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e)); 1018 debug_message(as, 250, "COND EXPR: %s", lw_expr_print(e));
994 1019
995 if (!e) 1020 if (!e)
996 { 1021 {
997 lwasm_register_error(as, as -> cl, "Bad expression"); 1022 lwasm_register_error(as, as -> cl, E_EXPRESSION_BAD);
998 return NULL; 1023 return NULL;
999 } 1024 }
1000 1025
1001 /* handle condundefzero */ 1026 /* handle condundefzero */
1002 if (CURPRAGMA(as -> cl, PRAGMA_CONDUNDEFZERO)) 1027 if (CURPRAGMA(as -> cl, PRAGMA_CONDUNDEFZERO))
1024 lwasm_save_expr(as -> cl, 4242, e); 1049 lwasm_save_expr(as -> cl, 4242, e);
1025 1050
1026 if (!lw_expr_istype(e, lw_expr_type_int)) 1051 if (!lw_expr_istype(e, lw_expr_type_int))
1027 { 1052 {
1028 debug_message(as, 250, "Non-constant expression"); 1053 debug_message(as, 250, "Non-constant expression");
1029 lwasm_register_error(as, as -> cl, "Conditions must be constant on pass 1"); 1054 lwasm_register_error(as, as -> cl, E_CONDITION_P1);
1030 return NULL; 1055 return NULL;
1031 } 1056 }
1032 debug_message(as, 250, "Returning expression"); 1057 debug_message(as, 250, "Returning expression");
1033 return e; 1058 return e;
1034 } 1059 }