MWCC/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c

2487 lines
70 KiB
C

#include "compiler/CPrepTokenizer.h"
#include "compiler/CError.h"
#include "compiler/CInt64.h"
#include "compiler/CMachine.h"
#include "compiler/CParser.h"
#include "compiler/CPrep.h"
#include "compiler/CompilerTools.h"
#include "compiler/InlineAsmPPC.h"
#include "compiler/tokens.h"
#include "cos.h"
static Boolean prepnextstringchar_foundnl;
short prepskipnextchar(void) {
short c;
StringPtr start;
StringPtr p;
start = (StringPtr) pos;
p = (StringPtr) pos;
loop:
switch ((c = *p)) {
case 0:
if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) {
pos = (char *) p;
nextcharpos = (char *) p;
return c;
} else {
pos = (char *) p++;
nextcharpos = (char *) p;
return c;
}
case 4:
case 5:
p++;
goto loop;
case ' ':
case '\t':
case '\n':
case '\v':
case '\f':
spaceskip = 1;
p++;
goto loop;
case ';':
pos = (char *) p++;
if (tokenstacklevel <= 0 && in_assembler && copts.asmsemicolcomment) {
spaceskip = 1;
nextcharpos = (char *) CPrep_SkipNewComment(p);
return CPrep_SkipNewCommentChar;
}
nextcharpos = (char *) p;
return c;
case '#':
pos = (char *) p++;
if (tokenstacklevel <= 0 && in_assembler && copts.asmpoundcomment) {
spaceskip = 1;
nextcharpos = (char *) CPrep_SkipNewComment(p);
return CPrep_SkipNewCommentChar;
}
nextcharpos = (char *) p;
return c;
case '/':
pos = (char *) p++;
if (copts.multibyteaware) {
while (p[0] == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
} else {
while (p[0] == '\\' && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
}
if (tokenstacklevel <= 0) {
if (p[0] == '/' && (!copts.ANSIstrict || copts.cplusplus || copts.c9x)) {
spaceskip = 1;
nextcharpos = (char *) CPrep_SkipNewComment(p + 1);
return CPrep_SkipNewCommentChar;
} else if (p[0] == '*') {
spaceskip = 1;
p++;
for (;;) {
if (!(c = *(p++))) {
if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) {
CPrep_Error(CErrorStr103);
nextcharpos = (char *) p - 1;
return c;
}
p[-1] = ' ';
}
if (c == '*') {
if (copts.multibyteaware) {
while (p[0] == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
} else {
while (p[0] == '\\' && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
}
if (*p == '/') {
p++;
goto loop;
}
}
if (c == '\r')
foundnl();
}
}
}
nextcharpos = (char *) p;
return c;
case '%':
pos = (char *) p++;
if (*p == ':' && copts.cplusplus) {
nextcharpos = (char *) p + 1;
return '#';
}
nextcharpos = (char *) p;
return c;
case '\\':
pos = (char *) p++;
mid_backslash:
if (*p == '\r') {
if (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1)) {
foundnl();
if (p[1] == '\n')
p += 2;
else
p += 1;
goto loop;
}
}
nextcharpos = (char *) p;
return c;
case '?':
pos = (char *) p++;
if (copts.trigraphs && p[0] == '?') {
switch (p[1]) {
case '=':
nextcharpos = (char *) p + 2;
return '#';
case '/':
c = '\\';
p += 2;
goto mid_backslash;
case '\'':
nextcharpos = (char *) p + 2;
return '^';
case '(':
nextcharpos = (char *) p + 2;
return '[';
case ')':
nextcharpos = (char *) p + 2;
return ']';
case '!':
nextcharpos = (char *) p + 2;
return '|';
case '<':
nextcharpos = (char *) p + 2;
return '{';
case '>':
nextcharpos = (char *) p + 2;
return '}';
case '-':
nextcharpos = (char *) p + 2;
return '~';
}
}
nextcharpos = (char *) p;
return c;
default:
pos = (char *) p++;
nextcharpos = (char *) p;
return c;
}
}
short prepnextchar(void) {
short c;
StringPtr start;
StringPtr p;
start = (StringPtr) pos;
p = (StringPtr) pos;
loop:
switch ((c = *(p++))) {
case 0:
pos = (char *) p - 1;
return c;
case '/':
if (copts.multibyteaware) {
while (p[0] == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
} else {
while (p[0] == '\\' && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
}
if (p[0] == '/' && (!copts.ANSIstrict || copts.cplusplus)) {
spaceskip = 1;
pos = (char *) CPrep_SkipNewComment(p + 1);
return CPrep_SkipNewCommentChar;
} else if (p[0] == '*') {
spaceskip = 1;
p++;
for (;;) {
if (!(c = *(p++))) {
if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) {
pos = (char *) p - 1;
CPrep_Error(CErrorStr103);
return c;
}
p[-1] = ' ';
}
if (c == '*') {
if (copts.multibyteaware) {
while (p[0] == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
} else {
while (p[0] == '\\' && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
}
if (*p == '/')
break;
}
if (c == '\r')
foundnl();
}
pos = (char *) p + 1;
return ' ';
} else {
pos = (char *) p;
return c;
}
case '\\':
backslash:
if (*p == '\r') {
if (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1)) {
foundnl();
if (p[1] == '\n')
p += 2;
else
p += 1;
goto loop;
}
}
pos = (char *) p;
return c;
case '%':
if (*p == ':' && copts.cplusplus) {
pos = (char *) p + 1;
return '#';
}
pos = (char *) p;
return c;
case '?':
if (copts.trigraphs && p[0] == '?') {
switch (p[1]) {
case '=':
pos = (char *) p + 2;
return '#';
case '/':
c = '\\';
p += 2;
goto backslash;
case '\'':
pos = (char *) p + 2;
return '^';
case '(':
pos = (char *) p + 2;
return '[';
case ')':
pos = (char *) p + 2;
return ']';
case '!':
pos = (char *) p + 2;
return '|';
case '<':
pos = (char *) p + 2;
return '{';
case '>':
pos = (char *) p + 2;
return '}';
case '-':
pos = (char *) p + 2;
return '~';
}
}
pos = (char *) p;
return c;
default:
pos = (char *) p;
return c;
}
}
short prepnextstringchar(StringPtr str, Boolean flag) {
StringPtr p;
short c;
p = (StringPtr) pos;
loop:
switch ((c = *(p++))) {
case 0:
pos = (char *) p - 1;
return c;
case '\\':
backslash:
if (p[0] == '\r' && (!copts.multibyteaware || !COS_IsMultiByte(str, p - 1))) {
if (flag)
foundnl();
else
prepnextstringchar_foundnl = 1;
if (p[1] == '\n')
p += 2;
else
p += 1;
goto loop;
}
pos = (char *) p;
return c;
case '?':
if (copts.trigraphs && p[0] == '?') {
switch (p[1]) {
case '=':
pos = (char *) p + 2;
return '#';
case '/':
c = '\\';
p += 2;
goto backslash;
case '\'':
pos = (char *) p + 2;
return '^';
case '(':
pos = (char *) p + 2;
return '[';
case ')':
pos = (char *) p + 2;
return ']';
case '!':
pos = (char *) p + 2;
return '|';
case '<':
pos = (char *) p + 2;
return '{';
case '>':
pos = (char *) p + 2;
return '}';
case '-':
pos = (char *) p + 2;
return '~';
}
}
pos = (char *) p;
return c;
default:
pos = (char *) p;
return c;
}
}
void CPrep_MatchChar(char ch, Boolean flag) {
char *p;
char *start;
char c;
Boolean haveBackslash;
p = start = pos;
haveBackslash = 0;
loop:
if (!(c = *(p++))) {
if (tokenstacklevel > 0 || p >= prep_file_end)
CPrep_Error(CErrorStr102);
else if (ch == '"')
CPrep_Error(CErrorStr101);
else if (ch == '\'')
CPrep_Error(CErrorStr100);
CPrep_Error(CErrorStr117);
pos = p - 1;
return;
}
if (c == '\r') {
if (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1)) {
if (flag)
foundnl();
if (*p == '\n')
p++;
CPrep_Error(CErrorStr112);
pos = p;
return;
}
haveBackslash = 0;
goto loop;
}
if (c == '?' && p[0] == '?' && copts.trigraphs) {
switch (p[1]) {
case '!':
case '\'':
case '(':
case ')':
case '-':
case '<':
case '=':
case '>':
haveBackslash = 0;
p += 2;
goto loop;
case '/':
p += 2;
goto backslash;
}
}
if (c == '\\' && !haveBackslash && (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1))) {
backslash:
if (*p == '\r') {
if (flag)
foundnl();
if (*(++p) == '\n')
p++;
haveBackslash = 0;
} else {
haveBackslash = 1;
}
goto loop;
}
if (c == ch && !haveBackslash) {
pos = p;
} else {
haveBackslash = 0;
goto loop;
}
}
char *CPrep_MatchChar2(char *start, char ch, Boolean flag) {
char *p;
char c;
Boolean haveBackslash;
p = start;
haveBackslash = 0;
loop:
if (!(c = *(p++))) {
if (tokenstacklevel > 0 || p >= prep_file_end)
CPrep_Error(CErrorStr102);
else if (ch == '"')
CPrep_Error(CErrorStr101);
else if (ch == '\'')
CPrep_Error(CErrorStr100);
CPrep_Error(CErrorStr117);
return p - 1;
}
if (c == '\r') {
if (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1)) {
if (flag)
foundnl();
if (*p == '\n')
p++;
CPrep_Error(CErrorStr112);
return p;
}
haveBackslash = 0;
goto loop;
}
if (c == '?' && p[0] == '?' && copts.trigraphs) {
switch (p[1]) {
case '!':
case '\'':
case '(':
case ')':
case '-':
case '<':
case '=':
case '>':
haveBackslash = 0;
p += 2;
goto loop;
case '/':
p += 2;
goto backslash;
}
}
if (c == '\\' && !haveBackslash && (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1))) {
backslash:
if (*p == '\r') {
if (flag)
foundnl();
if (*(++p) == '\n')
p++;
haveBackslash = 0;
} else {
haveBackslash = 1;
}
goto loop;
}
if (c == ch && !haveBackslash) {
return p;
} else {
haveBackslash = 0;
goto loop;
}
}
short prepcurchar(void) {
char *save_pos;
short t;
save_pos = pos;
t = prepnextchar();
nextcharpos = pos;
pos = save_pos;
return t;
}
static short prepcurstringchar(StringPtr str) {
char *save_pos;
short t;
save_pos = pos;
prepnextstringchar_foundnl = 0;
t = prepnextstringchar(str, 0);
nextcharpos = pos;
pos = save_pos;
return t;
}
static void prepcurstringchar_skip(void) {
pos = nextcharpos;
if (prepnextstringchar_foundnl)
foundnl();
}
char *ReadIdentifier(const char *p) {
char buf[256];
const char *start;
unsigned int ch;
int len;
start = p;
len = 0;
for (;;) {
ch = (unsigned char) *p;
if (cprep_idarray[ch]) {
if (len < 255)
buf[len++] = *p;
p++;
} else {
if (copts.multibyteaware) {
if ((unsigned char) *p == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') {
if (p[2] == '\n')
p += 3;
else
p += 2;
foundnl();
} else {
break;
}
} else {
if ((unsigned char) *p == '\\' && p[1] == '\r') {
if (p[2] == '\n')
p += 3;
else
p += 2;
foundnl();
} else {
break;
}
}
}
}
buf[len] = 0;
tkidentifier = GetHashNameNodeExport(buf);
return (char *) p;
}
static short intsuffix(short token, Boolean flag) {
Boolean is_unsigned;
Boolean is_long;
Boolean is_longlong;
short t;
is_unsigned = is_long = is_longlong = 0;
t = token;
switch (t) {
case 'u':
case 'U':
is_unsigned = 1;
pos = nextcharpos;
t = prepcurchar();
if (t == 'l' || t == 'L') {
is_long = 1;
pos = nextcharpos;
t = *pos;
if (copts.longlong) {
pos = nextcharpos;
t = prepcurchar();
if (t == 'l' || t == 'L') {
is_longlong = 1;
pos = nextcharpos;
t = *pos;
}
}
}
break;
case 'l':
case 'L':
is_long = 1;
pos = nextcharpos;
t = prepcurchar();
if (t == 'u' || t == 'U') {
is_unsigned = 1;
pos = nextcharpos;
t = *pos;
} else if (copts.longlong && (t == 'l' || t == 'L')) {
is_longlong = 1;
pos = nextcharpos;
t = prepcurchar();
if (t == 'u' || t == 'U') {
is_unsigned = 1;
pos = nextcharpos;
t = *pos;
}
}
break;
case 'i':
case 'I':
if (copts.cpp_extensions && !copts.ANSIstrict && copts.longlong) {
pos = nextcharpos;
t = prepcurchar();
if (t == '6') {
pos = nextcharpos;
t = prepcurchar();
if (t == '4') {
is_long = is_longlong = 1;
pos = nextcharpos;
t = *pos;
}
}
}
break;
case 'b':
case 'B':
case 'f':
case 'F':
if (InlineAsm_gccmode)
return IT_INT;
break;
}
if ((t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z') || (t == '_') || (t >= '0' && t <= '9'))
CPrep_Error(CErrorStr105);
if (!is_longlong && !is_long) {
if (!is_unsigned && CInt64_IsInRange(tkintconst, stsignedint.size))
return IT_INT;
if ((flag || is_unsigned) && CInt64_IsInURange(tkintconst, stunsignedint.size))
return IT_UINT;
}
if (!is_longlong) {
if (!is_unsigned && CInt64_IsInRange(tkintconst, stsignedlong.size))
return IT_LONG;
if (CInt64_IsInURange(tkintconst, stunsignedlong.size))
return IT_ULONG;
}
if (copts.longlong) {
if (!is_unsigned && CInt64_IsInRange(tkintconst, stsignedlonglong.size))
return IT_LONGLONG;
if (CInt64_IsInURange(tkintconst, stsignedlonglong.size))
return IT_ULONGLONG;
}
CError_Error(CErrorStr154);
tkintconst = cint64_zero;
return IT_INT;
}
static short floatsuffix(short token) {
short whichtype;
switch (token) {
case 'f':
case 'F':
pos = nextcharpos;
token = *pos;
whichtype = IT_FLOAT;
if (stfloat.size != stlongdouble.size)
tkfloatconst = CMach_CalcFloatConvert((Type *) &stfloat, tkfloatconst);
break;
case 'l':
case 'L':
pos = nextcharpos;
token = *pos;
whichtype = IT_LONGDOUBLE;
break;
case 'd':
case 'D':
if (!copts.ANSIstrict) {
pos = nextcharpos;
token = *pos;
whichtype = IT_DOUBLE;
if (stdouble.size != stlongdouble.size)
tkfloatconst = CMach_CalcFloatConvert((Type *) &stdouble, tkfloatconst);
}
break;
default:
if (copts.float_constants) {
whichtype = IT_FLOAT;
if (stfloat.size != stlongdouble.size)
tkfloatconst = CMach_CalcFloatConvert((Type *) &stfloat, tkfloatconst);
} else {
whichtype = IT_DOUBLE;
if (stdouble.size != stlongdouble.size)
tkfloatconst = CMach_CalcFloatConvert((Type *) &stdouble, tkfloatconst);
}
}
if ((token >= 'a' && token <= 'z') || (token >= 'A' && token <= 'Z') || (token == '_') || (token >= '0' && token <= '9')) {
CPrep_Error(CErrorStr105);
whichtype = IT_DOUBLE;
}
return whichtype;
}
static short tohex(short token) {
if (token >= '0' && token <= '9')
return token - '0';
if (token >= 'a' && token <= 'f')
return token - 'a' + 10;
if (token >= 'A' && token <= 'F')
return token - 'A' + 10;
return -1;
}
static SInt32 nextchar(StringPtr str) {
short tmpchr;
SInt32 chr_max;
Boolean out_of_bounds;
SInt32 chr;
short i;
short t;
chr_max = 0xFF;
if (widestring) chr_max = 0xFFFF;
was_escchar = 0;
t = prepnextstringchar(str, 1);
if (t == '\\' && (!copts.multibyteaware || !COS_IsMultiByte(str, pos - 1))) {
was_escchar = 1;
switch ((t = prepnextstringchar(str, 1))) {
case 'a': return 7;
case 'b': return 8;
case 't': return 9;
case 'v': return 11;
case 'f': return 12;
case 'n':
if (copts.mpwc_newline)
return 13;
else
return 10;
case 'r':
if (copts.mpwc_newline)
return 10;
else
return 13;
case 'e': return 27;
case 'x':
chr = tohex(prepnextstringchar(str, 1));
if (chr == -1) {
CPrep_Error(CErrorStr100);
return ' ';
}
out_of_bounds = 0;
while (tohex((tmpchr = prepcurstringchar(str))) != -1) {
chr = (chr << 4) + tohex(tmpchr);
prepcurstringchar_skip();
if (chr & ~chr_max)
out_of_bounds = 1;
}
if (out_of_bounds)
CError_Error(CErrorStr100);
break;
default:
if (t >= '0' && t <= '7') {
out_of_bounds = 0;
i = 1;
chr = t - '0';
while (i < 3 && (tmpchr = prepcurstringchar(str)) >= '0' && tmpchr <= '7') {
chr = (chr << 3) + tmpchr - '0';
prepcurstringchar_skip();
if (chr & ~chr_max)
out_of_bounds = 1;
i++;
}
if (out_of_bounds)
CError_Error(CErrorStr100);
} else {
chr = t;
}
}
} else {
chr = t;
}
if (chr_max == 0xFF)
return (char) (chr & chr_max);
else
return (chr & chr_max);
}
StringPtr CPrep_SkipNewComment(StringPtr str) {
StringPtr p;
p = str;
while (1) {
switch (*(p++)) {
case 0:
if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) {
CPrep_SkipNewCommentChar = 0;
return p - 1;
}
p[-1] = ' ';
continue;
case '\r':
CPrep_SkipNewCommentChar = '\r';
return p;
case '\\':
if (copts.multibyteaware && COS_IsMultiByte(str, p - 1))
continue;
if (*p == '\r') {
++p;
foundnl();
}
if (*p == '\n')
p++;
continue;
case '"':
if (InlineAsm_gccmode) {
CPrep_SkipNewCommentChar = '\r';
return p - 1;
}
continue;
}
}
}
Boolean skipendoflinematch(StringPtr str, short token) {
StringPtr start;
start = str - 1;
pos = (char *) start;
while (1) {
switch (*(str++)) {
case 0:
case '\r':
pos = (char *) str - 1;
return 0;
case '"':
if (token == '"') {
pos = (char *) str;
return 1;
}
break;
case '\'':
if (token == '\'') {
pos = (char *) str;
return 1;
}
break;
case '\\':
if (copts.multibyteaware && COS_IsMultiByte(start, str - 1))
continue;
switch (*(str++)) {
case 0:
pos = (char *) str - 1;
return 0;
case '\r':
foundnl();
if (*str == '\n')
str++;
break;
}
break;
case '?':
if (copts.trigraphs && str[0] == '?' && str[1] == '/' && str[2] == '\r') {
foundnl();
str += 3;
}
break;
}
}
}
void skipendofline(void) {
StringPtr start;
StringPtr p;
short ch;
start = (StringPtr) pos;
p = (StringPtr) pos;
while (1) {
switch (*(p++)) {
case 0:
case '\r':
pos = (char *) p - 1;
return;
case '"':
if (!skipendoflinematch(p, '"'))
return;
p = (StringPtr) pos;
break;
case '\'':
if (!skipendoflinematch(p, '\''))
return;
p = (StringPtr) pos;
break;
case '/':
if (copts.multibyteaware) {
while (*p == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
} else {
while (*p == '\\' && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
}
if (*p == '/' && (!copts.ANSIstrict || copts.cplusplus)) {
// EOL comment
pos = (char *) CPrep_SkipNewComment(p + 1);
if (CPrep_SkipNewCommentChar == '\r')
pos--;
return;
}
if (*p == '*') {
// Block comment
pos = (char *) p - 1;
spaceskip = 1;
p++;
while (1) {
if ((ch = *(p++)) == 0) {
if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) {
pos = (char *) p - 1;
CPrep_Error(CErrorStr103);
return;
}
p[-1] = ' ';
}
if (ch == '*') {
if (copts.multibyteaware) {
while (*p == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
} else {
while (*p == '\\' && p[1] == '\r') {
foundnl();
if (p[2] == '\n')
p += 3;
else
p += 2;
}
}
if (*p == '/') {
p++;
break;
}
}
if (ch == '\r')
foundnl();
}
}
break;
case '\\':
if (copts.multibyteaware && COS_IsMultiByte(start, p - 1))
continue;
if (*p == '\r') {
foundnl();
if (p[1] == '\n')
p += 2;
else
p += 1;
}
break;
case '?':
if (copts.trigraphs && p[0] == '?' && p[1] == '/' && p[2] == '\r') {
foundnl();
p += 3;
}
break;
}
}
}
void CPrep_SkipAsmComment(void) {
Boolean save_macrocheck = macrocheck;
skipendofline();
macrocheck = save_macrocheck;
}
static short tille(void) { return TK_ILLEGAL; }
static short tcret(void) {
newline();
if (cprep_eoltokens)
return TK_EOL;
else
return 0;
}
static short tapos(short _t) {
int t;
int t2;
int i;
StringPtr start;
UInt32 maxvalue;
int bytecount;
CInt64 newBits;
CInt64 val;
start = (StringPtr) pos;
t = nextchar((StringPtr) pos);
if ((t == '\'' || t == 0 || t == '\r') && !was_escchar) {
CPrep_Error(CErrorStr100);
tkintconst = cint64_zero;
tksize = IT_INT;
return TK_INTCONST;
}
t2 = nextchar(start);
if (t2 == '\'' && !was_escchar) {
if (widestring) {
switch (stwchar.size) {
case 1:
CInt64_SetULong(&tkintconst, (UInt8) t);
tksize = copts.cplusplus ? IT_SCHAR : IT_INT;
break;
case 2:
CInt64_SetULong(&tkintconst, (UInt16) t);
tksize = IT_UINT;
break;
case 4:
CInt64_SetULong(&tkintconst, (UInt32) t);
tksize = IT_UINT;
break;
default:
CError_FATAL(1386);
}
} else {
if (copts.unsigned_char)
t &= 0xFF;
CInt64_SetLong(&tkintconst, t);
tksize = copts.cplusplus ? IT_SCHAR : IT_INT;
}
} else {
if (widestring) {
switch (stwchar.size) {
case 1:
CInt64_SetULong(&val, 8);
maxvalue = 0xFF;
bytecount = 1;
break;
case 2:
CInt64_SetULong(&val, 16);
maxvalue = 0xFFFF;
bytecount = 2;
break;
case 4:
CInt64_SetULong(&val, 32);
maxvalue = 0xFFFFFFFF;
bytecount = 4;
break;
default:
CError_FATAL(1424);
}
} else {
CInt64_SetULong(&val, 8);
maxvalue = 0xFF;
bytecount = 1;
}
CInt64_SetULong(&tkintconst, t & maxvalue);
i = bytecount;
while (1) {
if ((t2 == 0 || t2 == '\r') && !was_escchar) {
CPrep_Error(CErrorStr100);
break;
}
CInt64_SetULong(&newBits, t2 & maxvalue);
tkintconst = CInt64_Or(CInt64_Shl(tkintconst, val), newBits);
i += bytecount;
t2 = nextchar(start);
if (t2 == '\'' && !was_escchar)
break;
if (i >= stunsignedlonglong.size) {
CPrep_Error(CErrorStr100);
break;
}
}
if (i <= stunsignedint.size && stunsignedint.size < stunsignedlong.size)
tksize = IT_UINT;
else if (i <= stunsignedlong.size)
tksize = IT_ULONG;
else
tksize = IT_ULONGLONG;
}
return TK_INTCONST;
}
static short tquot(short t) {
Type *type;
StringPtr string_ptr;
SInt32 size;
short c;
StringPtr save_pos;
StringPtr start_pos;
CInt64 ch64;
start_pos = (StringPtr) pos;
at_linestart = 0;
if (cprep_nostring)
return '"';
string_ptr = (StringPtr) *stringmem;
ispascalstring = 0;
size = 0;
if (widestring)
type = TYPE(&stwchar);
else
type = TYPE(&stchar);
if (prepcurstringchar(start_pos) == '\\') {
save_pos = (StringPtr) pos;
prepcurstringchar_skip();
if (prepcurstringchar(start_pos) == 'p') {
prepcurstringchar_skip();
ispascalstring = 1;
string_ptr += type->size;
} else {
pos = (char *) save_pos;
}
}
while (1) {
c = nextchar(start_pos);
if ((c == '"' || c == '\r' || c == 0) && !was_escchar) {
if (c == 0 && (tokenstacklevel > 0 || pos >= prep_file_end))
CPrep_Error(CErrorStr102);
else if (c != '"')
CPrep_Error(CErrorStr101);
break;
}
if ((size + type->size) >= maxstringsize) {
SInt32 offset = string_ptr - (StringPtr) *stringmem;
if (!COS_ResizeHandle(stringmem, maxstringsize += 256))
CError_NoMem();
string_ptr = (StringPtr) *stringmem + offset;
}
if (type->size != 1) {
CInt64_SetLong(&ch64, c);
CMach_InitIntMem(type, ch64, string_ptr);
string_ptr += type->size;
size += type->size;
} else {
*string_ptr = c;
string_ptr++;
size++;
}
}
if (ispascalstring) {
if (size > 255 && type->size == 1) {
CPrep_Error(CErrorStr106);
size = 255;
}
CInt64_SetLong(&ch64, size / type->size);
CMach_InitIntMem(type, ch64, *stringmem);
size += type->size;
} else {
if ((size + 1) >= maxstringsize) {
if (!COS_ResizeHandle(stringmem, maxstringsize += 256))
CError_NoMem();
}
CMach_InitIntMem(type, cint64_zero, *stringmem + size);
size += type->size;
}
tksize = size;
tkstring = galloc(size);
memcpy(tkstring, *stringmem, tksize);
if (widestring)
c = TK_STRING_WIDE;
else
c = TK_STRING;
return (short) c;
}
static short thash(void) {
if (at_linestart) {
preprocessor();
return 0;
}
return '#';
}
static short tmult(void) {
at_linestart = 0;
if (prepcurchar() == '=') {
pos = nextcharpos;
return TK_MULT_ASSIGN;
}
return '*';
}
static short tcolo(void) {
char t2;
at_linestart = 0;
if (copts.cplusplus) {
t2 = prepcurchar();
if (t2 == ':') {
pos = nextcharpos;
return TK_COLON_COLON;
}
if (t2 == '>' && !preprocessing_only) {
pos = nextcharpos;
return ']';
}
}
return ':';
}
static short tless(void) {
short t2;
at_linestart = 0;
t2 = prepcurchar();
if (t2 == '=') {
pos = nextcharpos;
return TK_LESS_EQUAL;
}
if (t2 == '<') {
pos = nextcharpos;
if (prepcurchar() == '=') {
pos = nextcharpos;
return TK_SHL_ASSIGN;
} else {
return TK_SHL;
}
}
if (t2 == '%' && copts.cplusplus && !preprocessing_only) {
pos = nextcharpos;
return '{';
}
if (t2 == ':' && copts.cplusplus && !preprocessing_only) {
pos = nextcharpos;
return '[';
}
return '<';
}
static short tequa(short) {
at_linestart = 0;
if (prepcurchar() == '=') {
pos = nextcharpos;
return TK_LOGICAL_EQ;
}
return '=';
}
static short tgrea(short) {
short t2;
at_linestart = 0;
t2 = prepcurchar();
if (t2 == '=') {
pos = nextcharpos;
return TK_GREATER_EQUAL;
}
if (t2 == '>') {
pos = nextcharpos;
if (prepcurchar() == '=') {
pos = nextcharpos;
return TK_SHR_ASSIGN;
} else {
return TK_SHR;
}
}
return '>';
}
static short tatsg(short) {
char save_idarray;
char *start_pos = pos;
at_linestart = 0;
if (copts.objective_c || in_assembler) {
save_idarray = cprep_idarray['@'];
cprep_idarray['@'] = 1;
pos = ReadIdentifier(start_pos - 1);
cprep_idarray['@'] = save_idarray;
if (copts.objective_c) {
if (!strcmp("@interface", tkidentifier->name))
return TK_AT_INTERFACE;
if (!strcmp("@implementation", tkidentifier->name))
return TK_AT_IMPLEMENTATION;
if (!strcmp("@protocol", tkidentifier->name))
return TK_AT_PROTOCOL;
if (!strcmp("@end", tkidentifier->name))
return TK_AT_END;
if (!strcmp("@private", tkidentifier->name))
return TK_AT_PRIVATE;
if (!strcmp("@protected", tkidentifier->name))
return TK_AT_PROTECTED;
if (!strcmp("@public", tkidentifier->name))
return TK_AT_PUBLIC;
if (!strcmp("@class", tkidentifier->name))
return TK_AT_CLASS;
if (!strcmp("@selector", tkidentifier->name))
return TK_AT_SELECTOR;
if (!strcmp("@encode", tkidentifier->name))
return TK_AT_ENCODE;
if (!strcmp("@defs", tkidentifier->name))
return TK_AT_DEFS;
}
if (in_assembler)
return TK_IDENTIFIER;
pos = start_pos;
}
return '@';
}
static short tperc(short) {
char t2;
at_linestart = 0;
t2 = prepcurchar();
if (t2 == '=') {
pos = nextcharpos;
return TK_MOD_ASSIGN;
}
if (t2 == '>' && copts.cplusplus && !preprocessing_only) {
pos = nextcharpos;
return '}';
}
return '%';
}
static short texcl(void) {
at_linestart = 0;
if (prepcurchar() == '=') {
pos = nextcharpos;
return TK_LOGICAL_NE;
}
return '!';
}
static short tplus(void) {
short t2;
at_linestart = 0;
t2 = prepcurchar();
if (t2 == '=') {
pos = nextcharpos;
return TK_ADD_ASSIGN;
}
if (t2 == '+') {
pos = nextcharpos;
return TK_INCREMENT;
}
return '+';
}
static short tminu(void) {
short t2;
at_linestart = 0;
t2 = prepcurchar();
if (t2 == '=') {
pos = nextcharpos;
return TK_SUB_ASSIGN;
}
if (t2 == '-') {
pos = nextcharpos;
return TK_DECREMENT;
}
if (t2 == '>') {
pos = nextcharpos;
if (copts.cplusplus && prepcurchar() == '*') {
pos = nextcharpos;
return TK_ARROW_STAR;
}
return TK_ARROW;
}
return '-';
}
static short torrr(void) {
short t2;
at_linestart = 0;
t2 = prepcurchar();
if (t2 == '=') {
pos = nextcharpos;
return TK_OR_ASSIGN;
}
if (t2 == '|') {
pos = nextcharpos;
return TK_LOGICAL_OR;
}
return '|';
}
static short tampe(void) {
short t2;
at_linestart = 0;
t2 = prepcurchar();
if (t2 == '=') {
pos = nextcharpos;
return TK_AND_ASSIGN;
}
if (t2 == '&') {
pos = nextcharpos;
return TK_LOGICAL_AND;
}
return '&';
}
static short tpowe(void) {
at_linestart = 0;
if (prepcurchar() == '=') {
pos = nextcharpos;
return TK_XOR_ASSIGN;
}
return '^';
}
static short tdivi(void) {
at_linestart = 0;
if (prepcurchar() == '=') {
pos = nextcharpos;
return TK_DIV_ASSIGN;
}
return '/';
}
// forward decl
static short tnumb(short t);
static short tzero(short t) {
char *p;
short ch;
Boolean failed;
Boolean floatFailed;
if (InlineAsm_gccmode && InlineAsm_labelref)
return tnumb(t);
at_linestart = 0;
p = pos - 1;
ch = prepnextchar();
if (ch == 'x' || ch == 'X') {
p = CInt64_ScanHexString(&tkintconst, pos, &failed);
if (pos == p)
CError_Error(CErrorStr105);
pos = p;
} else if (!copts.ANSIstrict && (ch == 'b' || ch == 'B')) {
p = CInt64_ScanBinString(&tkintconst, pos, &failed);
if (pos == p)
CError_Error(CErrorStr105);
pos = p;
} else {
while (ch >= '0' && ch <= '9')
ch = prepnextchar();
switch (ch) {
case '.':
case 'E':
case 'e':
pos = CMach_FloatScan(p, &tkfloatconst, &floatFailed);
if (floatFailed)
CPrep_Error(CErrorStr154);
tksize = floatsuffix(prepcurchar());
return TK_FLOATCONST;
}
pos = CInt64_ScanOctString(&tkintconst, p, &failed);
}
if (failed) {
CPrep_Error(CErrorStr154);
tkintconst = cint64_zero;
}
tksize = intsuffix(prepcurchar(), 1);
return TK_INTCONST;
}
static short tpoin(void) {
char *p;
short ch;
Boolean failed;
at_linestart = 0;
p = pos - 1;
ch = prepnextchar();
if (ch >= '0' && ch <= '9') {
pos = CMach_FloatScan(p, &tkfloatconst, &failed);
if (failed)
CPrep_Error(CErrorStr154);
tksize = floatsuffix(prepcurchar());
return TK_FLOATCONST;
}
if (copts.cplusplus && ch == '*')
return TK_DOT_STAR;
if (ch == '.' && prepnextchar() == '.')
return TK_ELLIPSIS;
pos = p + 1;
return '.';
}
static short tnumb(short t) {
char *p;
short ch;
Boolean failed;
Boolean floatFailed;
at_linestart = 0;
p = pos - 1;
pos = CInt64_ScanDecString(&tkintconst, p, &failed);
ch = prepcurchar();
if (ch == '.' || ch == 'e' || ch == 'E') {
pos = CMach_FloatScan(p, &tkfloatconst, &floatFailed);
if (floatFailed)
CPrep_Error(CErrorStr154);
tksize = floatsuffix(prepcurchar());
return TK_FLOATCONST;
}
if (failed) {
CPrep_Error(CErrorStr154);
tkintconst = cint64_zero;
}
tksize = intsuffix(prepcurchar(), 0);
return TK_INTCONST;
}
static short tiden(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
else
return TK_IDENTIFIER;
}
static short tchrL(void) {
short ch;
at_linestart = 0;
if ((ch = prepcurchar()) == '\'') {
widestring = 1;
pos = nextcharpos;
ch = tapos(ch);
widestring = 0;
tksize = (copts.wchar_type && copts.cplusplus) ? IT_WCHAR_T : IT_INT;
return ch;
}
if (ch == '"') {
widestring = 1;
pos = nextcharpos;
ch = tquot(ch);
widestring = 0;
return ch;
}
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
return TK_IDENTIFIER;
}
static short tchra(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("auto", tkidentifier->name))
return TK_AUTO;
if ((copts.cplusplus || !copts.onlystdkeywords) && !strcmp("asm", tkidentifier->name))
return TK_ASM;
if (copts.cplusplus && !in_assembler && !preprocessing_only) {
if (!strcmp("and", tkidentifier->name))
return TK_LOGICAL_AND;
if (!strcmp("and_eq", tkidentifier->name))
return TK_AND_ASSIGN;
}
return TK_IDENTIFIER;
}
static short tchrb(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("break", tkidentifier->name))
return TK_BREAK;
if (copts.cplusplus) {
if (copts.booltruefalse && !strcmp("bool", tkidentifier->name))
return TK_BOOL;
if (!in_assembler && !preprocessing_only) {
if (!strcmp("bitand", tkidentifier->name))
return '&';
if (!strcmp("bitor", tkidentifier->name))
return '|';
}
}
if (copts.objective_c) {
if (!strcmp("bycopy", tkidentifier->name))
return TK_BYCOPY;
if (!strcmp("byref", tkidentifier->name))
return TK_BYREF;
}
return TK_IDENTIFIER;
}
static short tchrc(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("case", tkidentifier->name))
return TK_CASE;
if (!strcmp("char", tkidentifier->name))
return TK_CHAR;
if (!strcmp("const", tkidentifier->name))
return TK_CONST;
if (!strcmp("continue", tkidentifier->name))
return TK_CONTINUE;
if (copts.cplusplus) {
if (!strcmp("const_cast", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_CONST_CAST;
}
if (!strcmp("catch", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_CATCH;
}
if (!strcmp("class", tkidentifier->name))
return TK_CLASS;
if (!in_assembler && !preprocessing_only) {
if (!strcmp("compl", tkidentifier->name))
return '~';
}
}
return TK_IDENTIFIER;
}
static short tchrd(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("default", tkidentifier->name))
return TK_DEFAULT;
if (!strcmp("do", tkidentifier->name))
return TK_DO;
if (!strcmp("double", tkidentifier->name))
return TK_DOUBLE;
if (copts.cplusplus) {
if (!strcmp("delete", tkidentifier->name))
return TK_DELETE;
if (!strcmp("dynamic_cast", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_DYNAMIC_CAST;
}
}
return TK_IDENTIFIER;
}
static short tchre(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("else", tkidentifier->name))
return TK_ELSE;
if (!strcmp("enum", tkidentifier->name))
return TK_ENUM;
if (!strcmp("extern", tkidentifier->name))
return TK_EXTERN;
if (copts.cplusplus) {
if (!strcmp("explicit", tkidentifier->name))
return TK_EXPLICIT;
if (!strcmp("export", tkidentifier->name) && !copts.ecplusplus)
return TK_EXPORT;
}
return TK_IDENTIFIER;
}
static short tchrf(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("float", tkidentifier->name))
return TK_FLOAT;
if (!strcmp("for", tkidentifier->name))
return TK_FOR;
if (copts.cplusplus) {
if (!strcmp("friend", tkidentifier->name))
return TK_FRIEND;
if (copts.booltruefalse && !strcmp("false", tkidentifier->name))
return TK_FALSE;
}
return TK_IDENTIFIER;
}
static short tchrg(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("goto", tkidentifier->name))
return TK_GOTO;
return TK_IDENTIFIER;
}
static short tchri(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("if", tkidentifier->name))
return TK_IF;
if (!strcmp("int", tkidentifier->name))
return TK_INT;
if (copts.cplusplus || copts.c9x) {
if (!strcmp("inline", tkidentifier->name))
return TK_INLINE;
} else if (!copts.onlystdkeywords) {
if (!strcmp("inline", tkidentifier->name))
return TK_INLINE;
}
if (copts.objective_c) {
if (!strcmp("in", tkidentifier->name))
return TK_IN;
if (!strcmp("inout", tkidentifier->name))
return TK_INOUT;
}
return TK_IDENTIFIER;
}
static short tchrl(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("long", tkidentifier->name))
return TK_LONG;
return TK_IDENTIFIER;
}
static short tchrm(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (copts.cplusplus && !strcmp("mutable", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_MUTABLE;
}
return TK_IDENTIFIER;
}
static short tchrn(short t) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (copts.cplusplus && t == 'n') {
if (!strcmp("new", tkidentifier->name))
return TK_NEW;
if (!strcmp("namespace", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_NAMESPACE;
}
if (!in_assembler && !preprocessing_only) {
if (!strcmp("not", tkidentifier->name))
return '!';
if (!strcmp("not_eq", tkidentifier->name))
return TK_LOGICAL_NE;
}
}
return TK_IDENTIFIER;
}
static short tchro(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (copts.cplusplus) {
if (!strcmp("operator", tkidentifier->name))
return TK_OPERATOR;
if (!in_assembler && !preprocessing_only) {
if (!strcmp("or", tkidentifier->name))
return TK_LOGICAL_OR;
if (!strcmp("or_eq", tkidentifier->name))
return TK_OR_ASSIGN;
}
}
if (copts.objective_c) {
if (!strcmp("out", tkidentifier->name))
return TK_OUT;
if (!strcmp("oneway", tkidentifier->name))
return TK_ONEWAY;
}
return TK_IDENTIFIER;
}
static short tchrp(short t) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!copts.onlystdkeywords && !strcmp("pascal", tkidentifier->name))
return TK_PASCAL;
if (copts.cplusplus && t == 'p') {
if (!strcmp("private", tkidentifier->name))
return TK_PRIVATE;
if (!strcmp("protected", tkidentifier->name))
return TK_PROTECTED;
if (!strcmp("public", tkidentifier->name))
return TK_PUBLIC;
}
return TK_IDENTIFIER;
}
static short tchrr(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("register", tkidentifier->name))
return TK_REGISTER;
if (!strcmp("return", tkidentifier->name))
return TK_RETURN;
if (copts.cplusplus && !strcmp("reinterpret_cast", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_REINTERPRET_CAST;
}
if (copts.c9x && !strcmp("restrict", tkidentifier->name))
return TK_RESTRICT;
return TK_IDENTIFIER;
}
static short tchrs(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("short", tkidentifier->name))
return TK_SHORT;
if (!strcmp("signed", tkidentifier->name))
return TK_SIGNED;
if (!strcmp("sizeof", tkidentifier->name))
return TK_SIZEOF;
if (!strcmp("static", tkidentifier->name))
return TK_STATIC;
if (!strcmp("struct", tkidentifier->name))
return TK_STRUCT;
if (!strcmp("switch", tkidentifier->name))
return TK_SWITCH;
if (copts.cplusplus && !strcmp("static_cast", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_STATIC_CAST;
}
return TK_IDENTIFIER;
}
static short tchrt(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("typedef", tkidentifier->name))
return TK_TYPEDEF;
if (copts.gcc_extensions && !strcmp("typeof", tkidentifier->name))
return TK_UU_TYPEOF_UU;
if (copts.cplusplus) {
if (!strcmp("this", tkidentifier->name))
return TK_THIS;
if (copts.booltruefalse && !strcmp("true", tkidentifier->name))
return TK_TRUE;
if (!strcmp("template", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_TEMPLATE;
}
if (!strcmp("try", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_TRY;
}
if (!strcmp("throw", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_THROW;
}
if (!strcmp("typeid", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_TYPEID;
}
if (!strcmp("typename", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_TYPENAME;
}
}
return TK_IDENTIFIER;
}
static short tchru(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("union", tkidentifier->name))
return TK_UNION;
if (!strcmp("unsigned", tkidentifier->name))
return TK_UNSIGNED;
if (copts.cplusplus && !strcmp("using", tkidentifier->name)) {
if (copts.ecplusplus)
CPrep_Warning(CErrorStr339);
return TK_USING;
}
return TK_IDENTIFIER;
}
static short tchrv(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("void", tkidentifier->name))
return TK_VOID;
if (!strcmp("volatile", tkidentifier->name))
return TK_VOLATILE;
if (copts.cplusplus && !strcmp("virtual", tkidentifier->name))
return TK_VIRTUAL;
return TK_IDENTIFIER;
}
static short tchrw(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("while", tkidentifier->name))
return TK_WHILE;
if (copts.cplusplus && copts.wchar_type && !strcmp("wchar_t", tkidentifier->name))
return TK_WCHAR_T;
return TK_IDENTIFIER;
}
static short tchrx(short t) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (copts.cplusplus && t == 'x' && !in_assembler && !preprocessing_only) {
if (!strcmp("xor", tkidentifier->name))
return '^';
if (!strcmp("xor_eq", tkidentifier->name))
return TK_XOR_ASSIGN;
}
return TK_IDENTIFIER;
}
static short tchr_(void) {
at_linestart = 0;
pos = ReadIdentifier(pos - 1);
if (macrocheck && macrotest())
return 0;
if (!strcmp("__stdcall", tkidentifier->name))
return TK_UU_STDCALL;
if (!strcmp("__cdecl", tkidentifier->name))
return TK_UU_CDECL;
if (!strcmp("__fastcall", tkidentifier->name))
return TK_UU_FASTCALL;
if (!strcmp("__declspec", tkidentifier->name))
return TK_UU_DECLSPEC;
if (!strcmp("__asm", tkidentifier->name))
return TK_ASM;
if (!strcmp("__asm__", tkidentifier->name))
return TK_ASM;
if (!strcmp("__inline", tkidentifier->name))
return TK_INLINE;
if (!strcmp("__inline__", tkidentifier->name))
return TK_INLINE;
if (!strcmp("__restrict", tkidentifier->name))
return TK_RESTRICT;
if (!strcmp("__restrict__", tkidentifier->name))
return TK_RESTRICT;
if (!strcmp("__attribute__", tkidentifier->name))
return TK_UU_ATTRIBUTE_UU;
if (!strcmp("__far", tkidentifier->name))
return TK_UU_FAR;
if (!strcmp("__alignof__", tkidentifier->name))
return TK_UU_ALIGNOF_UU;
if (!strcmp("__typeof__", tkidentifier->name))
return TK_UU_TYPEOF_UU;
if (copts.c9x) {
if (!strcmp("_Bool", tkidentifier->name))
return TK_BOOL;
if (!strcmp("_Complex", tkidentifier->name))
return TK_U_COMPLEX;
if (!strcmp("_Imaginary", tkidentifier->name))
return TK_U_IMAGINARY;
}
if (copts.altivec_model && !strcmp("__vector", tkidentifier->name))
return TK_UU_VECTOR;
return TK_IDENTIFIER;
}
static short token(short t) {
at_linestart = 0;
return t;
}
static short tdoll(short t) {
at_linestart = 0;
return t;
}
static short tisid(void) {
if (!tokenstacklevel)
CError_Error(CErrorStr105);
return 0;
}
static short tnull(short t) {
if (tokenstacklevel > 0 || pos >= prep_file_end) {
at_linestart = 0;
return t;
} else {
pos[-1] = -64;
return TK_ILLEGAL;
}
}
static short t0x1a(void) {
if (*pos == 0)
return 0;
else
return TK_ILLEGAL;
}
typedef short (*TokenizePtr)(short);
#define F(func) ((TokenizePtr) (&func))
static TokenizePtr cprep_tokenize[256] = {
F(tnull), F(tille), F(tille), F(tille), F(tisid), F(tisid), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tcret), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(t0x1a), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(texcl), F(tquot), F(thash), F(tdoll), F(tperc), F(tampe), F(tapos),
F(token), F(token), F(tmult), F(tplus), F(token), F(tminu), F(tpoin), F(tdivi),
F(tzero), F(tnumb), F(tnumb), F(tnumb), F(tnumb), F(tnumb), F(tnumb), F(tnumb),
F(tnumb), F(tnumb), F(tcolo), F(token), F(tless), F(tequa), F(tgrea), F(token),
F(tatsg), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden),
F(tiden), F(tiden), F(tiden), F(tiden), F(tchrL), F(tiden), F(tchrn), F(tiden),
F(tchrp), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden),
F(tchrx), F(tiden), F(tiden), F(token), F(token), F(token), F(tpowe), F(tchr_),
F(token), F(tchra), F(tchrb), F(tchrc), F(tchrd), F(tchre), F(tchrf), F(tchrg),
F(tiden), F(tchri), F(tiden), F(tiden), F(tchrl), F(tchrm), F(tchrn), F(tchro),
F(tchrp), F(tiden), F(tchrr), F(tchrs), F(tchrt), F(tchru), F(tchrv), F(tchrw),
F(tchrx), F(tiden), F(tiden), F(token), F(torrr), F(token), F(token), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille),
F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille)
};
short lookahead(void) {
SInt32 state;
short t;
CPrep_TokenStreamGetState(&state);
t = lex();
CPrep_TokenStreamSetState(&state);
return t;
}
short lookahead_noeol(void) {
SInt32 state;
short t;
CPrep_TokenStreamGetState(&state);
do {
t = lex();
} while (t == TK_EOL);
CPrep_TokenStreamSetState(&state);
return t;
}
typedef struct StringChunk {
struct StringChunk *next;
char *data;
SInt32 offset;
SInt32 size;
} StringChunk;
static void CPrep_StringConCat(Boolean flag) {
StringPtr buffer;
StringChunk *chunks;
StringChunk *chunk;
char *saveString;
SInt32 saveSize;
SInt32 offset;
Boolean savePascalString;
TStreamElement *elem;
short ch;
saveString = tkstring;
saveSize = tksize;
savePascalString = ispascalstring;
cprep_strconcat = 1;
chunks = NULL;
offset = tksize;
while (1) {
ch = lookahead_noeol();
if (ch != TK_STRING && ch != TK_STRING_WIDE) {
ispascalstring = savePascalString;
if (chunks) {
tksize = offset;
buffer = galloc(offset);
tkstring = (char *) buffer;
memcpy(buffer, saveString, saveSize);
for (chunk = chunks; chunk; chunk = chunk->next)
memcpy(buffer + chunk->offset, chunk->data, chunk->size);
if (savePascalString) {
if (offset > 256) {
CError_Error(CErrorStr106);
offset = 256;
}
buffer[0] = offset - 1;
} else if (flag) {
CMach_InitIntMem(TYPE(&stwchar), cint64_zero, buffer + offset - stwchar.size);
} else {
CMach_InitIntMem(TYPE(&stchar), cint64_zero, buffer + offset - stchar.size);
}
elem = ts_current - 1;
elem->data.tkstring.data = (char *) buffer;
elem->data.tkstring.size = offset;
elem->subtype = ispascalstring;
cprep_strconcat = 0;
} else {
tkstring = saveString;
tksize = saveSize;
cprep_strconcat = 0;
}
break;
}
do {
ch = lex();
elem = --ts_current;
memmove(elem, elem + 1, sizeof(TStreamElement) * ts_preread_elements);
} while (ch == TK_EOL);
chunk = lalloc(sizeof(StringChunk));
chunk->next = chunks;
chunk->data = tkstring;
chunk->size = tksize - 1;
chunk->offset = offset - 1;
chunks = chunk;
if (ispascalstring)
chunk->data++;
if (savePascalString)
chunk->offset++;
if (ch == TK_STRING_WIDE)
chunk->size = chunk->size + 1 - stwchar.size;
if (flag)
chunk->offset = chunk->offset + 1 - stwchar.size;
offset += chunk->size;
}
}
short lex(void) {
short t;
while (1) {
if (ts_preread_elements <= 0)
break;
t = ts_current->tokentype;
if (t < 0) {
switch (t) {
case TK_INTCONST:
tkintconst = ts_current->data.tkintconst;
tksize = ts_current->subtype;
break;
case TK_FLOATCONST:
tkfloatconst = ts_current->data.tkfloatconst;
tksize = ts_current->subtype;
break;
case TK_IDENTIFIER:
tkidentifier = ts_current->data.tkidentifier;
break;
case TK_STRING:
case TK_STRING_WIDE:
tkstring = ts_current->data.tkstring.data;
tksize = ts_current->data.tkstring.size;
ispascalstring = ts_current->subtype;
break;
case TK_EOL:
nlflag = 1;
if (!cprep_eoltokens) {
ts_current++;
ts_preread_elements--;
continue;
}
break;
default:
CError_FATAL(3007);
}
}
ts_current++;
ts_preread_elements--;
return t;
}
while (1) {
t = prepskipnextchar();
ts_current->tokenfile = prep_file;
if (tokenstacklevel > 0) {
ts_current->tokenoffset = tokenstack[0].pos - prep_file_start;
macropos = pos;
} else {
ts_current->tokenoffset = pos - prep_file_start;
}
ts_current->tokenline = linenumber;
pos = nextcharpos;
t = cprep_tokenize[t](t);
if (t != 0) {
if (ts_current >= ts_last)
CPrep_TSBufferGrow(1024);
ts_current->tokentype = t;
if ((t = ts_current->tokentype) < 0) {
switch (t) {
case TK_INTCONST:
ts_current->data.tkintconst = tkintconst;
ts_current->subtype = tksize;
break;
case TK_FLOATCONST:
ts_current->data.tkfloatconst = tkfloatconst;
ts_current->subtype = tksize;
break;
case TK_IDENTIFIER:
ts_current->data.tkidentifier = tkidentifier;
break;
case TK_STRING:
case TK_STRING_WIDE:
ts_current->data.tkstring.data = tkstring;
ts_current->data.tkstring.size = tksize;
ts_current->subtype = ispascalstring;
if (!cprep_strconcat) {
ts_current++;
CPrep_StringConCat(t == TK_STRING_WIDE);
return t;
}
break;
case TK_ILLEGAL:
ts_current++;
CError_Error(CErrorStr105);
ts_current--;
break;
}
}
ts_current++;
return t;
}
if (*pos == 0) {
if (tokenstacklevel > 0) {
poptokenseq();
} else if (tokenstacklevel > 0 || pos >= prep_file_end) {
if (filesp > 0)
popfile();
else
return 0;
} else {
ts_current++;
CError_ErrorTerm(CErrorStr105);
}
}
}
}
short plex(void) {
short t;
while (1) {
t = prepskipnextchar();
pos = nextcharpos;
if ((t = cprep_tokenize[t](t)))
return t;
if (!*pos) {
if (tokenstacklevel > 0) {
poptokenseq();
} else if (filesp > 0) {
popfile();
} else {
break;
}
}
}
return 0;
}
short lexidentifier(void) {
short t;
char *save_pos;
t = prepskipnextchar();
pos = nextcharpos;
at_linestart = 0;
if ((t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z') || (t == '_')) {
pos = ReadIdentifier(pos - 1);
return TK_IDENTIFIER;
} else if (t == '.') {
save_pos = pos;
if (prepnextchar() == '.' && prepnextchar() == '.')
return TK_ELLIPSIS;
else
pos = save_pos;
}
return t;
}