OpenCores
URL https://opencores.org/ocsvn/forwardcom/forwardcom/trunk

Subversion Repositories forwardcom

[/] [forwardcom/] [bintools/] [error.cpp] - Blame information for rev 58

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 58 Agner
/****************************   error.cpp   **********************************
2
* Author:        Agner Fog
3
* Date created:  2017-11-03
4
* Last modified: 2021-03-30
5
* Version:       1.11
6
* Project:       Binary tools for ForwardCom instruction set
7
* Module:        error.cpp
8
* Description:
9
* Standard procedure for error reporting to stderr
10
*
11
* Copyright 2006-2021 GNU General Public License http://www.gnu.org/licenses
12
******************************************************************************
13
 
14
You may set breakpoints here to trace errors (use stack trace)
15
 
16
Runtime errors during emulation are not going here, but to
17
CThread::interrupt in emulator6.cpp
18
 
19
*****************************************************************************/
20
 
21
#include "stdafx.h"
22
 
23
// Make and initialize error reporter object
24
CErrorReporter err;
25
 
26
// General error messages
27
 
28
// to do: remove unused error messages!
29
 
30
SErrorText errorTexts[] = {
31
    // Unknown error
32
    {0,    2, "Unknown error!"},
33
 
34
    // Warning messages
35
    {ERR_EMPTY_OPTION, 1, "Empty command line option"},
36
    {ERR_UNKNOWN_OPTION, 2, "Unknown command line option: %s"},
37
    {ERR_UNKNOWN_ERROR_NUM, 1, "Unknown warning/error number: %i"},
38
    {ERR_OUTFILE_IGNORED, 1, "Output file name ignored"},
39
    {ERR_MEMBER_NOT_FOUND_EXTRACT, 1, "Library member %s not found. Extraction failed"},
40
    {ERR_MEMBER_NOT_FOUND_DEL, 1, "Library member %s not found. Deletion failed"},
41
    {ERR_DUPLICATE_NAME_COMMANDL, 1, "Library member %s specified more than once"}, // duplicate name on command line
42
    {ERR_DUPLICATE_NAME_IN_LIB, 1, "Library has more than one members named %s"}, // duplicate name in library
43
    {ERR_DUPLICATE_SYMBOL_IN_LIB, 1, "More than one symbol named %s in modules %s"}, // duplicate symbol in library
44
    {ERR_NO_SYMTAB_IN_LIB, 2, "No ForwardCom symbol table found in library"}, // probably wrong library type
45
    {ERR_ABS_RELOCATION_WARN, 1, "Code at line %i is position dependent because it contains absolute address of symbol: %s"}, // warn if absolute address
46
 
47
 
48
    {ERR_LIBRARY_FILE_TYPE, 2, "Library file has wrong type: %s"}, // expecting library file
49
    {ERR_LIBRARY_FILE_CORRUPT, 2, "Library file is corrupt"}, // index out of range in library file
50
    {ERR_LIBRARY_LIST_ONLY, 2, "Library list command cannnot be combined with other commands"}, // conflicting commands
51
    {ERR_LIBRARY_MEMBER_TYPE, 2, "Library member %s has wrong type: %s"}, // expecting ForwardCom object file
52
 
53
    {ERR_LINK_LIST_ONLY, 2, "Linker list command cannnot be combined with other commands"}, // conflicting commands
54
    {ERR_LINK_FILE_TYPE, 2, "Wrong file type. Expecting ForwardCom object file: %s"}, // wrong file type to linker
55
    {ERR_LINK_FILE_TYPE_LIB, 2, "Wrong file type. Expecting ForwardCom library file: %s"}, // wrong file type to linker
56
    {ERR_LINK_FILE_TYPE_EXE, 2, "Wrong file type. Expecting ForwardCom executable file: %s"}, // wrong file type to emulator
57
    {ERR_LINK_COMMUNAL, 1, "Communal section %s has different sizes in modules %s"}, // communal sections not identical
58
    {ERR_LINK_DUPLICATE_SYMBOL, 1, "More than one symbol named %s in modules %s"}, // duplicate symbol encountered during linking
59
    {ERR_LINK_DIFFERENT_BASE, 2, "Link source and target use different base pointers. Cannot link from module %s to symbol %s in module %s"}, // link source and target use different base pointers
60
    {ERR_LINK_MISALIGNED_TARGET, 2, "Link target is misaligned. Scaling failed when linking from module %s to symbol %s in module %s"}, // link target alignment does not fit scale factor
61
    {ERR_LINK_OVERFLOW, 2, "Address overflow when linking from module %s to symbol %s in module %s"}, // relocation overflow
62
    {ERR_LINK_RELOCATION_OVERFLOW, 2, "Address overflow when linking to symbol %s"}, // relocation overflow    
63
    {ERR_LINK_REGUSE, 2, "Mismatched register use when linking from module %s to symbol %s. Missing registers: %s"}, // register use mismatch
64
    {ERR_LINK_MODULE_NOT_FOUND, 2, "Module %s not found in library %s"}, // cannot find explicitly specified library module
65
    {ERR_EVENT_SIZE, 1, "Wrong size of event handler records in module %s"}, // event section size not divisible by event record size
66
    {ERR_REL_SYMBOL_NOT_FOUND, 2, "Relocated symbol not found"}, // relocation failed. should not occur
67
    {ERR_CANT_RELINK_MODULE, 2, "Module %s is not relinkable. Cannot remove or replace"}, // attempt to delete or replace non-relinkable module
68
    {ERR_CANT_RELINK_LIBRARY, 2, "Library %s is not relinkable. Cannot remove or replace"}, // attempt to delete or replace non-relinkable library
69
    {ERR_RELINK_MODULE_NOT_FOUND, 1, "Module %s not found in input file. Cannot remove or replace"}, // attempt to delete or replace non-existing module
70
    {ERR_RELINK_LIBRARY_NOT_FOUND, 1, "Library %s not found in input file. Cannot remove or replace"}, // attempt to delete or replace non-existing library
71
    {ERR_RELINK_BASE_POINTER_MOD, 2, "Base pointer overridden during relinking. Relative addresses may be wrong"}, // base pointer has been overridden during relinking
72
    {ERR_INPUT_NOT_RELINKABLE, 2, "File %s is not relinkable"}, // attempt to relink non-relinkable file
73
    {ERR_LINK_UNRESOLVED, 2, "Unresolved external symbol %s in module %s"}, // symbol not found in any module or library
74
    {ERR_LINK_UNRESOLVED_WARN, 1, "Unresolved external symbol %s in module %s"}, // symbol not found. warn only because incomplete output allowed
75
 
76
    // Error messages
77
    {ERR_MULTIPLE_IO_FILES, 2, "No more than one input file and one output file can be specified"}, //?
78
    {ERR_MULTIPLE_COMMANDS, 2, "More than one command specified on command line: %s"},
79
    {ERR_UNKNOWN_OPTION, 2, "Unknown command line option: %s"},
80
    {ERR_FILES_SAME_NAME, 2, "Input file and output file cannot have same name: %s"},
81
    {ERR_DUMP_NOT_SUPPORTED, 2, "Sorry. Dump of file type %s is not supported"},
82
    {ERR_INDEX_OUT_OF_RANGE, 2, "Index out of range"},
83
 
84
    {ERR_ELF_RECORD_SIZE, 2, "Error in ELF file. Record size wrong"},
85
    {ERR_ELF_SYMTAB_MISSING, 2, "Symbol table not found in ELF file"},
86
    {ERR_ELF_INDEX_RANGE, 2, "Index out of range in object file"},
87
    {ERR_ELF_UNKNOWN_SECTION, 2, "Unknown section index in ELF file: %i"},
88
    {ERR_ELF_STRING_TABLE, 2, "String table corrupt"},
89
    {ERR_ELF_NO_SECTIONS, 2, "File with absolute constants must have at least one section, even if empty"},
90
 
91
    {ERR_CONTAINER_INDEX, 2, "Index out of range in internal container"},
92
    {ERR_CONTAINER_OVERFLOW, 2, "Overflow of internal container"},
93
 
94
    {ERR_INPUT_FILE, 2, "Cannot read input file %s"},
95
    {ERR_OUTPUT_FILE, 2, "Cannot write output file %s"},
96
    {ERR_UNKNOWN_FILE_TYPE, 2, "Unknown file type %i: %s"},
97
    {ERR_FILE_SIZE, 2, "Wrong size of file %s"},
98
 
99
    {ERR_TOO_MANY_RESP_FILES, 2, "Too many response files"},
100
    {ERR_FILE_NAME_LONG, 2, "File name %s too long"},
101
    {ERR_INSTRUCTION_LIST_SYNTAX, 2, "Syntax error in instruction list: %s"},
102
    {ERR_INSTRUCTION_LIST_QUOTE, 2, "Unmatched quote in instruction list, line %i"},  //?
103
 
104
    // Fatal errors makes the program stop immediately:
105
    {ERR_INTERNAL, 9, "Objconv program internal inconsistency"}, // table fault, etc.
106
    {ERR_TOO_MANY_ERRORS, 9, "Too many errors. Aborting"},
107
    {ERR_BIG_ENDIAN, 9, "This machine has big-endian memory organization or other incompatibility. Program cannot be compiled on this machine."},
108
    {ERR_MEMORY_ALLOCATION, 9, "Memory allocation failed"},
109
 
110
    // Mark end of list
111
    {9999, 9999, "End of error text list"}
112
};
113
 
114
 
115
// Error messages for assembly file
116
SErrorText assemErrorTexts[] = {
117
    // the status number indicates if an extra string is required
118
    {0,          0, "misplaced unknown token"},
119
    {TOK_NAM,    1, "unknown name: "},
120
    {TOK_LAB,    1, "misplaced label: "},
121
    {TOK_VAR,    1, "misplaced variable: "},
122
    {TOK_SEC,    1, "misplaced section name: "},
123
    {TOK_INS,    1, "misplaced instruction: "},
124
    {TOK_OPR,    1, "misplaced operator: "},
125
    {TOK_NUM,    1, "misplaced number: "},
126
    {TOK_FLT,    1, "misplaced floating point number: "},
127
    {TOK_CHA,    1, "misplaced character constant: "},
128
    {TOK_STR,    1, "misplaced string: "},
129
    {TOK_DIR,    1, "misplaced directive: "},
130
    {TOK_ATT,    1, "misplaced attribute: "},
131
    {TOK_TYP,    1, "misplaced type name: "},
132
    {TOK_OPT,    1, "misplaced option: "},
133
    {TOK_REG,    1, "misplaced register: "},
134
    {TOK_SYM,    1, "misplaced symbol: "},
135
    {TOK_XPR,    1, "misplaced expression: "},
136
    {TOK_HLL,    1, "misplaced keyword: "},
137
 
138
    {ERR_CONTROL_CHAR,       1, "illegal control character: "},
139
    {ERR_ILLEGAL_CHAR,       1, "illegal character: "},
140
    {ERR_COMMENT_BEGIN,      0, "unmatched comment begin: /*"},
141
    {ERR_COMMENT_END,        0, "unmatched comment end: */"},
142
    {ERR_BRACKET_BEGIN,      1, "unmatched begin bracket: "},
143
    {ERR_BRACKET_END,        1, "unmatched end bracket: "},
144
    {ERR_QUOTE_BEGIN,        1, "unmatched begin quote: "},
145
    {ERR_QUESTION_MARK,      0, "unmatched '?'"},
146
    {ERR_COLON,              0, "unmatched ':'"},
147
    {ERR_SYMBOL_DEFINED,     1, "symbol already defined, cannot redefine: "},
148
    {ERR_SYMBOL_UNDEFINED,   1, "symbol not defined: "},
149
    {ERR_MULTIDIMENSIONAL,   1, "multidimensional array not allowed: "},
150
    {ERR_UNFINISHED_VAR,     1, "unfinished variable declaration: "},
151
    {ERR_MISSING_EXPR,       1, "expecting expression: "},
152
    {ERR_CONFLICT_ARRAYSZ,   1, "conflicting array size: "},
153
    {ERR_CONFLICT_TYPE,      1, "conflicting type of symbol: "},
154
    {ERR_CONDITION,          1, "expression cannot be used for condition: "},
155
    {ERR_OVERFLOW,           1, "expression overflow: "},
156
    {ERR_WRONG_TYPE,         1, "wrong operand type for operator: "},
157
    {ERR_WRONG_TYPE_VAR,     1, "wrong or mismatched type for variable (must be int64, double, string, register, or memory operand): "},
158
    {ERR_WRONG_OPERANDS,     1, "wrong operands for this instruction: "},
159
    {ERR_MISSING_DESTINATION,1, "this instruction needs a destination: "},
160
    {ERR_NO_DESTINATION,     1, "this instruction should not have a destination: "},
161
    {ERR_NOT_OP_AMBIGUOUS,   0, "'!' operator is ambiguous. For booleans and masks replace !A by A^1. For numeric operands replace !A by A==0"},
162
    {ERR_TOO_COMPLEX,        1, "expression does not fit into a single instruction: "},
163
    {ERR_MASK_NOT_REGISTER,  1, "mask must be a register: "},
164
    {ERR_FALLBACK_WRONG,     1, "fallback must be a register 0-30 or zero: "},
165
    {ERR_CONSTANT_TOO_LARGE, 1, "constant too large for specified type: "},
166
    {ERR_ALIGNMENT,          1, "alignment must be a power of 2, not higher than 4096: "},  // maximum alignment value must equal MAX_ALIGN in assem.h
167
    {ERR_SECTION_DIFFERENT_TYPE,1, "redefinition of section is different type: "},
168
    {ERR_EXPECT_COLON,       1, "expecting colon after label: "},
169
    {ERR_STRING_TYPE,        1, "string must have type int8: "},
170
    {ERR_NONZERO_IN_BSS,     1, "data in uninitialized section must be zero: "},
171
    {ERR_SYMBOL_REDEFINED,   1, "symbol has been assigned more than one value: "},
172
    {ERR_EXPORT_EXPRESSION,  1, "cannot export expression: "},
173
    {ERR_CANNOT_EXPORT,      1, "cannot export: "},
174
    {ERR_CODE_WO_SECTION,    1, "code without section: "},
175
    {ERR_DATA_WO_SECTION,    1, "data without section: "},
176
    {ERR_MIX_DATA_AND_CODE,  1, "code and data in same section: "},
177
    {ERR_MUST_BE_CONSTANT,   1, "value must be constant: "},
178
    {ERR_MEM_COMPONENT_TWICE,1, "component of memory operand specified twice: "},
179
    {ERR_SCALE_FACTOR,       1, "wrong scale factor for this instruction: "},
180
    {ERR_MUST_BE_GP,         1, "vector length must be general purpose register: "},
181
    {ERR_LIMIT_AND_OFFSET,   1, "memory operand cannot have both limit and offset: "},
182
    {ERR_NOT_INSIDE_MEM,     1, "this option is not allowed inside memory operand: "},
183
    {ERR_TOO_MANY_OPERANDS,  1, "too many operands: "},
184
    {ERR_TOO_FEW_OPERANDS,   1, "not enough operands: "},
185
    {ERR_OPERANDS_WRONG_ORDER,1, "operands in wrong order. register operands must come first: "},
186
    {ERR_BOTH_MEM_AND_IMMEDIATE, 1, "this instruction cannot have both a memory operand and immediate constant: "},  // except store in format 2.7B and VARIANT_M1
187
    {ERR_BOTH_MEM_AND_OPTIONS, 1, "this instruction cannot have both a memory operand and options: "},
188
    {ERR_UNFINISHED_INSTRUCTION,  1, "unfinished instruction: "},
189
    {ERR_TYPE_MISSING,       1, "type must be specified: "},
190
    {ERR_MASK_FALLBACK_TYPE, 0, "mask and fallback must have same register type as destination"},
191
    {ERR_NEG_INDEX_LENGTH,   0, "length register must be the same as negative index register"},
192
    {ERR_INDEX_AND_LENGTH,   0, "memory operand cannot have length or broadcast with positive index"},
193
    {ERR_MASK_REGISTER,      0, "mask must be register 0-6"},
194
    {ERR_LIMIT_TOO_HIGH,     1, "limit on memory index cannot exceed 0xFFFF: "},
195
    {ERR_NO_INSTRUCTION_FIT, 1, "no version of this instruction fits the specified operands: "},
196
    {ERR_CANNOT_SWAP_VECT,   0, "cannot change the order of vector registers. if the vectors have the same length then put the register operands before the constant or memory operand"},
197
    {ERR_EXPECT_JUMP_TARGET, 1, "expecting jump target: "},
198
    {ERR_JUMP_TARGET_MISALIGN, 1, "jump target offset must be divisible by 4: "},
199
    {ERR_ABS_RELOCATION,     1, "absolute address not possible here: "},
200
    {ERR_RELOCATION_DOMAIN,  1, "cannot calculate difference between two symbols in different domains: "},
201
    {ERR_WRONG_REG_TYPE,     1, "wrong type for register operand: "},
202
    {ERR_CONFLICT_OPTIONS,   1, "conflicting options: "},
203
    {ERR_VECTOR_OPTION,      1, "vector option applied to non-vector operands: "},
204
    {ERR_LENGTH_OPTION_MISS, 1, "vector memory operand must have scalar, length, or broadcast option: "},
205
    {ERR_DEST_BROADCAST,     0, "memory destination cannot have broadcast"},
206
    {ERR_OFFSET_TOO_LARGE,   1, "address offset too large: "},
207
    {ERR_LIMIT_TOO_LARGE,    1, "limit too large: "},
208
    {ERR_IMMEDIATE_TOO_LARGE,1, "instruction format does not have space for full-size constant and option/signbits: "},
209
    {ERR_TOO_LARGE_FOR_JUMP, 1, "conditional jump does not have space for 64-bit constant: "},
210
    {ERR_CANNOT_HAVE_OPTION, 1, "this instruction cannot have options: "},
211
    {ERR_CANNOT_HAVEFALLBACK1, 1, "this instruction cannot have a fallback register: "},
212
    {ERR_CANNOT_HAVEFALLBACK2, 1, "the fallback must be the same as the first source operand when there is a memory operand with index or vector: "},
213
    {ERR_3OP_AND_FALLBACK,   1, "the fallback must be the same as the first source operand on instructions with three operands: "},
214
    {ERR_3OP_AND_MEM,        1, "the first source register must be the same as the destination when there is a memory operand with index or vector: "},
215
    {ERR_R28_30_BASE,        1, "cannot use r28-r30 as base pointer with more than 8 bits offset: "},
216
    {ERR_NO_BASE,            1, "memory operand has no base pointer: "},
217
    {ERR_MEM_WO_BRACKET,     1, "memory operand requires [] bracket: "},
218
    {ERR_UNKNOWN,            1, "unknown assembly error"},
219
    {ERR_UNMATCHED_END,      0, "unmatched end"},
220
    {ERR_SECTION_MISS_END,   1, "missing end of section: "},
221
    {ERR_FUNCTION_MISS_END,  1, "missing end of function: "},
222
    {ERR_ELSE_WO_IF,         1, "else without if: "},
223
    {ERR_EXPECT_PARENTHESIS, 1, "expecting parenthesis: "},
224
    {ERR_EXPECT_BRACKET,     1, "expecting '{' bracket: "},
225
    {ERR_EXPECT_LOGICAL,     1, "expecting logical expression: "},
226
    {ERR_MEM_NOT_ALLOWED,    1, "cannot have memory operand: "},
227
    //{ERR_MUST_BE_POW2,       1, "constant must have only one bit set: "},
228
    {ERR_WHILE_EXPECTED,     1, "'do' statement requires a 'while' here: "},
229
    {ERR_MISPLACED_BREAK,    1, "nothing: to break out of: "},
230
    {ERR_MISPLACED_CONTINUE, 1, "no loop to continue: "}
231
};
232
 
233
// buffer for text strings (this cannot be member of CMemoryBuffer because CErrorReporter must be defined before CMemoryBuffer)
234
static CMemoryBuffer strings;
235
 
236
// Members of class CErrorReporter: reporting of general errors
237
 
238
// Constructor for CErrorReporter
239
CErrorReporter::CErrorReporter() {
240
    numErrors = numWarnings = worstError = 0;
241
    maxWarnings = 50;      // Max number of warning messages to pring
242
    maxErrors = 50;      // Max number of error messages to print
243
}
244
 
245
SErrorText * CErrorReporter::FindError(int ErrorNumber) {
246
    // Search for error in ErrorTexts
247
    int e;
248
    const int ErrorTextsLength = sizeof(errorTexts) / sizeof(errorTexts[0]);
249
    for (e = 0; e < ErrorTextsLength; e++) {
250
        if (errorTexts[e].errorNumber == ErrorNumber) return errorTexts + e;
251
    }
252
    // Error number not found
253
    static SErrorText UnknownErr = errorTexts[0];
254
    UnknownErr.errorNumber = ErrorNumber;
255
    UnknownErr.status = 0x102;  // Unknown error
256
    return &UnknownErr;
257
}
258
 
259
 
260
void CErrorReporter::submit(int ErrorNumber) {
261
    // Print error message with no extra info
262
    SErrorText * err = FindError(ErrorNumber);
263
    handleError(err, err->text);
264
}
265
 
266
void CErrorReporter::submit(int ErrorNumber, int extra) {
267
    // Print error message with extra numeric info
268
    // ErrorTexts[ErrorNumber] must contain %i where extra is to be inserted
269
    SErrorText * err = FindError(ErrorNumber);
270
    strings.setSize((uint32_t)strlen(err->text) + 10);
271
    sprintf((char*)strings.buf(), err->text, extra);
272
    handleError(err, (char*)strings.buf());
273
}
274
 
275
void CErrorReporter::submit(int ErrorNumber, int extra1, int extra2) {
276
    // Print error message with 2 extra numeric values inserted
277
    // ErrorTexts[ErrorNumber] must contain two %i fields where extra numbers are to be inserted
278
    SErrorText * err = FindError(ErrorNumber);
279
    strings.setSize((uint32_t)strlen(err->text) + 20);
280
    sprintf((char*)strings.buf(), err->text, extra1, extra2);
281
    handleError(err, (char*)strings.buf());
282
}
283
 
284
void CErrorReporter::submit(int ErrorNumber, char const * extra) {
285
    // Print error message with extra text info
286
    // ErrorTexts[ErrorNumber] must contain %s where extra is to be inserted
287
    if (extra == 0) extra = "???";
288
    SErrorText * err = FindError(ErrorNumber);
289
    strings.setSize((uint32_t)strlen(err->text) + (uint32_t)strlen(extra));
290
    sprintf((char*)strings.buf(), err->text, extra);
291
    handleError(err, (char*)strings.buf());
292
}
293
 
294
void CErrorReporter::submit(int ErrorNumber, char const * extra1, char const * extra2) {
295
    // Print error message with two extra text info fields
296
    // ErrorTexts[ErrorNumber] must contain %s where extra texts are to be inserted
297
    if (extra1 == 0) extra1 = "???";
298
    if (extra2 == 0) extra2 = "???";
299
    SErrorText * err = FindError(ErrorNumber);
300
    strings.setSize((uint32_t)strlen(err->text) + (uint32_t)strlen(extra1) + (uint32_t)strlen(extra2));
301
    sprintf((char*)strings.buf(), err->text, extra1, extra2);
302
    handleError(err, (char*)strings.buf());
303
}
304
 
305
void CErrorReporter::submit(int ErrorNumber, char const * extra1, char const * extra2, char const * extra3) {
306
    // Print error message with three extra text info fields
307
    // ErrorTexts[ErrorNumber] must contain %s where extra texts are to be inserted
308
    if (extra1 == 0) extra1 = "???";
309
    if (extra2 == 0) extra2 = "???";
310
    if (extra3 == 0) extra3 = "???";
311
    SErrorText * err = FindError(ErrorNumber);
312
    strings.setSize((uint32_t)strlen(err->text) + (uint32_t)strlen(extra1) + (uint32_t)strlen(extra2) + (uint32_t)strlen(extra3));
313
    sprintf((char*)strings.buf(), err->text, extra1, extra2, extra3);
314
    handleError(err, (char*)strings.buf());
315
}
316
 
317
void CErrorReporter::submit(int ErrorNumber, int extra1, char const * extra2) {
318
    // Print error message with two extra text fields inserted
319
    // ErrorTexts[ErrorNumber] must contain %i and %s where extra texts are to be inserted
320
    if (extra2 == 0) extra2 = "???";
321
    SErrorText * err = FindError(ErrorNumber);
322
    strings.setSize((uint32_t)strlen(err->text) + 10 + (uint32_t)strlen(extra2));
323
    sprintf((char*)strings.buf(), err->text, extra1, extra2);
324
    handleError(err, (char*)strings.buf());
325
}
326
 
327
// Write an error message.
328
// To trace a runtime error message: set a breakpoint here !½
329
void CErrorReporter::handleError(SErrorText * err, char const * text) {
330
    // HandleError is used by submit functions
331
    // check severity
332
    int severity = err->status & 0x0F;
333
    if (severity == 0) {
334
        return;  // Ignore message
335
    }
336
    if (severity > 1 && err->errorNumber > worstError) {
337
        // Store highest error number
338
        worstError = err->errorNumber;
339
    }
340
    if (severity == 1) {
341
        // Treat message as warning
342
        if (++numWarnings > maxWarnings) return; // Maximum number of warnings has been printed
343
        // Treat message as warning
344
        fprintf(stderr, "\nWarning %i: %s", err->errorNumber, text);
345
        if (numWarnings == maxWarnings) {
346
            // Maximum number reached
347
            fprintf(stderr, "\nSupressing further warning messages");
348
        }
349
    }
350
    else {
351
        // Treat message as error
352
        if (++numErrors > maxErrors) return; // Maximum number of warnings has been printed
353
        fprintf(stderr, "\nError %i: %s", err->errorNumber, text);
354
        if (numErrors == maxErrors) {
355
            // Maximum number reached
356
            fprintf(stderr, "\nSupressing further warning messages");
357
        }
358
    }
359
    if (severity == 9) {
360
        // Abortion required
361
        fprintf(stderr, "\nAborting\n");
362
        exit(err->errorNumber);
363
    }
364
}
365
 
366
int CErrorReporter::number() {
367
    // Get number of fatal errors
368
    return numErrors;
369
}
370
 
371
int CErrorReporter::getWorstError() {
372
    // Get highest warning or error number encountered
373
    return worstError;
374
}
375
 
376
void CErrorReporter::clearError(int ErrorNumber) {
377
    // Ignore further occurrences of this error
378
    int e;
379
    const int ErrorTextsLength = sizeof(errorTexts) / sizeof(errorTexts[0]);
380
    for (e = 0; e < ErrorTextsLength; e++) {
381
        if (errorTexts[e].errorNumber == ErrorNumber) break;
382
    }
383
    if (e < ErrorTextsLength) {
384
        errorTexts[e].status = 0;
385
    }
386
}
387
 
388
 
389
 
390
// Members of class CAssemErrors: reporting of errors in assembly file
391
CAssemErrors::CAssemErrors() {                   // Constructor
392
    maxErrors = cmd.maxErrors;
393
}
394
 
395
void CAssemErrors::setOwner(CAssembler * a) {
396
    // Give access to CAssembler
397
    owner = a;
398
}
399
 
400
uint32_t CAssemErrors::numErrors() {
401
    // Return number of errors
402
    return list.numEntries();
403
}
404
 
405
bool CAssemErrors::tooMany() {
406
    // true if too many errors
407
    return list.numEntries() >= maxErrors;
408
}
409
 
410
// Report an error in assembly file
411
// To trace an assembly error: set a breakpoint here ½
412
void CAssemErrors::report(uint32_t position, uint32_t stringLength, uint32_t num) {
413
    // position: position in input file
414
    // stringLength: length of token
415
    // num = index into assemErrorTexts or token type
416
    owner->lineError = true;                         // avoid reporting multiple errors on same line
417
    uint32_t linei = owner->linei;
418
    if (linei < owner->lines.numEntries()) {
419
        owner->lines[owner->linei].type = LINE_ERROR;    // mark current line as error
420
    }
421
    if (tooMany()) return;
422
 
423
    SAssemError e;
424
    e.pos = position;
425
    e.stringLength = stringLength;
426
    e.file = owner->filei;
427
    e.num = num;
428
    e.pass = owner->pass;
429
 
430
    // save error record
431
    list.push(e);
432
}
433
 
434
// Report a misplaced token
435
void CAssemErrors::report(SToken const & token) {
436
    report(token.pos, token.stringLength, token.type);
437
}
438
 
439
// Report an error in current line
440
void CAssemErrors::reportLine(uint32_t num) {
441
    int tokenB = owner->lines[owner->linei].firstToken;
442
    int tokenN = owner->lines[owner->linei].numTokens;
443
    if (tokenB <= 0 || tokenN <= 0) {
444
        num = ERR_UNKNOWN;
445
        tokenB = 0;
446
        tokenN = 1;
447
    }
448
    report(owner->tokens[tokenB].pos,
449
        owner->tokens[tokenB + tokenN - 1].pos + owner->tokens[tokenB + tokenN - 1].stringLength - owner->tokens[tokenB].pos, num);
450
}
451
 
452
void CAssemErrors::outputErrors() {
453
    // Output errors to STDERR
454
    const uint32_t tabstops = 8;                      // default position of tabstops
455
 
456
    if (list.numEntries() == 0) return;
457
    const char * text1;
458
    char text2[256];
459
    const char * filename = cmd.getFilename(cmd.inputFile); // owner->fileName; // to do: support include filenames
460
    const uint32_t errorTextsLength = TableSize(assemErrorTexts);
461
    uint32_t i, j, texti;
462
 
463
    uint32_t lastPass = 0;
464
    for (i = 0; i < list.numEntries() && i < maxErrors; i++) {
465
        // tell which pass if verbose option
466
        if (list[i].pass != lastPass && cmd.verbose) {
467
            printf("\n\nDuring pass %i:", list[i].pass);
468
            lastPass = list[i].pass;
469
        }
470
 
471
        // find line containing error
472
        uint32_t line;
473
        uint32_t numLines = owner->lines.numEntries();
474
        uint32_t pos = list[i].pos;
475
        for (line = 0; line < numLines; line++) {
476
            if (pos < owner->lines[line].beginPos) break;
477
        }
478
        line--;
479
        // if this line has multiple records in lines[] then find the first one
480
        j = line;
481
        while (j > 0 && owner->lines[j - 1].linenum == owner->lines[line].linenum) j--;
482
        line = j;
483
 
484
        // find column
485
        uint32_t pos1 = owner->lines[line].beginPos;
486
        uint32_t stringLength = list[i].stringLength;
487
        uint32_t column = pos - pos1;
488
        // count UTF-8 multibyte characters in line up to error position
489
        int32_t extraBytes = 0;
490
        int8_t c;   // current character
491
        for (uint32_t pp = pos1; pp < pos1 + column; pp++) {
492
            if (pp >= owner->dataSize()) break;
493
            c = *(owner->buf() + pp);
494
            if ((c & 0xC0) == 0xC0) extraBytes--;   // count UTF-8 continuation bytes
495
            if (c == '\t') {
496
                uint32_t pos2 = (pp + tabstops) % tabstops;  // find next tabstop
497
                extraBytes += pos2 - pp - 1;
498
            }
499
        }
500
        // adjust column number to 1-based. count UTF-8 characters as one
501
        column += extraBytes + 1;
502
 
503
        // find text
504
        texti = list[i].num;
505
        for (j = 0; j < errorTextsLength; j++) {
506
            if ((uint32_t)assemErrorTexts[j].errorNumber == texti) break;
507
        }
508
        if (j >= errorTextsLength) j = 0;
509
        text1 = assemErrorTexts[j].text;
510
        if (assemErrorTexts[j].status && stringLength < sizeof(text2)) {
511
            // extra text required
512
            memcpy(text2, owner->buf() + pos, stringLength);
513
            text2[stringLength] = 0;
514
        }
515
        else text2[0] = 0;
516
 
517
        if (filename) {
518
            fprintf(stderr, "\n%s:", filename);
519
        }
520
        else {
521
            fprintf(stderr, "\n");
522
        }
523
        fprintf(stderr, "%i:%i: %s%s", owner->lines[line].linenum, column, text1, text2);
524
    }
525
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.