printf("\n");
}
-void lexwarn(lex_file *lex, int warn, const char *fmt, ...)
+bool lexwarn(lex_file *lex, int warn, const char *fmt, ...)
{
va_list ap;
if (!OPTS_WARN(warn))
- return;
+ return false;
if (lex)
printf("warning %s:%lu: ", lex->name, (unsigned long)lex->sline);
va_end(ap);
printf("\n");
+
+ return opts_werror;
}
token* token_new()
static bool lex_finish_frames(lex_file *lex)
{
do {
- int rc;
+ size_t i;
+ int rc;
frame_macro m;
rc = lex_parse_frame(lex);
if (rc < 0) /* error */
return false;
+ for (i = 0; i < lex->frames_count; ++i) {
+ if (!strcmp(lex->tok->value, lex->frames[i].name)) {
+ lex->frames[i].value = lex->framevalue++;
+ if (lexwarn(lex, WARN_FRAME_MACROS, "duplicate frame macro defined: `%s`", lex->tok->value))
+ return false;
+ continue;
+ }
+ }
+
m.value = lex->framevalue++;
m.name = lex->tok->value;
lex->tok->value = NULL;
options_set(opts_warn, WARN_VOID_VARIABLES, true);
options_set(opts_warn, WARN_IMPLICIT_FUNCTION_POINTER, true);
options_set(opts_warn, WARN_VARIADIC_FUNCTION, true);
+ options_set(opts_warn, WARN_FRAME_MACROS, true);
if (!options_parse(argc, argv)) {
return usage();
GMQCC_DEFINE_FLAG(VOID_VARIABLES)
GMQCC_DEFINE_FLAG(IMPLICIT_FUNCTION_POINTER)
GMQCC_DEFINE_FLAG(VARIADIC_FUNCTION)
+GMQCC_DEFINE_FLAG(FRAME_MACROS)