X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=lexer.c;h=7642d261b89b4b3b9eae3e8fa6c4c1ec0751b96e;hp=8289057e1f0f20c720aa506241c1afe17818b3d5;hb=ce07e8fe28458c0c4457da90b2ff662536014033;hpb=0eab97283f30db40344105a699440d7b5fbd2f96 diff --git a/lexer.c b/lexer.c index 8289057..7642d26 100644 --- a/lexer.c +++ b/lexer.c @@ -20,7 +20,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include #include #include @@ -38,8 +37,6 @@ static const char *keywords_qc[] = { "return", "const" }; -static size_t num_keywords_qc = sizeof(keywords_qc) / sizeof(keywords_qc[0]); - /* For fte/gmgqcc */ static const char *keywords_fg[] = { "switch", "case", "default", @@ -50,12 +47,10 @@ static const char *keywords_fg[] = { "__builtin_debug_printtype" }; -static size_t num_keywords_fg = sizeof(keywords_fg) / sizeof(keywords_fg[0]); /* * Lexer code */ - static char* *lex_filenames; static void lexerror(lex_file *lex, const char *fmt, ...) @@ -72,12 +67,13 @@ static void lexerror(lex_file *lex, const char *fmt, ...) static bool lexwarn(lex_file *lex, int warntype, const char *fmt, ...) { - bool r; - lex_ctx ctx; - va_list ap; + bool r; + lex_ctx_t ctx; + va_list ap; - ctx.file = lex->name; - ctx.line = lex->sline; + ctx.file = lex->name; + ctx.line = lex->sline; + ctx.column = lex->column; va_start(ap, fmt); r = vcompile_warning(ctx, warntype, fmt, ap); @@ -172,7 +168,7 @@ static void lex_token_new(lex_file *lex) #else if (lex->tok.value) vec_shrinkto(lex->tok.value, 0); - + lex->tok.constval.t = 0; lex->tok.ctx.line = lex->sline; lex->tok.ctx.file = lex->name; @@ -298,7 +294,7 @@ static int lex_try_trigraph(lex_file *lex, int old) lex->line++; lex->column = 0; } - + if (c2 != '?') { lex_ungetch(lex, c2); return old; @@ -309,7 +305,7 @@ static int lex_try_trigraph(lex_file *lex, int old) lex->line++; lex->column = 0; } - + switch (c3) { case '=': return '#'; case '/': return '\\'; @@ -356,14 +352,18 @@ static int lex_getch(lex_file *lex) if (lex->peekpos) { lex->peekpos--; - if (!lex->push_line && lex->peek[lex->peekpos] == '\n') + if (!lex->push_line && lex->peek[lex->peekpos] == '\n') { lex->line++; + lex->column = 0; + } return lex->peek[lex->peekpos]; } ch = lex_fgetc(lex); - if (!lex->push_line && ch == '\n') + if (!lex->push_line && ch == '\n') { lex->line++; + lex->column = 0; + } else if (ch == '?') return lex_try_trigraph(lex, ch); else if (!lex->flags.nodigraphs && (ch == '<' || ch == ':' || ch == '%')) @@ -388,12 +388,12 @@ static void lex_ungetch(lex_file *lex, int ch) /* Idents are alphanumberic, but they start with alpha or _ */ static bool isident_start(int ch) { - return isalpha(ch) || ch == '_'; + return util_isalpha(ch) || ch == '_'; } static bool isident(int ch) { - return isident_start(ch) || isdigit(ch); + return isident_start(ch) || util_isdigit(ch); } /* isxdigit_only is used when we already know it's not a digit @@ -573,7 +573,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) do { ch = lex_getch(lex); - while (ch != EOF && isspace(ch)) { + while (ch != EOF && util_isspace(ch)) { if (ch == '\n') { if (lex_try_pragma(lex)) continue; @@ -671,7 +671,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) ch = '/'; break; } - } while (ch != EOF && isspace(ch)); + } while (ch != EOF && util_isspace(ch)); if (haswhite) { lex_endtoken(lex); @@ -707,7 +707,7 @@ static int lex_parse_frame(lex_file *lex) lex_token_new(lex); ch = lex_getch(lex); - while (ch != EOF && ch != '\n' && isspace(ch)) + while (ch != EOF && ch != '\n' && util_isspace(ch)) ch = lex_getch(lex); if (ch == '\n') @@ -929,7 +929,7 @@ static int GMQCC_WARN lex_finish_digit(lex_file *lex, int lastch) lex_tokench(lex, ch); ch = lex_getch(lex); - if (ch != '.' && !isdigit(ch)) + if (ch != '.' && !util_isdigit(ch)) { if (lastch != '0' || ch != 'x') { @@ -950,7 +950,7 @@ static int GMQCC_WARN lex_finish_digit(lex_file *lex, int lastch) { lex_tokench(lex, ch); ch = lex_getch(lex); - while (isdigit(ch) || (ishex && isxdigit_only(ch))) + while (util_isdigit(ch) || (ishex && isxdigit_only(ch))) { lex_tokench(lex, ch); ch = lex_getch(lex); @@ -965,7 +965,7 @@ static int GMQCC_WARN lex_finish_digit(lex_file *lex, int lastch) /* continue digits-only */ ch = lex_getch(lex); - while (isdigit(ch)) + while (util_isdigit(ch)) { lex_tokench(lex, ch); ch = lex_getch(lex); @@ -1068,10 +1068,10 @@ int lex_do(lex_file *lex) if (!strcmp(v, "framevalue")) { ch = lex_getch(lex); - while (ch != EOF && isspace(ch) && ch != '\n') + while (ch != EOF && util_isspace(ch) && ch != '\n') ch = lex_getch(lex); - if (!isdigit(ch)) { + if (!util_isdigit(ch)) { lexerror(lex, "$framevalue requires an integer parameter"); return lex_do(lex); } @@ -1229,7 +1229,7 @@ int lex_do(lex_file *lex) if (ch == '.') { nextch = lex_getch(lex); /* digits starting with a dot */ - if (isdigit(nextch)) { + if (util_isdigit(nextch)) { lex_ungetch(lex, nextch); lex->tok.ttype = lex_finish_digit(lex, ch); lex_endtoken(lex); @@ -1306,15 +1306,17 @@ int lex_do(lex_file *lex) } if (ch == '+' || ch == '-' || /* ++, --, +=, -= and -> as well! */ - ch == '>' || ch == '<' || /* <<, >>, <=, >= */ + ch == '>' || ch == '<' || /* <<, >>, <=, >= and >< as well! */ ch == '=' || ch == '!' || /* <=>, ==, != */ ch == '&' || ch == '|' || /* &&, ||, &=, |= */ - ch == '~' /* ~=, ~ */ + ch == '~' || ch == '^' /* ~=, ~, ^ */ ) { lex_tokench(lex, ch); nextch = lex_getch(lex); - if ((nextch == '=' && ch != '<') || (nextch == ch && ch != '!')) { + if ((nextch == '=' && ch != '<') || + (nextch == ch && ch != '!') || + (nextch == '<' && ch == '>')) { lex_tokench(lex, nextch); } else if (ch == '<' && nextch == '=') { lex_tokench(lex, nextch); @@ -1337,7 +1339,7 @@ int lex_do(lex_file *lex) } } else if (lex->flags.preprocessing && - ch == '-' && isdigit(nextch)) + ch == '-' && util_isdigit(nextch)) { lex->tok.ttype = lex_finish_digit(lex, nextch); if (lex->tok.ttype == TOKEN_INTCONST) @@ -1416,12 +1418,12 @@ int lex_do(lex_file *lex) lex->tok.constval.t = TYPE_VECTOR; } else { size_t kw; - for (kw = 0; kw < num_keywords_qc; ++kw) { + for (kw = 0; kw < GMQCC_ARRAY_COUNT(keywords_qc); ++kw) { if (!strcmp(v, keywords_qc[kw])) return (lex->tok.ttype = TOKEN_KEYWORD); } if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_QCC) { - for (kw = 0; kw < num_keywords_fg; ++kw) { + for (kw = 0; kw < GMQCC_ARRAY_COUNT(keywords_fg); ++kw) { if (!strcmp(v, keywords_fg[kw])) return (lex->tok.ttype = TOKEN_KEYWORD); } @@ -1504,7 +1506,7 @@ int lex_do(lex_file *lex) return lex->tok.ttype; } - if (isdigit(ch)) + if (util_isdigit(ch)) { lex->tok.ttype = lex_finish_digit(lex, ch); lex_endtoken(lex); @@ -1517,6 +1519,6 @@ int lex_do(lex_file *lex) return (lex->tok.ttype = ch); } - lexerror(lex, "unknown token: `%s`", lex->tok.value); + lexerror(lex, "unknown token: `%c`", ch); return (lex->tok.ttype = TOKEN_ERROR); }