X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=lexer.c;h=3781496927cdbc5b31209f92389130148ca0c72e;hb=496aededb11fff56e998254d56e6876ca0980655;hp=43182c335ae93ef94bf262ce82c065375a9b1423;hpb=e2f9aa5027ea5831ee0f53aba651273d04018dcd;p=xonotic%2Fgmqcc.git diff --git a/lexer.c b/lexer.c index 43182c3..3781496 100644 --- a/lexer.c +++ b/lexer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 + * Copyright (C) 2012, 2013 * Wolfgang Bumiller * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -291,12 +291,16 @@ static int lex_try_trigraph(lex_file *lex, int old) { int c2, c3; c2 = lex_fgetc(lex); + if (!lex->push_line && c2 == '\n') + lex->line++; if (c2 != '?') { lex_ungetch(lex, c2); return old; } c3 = lex_fgetc(lex); + if (!lex->push_line && c3 == '\n') + lex->line++; switch (c3) { case '=': return '#'; case '/': return '\\'; @@ -485,7 +489,7 @@ unroll: if (command) { vec_pop(command); while (vec_size(command)) { - lex_ungetch(lex, vec_last(command)); + lex_ungetch(lex, (unsigned char)vec_last(command)); vec_pop(command); } vec_free(command); @@ -494,7 +498,7 @@ unroll: if (command) { vec_pop(command); while (vec_size(command)) { - lex_ungetch(lex, vec_last(command)); + lex_ungetch(lex, (unsigned char)vec_last(command)); vec_pop(command); } vec_free(command); @@ -503,7 +507,7 @@ unroll: if (pragma) { vec_pop(pragma); while (vec_size(pragma)) { - lex_ungetch(lex, vec_last(pragma)); + lex_ungetch(lex, (unsigned char)vec_last(pragma)); vec_pop(pragma); } vec_free(pragma); @@ -742,6 +746,7 @@ static bool lex_finish_frames(lex_file *lex) static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) { + uchar_t chr; int ch = 0; int nextch; bool hex; @@ -827,7 +832,7 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) case '[': ch = 16; break; case ']': ch = 17; break; case '{': - ch = 0; + chr = 0; nextch = lex_getch(lex); hex = (nextch == 'x'); if (!hex) @@ -835,32 +840,31 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) for (nextch = lex_getch(lex); nextch != '}'; nextch = lex_getch(lex)) { if (!hex) { if (nextch >= '0' && nextch <= '9') - ch = ch * 10 + nextch - '0'; + chr = chr * 10 + nextch - '0'; else { lexerror(lex, "bad character code"); return (lex->tok.ttype = TOKEN_ERROR); } } else { - if (nextch >= '0' || nextch <= '9') - ch = ch * 16 + nextch - '0'; + if (nextch >= '0' && nextch <= '9') + chr = chr * 0x10 + nextch - '0'; else if (nextch >= 'a' && nextch <= 'f') - ch = ch * 16 + nextch - 'a' + 10; + chr = chr * 0x10 + nextch - 'a' + 10; else if (nextch >= 'A' && nextch <= 'F') - ch = ch * 16 + nextch - 'A' + 10; + chr = chr * 0x10 + nextch - 'A' + 10; else { lexerror(lex, "bad character code"); return (lex->tok.ttype = TOKEN_ERROR); } } - if ( (!OPTS_FLAG(UTF8) && ch > 255) || - ( OPTS_FLAG(UTF8) && ch > 0x10FFFF) ) + if (chr > 0x10FFFF || (!OPTS_FLAG(UTF8) && chr > 255)) { lexerror(lex, "character code out of range"); return (lex->tok.ttype = TOKEN_ERROR); } } - if (OPTS_FLAG(UTF8) && ch >= 128) { - u8len = u8_fromchar((uchar_t)ch, u8buf, sizeof(u8buf)); + if (OPTS_FLAG(UTF8) && chr >= 128) { + u8len = u8_fromchar(chr, u8buf, sizeof(u8buf)); if (!u8len) ch = 0; else { @@ -873,6 +877,8 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) ch = u8buf[uc]; } } + else + ch = chr; break; case '\n': ch = '\n'; break; @@ -1242,31 +1248,37 @@ int lex_do(lex_file *lex) default: break; } + } - if (ch == '.') - { - lex_tokench(lex, ch); - /* peak ahead once */ - nextch = lex_getch(lex); - if (nextch != '.') { - lex_ungetch(lex, nextch); - lex_endtoken(lex); - return (lex->tok.ttype = ch); - } - /* peak ahead again */ - nextch = lex_getch(lex); - if (nextch != '.') { - lex_ungetch(lex, nextch); - lex_ungetch(lex, '.'); - lex_endtoken(lex); + if (ch == '.') + { + lex_tokench(lex, ch); + /* peak ahead once */ + nextch = lex_getch(lex); + if (nextch != '.') { + lex_ungetch(lex, nextch); + lex_endtoken(lex); + if (lex->flags.noops) return (lex->tok.ttype = ch); - } - /* fill the token to be "..." */ - lex_tokench(lex, ch); - lex_tokench(lex, ch); + else + return (lex->tok.ttype = TOKEN_OPERATOR); + } + /* peak ahead again */ + nextch = lex_getch(lex); + if (nextch != '.') { + lex_ungetch(lex, nextch); + lex_ungetch(lex, '.'); lex_endtoken(lex); - return (lex->tok.ttype = TOKEN_DOTS); + if (lex->flags.noops) + return (lex->tok.ttype = ch); + else + return (lex->tok.ttype = TOKEN_OPERATOR); } + /* fill the token to be "..." */ + lex_tokench(lex, ch); + lex_tokench(lex, ch); + lex_endtoken(lex); + return (lex->tok.ttype = TOKEN_DOTS); } if (ch == ',' || ch == '.') { @@ -1297,6 +1309,17 @@ int lex_do(lex_file *lex) lex_tokench(lex, nextch); lex_tokench(lex, thirdch); } + } + else if (lex->flags.preprocessing && + ch == '-' && isdigit(nextch)) + { + lex->tok.ttype = lex_finish_digit(lex, nextch); + if (lex->tok.ttype == TOKEN_INTCONST) + lex->tok.constval.i = -lex->tok.constval.i; + else + lex->tok.constval.f = -lex->tok.constval.f; + lex_endtoken(lex); + return lex->tok.ttype; } else lex_ungetch(lex, nextch);