X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=lexer.c;h=606ef5a9fee5cf768864d6a31e3cb84e5fe96c1a;hb=812cb5be649c863e8d12289d858b15de60e86fd4;hp=1bea430edd36b1929505d8baf2fba3b7b9457cde;hpb=331c00dd50b07af4e31225c8533e88bdf604709b;p=xonotic%2Fgmqcc.git diff --git a/lexer.c b/lexer.c index 1bea430..606ef5a 100644 --- a/lexer.c +++ b/lexer.c @@ -24,6 +24,25 @@ void lexerror(lex_file *lex, const char *fmt, ...) printf("\n"); } +void lexwarn(lex_file *lex, int warn, const char *fmt, ...) +{ + va_list ap; + + if (!OPTS_WARN(warn)) + return; + + if (lex) + printf("warning %s:%lu: ", lex->name, (unsigned long)lex->sline); + else + printf("warning: "); + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + + printf("\n"); +} + token* token_new() { token *tok = (token*)mem_a(sizeof(token)); @@ -333,10 +352,6 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) if (ch == quote) return TOKEN_STRINGCONST; - if (!lex_tokench(lex, ch)) - return (lex->tok->ttype = TOKEN_FATAL); - - /* as lexer we only care about \" to not terminate the string prematurely */ if (ch == '\\') { ch = lex_getch(lex); if (ch == EOF) { @@ -344,10 +359,28 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */ return (lex->tok->ttype = TOKEN_ERROR); } - /* so we just add the next character no matter what it actually is */ + + switch (ch) { + case '\\': break; + case 'a': ch = '\a'; break; + case 'b': ch = '\b'; break; + case 'r': ch = '\r'; break; + case 'n': ch = '\n'; break; + case 't': ch = '\t'; break; + case 'f': ch = '\f'; break; + case 'v': ch = '\v'; break; + default: + lexwarn(lex, WARN_UNKNOWN_CONTROL_SEQUENCE, "unrecognized control sequence: \\%c", ch); + /* so we just add the character plus backslash no matter what it actually is */ + if (!lex_tokench(lex, '\\')) + return (lex->tok->ttype = TOKEN_FATAL); + } + /* add the character finally */ if (!lex_tokench(lex, ch)) return (lex->tok->ttype = TOKEN_FATAL); } + else if (!lex_tokench(lex, ch)) + return (lex->tok->ttype = TOKEN_FATAL); } lexerror(lex, "unexpected end of file within string constant"); lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */ @@ -464,8 +497,6 @@ int lex_do(lex_file *lex) case '[': case ']': - case ',': - case '#': return (lex->tok->ttype = ch); @@ -491,12 +522,23 @@ int lex_do(lex_file *lex) case '|': case '^': case '~': - return ch; + case ',': + case '.': + return (lex->tok->ttype = ch); default: break; } } + if (ch == ',' || ch == '.') { + if (!lex_tokench(lex, ch) || + !lex_endtoken(lex)) + { + return (lex->tok->ttype = TOKEN_FATAL); + } + return (lex->tok->ttype = TOKEN_OPERATOR); + } + if (ch == '+' || ch == '-' || /* ++, --, +=, -= and -> as well! */ ch == '>' || ch == '<' || /* <<, >>, <=, >= */ ch == '=' || /* == */ @@ -582,7 +624,10 @@ int lex_do(lex_file *lex) } else if (!strcmp(v, "for") || !strcmp(v, "while") || !strcmp(v, "do") || + !strcmp(v, "if") || + !strcmp(v, "else") || !strcmp(v, "var") || + !strcmp(v, "local") || !strcmp(v, "return") || !strcmp(v, "const")) lex->tok->ttype = TOKEN_KEYWORD; @@ -621,7 +666,13 @@ int lex_do(lex_file *lex) return (lex->tok->ttype = TOKEN_FATAL); /* It's a vector if we can successfully scan 3 floats */ - if (sscanf(lex->tok->value, " %f %f %f ", &lex->tok->constval.v.x, &lex->tok->constval.v.y, &lex->tok->constval.v.z) == 3) +#ifdef WIN32 + if (sscanf_s(lex->tok->value, " %f %f %f ", + &lex->tok->constval.v.x, &lex->tok->constval.v.y, &lex->tok->constval.v.z) == 3) +#else + if (sscanf(lex->tok->value, " %f %f %f ", + &lex->tok->constval.v.x, &lex->tok->constval.v.y, &lex->tok->constval.v.z) == 3) +#endif { lex->tok->ttype = TOKEN_VECTORCONST; }