refactored "macro twice" code. messages about initial definitions and macro

call stacks are now output as "info" instead of "warning".


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@405 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-08-29 15:14:11 +00:00
parent be1b072288
commit 45ce8164e9
5 changed files with 28 additions and 18 deletions

View File

@ -312,8 +312,8 @@ Index out of range.
Macro already defined.
Macros can only be defined once. If you define a macro twice, ACME
will help you find the definitions by giving a warning for the
earlier definition and then an error for the new definition.
will give an error for the new definition and then output an info
message pointing to the initial definition.
Macro not defined (or wrong signature).
You tried to call a macro that either wasn't defined yet (always

View File

@ -341,6 +341,14 @@ static void parse_forward_anon_def(void)
}
// status var to tell mainloop (actually "statement loop") to exit.
// this is better than the error handler exiting directly, because
// there are cases where an error message is followed by an info message
// (like "macro redefined _here_" and "original definition _there_"),
// and this way the program does not exit between the two.
// FIXME - there is still the problem of not getting a dump of the macro call stack for the final error!
static boolean too_many_errors = FALSE;
// Parse block, beginning with next byte.
// End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards
// Has to be re-entrant.
@ -404,6 +412,9 @@ void parse_until_eob_or_eof(void)
}
} while (GotByte != CHAR_EOS); // until end-of-statement
output_end_statement(); // adjust program counter
// did the error handler decide to give up?
if (too_many_errors)
exit(ACME_finalize(EXIT_FAILURE));
// go on with next byte
GetByte(); //NEXTANDSKIPSPACE();
}
@ -539,7 +550,7 @@ void throw_message(enum debuglevel level, const char msg[], struct location *opt
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));
too_many_errors = TRUE; // this causes mainloop to exit
break;
case DEBUGLEVEL_WARNING:
// output a warning
@ -554,7 +565,7 @@ void throw_message(enum debuglevel level, const char msg[], struct location *opt
if (config.all_warnings_are_errors) {
++pass.counters.errors;
if (pass.counters.errors >= config.max_errors)
exit(ACME_finalize(EXIT_FAILURE));
too_many_errors = TRUE; // this causes mainloop to exit
}
break;
case DEBUGLEVEL_INFO:
@ -607,13 +618,15 @@ 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.
void throw_redef_error(struct location *old_def, const char msg[])
// first output error as "error", then location of initial definition as "info"
void throw_redef_error(const char error_msg[], struct location *old_def, const char info_msg[])
{
const char *buffered_section_type;
char *buffered_section_title;
// show error with current location
throw_error(error_msg);
// CAUTION, ugly kluge: fiddle with section_now data to generate
// "earlier definition" section.
// buffer old section
@ -621,14 +634,12 @@ void throw_redef_error(struct location *old_def, const char msg[])
buffered_section_title = section_now->title;
// set new (fake) section
section_now->type = "earlier";
section_now->title = "definition";
// show warning with location of earlier definition
throw_message(DEBUGLEVEL_WARNING, msg, old_def); // FIXME - throw as info?
section_now->title = "section";
// show info message with location of earlier definition
throw_message(DEBUGLEVEL_INFO, info_msg, old_def);
// restore old section
section_now->type = buffered_section_type;
section_now->title = buffered_section_title;
// show error with location of current definition
throw_error(msg);
}
// handle bugs

View File

@ -235,9 +235,8 @@ extern void throw_pass1_warning(const char msg[]);
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[]);
// first output error as "error", then location of initial definition as "info"
extern void throw_redef_error(const char error_msg[], struct location *old_def, const char info_msg[]);
// handle bugs
extern void BUG(const char *msg, int code);

View File

@ -162,7 +162,7 @@ void macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
// But if found, complain (macro twice).
if (search_for_macro(&macro_node, macro_scope, TRUE) == FALSE) {
original_macro = macro_node->body;
throw_redef_error(&(original_macro->definition), "Macro already defined.");
throw_redef_error("Macro already defined.", &(original_macro->definition), "Initial definition.");
}
// Create new macro struct and set it up. Finally we'll read the body.
new_macro = safe_malloc(sizeof(*new_macro));
@ -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."); // FIXME - use DEBUGLEVEL_INFO instead!
throw_message(DEBUGLEVEL_INFO, "...called from here.", NULL);
parser_ensure_EOS();
}

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release
#define CHANGE_DATE "7 Aug" // update before release FIXME
#define CHANGE_DATE "8 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