MEM_VEC_FUNCTIONS(token, char, value)
MEM_VEC_FUNCTIONS(lex_file, frame_macro, frames)
+VECTOR_MAKE(char*, lex_filenames);
+
void lexerror(lex_file *lex, const char *fmt, ...)
{
va_list ap;
lex->line = 1; /* we start counting at 1 */
lex->peekpos = 0;
+ lex->eof = false;
+
+ lex_filenames_add(lex->name);
return lex;
}
+void lex_cleanup(void)
+{
+ size_t i;
+ for (i = 0; i < lex_filenames_elements; ++i)
+ mem_d(lex_filenames_data[i]);
+ mem_d(lex_filenames_data);
+}
+
void lex_close(lex_file *lex)
{
size_t i;
mem_d(lex->frames[i].name);
MEM_VECTOR_CLEAR(lex, frames);
+ if (lex->modelname)
+ mem_d(lex->modelname);
+
if (lex->file)
fclose(lex->file);
if (lex->tok)
token_delete(lex->tok);
- mem_d(lex->name);
+ /* mem_d(lex->name); collected in lex_filenames */
mem_d(lex);
}
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 == '.') {