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()
lex->line = 1; /* we start counting at 1 */
lex->peekpos = 0;
+ lex->eof = false;
lex_filenames_add(lex->name);
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;
lex->tok->ctx.line = lex->sline;
lex->tok->ctx.file = lex->name;
- if (ch == EOF)
+ if (lex->eof)
+ return (lex->tok->ttype = TOKEN_FATAL);
+
+ if (ch == EOF) {
+ lex->eof = true;
return (lex->tok->ttype = TOKEN_EOF);
+ }
/* modelgen / spiritgen commands */
if (ch == '$') {
case '^':
case '~':
case ',':
- case '.':
case '!':
if (!lex_tokench(lex, ch) ||
!lex_endtoken(lex))
default:
break;
}
+
+ if (ch == '.')
+ {
+ if (!lex_tokench(lex, ch))
+ return (lex->tok->ttype = TOKEN_FATAL);
+ /* peak ahead once */
+ nextch = lex_getch(lex);
+ if (nextch != '.') {
+ lex_ungetch(lex, nextch);
+ if (!lex_endtoken(lex))
+ return (lex->tok->ttype = TOKEN_FATAL);
+ return (lex->tok->ttype = ch);
+ }
+ /* peak ahead again */
+ nextch = lex_getch(lex);
+ if (nextch != '.') {
+ lex_ungetch(lex, nextch);
+ lex_ungetch(lex, nextch);
+ if (!lex_endtoken(lex))
+ return (lex->tok->ttype = TOKEN_FATAL);
+ return (lex->tok->ttype = ch);
+ }
+ /* fill the token to be "..." */
+ if (!lex_tokench(lex, ch) ||
+ !lex_tokench(lex, ch) ||
+ !lex_endtoken(lex))
+ {
+ return (lex->tok->ttype = TOKEN_FATAL);
+ }
+ return (lex->tok->ttype = TOKEN_DOTS);
+ }
}
if (ch == ',' || ch == '.') {