#include "gmqcc.h"
#include "lexer.h"
+
/*
* List of Keywords
*/
lex_file* lex_open(const char *file)
{
- lex_file *lex;
- FILE *in = fs_file_open(file, "rb");
+ lex_file *lex;
+ fs_file_t *in = fs_file_open(file, "rb");
if (!in) {
lexerror(NULL, "open failed: '%s'\n", file);
}
if (lex->open_string) {
if (lex->open_string_pos >= lex->open_string_length)
- return EOF;
+ return FS_FILE_EOF;
lex->column++;
return lex->open_string[lex->open_string_pos++];
}
- return EOF;
+ return FS_FILE_EOF;
}
/* Get or put-back data
goto unroll;
lex->line = line;
- while (ch != '\n' && ch != EOF)
+ while (ch != '\n' && ch != FS_FILE_EOF)
ch = lex_getch(lex);
vec_free(command);
vec_free(param);
do
{
ch = lex_getch(lex);
- while (ch != EOF && util_isspace(ch)) {
+ while (ch != FS_FILE_EOF && util_isspace(ch)) {
if (ch == '\n') {
if (lex_try_pragma(lex))
continue;
lex_tokench(lex, ' ');
}
- while (ch != EOF && ch != '\n') {
+ while (ch != FS_FILE_EOF && ch != '\n') {
if (lex->flags.preprocessing)
lex_tokench(lex, ' '); /* ch); */
ch = lex_getch(lex);
lex_tokench(lex, ' ');
}
- while (ch != EOF)
+ while (ch != FS_FILE_EOF)
{
ch = lex_getch(lex);
if (ch == '*') {
ch = '/';
break;
}
- } while (ch != EOF && util_isspace(ch));
+ } while (ch != FS_FILE_EOF && util_isspace(ch));
if (haswhite) {
lex_endtoken(lex);
int ch;
ch = lex_getch(lex);
- while (ch != EOF && isident(ch))
+ while (ch != FS_FILE_EOF && isident(ch))
{
lex_tokench(lex, ch);
ch = lex_getch(lex);
lex_token_new(lex);
ch = lex_getch(lex);
- while (ch != EOF && ch != '\n' && util_isspace(ch))
+ while (ch != FS_FILE_EOF && ch != '\n' && util_isspace(ch))
ch = lex_getch(lex);
if (ch == '\n')
static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote)
{
- uchar_t chr;
+ utf8ch_t chr = 0;
int ch = 0;
int nextch;
bool hex;
+ bool oct;
char u8buf[8]; /* way more than enough */
int u8len, uc;
- while (ch != EOF)
+ while (ch != FS_FILE_EOF)
{
ch = lex_getch(lex);
if (ch == quote)
if (lex->flags.preprocessing && ch == '\\') {
lex_tokench(lex, ch);
ch = lex_getch(lex);
- if (ch == EOF) {
+ if (ch == FS_FILE_EOF) {
lexerror(lex, "unexpected end of file");
- lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
+ lex_ungetch(lex, FS_FILE_EOF); /* next token to be TOKEN_EOF */
return (lex->tok.ttype = TOKEN_ERROR);
}
lex_tokench(lex, ch);
}
else if (ch == '\\') {
ch = lex_getch(lex);
- if (ch == EOF) {
+ if (ch == FS_FILE_EOF) {
lexerror(lex, "unexpected end of file");
- lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
+ lex_ungetch(lex, FS_FILE_EOF); /* next token to be TOKEN_EOF */
return (lex->tok.ttype = TOKEN_ERROR);
}
chr = 0;
nextch = lex_getch(lex);
hex = (nextch == 'x');
- if (!hex)
+ oct = (nextch == '0');
+ if (!hex && !oct)
lex_ungetch(lex, nextch);
for (nextch = lex_getch(lex); nextch != '}'; nextch = lex_getch(lex)) {
- if (!hex) {
+ if (!hex && !oct) {
if (nextch >= '0' && nextch <= '9')
chr = chr * 10 + nextch - '0';
else {
lexerror(lex, "bad character code");
return (lex->tok.ttype = TOKEN_ERROR);
}
- } else {
+ } else if (!oct) {
if (nextch >= '0' && nextch <= '9')
chr = chr * 0x10 + nextch - '0';
else if (nextch >= 'a' && nextch <= 'f')
lexerror(lex, "bad character code");
return (lex->tok.ttype = TOKEN_ERROR);
}
+ } else {
+ if (nextch >= '0' && nextch <= '9')
+ chr = chr * 8 + chr - '0';
+ else {
+ lexerror(lex, "bad character code");
+ return (lex->tok.ttype = TOKEN_ERROR);
+ }
}
if (chr > 0x10FFFF || (!OPTS_FLAG(UTF8) && chr > 255))
{
}
}
if (OPTS_FLAG(UTF8) && chr >= 128) {
- u8len = u8_fromchar(chr, u8buf, sizeof(u8buf));
+ u8len = utf8_from(u8buf, chr);
if (!u8len)
ch = 0;
else {
lex->column += u8len;
for (uc = 0; uc < u8len; ++uc)
lex_tokench(lex, u8buf[uc]);
- /* the last character will be inserted with the tokench() call
+ /*
+ * the last character will be inserted with the tokench() call
* below the switch
*/
ch = u8buf[uc];
lex_tokench(lex, ch);
}
lexerror(lex, "unexpected end of file within string constant");
- lex_ungetch(lex, EOF); /* next token to be TOKEN_EOF */
+ lex_ungetch(lex, FS_FILE_EOF); /* next token to be TOKEN_EOF */
return (lex->tok.ttype = TOKEN_ERROR);
}
if (lex->eof)
return (lex->tok.ttype = TOKEN_FATAL);
- if (ch == EOF) {
+ if (ch == FS_FILE_EOF) {
lex->eof = true;
return (lex->tok.ttype = TOKEN_EOF);
}
if (!strcmp(v, "framevalue"))
{
ch = lex_getch(lex);
- while (ch != EOF && util_isspace(ch) && ch != '\n')
+ while (ch != FS_FILE_EOF && util_isspace(ch) && ch != '\n')
ch = lex_getch(lex);
if (!util_isdigit(ch)) {
vec_free(lex->frames);
/* skip line (fteqcc does it too) */
ch = lex_getch(lex);
- while (ch != EOF && ch != '\n')
+ while (ch != FS_FILE_EOF && ch != '\n')
ch = lex_getch(lex);
return lex_do(lex);
}
{
/* skip line */
ch = lex_getch(lex);
- while (ch != EOF && ch != '\n')
+ while (ch != FS_FILE_EOF && ch != '\n')
ch = lex_getch(lex);
return lex_do(lex);
}
}
if (ch == '+' || ch == '-' || /* ++, --, +=, -= and -> as well! */
- ch == '>' || ch == '<' || /* <<, >>, <=, >= */
+ ch == '>' || ch == '<' || /* <<, >>, <=, >= and >< as well! */
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);
lex_endtoken(lex);
lex->tok.ttype = TOKEN_CHARCONST;
- /* It's a vector if we can successfully scan 3 floats */
-#ifdef _MSC_VER
- 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 ",
+
+ /* It's a vector if we can successfully scan 3 floats */
+ if (util_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;
else
{
if (!lex->flags.preprocessing && strlen(lex->tok.value) > 1) {
- uchar_t u8char;
+ utf8ch_t u8char;
/* check for a valid utf8 character */
- if (!OPTS_FLAG(UTF8) || !u8_analyze(lex->tok.value, NULL, NULL, &u8char, 8)) {
+ if (!OPTS_FLAG(UTF8) || !utf8_to(&u8char, (const unsigned char *)lex->tok.value, 8)) {
if (lexwarn(lex, WARN_MULTIBYTE_CHARACTER,
( OPTS_FLAG(UTF8) ? "invalid multibyte character sequence `%s`"
: "multibyte character: `%s`" ),
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);
}