refactored error/warning stuff

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@404 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-08-28 16:45:31 +00:00
parent ec4db48d07
commit be1b072288
19 changed files with 274 additions and 238 deletions

View File

@ -27,6 +27,7 @@
#define PLATFORM_SETFILETYPE_TEXT(a)
// platform specific message output
#define PLATFORM_INFO(a)
#define PLATFORM_WARNING(a)
#define PLATFORM_ERROR(a)
#define PLATFORM_SERIOUS(a)

View File

@ -27,6 +27,7 @@
#define PLATFORM_SETFILETYPE_TEXT(a)
// platform specific message output
#define PLATFORM_INFO(a)
#define PLATFORM_WARNING(a)
#define PLATFORM_ERROR(a)
#define PLATFORM_SERIOUS(a)

View File

@ -30,6 +30,7 @@
#define PLATFORM_SETFILETYPE_TEXT(a) RISCOS_set_filetype(a, 0xfff)
// platform specific message output
#define PLATFORM_INFO(a) RISCOS_throwback(a, 0)
#define PLATFORM_WARNING(a) RISCOS_throwback(a, 0)
#define PLATFORM_ERROR(a) RISCOS_throwback(a, 1)
#define PLATFORM_SERIOUS(a) RISCOS_throwback(a, 2)

View File

@ -27,6 +27,7 @@
#define PLATFORM_SETFILETYPE_TEXT(a)
// platform specific message output
#define PLATFORM_INFO(a)
#define PLATFORM_WARNING(a)
#define PLATFORM_ERROR(a)
#define PLATFORM_SERIOUS(a)

View File

@ -333,6 +333,7 @@ static void save_output_file(void)
#define PF_COMPLAIN_ABOUT_UNDEFINEDS (1u << 0) // throw "Symbol not defined" errors
#define PF_THROW_SEGMENT_MESSAGES (1u << 1) // throw segment warnings/errors
#define PF_GENERATE_OUTPUT (1u << 2) // generate output and/or report file
#define PF_IS_FINAL_PASS (1u << 3) // mostly for special warnings
// perform a single pass
static void perform_pass(bits passflags)
@ -347,6 +348,7 @@ static void perform_pass(bits passflags)
pass.counters.errors = 0;
pass.counters.warnings = 0;
pass.flags.complain_about_undefined = !!(passflags & PF_COMPLAIN_ABOUT_UNDEFINEDS);
pass.flags.is_final_pass = !!(passflags & PF_IS_FINAL_PASS);
pass.flags.throw_segment_messages = !!(passflags & PF_THROW_SEGMENT_MESSAGES);
pass.flags.generate_output = !!(passflags & PF_GENERATE_OUTPUT);
@ -439,19 +441,19 @@ static void do_actual_work(void)
}
}
// last pass:
// final pass:
// any errors left?
if (pass.counters.undefineds == 0) { // FIXME - use pass.counters.needvalue instead!
// victory lap
if (config.process_verbosity >= 2)
puts("Extra pass to generate output.");
perform_pass(PF_GENERATE_OUTPUT);
perform_pass(PF_IS_FINAL_PASS | PF_GENERATE_OUTPUT);
} else {
// There are still errors (unsolvable by doing further passes),
// so perform additional pass to find and show them.
if (config.process_verbosity >= 2)
puts("Extra pass to display errors.");
perform_pass(PF_COMPLAIN_ABOUT_UNDEFINEDS); // perform pass, but now show "value undefined"
perform_pass(PF_IS_FINAL_PASS | PF_COMPLAIN_ABOUT_UNDEFINEDS); // perform pass, but now show "value undefined"
// FIXME - perform_pass() calls exit() when there were errors,
// so if controls returns here, call BUG()!
// (this can be triggered using ifdef/ifndef)

100
src/alu.c
View File

@ -250,7 +250,7 @@ static void enlarge_operator_stack(void)
//printf("Doubling op stack size to %d.\n", opstack_size);
op_stack = realloc(op_stack, opstack_size * sizeof(*op_stack));
if (op_stack == NULL)
Throw_serious_error(exception_no_memory_left);
throw_serious_error(exception_no_memory_left);
}
@ -261,7 +261,7 @@ static void enlarge_argument_stack(void)
//printf("Doubling arg stack size to %d.\n", argstack_size);
arg_stack = realloc(arg_stack, argstack_size * sizeof(*arg_stack));
if (arg_stack == NULL)
Throw_serious_error(exception_no_memory_left);
throw_serious_error(exception_no_memory_left);
}
@ -332,7 +332,7 @@ static void is_not_defined(struct symbol *optional_symbol, char *name, size_t le
}
dynabuf_add_string(errormsg_dyna_buf, ").");
dynabuf_append(errormsg_dyna_buf, '\0');
Throw_error(errormsg_dyna_buf->buffer);
throw_error(errormsg_dyna_buf->buffer);
}
@ -367,7 +367,7 @@ static void get_symbol_value(scope_t scope, size_t name_length, unsigned int unp
if (arg->type == &type_number) {
pseudopc_unpseudo(&arg->u.number, symbol->pseudopc, unpseudo_count);
} else {
Throw_error("Un-pseudopc operator '&' can only be applied to number symbols.");
throw_error("Un-pseudopc operator '&' can only be applied to number symbols.");
}
}
// if needed, output "value not defined" error
@ -438,13 +438,13 @@ static void parse_quoted(char closing_quote)
// single character ////////////////////////
// too short?
if (GlobalDynaBuf->size == 0) {
Throw_error(exception_missing_string);
throw_error(exception_missing_string);
goto fail;
}
// too long?
if (GlobalDynaBuf->size != 1)
Throw_error("There's more than one character.");
throw_error("There's more than one character.");
// parse character
value = encoding_encode_char(GLOBALDYNABUF_CURRENT[0]);
PUSH_INT_ARG(value, 0, 0); // no flags, no addr refs
@ -482,11 +482,10 @@ static void parse_binary_literal(void) // Now GotByte = "%" or "b"
break; // found illegal character
}
if (!digits) {
Throw_error("Binary literal without any digits.");
throw_error("Binary literal without any digits.");
}
if (digits & config.warn_bin_mask) {
if (pass.number == 1)
Throw_warning("Binary literal with strange number of digits.");
throw_finalpass_warning("Binary literal with strange number of digits.");
}
// set force bits
if (config.honor_leading_zeroes) {
@ -534,7 +533,7 @@ static void parse_hex_literal(void) // Now GotByte = "$" or "x"
break; // found illegal character
}
if (!digits)
Throw_error("Hex literal without any digits.");
throw_error("Hex literal without any digits.");
// set force bits
if (config.honor_leading_zeroes) {
if (digits > 2) {
@ -657,7 +656,7 @@ static void parse_function_call(void)
if (tree_easy_scan(function_tree, &node_body, function_dyna_buf)) {
PUSH_OP((struct op *) node_body);
} else {
Throw_error("Unknown function.");
throw_error("Unknown function.");
alu_state = STATE_ERROR;
}
}
@ -732,7 +731,7 @@ static int parse_octal_or_unpseudo(void) // now GotByte = '&'
// // anonymous symbol
// "unpseudo"-ing anonymous symbols is not supported
} else {
Throw_error(exception_missing_string); // FIXME - create some "expected octal value or symbol name" error instead!
throw_error(exception_missing_string); // FIXME - create some "expected octal value or symbol name" error instead!
return 1; // error
}
return 0; // ok
@ -784,7 +783,7 @@ static void handle_special_operator(struct expression *expression, enum op_id pr
alu_state = STATE_EXPECT_DYADIC_OP;
} else {
// unmatched bracket
Throw_error("Unterminated list.");
throw_error("Unterminated list.");
alu_state = STATE_ERROR;
// remove previous operator by overwriting with newest one...
PREVIOUS_OPERATOR = NEWEST_OPERATOR;
@ -798,7 +797,7 @@ static void handle_special_operator(struct expression *expression, enum op_id pr
alu_state = STATE_EXPECT_DYADIC_OP;
} else {
// unmatched bracket
Throw_error("Unterminated index spec.");
throw_error("Unterminated index spec.");
alu_state = STATE_ERROR;
// remove previous operator by overwriting with newest one...
PREVIOUS_OPERATOR = NEWEST_OPERATOR;
@ -1053,7 +1052,7 @@ static boolean expect_argument_or_monadic_operator(struct expression *expression
if (op_stack[op_sp - 1] == &ops_start_expression) {
push_dyadic_and_check(expression, &ops_terminating_char);
} else {
Throw_error(exception_syntax);
throw_error(exception_syntax);
alu_state = STATE_ERROR;
}
return FALSE; // found delimiter
@ -1131,8 +1130,7 @@ static void expect_dyadic_operator(struct expression *expression)
if (GetByte() == '=') {
GetByte(); // eat second '=' character
} else {
//if (pass.number == 1)
// Throw_warning("old-style \"=\" comparison detected, please use \"==\" instead."); ACTIVATE!
//throw_finalpass_warning("old-style \"=\" comparison detected, please use \"==\" instead."); ACTIVATE!
}
goto push_dyadic_op;
@ -1211,7 +1209,7 @@ static void expect_dyadic_operator(struct expression *expression)
goto push_dyadic_op;
}
Throw_error("Unknown operator.");
throw_error("Unknown operator.");
alu_state = STATE_ERROR;
//goto end;
} else {
@ -1252,7 +1250,7 @@ static void unsupported_operation(const struct object *optional, const struct op
dynabuf_add_string(errormsg_dyna_buf, arg->type->name);
dynabuf_add_string(errormsg_dyna_buf, "\".");
dynabuf_append(errormsg_dyna_buf, '\0');
Throw_error(errormsg_dyna_buf->buffer);
throw_error(errormsg_dyna_buf->buffer);
}
@ -1430,7 +1428,7 @@ static void number_assign(struct object *self, const struct object *new_value, b
// symbol is already defined, so compare new and old values
// if values differ, complain and return
if (number_differs(self, new_value)) {
Throw_error(exception_symbol_defined);
throw_error(exception_symbol_defined);
return;
}
// values are the same, so only fiddle with flags
@ -1458,7 +1456,7 @@ static void number_assign(struct object *self, const struct object *new_value, b
static void list_assign(struct object *self, const struct object *new_value, boolean accept_change)
{
if ((!accept_change) && list_differs(self, new_value)) {
Throw_error(exception_symbol_defined);
throw_error(exception_symbol_defined);
return;
}
*self = *new_value;
@ -1469,7 +1467,7 @@ static void list_assign(struct object *self, const struct object *new_value, boo
static void string_assign(struct object *self, const struct object *new_value, boolean accept_change)
{
if ((!accept_change) && string_differs(self, new_value)) {
Throw_error(exception_symbol_defined);
throw_error(exception_symbol_defined);
return;
}
*self = *new_value;
@ -1581,7 +1579,7 @@ static void float_ranged_fn(double (*fn)(double), struct object *self)
if ((self->u.number.val.fpval >= -1) && (self->u.number.val.fpval <= 1)) {
self->u.number.val.fpval = fn(self->u.number.val.fpval);
} else {
Throw_error("Argument out of range."); // TODO - add number output to error message
throw_error("Argument out of range."); // TODO - add number output to error message
self->u.number.val.fpval = 0;
}
}
@ -1796,8 +1794,7 @@ static void undef_handle_dyadic_operator(struct object *self, const struct op *o
goto shared;
case OPID_EOR:
if (pass.number == 1)
Throw_warning("\"EOR\" is deprecated; use \"XOR\" instead.");
throw_finalpass_warning("\"EOR\" is deprecated; use \"XOR\" instead."); // FIXME - change to error, at least for newest dialect!
/*FALLTHROUGH*/
case OPID_XOR:
case OPID_AND:
@ -1858,8 +1855,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
case OPID_EOR:
case OPID_XOR:
// convert other to int, warning user
if (pass.number == 1)
Throw_warning(exception_float_to_int); // FIXME - warning is never seen if arguments are undefined in first pass!
throw_finalpass_warning(exception_float_to_int);
/*FALLTHROUGH*/
case OPID_MODULO:
case OPID_SHIFTLEFT:
@ -1892,7 +1888,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
if (other->u.number.val.intval >= 0) {
self->u.number.val.intval = my_pow(self->u.number.val.intval, other->u.number.val.intval);
} else {
Throw_error("Exponent is negative.");
throw_error("Exponent is negative.");
self->u.number.val.intval = 0;
}
break;
@ -1911,7 +1907,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
if (other->u.number.val.intval) {
self->u.number.val.intval %= other->u.number.val.intval;
} else {
Throw_error(exception_div_by_zero);
throw_error(exception_div_by_zero);
self->u.number.val.intval = 0;
}
break;
@ -1965,8 +1961,7 @@ static void int_handle_dyadic_operator(struct object *self, const struct op *op,
refs = self->u.number.addr_refs + other->u.number.addr_refs; // add address references
break;
case OPID_EOR:
if (pass.number == 1)
Throw_warning("\"EOR\" is deprecated; use \"XOR\" instead.");
throw_finalpass_warning("\"EOR\" is deprecated; use \"XOR\" instead."); // FIXME - change to error, at least for newest dialect!
/*FALLTHROUGH*/
case OPID_XOR:
self->u.number.val.intval ^= other->u.number.val.intval;
@ -2049,7 +2044,7 @@ static void float_handle_dyadic_operator(struct object *self, const struct op *o
if (other->u.number.val.fpval) {
self->u.number.val.fpval /= other->u.number.val.fpval;
} else {
Throw_error(exception_div_by_zero);
throw_error(exception_div_by_zero);
self->u.number.val.fpval = 0;
}
break;
@ -2057,7 +2052,7 @@ static void float_handle_dyadic_operator(struct object *self, const struct op *o
if (other->u.number.val.fpval) {
self->u.number.val.intval = self->u.number.val.fpval / other->u.number.val.fpval; // fp becomes int!
} else {
Throw_error(exception_div_by_zero);
throw_error(exception_div_by_zero);
self->u.number.val.intval = 0;
}
self->u.number.ntype = NUMTYPE_INT; // result is int
@ -2067,8 +2062,7 @@ static void float_handle_dyadic_operator(struct object *self, const struct op *o
case OPID_OR:
case OPID_EOR:
case OPID_XOR:
if (pass.number == 1)
Throw_warning(exception_float_to_int); // FIXME - warning is never seen if arguments are undefined in first pass!
throw_finalpass_warning(exception_float_to_int);
/*FALLTHROUGH*/
case OPID_MODULO:
float_to_int(self);
@ -2163,7 +2157,7 @@ static int get_valid_index(int *target, int length, const struct object *self, c
return 1;
}
if (other->u.number.ntype == NUMTYPE_UNDEFINED) {
Throw_error("Index is undefined.");
throw_error("Index is undefined.");
return 1;
}
if (other->u.number.ntype == NUMTYPE_FLOAT)
@ -2176,7 +2170,7 @@ static int get_valid_index(int *target, int length, const struct object *self, c
if (index < 0)
index += length;
if ((index < 0) || (index >= length)) {
Throw_error("Index out of range.");
throw_error("Index out of range.");
return 1;
}
*target = index;
@ -2550,9 +2544,9 @@ void ALU_any_int(intval_t *target) // ACCEPT_UNDEFINED
parse_expression(&expression); // FIXME - check return value and pass to caller!
if (expression.open_parentheses)
Throw_error(exception_paren_open);
throw_error(exception_paren_open);
if (expression.is_empty)
Throw_error(exception_no_value);
throw_error(exception_no_value);
if (expression.result.type == &type_number) {
if (expression.result.u.number.ntype == NUMTYPE_UNDEFINED)
*target = 0;
@ -2566,7 +2560,7 @@ void ALU_any_int(intval_t *target) // ACCEPT_UNDEFINED
// accept single-char strings, to be more
// compatible with versions before 0.97:
if (expression.result.u.string->length != 1) {
Throw_error(exception_lengthnot1);
throw_error(exception_lengthnot1);
} else {
// FIXME - throw a warning?
}
@ -2574,7 +2568,7 @@ void ALU_any_int(intval_t *target) // ACCEPT_UNDEFINED
*target = expression.result.u.number.val.intval;
} else {
*target = 0;
Throw_error(exception_not_number);
throw_error(exception_not_number);
}
}
@ -2604,12 +2598,12 @@ or
throws errors even though the result is defined!
*/
if (expression.open_parentheses)
Throw_error(exception_paren_open);
throw_error(exception_paren_open);
if (expression.is_empty)
Throw_serious_error(exception_no_value);
throw_serious_error(exception_no_value);
if (expression.result.type == &type_number) {
if (expression.result.u.number.ntype == NUMTYPE_UNDEFINED) {
Throw_serious_error("Value not defined.");
throw_serious_error("Value not defined.");
expression.result.u.number.val.intval = 0;
} else if (expression.result.u.number.ntype == NUMTYPE_INT) {
// ok
@ -2622,13 +2616,13 @@ throws errors even though the result is defined!
// accept single-char strings, to be more
// compatible with versions before 0.97:
if (expression.result.u.string->length != 1) {
Throw_error(exception_lengthnot1);
throw_error(exception_lengthnot1);
} else {
// FIXME - throw a warning?
}
string_to_byte(&(expression.result), 0);
} else {
Throw_serious_error(exception_not_number);
throw_serious_error(exception_not_number);
}
*intresult = expression.result.u.number;
}
@ -2655,20 +2649,20 @@ void ALU_addrmode_int(struct expression *expression, int paren) // ACCEPT_UNDEFI
// accept single-char strings, to be more
// compatible with versions before 0.97:
if (expression->result.u.string->length != 1) {
Throw_error(exception_lengthnot1);
throw_error(exception_lengthnot1);
} else {
// FIXME - throw a warning?
}
string_to_byte(&(expression->result), 0);
} else {
Throw_error(exception_not_number);
throw_error(exception_not_number);
}
if (expression->open_parentheses > paren) {
expression->open_parentheses = 0;
Throw_error(exception_paren_open);
throw_error(exception_paren_open);
}
if (expression->is_empty)
Throw_error(exception_no_value);
throw_error(exception_no_value);
}
@ -2685,9 +2679,9 @@ void ALU_any_result(struct object *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT
parse_expression(&expression); // FIXME - check return value and pass to caller!
*result = expression.result;
if (expression.open_parentheses)
Throw_error(exception_paren_open);
throw_error(exception_paren_open);
if (expression.is_empty)
Throw_error(exception_no_value);
throw_error(exception_no_value);
}
@ -2695,7 +2689,7 @@ void ALU_any_result(struct object *result) // ACCEPT_UNDEFINED | ACCEPT_FLOAT
maybe move
if (expression.is_empty)
Throw_error(exception_no_value);
throw_error(exception_no_value);
to end of parse_expression()

View File

@ -130,7 +130,7 @@ const struct cpu_type *cputype_find(void)
void vcpu_check_and_set_reg_length(boolean *var, boolean make_long)
{
if (((cpu_current_type->flags & CPUFLAG_SUPPORTSLONGREGS) == 0) && make_long)
Throw_error("Chosen CPU does not support long registers.");
throw_error("Chosen CPU does not support long registers.");
else
*var = make_long;
}

View File

@ -38,7 +38,7 @@ static void resize(struct dynabuf *db, size_t new_size)
//printf("Growing dynabuf to size %d.\n", new_size);
new_buf = realloc(db->buffer, new_size);
if (new_buf == NULL)
Throw_serious_error(exception_no_memory_left);
throw_serious_error(exception_no_memory_left);
db->reserved = new_size;
db->buffer = new_buf;
}

View File

@ -192,7 +192,7 @@ void flow_store_doloop_condition(struct condition *condition, char terminator)
} else if (strcmp(GlobalDynaBuf->buffer, "until") == 0) {
condition->invert = TRUE;
} else {
Throw_error("Expected WHILE or UNTIL keyword, or an empty loop condition.");
throw_error("Expected WHILE or UNTIL keyword, or an empty loop condition.");
return;
}
// write given condition into buffer
@ -230,7 +230,7 @@ static boolean check_condition(struct condition *condition)
GetByte(); // proceed with next char
ALU_defined_int(&intresult);
if (GotByte)
Throw_serious_error("Unexpected char when evaluating loop condition."); // FIXME - include that char in the error message!
throw_serious_error("Unexpected char when evaluating loop condition."); // FIXME - include that char in the error message!
return condition->invert ? !intresult.val.intval : !!intresult.val.intval;
}

View File

@ -143,7 +143,7 @@ void *safe_malloc(size_t size)
void *block = malloc(size);
if (block == NULL)
Throw_serious_error(exception_no_memory_left);
throw_serious_error(exception_no_memory_left);
return block;
}
@ -197,7 +197,7 @@ extern void parser_set_nowarn_prefix(void)
static int first_symbol_of_statement(void)
{
if (statement_flags & SF_FOUND_SYMBOL) {
Throw_error("Unknown mnemonic");
throw_error("Unknown mnemonic");
parser_skip_remainder();
return FALSE;
}
@ -216,8 +216,7 @@ static void set_label(scope_t scope, bits force_bit, bits powers)
struct object result;
if ((statement_flags & SF_FOUND_BLANK) && config.warn_on_indented_labels) {
if (pass.number == 1)
Throw_warning("Label name not in leftmost column.");
throw_finalpass_warning("Label name not in leftmost column.");
}
symbol = symbol_find(scope);
result.type = &type_number;
@ -288,8 +287,7 @@ static void parse_mnemo_or_global_symbol_def(void)
// 17 May 2014: now it works for UTF-8 as well.
if ((*GLOBALDYNABUF_CURRENT == (char) 0xa0)
|| ((GlobalDynaBuf->size >= 2) && (GLOBALDYNABUF_CURRENT[0] == (char) 0xc2) && (GLOBALDYNABUF_CURRENT[1] == (char) 0xa0))) {
if (pass.number == 1)
Throw_warning("Symbol name starts with a shift-space character.");
throw_finalpass_warning("Symbol name starts with a shift-space character.");
}
parse_symbol_definition(SCOPE_GLOBAL);
}
@ -399,7 +397,7 @@ void parse_until_eob_or_eof(void)
if (BYTE_STARTS_KEYWORD(GotByte)) {
parse_mnemo_or_global_symbol_def();
} else {
Throw_error(exception_syntax); // FIXME - include char in error message!
throw_error(exception_syntax); // FIXME - include char in error message!
parser_skip_remainder();
}
}
@ -423,7 +421,7 @@ int parse_optional_block(void)
parse_until_eob_or_eof();
if (GotByte != CHAR_EOB)
Throw_serious_error(exception_no_right_brace);
throw_serious_error(exception_no_right_brace);
GetByte();
return TRUE;
}
@ -451,7 +449,7 @@ void parse_source_code_file(FILE *fd, const char *eternal_plat_filename)
// parse block and check end reason
parse_until_eob_or_eof();
if (GotByte != CHAR_EOF)
Throw_error("Expected EOF, found '}' instead." );
throw_error("Expected EOF, found '}' instead." );
// restore outer input
inputchange_back(&icb);
@ -476,7 +474,7 @@ bits parser_get_force_bit(void)
if (force_bit)
GetByte();
else
Throw_error("Illegal postfix.");
throw_error("Illegal postfix.");
}
SKIPSPACE();
return force_bit;
@ -489,7 +487,7 @@ bits parser_get_force_bit(void)
// errors. It shows the given message string, as well as the current
// context: file name, line number, source type and source title.
// if the "optional alternative location" given is NULL, the current location is used
static void throw_msg(const char *message, const char *ansicolor, const char *type, struct location *opt_alt_loc)
static void print_msg(const char *message, const char *ansicolor, const char *type, struct location *opt_alt_loc)
{
const char *resetcolor = "\033[0m";
struct location location;
@ -531,14 +529,14 @@ void throw_message(enum debuglevel level, const char msg[], struct location *opt
// output a serious error
// (assembly stops, for example if outbuffer overruns).
PLATFORM_SERIOUS(msg);
throw_msg(msg, "\033[1m\033[31m", "Serious error", opt_alt_loc); // bold + red
print_msg(msg, "\033[1m\033[31m", "Serious error", opt_alt_loc); // bold + red
//++pass.counters.errors; // FIXME - needed when problem below is solved
exit(ACME_finalize(EXIT_FAILURE)); // FIXME - this inhibits output of macro call stack
case DEBUGLEVEL_ERROR:
// output an error
// (something is wrong, no output file will be generated).
PLATFORM_ERROR(msg);
throw_msg(msg, "\033[31m", "Error", opt_alt_loc); // red
print_msg(msg, "\033[31m", "Error", opt_alt_loc); // red
++pass.counters.errors;
if (pass.counters.errors >= config.max_errors)
exit(ACME_finalize(EXIT_FAILURE));
@ -550,7 +548,7 @@ void throw_message(enum debuglevel level, const char msg[], struct location *opt
if (in_nowarn_block || (statement_flags & SF_NOWARN_PREFIX))
break;
PLATFORM_WARNING(msg);
throw_msg(msg, "\033[33m", "Warning", opt_alt_loc); // yellow
print_msg(msg, "\033[33m", "Warning", opt_alt_loc); // yellow
++pass.counters.warnings;
// then check if warnings should be handled like errors:
if (config.all_warnings_are_errors) {
@ -560,15 +558,53 @@ void throw_message(enum debuglevel level, const char msg[], struct location *opt
}
break;
case DEBUGLEVEL_INFO:
throw_msg(msg, "\033[32m", "Info", opt_alt_loc); // green
PLATFORM_INFO(msg);
print_msg(msg, "\033[32m", "Info", opt_alt_loc); // green
break;
default:
// debug
throw_msg(msg, "\033[36m", "Debug", opt_alt_loc); // cyan
print_msg(msg, "\033[36m", "Debug", opt_alt_loc); // cyan
break;
}
}
// output a warning (something looks wrong)
void throw_warning(const char msg[])
{
throw_message(DEBUGLEVEL_WARNING, msg, NULL);
}
// output an error (something is wrong, no output file will be generated).
// the assembler will try to go on with the assembly, so the user gets to know
// about more than one of his typos at a time.
void throw_error(const char msg[])
{
throw_message(DEBUGLEVEL_ERROR, msg, NULL);
}
// output a serious error (assembly stops, for example if outbuffer overruns).
extern void throw_serious_error(const char msg[])
{
throw_message(DEBUGLEVEL_SERIOUS, msg, NULL);
}
// output a warning, but only if we are in first pass, otherwise suppress
// (only use this if using throw_finalpass_warning is impossible,
// for example in cases where the code is skipped in later passes)
void throw_pass1_warning(const char msg[])
{
if (pass.number == 1)
throw_warning(msg);
}
// output a warning, but only if we are in final pass, otherwise suppress
// (for example "converted float to int for XOR" -> must be done in
// final pass because values might be undefined earlier!)
void throw_finalpass_warning(const char msg[])
{
if (pass.flags.is_final_pass)
throw_warning(msg);
}
// throw "macro twice" error (FIXME - also use for "symbol twice"!)
// first output a warning, then an error, this guarantees that ACME does not
@ -592,30 +628,28 @@ void throw_redef_error(struct location *old_def, const char msg[])
section_now->type = buffered_section_type;
section_now->title = buffered_section_title;
// show error with location of current definition
Throw_error(msg);
throw_error(msg);
}
// process error that might vanish if symbols change:
// if current pass is an "error output" pass, actually throw error.
// otherwise just increment counter to let mainloop know this pass wasn't successful.
void throw_symbol_error(const char *msg)
{
// atm we just mimic the old behaviour. in future, do something like this:
//if (pass.is_error_pass)
Throw_error(msg);
//else
//++pass.symbol_errors;
}
// handle bugs
// FIXME - use a local buffer and sprintf/snprintf to put error code into message!
void BUG(const char *message, int code)
{
Throw_warning("Bug in ACME, code follows");
throw_warning("Bug in ACME, code follows");
fprintf(stderr, "(0x%x:)", code);
Throw_serious_error(message);
throw_serious_error(message);
}
// process error that might vanish if symbols change:
// if current pass is an "error output" pass, actually throw error.
// otherwise just increment counter to let mainloop know this pass wasn't successful.
void countorthrow_value_error(const char *msg)
{
// atm we just mimic the old behaviour. in future, do something like this:
//if (pass.is_error_pass)
throw_error(msg);
//else
//++pass.counters.suppressed_errors;
}
@ -652,7 +686,7 @@ void output_object(struct object *object, struct iter_context *iter)
while (length--)
iter->fn(iter->stringxor ^ encoding_encode_char(*(read++)));
} else {
Throw_error("There's more than one character."); // see alu.c for the original of this error
throw_error("There's more than one character."); // see alu.c for the original of this error
}
} else {
BUG("IllegalObjectType", 0);
@ -664,7 +698,7 @@ void output_object(struct object *object, struct iter_context *iter)
void output_8(intval_t value)
{
if ((value < -0x80) || (value > 0xff))
throw_symbol_error(exception_number_out_of_8b_range);
countorthrow_value_error(exception_number_out_of_8b_range);
output_byte(value);
}
@ -673,7 +707,7 @@ void output_8(intval_t value)
void output_be16(intval_t value)
{
if ((value < -0x8000) || (value > 0xffff))
throw_symbol_error(exception_number_out_of_16b_range);
countorthrow_value_error(exception_number_out_of_16b_range);
output_byte(value >> 8);
output_byte(value);
}
@ -683,7 +717,7 @@ void output_be16(intval_t value)
void output_le16(intval_t value)
{
if ((value < -0x8000) || (value > 0xffff))
throw_symbol_error(exception_number_out_of_16b_range);
countorthrow_value_error(exception_number_out_of_16b_range);
output_byte(value);
output_byte(value >> 8);
}
@ -693,7 +727,7 @@ void output_le16(intval_t value)
void output_be24(intval_t value)
{
if ((value < -0x800000) || (value > 0xffffff))
throw_symbol_error(exception_number_out_of_24b_range);
countorthrow_value_error(exception_number_out_of_24b_range);
output_byte(value >> 16);
output_byte(value >> 8);
output_byte(value);
@ -704,7 +738,7 @@ void output_be24(intval_t value)
void output_le24(intval_t value)
{
if ((value < -0x800000) || (value > 0xffffff))
throw_symbol_error(exception_number_out_of_24b_range);
countorthrow_value_error(exception_number_out_of_24b_range);
output_byte(value);
output_byte(value >> 8);
output_byte(value >> 16);
@ -721,7 +755,7 @@ void output_le24(intval_t value)
void output_be32(intval_t value)
{
// if ((value < -0x80000000) || (value > 0xffffffff))
// throw_symbol_error(exception_number_out_of_32b_range);
// countorthrow_value_error(exception_number_out_of_32b_range);
output_byte(value >> 24);
output_byte(value >> 16);
output_byte(value >> 8);
@ -733,7 +767,7 @@ void output_be32(intval_t value)
void output_le32(intval_t value)
{
// if ((value < -0x80000000) || (value > 0xffffffff))
// throw_symbol_error(exception_number_out_of_32b_range);
// countorthrow_value_error(exception_number_out_of_32b_range);
output_byte(value);
output_byte(value >> 8);
output_byte(value >> 16);

View File

@ -110,15 +110,17 @@ struct pass {
int undefineds; // counts undefined expression results (if this stops decreasing, next pass must list them as errors)
//int needvalue; // counts undefined expression results actually needed for output (when this hits zero, we're done) FIXME - use
int symbolchanges; // count symbol changes (if nonzero, another pass is needed)
int errors;
int warnings;
// FIXME - add a counter for "errors not reported because pass flags
// said so", because then we can read the value after all symbol changes
// have finally settled and know if the next pass is a victory lap or an
// error output pass.
int errors; // if nonzero -> stop after this pass
int warnings; // this is needed for showing macro call stack
//int suppressed_errors; // FIXME - this is for
// "errors not reported because pass flags said so", because
// then we can read the value after all symbol changes have
// finally settled and know if the next pass is a victory lap or
// an error output pass.
} counters;
struct {
boolean complain_about_undefined; // will be FALSE until error pass is needed
boolean is_final_pass; // needed for warnings like "converted float to int for xor"
boolean throw_segment_messages; // atm only used in pass 1, should be used in _last_ pass!
boolean generate_output; // create output and/or report file
} flags;
@ -211,29 +213,39 @@ extern bits parser_get_force_bit(void);
// if the "optional alternative location" given is NULL, the current location is used
extern void throw_message(enum debuglevel level, const char msg[], struct location *opt_alt_loc);
// output a warning (something looks wrong, like "label name starts with shift-space character")
#define Throw_warning(msg) throw_message(DEBUGLEVEL_WARNING, msg, NULL)
// output a warning (something looks wrong)
extern void throw_warning(const char msg[]);
// output an error (something is wrong, no output file will be generated).
// the assembler will try to go on with the assembly, so the user gets to know
// about more than one of his typos at a time.
#define Throw_error(msg) throw_message(DEBUGLEVEL_ERROR, msg, NULL)
extern void throw_error(const char msg[]);
// output a serious error (assembly stops, for example if outbuffer overruns).
extern void throw_serious_error(const char msg[]);
// output a warning, but only if we are in first pass, otherwise suppress
// (only use this if using throw_finalpass_warning is impossible,
// for example in cases where the code is skipped in later passes)
extern void throw_pass1_warning(const char msg[]);
// output a warning, but only if we are in final pass, otherwise suppress
// (for example "converted float to int for XOR" -> must be done in
// final pass because values might be undefined earlier!)
extern void throw_finalpass_warning(const char msg[]);
// throw "macro twice" error (FIXME - also use for "symbol twice"!)
// first output a warning, then an error, this guarantees that ACME does not
// reach the maximum error limit inbetween.
extern void throw_redef_error(struct location *old_def, const char msg[]);
// handle bugs
extern void BUG(const char *msg, int code);
// process error that might vanish if symbols change:
// if current pass is an "error output" pass, actually throw error.
// otherwise just increment counter to let mainloop know this pass wasn't successful.
extern void throw_symbol_error(const char *msg);
// output a serious error (assembly stops, for example if outbuffer overruns).
#define Throw_serious_error(msg) throw_message(DEBUGLEVEL_SERIOUS, msg, NULL)
// handle bugs
extern void BUG(const char *msg, int code);
extern void countorthrow_value_error(const char *msg);
// insert object (in case of list, will iterate/recurse until done)
struct iter_context {

View File

@ -253,7 +253,7 @@ static char get_processed_from_file(void)
default:
// complain if byte is 0
Throw_error("Source file contains illegal character."); // FIXME - throw some dynamic "did not expect XYZ character" error instead!
throw_error("Source file contains illegal character."); // FIXME - throw some dynamic "did not expect XYZ character" error instead!
return (char) from_file;
}
case INPUTSTATE_SKIPBLANKS:
@ -372,19 +372,19 @@ static void subst_substitute(void) // now GotByte = '?'
goto fail; // input_read_scope_and_symbol_name will have thrown error
}
if (tmp_symbol->object.type == NULL) {
Throw_error("Substitution symbol is undefined.");
throw_error("Substitution symbol is undefined.");
// FIXME - set type to undefined int, just to make sure later refs via type do not crash!
goto fail;
} else if (tmp_symbol->object.type == &type_number) {
if (tmp_symbol->object.u.number.ntype != NUMTYPE_INT) {
Throw_error("Substitution symbol is undefined or not integer.");
throw_error("Substitution symbol is undefined or not integer.");
goto fail;
}
dynabuf_add_signed_long(subst_buffer, (long) tmp_symbol->object.u.number.val.intval);
} else if (tmp_symbol->object.type == &type_string) {
dynabuf_add_bytes(subst_buffer, tmp_symbol->object.u.string->payload, tmp_symbol->object.u.string->length);
} else {
Throw_error("Substitution symbol is neither number nor string.");
throw_error("Substitution symbol is neither number nor string.");
goto fail;
}
@ -394,7 +394,7 @@ static void subst_substitute(void) // now GotByte = '?'
if (GotByte == ')') {
GetByte(); // eat ')'
} else {
Throw_error("Substitution does not end with ')' character.");
throw_error("Substitution does not end with ')' character.");
goto fail;
}
}
@ -522,7 +522,7 @@ static void get_quoted_byte(void)
}
// now check for end of statement
if (GotByte == CHAR_EOS)
Throw_error("Quotes still open at end of line.");
throw_error("Quotes still open at end of line.");
}
// skip remainder of statement, for example on error
@ -555,7 +555,7 @@ void parser_ensure_EOS(void) // now GotByte = first char to test
// FIXME - change quoting: do not assume char is printable!
quote = (GotByte == '\'') ? '"' : '\''; // use single quotes, unless byte is a single quote (then use double quotes)
sprintf(buf, "Expected end-of-statement, found %c%c%c instead.", quote, GotByte, quote);
Throw_error(buf);
throw_error(buf);
parser_skip_remainder();
}
}
@ -628,7 +628,7 @@ int input_unescape_dynabuf(void)
break;
// TODO - 'a' to BEL? others?
default:
Throw_error("Unsupported backslash sequence."); // TODO - add unexpected character to error message?
throw_error("Unsupported backslash sequence."); // TODO - add unexpected character to error message?
}
GLOBALDYNABUF_CURRENT[write_index++] = byte;
escaped = FALSE;
@ -668,7 +668,7 @@ static void block_to_dynabuf(void)
// now check for some special characters
switch (byte) {
case CHAR_EOF: // End-of-file in block? Sorry, no way.
Throw_serious_error(exception_no_right_brace);
throw_serious_error(exception_no_right_brace);
case '"': // Quotes? Okay, read quoted stuff.
case '\'':
@ -725,7 +725,7 @@ static int append_keyword_to_global_dynabuf(void)
GetByte();
}
if (length == 0)
Throw_error(exception_missing_string);
throw_error(exception_missing_string);
return length;
}
@ -741,7 +741,7 @@ int input_append_symbol_name_to_global_dynabuf(void)
GetByte();
} else if (!BYTE_STARTS_KEYWORD(GotByte)) {
// FIXME - show invalid char in error message!
Throw_error(exception_missing_string);
throw_error(exception_missing_string);
return 1; // error
}
return append_keyword_to_global_dynabuf() == 0; // zero length -> error!
@ -822,7 +822,7 @@ static int read_filename_shared_end(boolean *absolute)
{
// check length
if (GlobalDynaBuf->size == 0) {
Throw_error("No file name given.");
throw_error("No file name given.");
return 1; // error
}
@ -871,7 +871,7 @@ int input_read_input_filename(struct filespecflags *flags)
flags->uses_lib = FALSE;
// old algo (do not merge with similar parts from "if" block!):
if (GotByte != '"') {
Throw_error("File name quotes not found (\"\" or <>).");
throw_error("File name quotes not found (\"\" or <>).");
return 1; // error
}
// read file name string
@ -913,7 +913,7 @@ int parser_expect(int chr)
GetByte(); // eat expected char
return TRUE;
}
Throw_error(exception_syntax); // FIXME - build "expected X, found Y" error msg!
throw_error(exception_syntax); // FIXME - build "expected X, found Y" error msg!
return FALSE;
}
@ -943,7 +943,7 @@ static void library_path_to_pathbuf(void)
dynabuf_clear(pathbuf);
lib_prefix = PLATFORM_LIBPREFIX;
if ((PLATFORM_NEEDS_ENV_VAR) && (lib_prefix == NULL)) {
Throw_error("\"ACME\" environment variable not found.");
throw_error("\"ACME\" environment variable not found.");
} else {
dynabuf_add_string(pathbuf, lib_prefix);
}
@ -995,11 +995,11 @@ int input_read_output_filename(void)
SKIPSPACE();
if (GotByte == '<') {
Throw_error("Writing to library not supported.");
throw_error("Writing to library not supported.");
return 1; // error
}
if (GotByte != '"') {
Throw_error("File name quotes not found (\"\").");
throw_error("File name quotes not found (\"\").");
return 1; // error
}
dynabuf_clear(GlobalDynaBuf);
@ -1213,7 +1213,7 @@ FILE *includepaths_open_ro(struct filespecflags *flags)
dynabuf_append(pathbuf, flags->uses_lib ? '>' : '\"');
dynabuf_append(pathbuf, '.');
dynabuf_append(pathbuf, '\0');
Throw_error(pathbuf->buffer);
throw_error(pathbuf->buffer);
}
//fprintf(stderr, "File is [%s]\n", GLOBALDYNABUF_CURRENT);
return stream;

View File

@ -60,7 +60,7 @@ static void enlarge_arg_table(void)
//printf("Doubling arg table size to %d.\n", argtable_size);
arg_table = realloc(arg_table, argtable_size * sizeof(*arg_table));
if (arg_table == NULL)
Throw_serious_error(exception_no_memory_left);
throw_serious_error(exception_no_memory_left);
}
// Read macro scope and title. Title is read to GlobalDynaBuf and then copied
@ -149,7 +149,7 @@ void macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
} while (pipe_comma());
// ensure CHAR_SOB ('{')
if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace);
throw_serious_error(exception_no_left_brace);
}
dynabuf_append(GlobalDynaBuf, CHAR_EOS); // terminate param list
// now GlobalDynaBuf = comma-separated parameter list without spaces,
@ -197,7 +197,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
// Enter deeper nesting level
// Quit program if recursion too deep.
if (--sanity.macro_recursions_left < 0)
Throw_serious_error("Too deeply nested. Recursive macro calls?");
throw_serious_error("Too deeply nested. Recursive macro calls?");
macro_scope = get_scope_and_title();
// now GotByte = first non-space after title
// internal_name = MacroTitle ARG_SEPARATOR (grows to signature)
@ -234,7 +234,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
// Search for macro. Do not create if not found.
search_for_macro(&macro_node, macro_scope, FALSE);
if (macro_node == NULL) {
Throw_error("Macro not defined (or wrong signature).");
throw_error("Macro not defined (or wrong signature).");
parser_skip_remainder();
} else {
// make macro_node point to the macro struct
@ -269,7 +269,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
if (tree_hard_scan(&symbol_node, symbols_forest, symbol_scope, TRUE) == FALSE) {
// we expect it to exist in later passes, but in pass 1 it's an error:
if (pass.number == 1)
Throw_error("Macro parameter twice.");
throw_error("Macro parameter twice.");
}
symbol_node->body = arg_table[arg_count].symbol; // CAUTION, object type may be NULL
} else {
@ -301,7 +301,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
// if needed, dump call stack
if (outer_msg_sum != pass.counters.warnings + pass.counters.errors)
Throw_warning("...called from here.");
throw_warning("...called from here."); // FIXME - use DEBUGLEVEL_INFO instead!
parser_ensure_EOS();
}

View File

@ -571,7 +571,7 @@ static int get_index(void)
NEXTANDSKIPSPACE();
return INDEX_Z;
}
Throw_error("Expected index register after comma.");
throw_error("Expected index register after comma.");
return INDEX_NONE;
}
@ -584,8 +584,7 @@ static void get_int_arg(struct number *result, boolean complain_about_indirect)
ALU_addrmode_int(&expression, 0); // accept 0 parentheses still open (-> complain!)
if (expression.is_parenthesized && complain_about_indirect) {
// TODO - raise error and be done with it?
if (pass.number == 1)
Throw_warning("There are unneeded parentheses, you know indirect addressing is impossible here, right?"); // FIXME - rephrase? add to docs!
throw_finalpass_warning("There are unneeded parentheses, you know indirect addressing is impossible here, right?"); // FIXME - rephrase? add to docs!
}
*result = expression.result.u.number;
}
@ -652,11 +651,11 @@ static void check_oversize(bits size_bit, struct number *argument)
if (size_bit == NUMBER_FORCES_16) {
// check 16-bit argument for high byte zero
if ((argument->val.intval <= 255) && (argument->val.intval >= -128))
Throw_warning(exception_oversized_addrmode);
throw_finalpass_warning(exception_oversized_addrmode);
} else {
// check 24-bit argument for bank byte zero
if ((argument->val.intval <= 65535) && (argument->val.intval >= -32768))
Throw_warning(exception_oversized_addrmode);
throw_finalpass_warning(exception_oversized_addrmode);
}
}
}
@ -674,7 +673,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
{
// if there are no possible addressing modes, complain
if (addressing_modes == MAYBE______) {
Throw_error(exception_illegal_combination);
throw_error(exception_illegal_combination);
return 0;
}
// if a force bit postfix was given, act upon it
@ -684,7 +683,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
return force_bit;
// if not, complain
Throw_error("CPU does not support this postfix for this mnemonic.");
throw_error("CPU does not support this postfix for this mnemonic.");
return 0;
}
@ -701,7 +700,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
if (NUMBER_FORCES_24 & addressing_modes)
return NUMBER_FORCES_24;
Throw_error(exception_number_out_of_range); // else error
throw_error(exception_number_out_of_range); // else error
return 0;
}
@ -744,7 +743,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
// Value is sure, so use its own size
// if value is negative, size cannot be chosen. Complain!
if (argument->val.intval < 0) {
throw_symbol_error("Negative value - cannot choose addressing mode.");
countorthrow_value_error("Negative value - cannot choose addressing mode.");
return 0;
}
@ -766,7 +765,7 @@ static bits calc_arg_size(bits force_bit, struct number *argument, bits addressi
}
// Value is too big for all possible addressing modes
throw_symbol_error(exception_number_out_of_range);
countorthrow_value_error(exception_number_out_of_range);
return 0;
}
@ -777,8 +776,7 @@ static void group_only_implied_addressing(int opcode)
// TODO - accept argument and complain about it? error message should tell more than "garbage data at end of line"!
// for 65ce02 and 4502, warn about buggy decimal mode
if ((opcode == 0xf8) && (cpu_current_type->flags & CPUFLAG_DECIMALSUBTRACTBUGGY)) {
if (pass.number == 1)
Throw_warning("Found SED instruction for CPU with known decimal SBC bug.");
throw_finalpass_warning("Found SED instruction for CPU with known decimal SBC bug.");
}
output_byte(opcode);
parser_ensure_EOS();
@ -790,7 +788,7 @@ static void not_in_bank(intval_t target)
char buffer[60]; // 640K should be enough for anybody
sprintf(buffer, "Target not in bank (0x%lx).", (long) target);
throw_symbol_error(buffer);
countorthrow_value_error(buffer);
}
// helper function for branches with 8-bit offset (including bbr0..7/bbs0..7)
@ -816,7 +814,7 @@ static void near_branch(int preoffset)
char buffer[60]; // 640K should be enough for anybody
sprintf(buffer, "Target out of range (%ld; %ld too far).", (long) offset, (long) (offset < -128 ? -128 - offset : offset - 127));
throw_symbol_error(buffer);
countorthrow_value_error(buffer);
}
}
}
@ -917,7 +915,7 @@ static void check_zp_wraparound(struct number *result)
if ((result->ntype == NUMTYPE_INT)
&& (result->val.intval == 0xff)
&& (cpu_current_type->flags & CPUFLAG_WARN_ABOUT_FF_PTR))
Throw_warning("Zeropage pointer wraps around from $ff to $00");
throw_finalpass_warning("Zeropage pointer wraps around from $ff to $00");
}
// The main accumulator stuff (ADC, AND, CMP, EOR, LDA, ORA, SBC, STA)
@ -981,7 +979,7 @@ static void group_main(int index, bits flags)
make_instruction(force_bit, &result, accu_lindz8[index]);
break;
default: // other combinations are illegal
Throw_error(exception_illegal_combination);
throw_error(exception_illegal_combination);
}
}
@ -997,7 +995,7 @@ static void group_misc(int index, bits immediate_mode)
if (misc_impl[index])
output_byte(misc_impl[index]);
else
Throw_error(exception_illegal_combination);
throw_error(exception_illegal_combination);
break;
case IMMEDIATE_ADDRESSING: // #$ff or #$ffff (depending on index register length)
immediate_opcodes = imm_ops(&force_bit, misc_imm[index], immediate_mode);
@ -1009,9 +1007,9 @@ static void group_misc(int index, bits immediate_mode)
&& (result.ntype == NUMTYPE_INT)
&& (result.val.intval != 0x00)) {
if (immediate_opcodes == 0x8b)
Throw_warning("Assembling unstable ANE #NONZERO instruction");
throw_finalpass_warning("Assembling unstable ANE #NONZERO instruction");
else if (immediate_opcodes == 0xab)
Throw_warning("Assembling unstable LXA #NONZERO instruction");
throw_finalpass_warning("Assembling unstable LXA #NONZERO instruction");
}
break;
case ABSOLUTE_ADDRESSING: // $ff or $ffff
@ -1024,7 +1022,7 @@ static void group_misc(int index, bits immediate_mode)
make_instruction(force_bit, &result, misc_yabs[index]);
break;
default: // other combinations are illegal
Throw_error(exception_illegal_combination);
throw_error(exception_illegal_combination);
}
}
@ -1096,7 +1094,7 @@ static void group_mvn_mvp(int opcode)
output_8(source.val.intval);
// sanity check
if (unmatched_hash)
Throw_error(exception_syntax); // FIXME - maybe "Use ARG,ARG or #ARG,#ARG but do not mix and match"?
throw_error(exception_syntax); // FIXME - maybe "Use ARG,ARG or #ARG,#ARG but do not mix and match"?
parser_ensure_EOS();
}
@ -1120,7 +1118,7 @@ static void group_prefix(int opcode)
char buffer[100]; // 640K should be enough for anybody
sprintf(buffer, "The chosen CPU uses opcode 0x%02x as a prefix code, do not use this mnemonic!", opcode);
Throw_error(buffer);
throw_error(buffer);
}
// The jump instructions.
@ -1139,7 +1137,7 @@ static void group_jump(int index)
if ((result.ntype == NUMTYPE_INT)
&& ((result.val.intval & 0xff) == 0xff)
&& (cpu_current_type->flags & CPUFLAG_INDIRECTJMPBUGGY))
Throw_warning("Assembling buggy JMP($xxff) instruction");
throw_finalpass_warning("Assembling buggy JMP($xxff) instruction");
break;
case X_INDEXED_INDIRECT_ADDRESSING: // ($ffff,x)
make_instruction(force_bit, &result, jump_xind[index]);
@ -1148,7 +1146,7 @@ static void group_jump(int index)
make_instruction(force_bit, &result, jump_lind[index]);
break;
default: // other combinations are illegal
Throw_error(exception_illegal_combination);
throw_error(exception_illegal_combination);
}
}

View File

@ -105,7 +105,7 @@ static void border_crossed(int current_offset)
// so it can be suppressed until we are sure the program won't shrink any
// further:
if (current_offset >= OUTBUF_MAXSIZE)
Throw_serious_error("Reached memory limit.");
throw_serious_error("Reached memory limit.");
if (pass.flags.throw_segment_messages) {
throw_message(config.debuglevel_segmentprobs, "Segment reached another one, overwriting it.", NULL);
find_segment_max(current_offset + 1); // find new (next) limit
@ -148,7 +148,7 @@ static void real_output(intval_t byte)
// not happen again
static void complain_and_use_dummy_pc(void)
{
Throw_error(exception_pc_undefined);
throw_error(exception_pc_undefined);
programcounter_set(cpu_current_type->dummy_pc, 0); // 0 = no flags
}
@ -287,7 +287,7 @@ void output_passinit(void)
out->needed_bufsize = 16; // actually 1 would suffice...
}
if (out->needed_bufsize > OUTBUF_MAXSIZE) {
Throw_serious_error("Output buffer size exceeds maximum.");
throw_serious_error("Output buffer size exceeds maximum.");
}
//fprintf(stderr, "Allocating outbuf of size 0x%06x.\n", out->needed_bufsize);
out->buffer = safe_malloc(out->needed_bufsize);
@ -404,9 +404,9 @@ static void start_segment(intval_t address_change, bits segment_flags)
// calculate start of new segment
out->write_idx = out->write_idx + address_change;
if (out->write_idx < 0) {
Throw_serious_error("Tried to write to negative addresses.");
throw_serious_error("Tried to write to negative addresses.");
} else if (out->write_idx >= OUTBUF_MAXSIZE) {
Throw_serious_error("Reached memory limit.");
throw_serious_error("Reached memory limit.");
}
out->segm.start = out->write_idx;
out->segm.flags = segment_flags;
@ -556,11 +556,11 @@ int pseudopc_unpseudo(struct number *target, struct pseudopc *context, unsigned
return 0; // ok (no sense in trying to unpseudo this, and it might be an unresolved forward ref anyway)
if (context == NULL) {
Throw_error("Un-pseudopc operator '&' only works on addresses.");
throw_error("Un-pseudopc operator '&' only works on addresses.");
return 1; // error
}
if (context == &outermost_pseudopc_context) {
Throw_error("Un-pseudopc operator '&' has no !pseudopc context.");
throw_error("Un-pseudopc operator '&' has no !pseudopc context.");
return 1; // error
}
target->val.intval = target->val.intval - context->offset; // remove offset

View File

@ -57,7 +57,7 @@ static enum eos po_initmem(void)
// the "--initmem" cli arg and earlier calls have priority
if (config.mem_init_value != NO_VALUE_GIVEN) {
Throw_warning("Memory already initialised.");
throw_pass1_warning("Memory already initialised.");
return SKIP_REMAINDER;
}
@ -67,7 +67,7 @@ static enum eos po_initmem(void)
// first pass)
ALU_defined_int(&intresult);
if ((intresult.val.intval > 255) || (intresult.val.intval < -128))
Throw_error(exception_number_out_of_8b_range);
throw_error(exception_number_out_of_8b_range);
// remember value
config.mem_init_value = intresult.val.intval & 0xff;
@ -86,7 +86,7 @@ static enum eos po_to(void)
// the "--outfile" cli arg and earlier calls have priority
if (config.output_filename) {
Throw_warning("Output file name already chosen.");
throw_pass1_warning("Output file name already chosen.");
return SKIP_REMAINDER;
}
@ -107,20 +107,20 @@ static enum eos po_to(void)
format = outputformat_find();
if (format == OUTFILE_FORMAT_UNSPECIFIED) {
Throw_error("Unknown output format.");
throw_error("Unknown output format.");
return SKIP_REMAINDER;
}
} else {
// no comma: complain unless user requested really old behaviour
if (config.dialect >= V0_86__DEPRECATE_REALPC)
Throw_warning("Used \"!to\" without file format indicator.");
throw_pass1_warning("Used \"!to\" without file format indicator.");
// default to cbm
format = OUTFILE_FORMAT_CBM;
}
// the "--format" cli arg has priority
if (config.outfile_format != OUTFILE_FORMAT_UNSPECIFIED) {
Throw_warning("Output file format already chosen.");
throw_pass1_warning("Output file format already chosen.");
} else {
config.outfile_format = format;
}
@ -137,7 +137,7 @@ static enum eos po_symbollist(void)
// cli arg and earlier calls have priority
if (config.symbollist_filename) {
Throw_warning("Symbol list file name already chosen.");
throw_pass1_warning("Symbol list file name already chosen.");
return SKIP_REMAINDER;
}
@ -163,8 +163,7 @@ static enum eos po_outfilestart(void)
if ((config.outfile_start != NO_VALUE_GIVEN)
|| (last_pass_number == pass.number)) {
if (pass.number == 1)
Throw_warning("Start of output file already chosen.");
throw_pass1_warning("Start of output file already chosen.");
} else {
last_pass_number = pass.number;
outbuf_set_outfile_start();
@ -179,8 +178,7 @@ static enum eos po_outfilelimit(void)
if ((config.outfile_limit != NO_VALUE_GIVEN)
|| (last_pass_number == pass.number)) {
if (pass.number == 1)
Throw_warning("End of output file already chosen.");
throw_pass1_warning("End of output file already chosen.");
} else {
last_pass_number = pass.number;
outbuf_set_outfile_limit();
@ -202,7 +200,7 @@ static enum eos po_xor(void)
old_value = output_get_xor();
ALU_any_int(&change);
if ((change > 255) || (change < -128)) {
Throw_error(exception_number_out_of_8b_range);
throw_error(exception_number_out_of_8b_range);
change = 0;
}
output_set_xor(old_value ^ change);
@ -321,7 +319,7 @@ static enum eos po_hex(void) // now GotByte = illegal char
// if we're here, the current character is not a hex digit,
// which is only allowed outside of pairs:
if (digits == 1) {
Throw_error("Hex digits are not given in pairs.");
throw_error("Hex digits are not given in pairs.");
return SKIP_REMAINDER; // error exit
}
switch (GotByte) {
@ -332,7 +330,7 @@ static enum eos po_hex(void) // now GotByte = illegal char
case CHAR_EOS:
return AT_EOS_ANYWAY; // normal exit
default:
Throw_error(exception_syntax); // FIXME - include character in error message!
throw_error(exception_syntax); // FIXME - include character in error message!
return SKIP_REMAINDER; // error exit
}
}
@ -343,11 +341,10 @@ static enum eos po_hex(void) // now GotByte = illegal char
static enum eos po_cbm(void)
{
if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) {
Throw_error("\"!cbm\" is obsolete; use \"!ct pet\" instead.");
throw_error("\"!cbm\" is obsolete; use \"!ct pet\" instead.");
} else {
encoder_current = &encoder_pet;
if (pass.number == 1)
Throw_warning("\"!cbm\" is deprecated; use \"!ct pet\" instead.");
throw_finalpass_warning("\"!cbm\" is deprecated; use \"!ct pet\" instead.");
}
return ENSURE_EOS;
}
@ -371,7 +368,7 @@ static enum eos use_encoding_from_file(void)
if (stream) {
// try to load encoding table from given file
if (fread(local_table, sizeof(char), 256, stream) != 256)
Throw_error("Conversion table incomplete.");
throw_error("Conversion table incomplete.");
fclose(stream);
}
@ -445,7 +442,7 @@ static enum eos po_convtab(void)
return use_encoding_from_file();
}
Throw_error("Unknown encoding.");
throw_error("Unknown encoding.");
return use_predefined_encoding(encoder_current); // keep going
}
// insert string(s)
@ -555,7 +552,7 @@ static enum eos po_binary(void)
// then parse it
ALU_defined_int(&size);
if (size.val.intval < 0)
Throw_serious_error(exception_negative_size);
throw_serious_error(exception_negative_size);
}
// more?
if (parser_accept_comma()) {
@ -585,7 +582,7 @@ static enum eos po_binary(void)
}
// if more should have been read, warn and add padding
if (size.val.intval > 0) {
Throw_warning("Padding with zeroes.");
throw_warning("Padding with zeroes.");
do {
output_byte(0);
} while (--size.val.intval);
@ -625,7 +622,7 @@ static enum eos po_skip(void) // now GotByte = illegal char
ALU_defined_int(&amount); // FIXME - forbid addresses!
if (amount.val.intval < 0)
Throw_serious_error(exception_negative_size); // TODO - allow this?
throw_serious_error(exception_negative_size); // TODO - allow this?
else
output_skip(amount.val.intval);
return ENSURE_EOS;
@ -656,7 +653,7 @@ static enum eos po_align(void)
// make sure PC is defined
programcounter_read(&pc);
if (pc.ntype == NUMTYPE_UNDEFINED) {
Throw_error(exception_pc_undefined);
throw_error(exception_pc_undefined);
return SKIP_REMAINDER;
}
@ -671,11 +668,10 @@ static void old_offset_assembly(void)
{
if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) {
// now it's obsolete
Throw_error("\"!pseudopc/!realpc\" are obsolete; use \"!pseudopc {}\" instead."); // FIXME - amend msg, tell user how to use old behaviour!
throw_error("\"!pseudopc/!realpc\" are obsolete; use \"!pseudopc {}\" instead."); // FIXME - amend msg, tell user how to use old behaviour!
} else if (config.dialect >= V0_86__DEPRECATE_REALPC) {
// earlier it was deprecated
if (pass.number == 1)
Throw_warning("\"!pseudopc/!realpc\" are deprecated; use \"!pseudopc {}\" instead.");
throw_finalpass_warning("\"!pseudopc/!realpc\" are deprecated; use \"!pseudopc {}\" instead.");
} else {
// really old versions allowed it
}
@ -703,13 +699,13 @@ static enum eos po_pseudopc(void)
skip '='
read segment name (quoted string!)
} else {
Throw_error("Unknown !pseudopc segment modifier.");
throw_error("Unknown !pseudopc segment modifier.");
return SKIP_REMAINDER;
}
}
*/
if (new_pc.val.intval < 0) {
Throw_error("Program counter cannot be negative.");
throw_error("Program counter cannot be negative.");
new_pc.val.intval = cpu_current_type->dummy_pc;
}
pseudopc_start(&new_pc);
@ -756,7 +752,7 @@ static enum eos po_cpu(void)
if (new_cpu_type)
cpu_current_type = new_cpu_type; // activate new cpu type
else
Throw_error("Unknown processor.");
throw_error("Unknown processor.");
}
// if there's a block, parse that and then restore old value
if (parse_optional_block())
@ -808,7 +804,7 @@ static enum eos po_enum(void) // now GotByte = illegal char
step.val.intval = 1;
ALU_defined_int(&step);
Throw_serious_error("Not yet"); // FIXME
throw_serious_error("Not yet"); // FIXME
return ENSURE_EOS;
}
#endif
@ -879,10 +875,9 @@ static enum eos po_zone(void)
static enum eos po_subzone(void)
{
if (config.dialect >= V0_94_8__DISABLED_OBSOLETE) {
Throw_error("\"!subzone {}\" is obsolete; use \"!zone {}\" instead.");
throw_error("\"!subzone {}\" is obsolete; use \"!zone {}\" instead.");
} else {
if (pass.number == 1)
Throw_warning("\"!subzone {}\" is deprecated; use \"!zone {}\" instead.");
throw_finalpass_warning("\"!subzone {}\" is deprecated; use \"!zone {}\" instead.");
}
// call "!zone" instead
return po_zone();
@ -898,7 +893,7 @@ static enum eos po_source(void) // now GotByte = illegal char
// enter new nesting level
// quit program if recursion too deep
if (--sanity.source_recursions_left < 0)
Throw_serious_error("Too deeply nested. Recursive \"!source\"?");
throw_serious_error("Too deeply nested. Recursive \"!source\"?");
// read file name and convert from UNIX style to platform style
if (input_read_input_filename(&flags))
@ -937,7 +932,7 @@ static enum eos ifelse(enum ifmode mode)
ALU_defined_int(&ifresult);
condition_met = !!ifresult.val.intval;
if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace);
throw_serious_error(exception_no_left_brace);
break;
case IFMODE_IFDEF:
condition_met = check_ifdef_condition();
@ -960,7 +955,7 @@ static enum eos ifelse(enum ifmode mode)
parse_until_eob_or_eof(); // parse block
// if block isn't correctly terminated, complain and exit
if (GotByte != CHAR_EOB)
Throw_serious_error(exception_no_right_brace);
throw_serious_error(exception_no_right_brace);
} else {
return PARSE_REMAINDER; // parse line (only for ifdef/ifndef)
}
@ -977,7 +972,7 @@ static enum eos ifelse(enum ifmode mode)
if (mode == IFMODE_ELSE) {
// we could just return ENSURE_EOS, but checking here allows for better error message
if (GotByte != CHAR_EOS)
Throw_error("Expected end-of-statement after ELSE block.");
throw_error("Expected end-of-statement after ELSE block.");
return SKIP_REMAINDER; // normal exit after ELSE {...}
}
@ -991,7 +986,7 @@ static enum eos ifelse(enum ifmode mode)
// make sure it's "else"
if (strcmp(GlobalDynaBuf->buffer, "else")) {
Throw_error("Expected end-of-statement or ELSE keyword after '}'.");
throw_error("Expected end-of-statement or ELSE keyword after '}'.");
return SKIP_REMAINDER; // an error has been reported, so ignore rest of line
}
// anything more?
@ -1014,7 +1009,7 @@ static enum eos ifelse(enum ifmode mode)
} else if (strcmp(GlobalDynaBuf->buffer, "ifndef") == 0) {
mode = IFMODE_IFNDEF;
} else {
Throw_error("Expected '{' or IF/IFDEF/IFNDEF keyword after ELSE keyword.");
throw_error("Expected '{' or IF/IFDEF/IFNDEF keyword after ELSE keyword.");
return SKIP_REMAINDER; // an error has been reported, so ignore rest of line
}
}
@ -1067,16 +1062,14 @@ static enum eos po_for(void) // now GotByte = illegal char
// new counter syntax
loop.algorithm = FORALGO_NEWCOUNT;
if (config.dialect < V0_94_12__NEW_FOR_SYNTAX) {
if (pass.number == 1)
Throw_warning("Found new \"!for\" syntax.");
throw_finalpass_warning("Found new \"!for\" syntax.");
}
loop.u.counter.first = intresult.val.intval; // use first argument
ALU_defined_int(&intresult); // read second argument
// compare addr_ref counts and complain if not equal!
if (config.warn_on_type_mismatch
&& (intresult.addr_refs != loop.u.counter.addr_refs)) {
if (pass.number == 1)
Throw_warning("Wrong type for loop's END value - must match type of START value.");
throw_finalpass_warning("Wrong type for loop's END value - must match type of START value.");
}
// setup direction and total
if (loop.u.counter.first <= intresult.val.intval) {
@ -1092,11 +1085,10 @@ static enum eos po_for(void) // now GotByte = illegal char
// old counter syntax
loop.algorithm = FORALGO_OLDCOUNT;
if (config.dialect >= V0_94_12__NEW_FOR_SYNTAX) {
if (pass.number == 1)
Throw_warning("Found old \"!for\" syntax.");
throw_finalpass_warning("Found old \"!for\" syntax.");
}
if (intresult.val.intval < 0) {
Throw_serious_error("Loop count is negative.");
throw_serious_error("Loop count is negative.");
}
// count up
loop.u.counter.first = 1;
@ -1108,11 +1100,11 @@ static enum eos po_for(void) // now GotByte = illegal char
loop.algorithm = FORALGO_ITERATE;
// check for "in" keyword
if ((GotByte != 'i') && (GotByte != 'I')) {
Throw_error(exception_want_IN_or_comma);
throw_error(exception_want_IN_or_comma);
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
}
/* checking for the first character explicitly here looks dumb, but actually
solves a purpose: we're here because the check for comma failed, but maybe that
serves a purpose: we're here because the check for comma failed, but maybe that
was just a typo. if the current byte is '.' or '-' or whatever, then trying to
read a keyword will result in "No string given" - which is confusing for the
user if they did not even want to put a string there.
@ -1121,23 +1113,23 @@ knowing there is an "i" also makes sure that parser_read_and_lower_keyword()
does not fail. */
parser_read_and_lower_keyword();
if (strcmp(GlobalDynaBuf->buffer, "in") != 0) {
Throw_error(exception_want_IN_or_comma);
throw_error(exception_want_IN_or_comma);
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
}
if (force_bit) {
Throw_error("Force bits can only be given to counters, not when iterating over string/list contents.");
throw_error("Force bits can only be given to counters, not when iterating over string/list contents.");
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
}
ALU_any_result(&loop.u.iter.obj); // get iterable
loop.iterations_left = loop.u.iter.obj.type->length(&loop.u.iter.obj);
if (loop.iterations_left < 0) {
Throw_error("Given object is not iterable.");
throw_error("Given object is not iterable.");
return SKIP_REMAINDER; // FIXME - this ignores '{' and will then complain about '}'
}
}
if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace);
throw_serious_error(exception_no_left_brace);
input_block_getcopy(&loop.block); // "body" must be freed afterward...
flow_forloop(&loop);
@ -1158,7 +1150,7 @@ static enum eos po_do(void) // now GotByte = illegal char
SKIPSPACE();
flow_store_doloop_condition(&loop.head_cond, CHAR_SOB); // must be freed!
if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace);
throw_serious_error(exception_no_left_brace);
input_block_getcopy(&loop.block); // "body" must be freed!
// now GotByte = '}'
@ -1184,7 +1176,7 @@ static enum eos po_while(void) // now GotByte = illegal char
SKIPSPACE();
flow_store_while_condition(&loop.head_cond); // "body" must be freed!
if (GotByte != CHAR_SOB)
Throw_serious_error(exception_no_left_brace);
throw_serious_error(exception_no_left_brace);
// read block
input_block_getcopy(&loop.block); // "body" must be freed!
// clear tail condition
@ -1245,7 +1237,7 @@ static enum eos tracewatch(boolean enter_monitor)
} else if (strcmp(GlobalDynaBuf->buffer, "exec") == 0) {
flags |= TRACEWATCH_EXEC;
} else {
Throw_error("Unknown flag (known are: load, store, exec)."); // FIXME - add to docs!
throw_error("Unknown flag (known are: load, store, exec)."); // FIXME - add to docs!
return SKIP_REMAINDER;
}
} while (parser_accept_comma());
@ -1501,7 +1493,7 @@ void pseudoopcode_parse(void) // now GotByte = '!' (or '.' in case of --fullstop
// call function
then = fn();
} else {
Throw_error("Unknown pseudo opcode.");
throw_error("Unknown pseudo opcode.");
}
}
if (then == SKIP_REMAINDER)
@ -1550,7 +1542,7 @@ void notreallypo_setpc(void) // GotByte is '*'
skip '='
read segment name (quoted string!) */
} else {
Throw_error("Unknown \"*=\" segment modifier.");
throw_error("Unknown \"*=\" segment modifier.");
goto fail;
}
}
@ -1562,7 +1554,7 @@ void notreallypo_setpc(void) // GotByte is '*'
// current behaviour:
// setting pc does not disable pseudopc
} else if (config.dialect >= V0_93__SHORTER_SETPC_WARNING) {
Throw_warning("Offset assembly still active at end of segment.");
throw_warning("Offset assembly still active at end of segment.");
end_all_pseudopc(); // warning did not say it would
// disable pseudopc, but still did. nevertheless, there
// is something different to older versions: when the
@ -1570,13 +1562,13 @@ void notreallypo_setpc(void) // GotByte is '*'
// stuff happens! i see no reason to try to mimic that.
} else {
// prior to 0.93, setting pc disabled pseudopc with a warning:
Throw_warning("Offset assembly still active at end of segment. Switched it off.");
throw_warning("Offset assembly still active at end of segment. Switched it off.");
end_all_pseudopc();
}
}
if (intresult.val.intval < 0) {
Throw_error("Program counter cannot be negative.");
throw_error("Program counter cannot be negative.");
intresult.val.intval = cpu_current_type->dummy_pc;
}
programcounter_set(intresult.val.intval, segment_flags);

View File

@ -154,7 +154,7 @@ void symbol_set_object(struct symbol *symbol, struct object *new_value, bits pow
// if too different, needs power (or complains)
if (symbol->object.type != new_value->type) {
if (!(powers & POWER_CHANGE_OBJTYPE))
Throw_error(exception_symbol_defined);
throw_error(exception_symbol_defined);
// CAUTION: if above line throws error, we still go ahead and change type!
// this is to keep "!for" working, where the counter var is accessed.
symbol->object = *new_value; // copy whole struct including type
@ -182,7 +182,7 @@ void symbol_set_force_bit(struct symbol *symbol, bits force_bit)
BUG("NullTypeObject", 0);
if (symbol->object.type != &type_number) {
Throw_error("Force bits can only be given to numbers.");
throw_error("Force bits can only be given to numbers.");
return;
}
@ -195,7 +195,7 @@ void symbol_set_force_bit(struct symbol *symbol, bits force_bit)
// it's too late to change, so check if the wanted bit is actually different
if ((symbol->object.u.number.flags & NUMBER_FORCEBITS) != force_bit)
Throw_error("Too late for postfix.");
throw_error("Too late for postfix.");
}

View File

@ -19,7 +19,7 @@ void typesystem_want_nonaddr(struct number *result)
return;
if (result->addr_refs != 0) {
Throw_warning("Wrong type - expected integer.");
throw_finalpass_warning("Wrong type - expected integer.");
//printf("refcount should be 0, but is %d\n", result->addr_refs);
}
}
@ -34,7 +34,7 @@ void typesystem_want_addr(struct number *result)
return;
if (result->addr_refs != 1) {
Throw_warning("Wrong type - expected address.");
throw_finalpass_warning("Wrong type - expected address.");
//printf("refcount should be 1, but is %d\n", result->addr_refs);
}
}

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release
#define CHANGE_DATE "6 Aug" // update before release FIXME
#define CHANGE_DATE "7 Aug" // update before release FIXME
#define CHANGE_YEAR "2024" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME