From 9a46dd0e2e80790d9848c0bbd718932a27c23269 Mon Sep 17 00:00:00 2001 From: Ash Wolf Date: Mon, 7 Nov 2022 03:06:21 +0000 Subject: honk --- compiler_and_linker/FrontEnd/C/CPrep.c | 3144 ++++++++++++++++++++++++++++++-- 1 file changed, 2965 insertions(+), 179 deletions(-) (limited to 'compiler_and_linker/FrontEnd/C/CPrep.c') diff --git a/compiler_and_linker/FrontEnd/C/CPrep.c b/compiler_and_linker/FrontEnd/C/CPrep.c index e69bcfb..4e3ffea 100644 --- a/compiler_and_linker/FrontEnd/C/CPrep.c +++ b/compiler_and_linker/FrontEnd/C/CPrep.c @@ -1,7 +1,47 @@ #include "compiler.h" #include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" #include "compiler/tokens.h" #include "cos.h" +#include "compiler/CMachine.h" +#include "compiler/CParser.h" +#include "compiler/CPrep.h" +#include "compiler/CPrepTokenizer.h" +#include "compiler/CScope.h" +#include "compiler/CodeGen.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct PrepValue { + CInt64 val; + char is_unsigned; +} PrepValue; + +typedef struct IfStack { + CPrepFileInfo *file; + SInt32 pos; + short state; +} IfStack; + +enum { + IfState_0 = 0, + IfState_1 = 1, + IfState_2 = 2, + IfState_3 = 3, + IfState_4 = 4, + IfState_5 = 5 +}; + +// forward declarations +static PrepValue CPrep_ParseCond(); +static PrepValue CPrep_ParseBinary(PrepValue *rhs, short op); +static char *XpandMacro(Macro *macro); +static void prepmacro(Macro *macro); +static void prepifskip(); +static void gotonexttoken(); extern SInt16 *CLT_filesp; extern CPrepFileInfo **CLT_filestack; @@ -9,11 +49,13 @@ extern CPrepFileInfo **CLT_filestack; //#define OPT_OFFSET(optname) ((short) (((char *) (&copts.optname)) - ((char *) &copts))) #define OPT_OFFSET(optname) ((short) ( &((COpts *)0)->optname )) enum { + OPT_OFFSET_MASK = 0x1FFF, OPT_FLAG_2000 = 0x2000, - OPT_FLAG_4000 = 0x4000 + OPT_FLAG_4000 = 0x4000, + OPT_FLAG_8000 = 0x8000 }; -struct { +struct CompilerOption { char *name; short bits; } compileroptions[138] = { @@ -172,15 +214,15 @@ Macro **macrohashtable; Boolean cprep_nomem_exit; Boolean cprep_nostring; Boolean cprep_eoltokens; -static void *ifstack[100]; // TODO type+size +static IfStack ifstack[64]; static short iflevel; TokenStack tokenstack[128]; short tokenstacklevel; -SInt32 cprep_cursymfile; // might be a ptr? +CPrepFileInfo *cprep_cursymfile; char *pos; char *macropos; char *nextcharpos; -char CPrep_SkipNewCommentChar; +unsigned char CPrep_SkipNewCommentChar; Boolean preprocessing_only; Handle stringmem; SInt32 maxstringsize; @@ -197,8 +239,12 @@ CPrepFileInfo *prep_file; short filesp; SInt32 linenumber; static CPrepFileInfo *filestack[32]; -static void *cprep_files; // TODO type -static SInt32 linetick; +typedef struct CPrepFileInfoList { + struct CPrepFileInfoList *next; + CPrepFileInfo *fileinfo; +} CPrepFileInfoList; +static CPrepFileInfoList *cprep_files; +static UInt32 linetick; static Boolean waslockedmacro; static Boolean include_once; static time_t now_time; @@ -206,7 +252,11 @@ static SInt32 lineoffset; static Boolean was_prep_error; static Boolean cprep_hasprepline; static Boolean cprep_incondexpr; -static void *cprep_packstack[100]; // TODO type+size +struct PackStack { + HashNameNode *identifier; + short align_mode; +}; +static struct PackStack cprep_packstack[128]; static short cprep_packstackp; static Macro lineM; static Macro fileM; @@ -227,9 +277,15 @@ struct COptsPush { struct COptsPush *next; COpts opts; }; +struct COptPush { + struct COptPush *next; + SInt32 id; + Boolean x8; + UInt8 value; +}; static struct COptsPush *coptpushs; -static void *coptpush; // TODO type -static void *coptssave; // TODO type +static struct COptPush *coptpush; +static COpts *coptssave; static Boolean dofreeaheap; static GList mlist; static Handle ts_buffer; @@ -240,8 +296,10 @@ static SInt32 ts_elements; SInt32 ts_preread_elements; static SInt32 gDirectiveStart; static SInt32 high_mem_mark; -// static TStreamElement dummyelement; // in CPrep_CurStreamElement static short exprtk; +#ifdef __MWERKS__ +#pragma options align=reset +#endif static void cannotopenerror(StringPtr filename, Boolean err) { static char fname[64]; @@ -433,11 +491,15 @@ static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { OSType file_type; SInt32 file_size; SInt32 file_dirid; - CWMemHandle cache_hnd; void *cache; + CWMemHandle cache_hnd; SInt16 refnum; SInt16 file_vrefnum; char *extpos; + unsigned char *src; + char *append; + char *dst; + int len; if (filesp >= 31) { was_prep_error = 1; @@ -446,10 +508,10 @@ static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { } memclrw(&prepinfo, sizeof(CPrepFileInfo)); - prepinfo.unkfield126 = !flag1; // may be wrong field! + prepinfo.unkfield126 = !flag1; if (filename) { memclrw(&fileinfo, sizeof(CWFileInfo)); - fileinfo.fullsearch = flag2; + fileinfo.fullsearch = flag1; fileinfo.dependencyType = cwNormalDependency; fileinfo.isdependentoffile = -1; memcpy(myfilename, &filename[1], filename[0]); @@ -458,7 +520,26 @@ static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { if (CWFindAndLoadFile(cparamblkptr->context, myfilename, &fileinfo) != cwNoErr) { if (filename[0] + strlen(".framework/Headers") < 255) { if ((extpos = strchr(myfilename, '/'))) { - // Do Me! 37D8C + src = filename + 1; + append = ".framework/Headers"; + dst = myfilename; + len = filename[0]; + while (dst < extpos) { + *(dst++) = *(src++); + len--; + } + while (*append) { + *(dst++) = *(append++); + } + while (len) { + *(dst++) = *(src++); + len--; + } + *dst = 0; + if (CWFindAndLoadFile(cparamblkptr->context, myfilename, &fileinfo) != cwNoErr) { + cannotopenerror(filename, 0); + return 0; + } } else { cannotopenerror(filename, 0); return 0; @@ -598,19 +679,519 @@ void CPrep_TokenStreamSetCurState(SInt32 *state) { tk = lex(); } -static void CPrep_StreamSkipToBrace() {} -static void CPrep_StreamSkipBlock() {} -void CPrep_StreamGetBlock() {} -void CPrep_StreamGetSemicolon() {} -void CPrep_StreamGetTemplate() {} -void CPrep_StreamInsert() {} -void CPrep_StreamRemove() {} -void CPrep_RemoveTokens() {} -void CPrep_TokenStreamFlush() {} -static void CPrep_TokenSize() {} -void CPrep_CurStreamElement() {} +static SInt32 CPrep_StreamSkipToBrace(CPrepStreamFuncPtr func, SInt32 val) { + TStreamElement ts; + SInt32 v = val + 1; + + do { + switch (lex()) { + case '{': + return v; + case 0: + case ';': + return 0; + case TK_IDENTIFIER: + if (func) { + ts = ts_current[-1]; + func(&ts); + ts_current[-1] = ts; + tk = ts.tokentype; + } + break; + } + v++; + } while (1); +} + +static SInt32 CPrep_StreamSkipBlock(CPrepStreamFuncPtr func, SInt32 val) { + TStreamElement ts; + SInt32 brace_level; + char save_asmpoundcomment; + char save_cplusplus; + char starttoken; + char endtoken; + SInt32 level; + SInt32 v; + SInt16 t; + + save_asmpoundcomment = copts.asmpoundcomment; + save_cplusplus = copts.cplusplus; + level = 0; + brace_level = 1; + v = val + 1; + +loop: + v++; + switch ((t = lex())) { + case 0: + return 0; + case TK_ASM: + cprep_nostring = 1; + v++; + t = lex(); + if ((t == TK_VOLATILE) || ((t == TK_IDENTIFIER) && !strcmp(tkidentifier->name, "__volatile__"))) { + v++; + t = lex(); + } + if (!t) + return 0; + if (t == TK_NEG7) { + t = lex(); + v++; + } + if (t == '(') { + starttoken = '('; + endtoken = ')'; + } else if (t == '{') { + starttoken = '{'; + endtoken = '}'; + brace_level++; + } + level = 1; + in_assembler = 1; + v++; + t = lex(); + if (t == '"') { + copts.cplusplus = 0; + copts.asmpoundcomment = 1; + goto loop; + } + if (t) + goto loop; + return 0; + + case '(': + if (starttoken == t) + level++; + goto loop; + case ')': + if (level && endtoken == t && !--level) { + cprep_nostring = 0; + in_assembler = 0; + copts.cplusplus = save_cplusplus; + copts.asmpoundcomment = save_asmpoundcomment; + } + goto loop; + + case TK_IDENTIFIER: + if (func) { + ts = ts_current[-1]; + func(&ts); + ts_current[-1] = ts; + tk = ts.tokentype; + } + goto loop; + + case '{': + brace_level++; + if (starttoken == t) + level++; + goto loop; + case '}': + if (level && endtoken == t && !--level) { + cprep_nostring = 0; + in_assembler = 0; + copts.cplusplus = save_cplusplus; + copts.asmpoundcomment = save_asmpoundcomment; + } + if (--brace_level > 0) + goto loop; + break; + default: + goto loop; + } + + return v; +} + +void CPrep_StreamGetBlock(TStream *stream, CPrepStreamFuncPtr func, int arg) { + Boolean save_eoltokens; + SInt32 start_offset; + Boolean tryflag; + SInt32 count; + + start_offset = ts_current - ts_first - 1; + tryflag = 0; + stream->tokens = 0; + stream->firsttoken = NULL; + count = 0; + save_eoltokens = cprep_eoltokens; + cprep_eoltokens = 1; + + switch (tk) { + case TK_TRY: + tryflag = 1; + case ':': + if (!(count = CPrep_StreamSkipToBrace(func, 0))) { + CError_Error(121); + cprep_eoltokens = save_eoltokens; + return; + } + case '{': + break; + default: + CError_Error(121); + cprep_eoltokens = save_eoltokens; + return; + } + + if (!(count = CPrep_StreamSkipBlock(func, count))) { + CError_Error(121); + cprep_eoltokens = save_eoltokens; + return; + } + + if (tryflag) { + tryloop: + switch (lex()) { + case TK_NEG7: + count++; + goto tryloop; + case TK_CATCH: + if (!(count = CPrep_StreamSkipToBrace(func, count)) || !(count = CPrep_StreamSkipBlock(func, count))) { + CError_Error(242); + cprep_eoltokens = save_eoltokens; + return; + } + if (lookahead_noeol() == TK_CATCH) + goto tryloop; + break; + default: + CError_Error(242); + cprep_eoltokens = save_eoltokens; + return; + } + } + + cprep_eoltokens = save_eoltokens; + stream->tokens = count; + stream->firsttoken = galloc(count * sizeof(TStreamElement)); + memcpy(stream->firsttoken, ts_first + start_offset, count * sizeof(TStreamElement)); +} + +void CPrep_StreamGetSemicolon(TStream *stream, CPrepStreamFuncPtr func) { + SInt32 count; + SInt32 start_offset; + Boolean save_eoltokens; + + start_offset = ts_current - ts_first - 1; + save_eoltokens = cprep_eoltokens; + cprep_eoltokens = 1; + stream->tokens = 0; + stream->firsttoken = NULL; + count = 1; + + while (tk && tk != ';') { + tk = lex(); + if ((tk == TK_IDENTIFIER) && func) { + func(&ts_current[-1]); + tk = ts_current[-1].tokentype; + } + count++; + } + + stream->tokens = count; + stream->firsttoken = galloc(count * sizeof(TStreamElement)); + memcpy(stream->firsttoken, ts_first + start_offset, count * sizeof(TStreamElement)); + cprep_eoltokens = save_eoltokens; +} + +void CPrep_StreamGetTemplate(TStream *stream, CPrepStreamFuncPtr func) { + SInt32 count; + SInt32 start_offset; + Boolean save_eoltokens; + SInt16 level; + + start_offset = ts_current - ts_first - 1; + save_eoltokens = cprep_eoltokens; + cprep_eoltokens = 1; + stream->tokens = 0; + stream->firsttoken = NULL; + count = 0; + +loop: + switch (tk) { + case 0: + CError_ErrorTerm(102); + case '}': + CError_Error(229); + return; + case ';': + count++; + break; + case TK_IDENTIFIER: + if (func) { + func(&ts_current[-1]); + tk = ts_current[-1].tokentype; + } + default: + count++; + tk = lex(); + goto loop; + case '{': + level = 0; + do { + count++; + switch (tk) { + case TK_IDENTIFIER: + if (func) { + func(&ts_current[-1]); + tk = ts_current[-1].tokentype; + } + break; + case '{': + level++; + break; + case '}': + level--; + break; + } + if (level <= 0) + break; + if (!(tk = lex())) + CError_ErrorTerm(102); + } while (1); + if (lookahead() == ';') { + tk = lex(); + count++; + } + } + + stream->tokens = count; + stream->firsttoken = galloc(count * sizeof(TStreamElement)); + memcpy(stream->firsttoken, ts_first + start_offset, count * sizeof(TStreamElement)); + cprep_eoltokens = save_eoltokens; +} + +void CPrep_StreamInsert(TStream *stream, SInt32 *state) { + if (ts_preread_elements + (ts_current - ts_first) + stream->tokens >= ts_elements) + CPrep_TSBufferGrow(stream->tokens); + if (ts_preread_elements) + memmove(ts_current + stream->tokens, ts_current, sizeof(TStreamElement) * ts_preread_elements); + memcpy(ts_current, stream->firsttoken, sizeof(TStreamElement) * stream->tokens); + ts_preread_elements += stream->tokens; + CPrep_TokenStreamGetState(state); +} + +void CPrep_StreamRemove(TStream *stream, SInt32 *state) { + TStreamElement *end; + SInt32 amount; + + end = ts_first + *state; + amount = ts_preread_elements + ((ts_current - ts_first) - *state - stream->tokens); + if (amount >= 0) { + if (amount) + memmove(end, end + stream->tokens, sizeof(TStreamElement) * amount); + ts_current = end; + ts_preread_elements = amount; + } +} + +void CPrep_RemoveTokens(SInt32 amount) { +#line 1296 + CError_ASSERT(ts_preread_elements >= amount); + + ts_preread_elements -= amount; + memmove(ts_current, ts_current + amount, sizeof(TStreamElement) * ts_preread_elements); +} + +void CPrep_TokenStreamFlush() { + if (!ts_preread_elements) + ts_current = ts_first; +} + +static int CPrep_TokenSize(char *str) { + int len; + int c; + + if ((str[0] >= 'a' && str[0] <= 'z') || (str[0] >= 'A' && str[0] <= 'Z') || (str[0] == '_')) { + len = 1; + str++; + do { + c = *(str++); + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_')) + len++; + else + break; + } while (1); + return len; + } + + switch (str[0]) { + case '*': + if (str[1] == '=') return 2; + break; + case '/': + if (str[1] == '=' || str[1] == '*' || str[1] == '/') return 2; + break; + case '%': + if (str[1] == '=') return 2; + break; + case '+': + if (str[1] == '=' || str[1] == '+') return 2; + break; + case '-': + if (str[1] == '>') return (str[2] == '*') ? 3 : 2; + if (str[1] == '=' || str[1] == '-') return 2; + break; + case '<': + if (str[1] == '=') return 2; + if (str[1] == '<') return (str[2] == '=') ? 3 : 2; + break; + case '>': + if (str[1] == '=') return 2; + if (str[1] == '>') return (str[2] == '=') ? 3 : 2; + break; + case '&': + if (str[1] == '=' || str[1] == '&') return 2; + break; + case '^': + if (str[1] == '=') return 2; + break; + case '|': + if (str[1] == '=' || str[1] == '|') return 2; + break; + case '=': + if (str[1] == '=') return 2; + break; + case '!': + if (str[1] == '=') return 2; + break; + case '.': + if (str[1] == '.' && str[2] == '.') return 3; + if (str[1] == '*') return 2; + break; + case ':': + if (str[1] == ':') return 2; + break; + } + + return 1; +} + +TStreamElement *CPrep_CurStreamElement() { + static TStreamElement dummyelement; + if (ts_first < ts_current) + return ts_current - 1; + else + return &dummyelement; +} + +void CPrep_GetTokenContext(TStreamElement *token, CPrepFileInfo **tokenfile, SInt32 *selectionoffset, short *tokensize, SInt32 *plinenumber, char *buf1, short *tokenoffset, short *tokenlength, char *buf2, short *lastarg) { + // misassigned registers + SInt32 p; + TStreamElement *prevtoken; + char *filedata; + char *tokendata; + Boolean hasowndata; + SInt32 line; + SInt32 i; + char *r4; + int r5; + int r6; + char *r7; + char *r5x; + SInt16 c; + + if (token && !token->tokenfile) + token = NULL; + + prevtoken = token; + if (!token && ts_first < ts_current) + prevtoken = ts_current - 1; + + if (prevtoken && !prevtoken->tokenfile) { +#line 1454 + CError_FATAL(); + } + + if (was_prep_error || !prevtoken) { + if (!prep_file) + CError_CannotOpen(); + *tokenfile = prep_file; + if (!tokenstacklevel) { + p = pos - prep_file_start; + if (was_prep_error && p > 0) + p--; + } else { + p = tokenstack[0].pos - prep_file_start; + } + *selectionoffset = p; + } else { + *tokenfile = prevtoken->tokenfile; + p = prevtoken->tokenoffset; + *selectionoffset = p; + } + + filedata = (*tokenfile)->textbuffer; + if (!filedata) { + filedata = getfiledata(&(*tokenfile)->textfile); + hasowndata = 1; + } else { + hasowndata = 0; + } + + if (!cprep_hasprepline) { + line = 1; + for (i = 0; i < p; i++) { + if (filedata[i] == '\r') + line++; + } + *plinenumber = line; + } else { + *plinenumber = linenumber; + } -void CPrep_GetTokenContext(TStreamElement *token, CPrepFileInfo **tokenfile, SInt32 *selectionoffset, short *tokensize, SInt32 *linenumber, char *buf1, short *tokenoffset, short *tokenlength, char *buf2, short *lastarg) { + tokendata = filedata + p; + *tokensize = CPrep_TokenSize(tokendata); + if (!token && tokenstacklevel == 1) { + r4 = macrostart; + r7 = macropos; + } else { + r4 = filedata; + r7 = tokendata; + } + *tokenoffset = 0; + r5 = 1; + while (r5 < 80 && (r7 - r5) >= r4 && r7[-r5] != '\r') + r5++; + r5--; + while ((c = r7[-r5]) && (c == ' ' || c == '\t' || c == 4)) + r5--; + r6 = 0; + while ((c = r7[-r5]) != '\r' && c && r6 < 126) { + if (!r5) + *tokenoffset = r6; + if (c != 4) { + buf1[r6++] = (c != '\t') ? c : ' '; + } + r5--; + } + if (!r5) { + buf1[r6] = ' '; + *tokenoffset = r6; + buf1[r6 + 1] = 0; + *tokenlength = 1; + } else { + buf1[r6] = 0; + *tokenlength = CPrep_TokenSize(buf1 + *tokenoffset); + } + + if (p > 16) { + r5x = tokendata - 16; + *lastarg = 16; + } else { + r5x = filedata; + *lastarg = p; + } + for (i = 0; i < 31 && *r5x; i++) { + buf2[i] = *(r5x++); + } + buf2[i] = 0; + + if (hasowndata) + CWReleaseFileText(cparamblkptr->context, filedata); + was_prep_error = 0; } void CPrep_Error(short code) { @@ -685,16 +1266,281 @@ void popfile() { } } -static void prepoffset() {} -static void prepoffset2() {} -void CPrep_SetSourceFile() {} -void CPrep_GetSourceFilePath() {} -void CPrep_NewFileOffsetInfo() {} -void CPrep_GetFileOffsetInfo() {} -void CPrep_GetFileOffsetInfo2() {} -void CPrep_ResetFileInfo() {} -void CPrep_GetPrepPos() {} -Boolean C_Compiler(CParams *param) {} +static SInt32 prepoffset() { + if (filesp > 0) + return filestack[0]->pos; + else if (tokenstacklevel) + return tokenstack[0].pos - filestack[filesp]->textbuffer; + else + return pos - filestack[0]->textbuffer; +} + +static SInt32 prepoffset2() { + return lineoffset; +} + +void CPrep_SetSourceFile(FileOffsetInfo *foi) { + CPrepFileInfoList *list; + + if (foi->file) { + if (foi->file == filestack[0]) { + if (cprep_cursymfile) { + if (cparamblkptr->isPrecompiling != 1) + ObjGen_SrcBreakName(NULL, 0, 0); + cprep_cursymfile = NULL; + } + } else { + if (cprep_cursymfile != foi->file) { + for (list = cprep_files; list; list = list->next) { + if (foi->file == list->fileinfo) { + if (cparamblkptr->isPrecompiling != 1) + ObjGen_SrcBreakName(list->fileinfo->nameNode, list->fileinfo->fileModDate, 0); + cprep_cursymfile = foi->file; + return; + } + } + + list = galloc(sizeof(CPrepFileInfoList)); + list->next = cprep_files; + cprep_files = list; + list->fileinfo = foi->file; + if (cparamblkptr->isPrecompiling != 1) + ObjGen_SrcBreakName(list->fileinfo->nameNode, list->fileinfo->fileModDate, 1); + cprep_cursymfile = foi->file; + } + } + } +} + +HashNameNode *CPrep_GetSourceFilePath(CPrepFileInfo *fileinfo) { + HashNameNode *node; + if ((node = fileinfo->nameNode) == NULL) + node = CTool_GetPathName(&fileinfo->textfile, NULL); + return node; +} + +void CPrep_NewFileOffsetInfo(FileOffsetInfo *foi, TStreamElement *ts) { + if (!ts || !ts->tokenfile) { + if (ts_first < ts_current) { + foi->file = ts_current[-1].tokenfile; + foi->tokenline = ts_current[-1].tokenline; + foi->tokenoffset = ts_current[-1].tokenoffset; + } else { + foi->file = filestack[filesp]; + foi->tokenline = linenumber; + if (tokenstacklevel) + foi->tokenoffset = tokenstack[0].pos - filestack[filesp]->textbuffer; + else + foi->tokenoffset = pos - filestack[filesp]->textbuffer; + } + } else { + foi->file = ts->tokenfile; + foi->tokenline = ts->tokenline; + foi->tokenoffset = ts->tokenoffset; + } + foi->is_inline = 0; +} + +SInt32 CPrep_GetFileOffsetInfo(FileOffsetInfo *foi) { + SInt32 p; + SInt32 i; + + if (ts_first < ts_current && ts_current[-1].tokenfile == foi->file) { + if (ts_current[-1].tokenline > foi->tokenline) + foi->tokenline = ts_current[-1].tokenline; + if (ts_current[-1].tokenoffset > foi->tokenoffset) + foi->tokenoffset = ts_current[-1].tokenoffset; + } else if (foi->file == filestack[filesp]) { + if (linenumber > foi->tokenline) + foi->tokenline = linenumber; + if (tokenstacklevel) + p = tokenstack[0].pos - filestack[filesp]->textbuffer; + else + p = pos - filestack[filesp]->textbuffer; + if (p > foi->tokenoffset) + foi->tokenoffset = p; + } else { + for (i = filesp - 1; i >= 0; i--) { + if (foi->file == filestack[i]) { + if (filestack[i]->linenumber > foi->tokenline) + foi->tokenline = filestack[i]->linenumber; + if (filestack[i]->pos > foi->tokenoffset) + foi->tokenoffset = filestack[i]->pos; + break; + } + } + } + + return foi->tokenline; +} + +void CPrep_GetFileOffsetInfo2(FileOffsetInfo *foi, SInt32 *pLine, HashNameNode **pName) { + SInt32 p; + SInt32 i; + + if (ts_first < ts_current && ts_current[-1].tokenfile == foi->file) { + if (ts_current[-1].tokenline > foi->tokenline) + foi->tokenline = ts_current[-1].tokenline; + if (ts_current[-1].tokenoffset > foi->tokenoffset) + foi->tokenoffset = ts_current[-1].tokenoffset; + } else if (foi->file == filestack[filesp]) { + if (linenumber > foi->tokenline) + foi->tokenline = linenumber; + if (tokenstacklevel) + p = tokenstack[0].pos - filestack[filesp]->textbuffer; + else + p = pos - filestack[filesp]->textbuffer; + if (p > foi->tokenoffset) + foi->tokenoffset = p; + } else { + for (i = filesp - 1; i >= 0; i--) { + if (foi->file == filestack[i]) { + if (filestack[i]->linenumber > foi->tokenline) + foi->tokenline = filestack[i]->linenumber; + if (filestack[i]->pos > foi->tokenoffset) + foi->tokenoffset = filestack[i]->pos; + break; + } + } + } + + *pLine = foi->tokenline; +#line 2010 + CError_ASSERT(*pLine >= 0); + *pName = foi->file ? foi->file->nameNode : NULL; +} + +void CPrep_ResetFileInfo(FileOffsetInfo *foi) { + // this function is empty so i can only assume... +} + +void CPrep_GetPrepPos(CPrepFileInfo **file, SInt32 *ppos) { + *file = prep_file; + if (tokenstacklevel > 0) + *ppos = tokenstack->pos - prep_file_start; + else + *ppos = pos - prep_file_start; +} + +UInt8 C_Compiler(CParams *param) { + TStreamElement ts; + UInt8 code; + + CInt64_Init(); + cprep_packstackp = 128; + widestring = 0; + cprep_nomem_exit = 0; + cparamblkptr = param; + prep_file = NULL; + lines = 0; + linenumber = 0; + cprep_hasprepline = 0; + + if (CWDisplayLines(param->context, 0) != cwNoErr) + return 0; + + linetick = COS_GetTicks() + 5; + code = 0; + copts.delete_exception = 1; + copts.som_call_opt = 1; + copts.template_patch = 1; + copts.template_friends = 1; + copts.simple_class_byval = 1; + copts.array_new_delete = 1; + copts.syspath_once = 1; + copts.arg_dep_lookup = 1; + copts.longlong = 1; + copts.longlong_prepeval = copts.longlong; + copts.vbase_ctor_offset = 1; + copts.vbase_abi_v2 = 1; + copts.optEH = 1; + copts.optEH2 = 0; + if (copts.cplusplus) + copts.const_strings = 1; + copts.inline_bottom_up = 1; + + if (initheaps(&CError_NoMem)) { + releaseheaps(); + cprep_nomem_exit = 1; + code = 255; + } else { + if (setjmp(errorreturn) == 0) { + InitNameHash(); + setupprep(); + CParser_Setup(); + SetupPrecompiler(cparamblkptr->isPrecompiling); + SetupAssembler(); + ObjGen_Setup(); + PointerAnalysis_Setup(); + CBrowse_Setup(param); + + setupfile(NULL, 1, 0); + if (copts.oldprefixname[0]) + setupfile(copts.oldprefixname, 1, 0); + + coptssave = galloc(sizeof(COpts)); + *coptssave = copts; + coptpushs = NULL; + coptpush = NULL; + preprocessing_only = param->isPreprocessing; + if (param->isPreprocessing) + CPrep_Preprocess(); + else + cparser(); + + if (CWDisplayLines(param->context, lines) != cwNoErr) + anyerrors = 1; + + if (tokenstacklevel) { + was_prep_error = 1; + CError_ErrorTerm(119); + } else if (iflevel) { + was_prep_error = 0; + ts.tokenfile = ifstack[iflevel - 1].file; + ts.tokenoffset = ifstack[iflevel - 1].pos; + if (iflevel) + CError_SetErrorToken(&ts); + CError_ErrorTerm(119); + } + + if (!anyerrors) { + if (param->isPrecompiling == 1) { + CBrowse_Finish(param); + PrecompilerWrite(); + } else if (!param->isPreprocessing) { + ObjGen_Finish(); + CBrowse_Finish(param); + } + code = 1; + } + + if (param->isPreprocessing) { + cparamblkptr->objectDataHandle = pplist.data; + pplist.data = NULL; + cparamblkptr->browseDataHandle = NULL; + } + } else { + CWDisplayLines(param->context, lines); + } + + CParser_Cleanup(); + CleanupPrecompiler(); + CleanupAssembler(); + ObjGen_Cleanup(); + ObjGen_CodeCleanup(); + PointerAnalysis_Cleanup(); + cleanupprep(); + CBrowse_Cleanup(param); + } + + param->objectdata.compiledlines = lines; + if (cprep_nomem_exit) { + CompilerGetCString(7, string); + CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0); + } + + return code; +} static void pushtokenseq(Macro *macro) { if (tokenstacklevel >= 128) { @@ -723,175 +1569,2115 @@ void poptokenseq() { spaceskip = 1; } -static void is_nextchar() {} -static void ismacroname() {} -static void ismacroname2() {} -static void ismacroname5() {} -static void ismacroname3() {} -static void ismacroname4() {} -void foundnl() {} -void newline() {} -static void gotonexttoken() {} -short notendofline() {} -static void CPrep_MacroRedefError() {} -static void goendofline() {} -static void CPrep_Define() {} -static void prepundefine() {} -static Boolean CPrep_CheckTarget() {} -static Boolean CPrep_CheckOption() {} -static void CPrep_XpandDefinedCheck() {} -static void XpandString() {} -char *CPrep_GetFileName(char *buffer, Boolean flag1, Boolean flag2) { +static Boolean is_nextchar(short t) { + char *p = pos; + short level = tokenstacklevel; + int c; + + do { + switch ((c = *p)) { + case 0: + if (level <= 0) + return 0; + p = tokenstack[--level].pos; + continue; + case '\r': + p++; + continue; + } + if (c == t) + return 1; + if (c != ' ' && (c < 9 || c > 12)) + break; + p++; + } while (1); + + return 0; } -static char *XpandSpecialMacro(Macro *macro) { - char buf[512]; - char smallbuf[32]; - char *strptr; - struct tm *tm; +static Macro *ismacroname() { + Macro *scan; + Boolean save_macrocheck; + HashNameNode *name = tkidentifier; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->is_special) { + if (scan == &vecM && !copts.altivec_model) + return NULL; + if (scan == &stdcM && copts.cplusplus) + return NULL; + if (scan == &cpplM && !copts.cplusplus) + return NULL; + if (scan == &ecppM && (!copts.cplusplus || !copts.ecplusplus)) + return NULL; + } - if (macro == &optiM) { - return CPrep_CheckOption() ? "1" : "0"; - } else if (macro == &trgtM) { - return CPrep_CheckTarget() ? "1" : "0"; - } else if (macro == &lineM) { - sprintf(buf, "%ld", linenumber); - do_string: - strptr = aalloc(strlen(buf) + 1); - strcpy(strptr, buf); - return strptr; - } else if (macro == &fileM) { - CPrep_GetFileName(buf, 0, 1); - goto do_string; - } else if (macro == &dateM) { - tm = localtime(&now_time); - strftime(buf, 64, "\"%b ", tm); - strftime(smallbuf, 32, "%d", tm); - if (smallbuf[0] == '0') - smallbuf[0] = ' '; - strcat(buf, smallbuf); - strftime(smallbuf, 32, " %Y\"", tm); - strcat(buf, smallbuf); - goto do_string; - } else if (macro == &timeM) { - strftime(buf, 64, "\"%H:%M:%S\"", localtime(&now_time)); - goto do_string; - } else if (macro == &stdcM) { - return "1"; - } else if (macro == &casmM || macro == &MWRSM) { - return "0x2405"; - } else if (macro == &cpplM) { - return "199711L"; - } else if (macro == &dtsomM) { - return copts.direct_to_som ? "1" : "0"; - } else if (macro == &ecppM) { - return copts.ecplusplus ? "1" : "0"; - } else if (macro == &stcvM) { - return copts.c9x ? "199901L" : "199409L"; - } else if (macro == &stchM) { - return "0"; - } else { - return CodeGen_ExpandSpecialMacro(macro); + if (scan->xF) { + waslockedmacro = 1; + return NULL; + } + + if (scan->xC) { + save_macrocheck = macrocheck; + macrocheck = 0; + gotonexttoken(); + macrocheck = save_macrocheck; + if (*pos != '(') + return NULL; + } + + return scan; + } } + + return NULL; } -static void XpandMacro() {} -static void prepmacro() {} -void macrotest() {} -void CPrep_PragmaLex() {} -void CPrep_PushOption() {} -void CPrep_PopOption() {} -static void CPrep_PragmaImExport() {} -static void pragma_on_off_reset() {} -static void CPrep_PragmaOnceName() {} -static void pragma_precompile_target() {} -static void CPrep_DefinePragmaOnceMacro() {} -static void CPrep_PragmaOnce() {} -static void CPrep_PragmaUnused() {} -static void CPrep_PragmaInlineDepth() {} -static void CPrep_PragmaInlineMaxSize() {} -static void CPrep_PragmaInlineMaxTotalSize() {} +static Macro *ismacroname2(char *str) { + Macro *scan; + HashNameNode *name = tkidentifier; -static void pragma_segment() { - short i; - short t; - char name[256]; + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->xF) { + waslockedmacro = 1; + return NULL; + } - if (notendofline()) { - for (i = 0; i < 255; i++) { - spaceskip = 0; - t = prepskipnextchar(); - if (spaceskip) - break; - if (t <= ' ') - break; - name[i] = t; - pos = nextcharpos; + if (scan->xC) { + while (*str == ' ' || (*str >= 9 && *str <= 12)) + str++; + if (*str != '(' && !is_nextchar('(')) + return NULL; + } + + return scan; } - name[i] = 0; + } - if (!i || i >= 255) + return NULL; +} + +static Macro *ismacroname5(char *str) { + Macro *scan; + HashNameNode *name = tkidentifier; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->xF) { + waslockedmacro = 1; + return NULL; + } + + if (scan->xC) { + while (*str == ' ' || (*str >= 9 && *str <= 12)) + str++; + if (*str != '(') + return NULL; + } + + return scan; + } + } + + return NULL; +} + +static Macro *ismacroname3() { + Macro *scan; + HashNameNode *name = tkidentifier; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->is_special) { + if (scan == &vecM && !copts.altivec_model) + return NULL; + if (scan == &stdcM && copts.cplusplus) + return NULL; + if (scan == &cpplM && !copts.cplusplus) + return NULL; + } + break; + } + } + + return scan; +} + +static Macro *ismacroname4(HashNameNode *name) { + Macro *scan; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->is_special) { + if (scan == &vecM && !copts.altivec_model) + return NULL; + if (scan == &stdcM && copts.cplusplus) + return NULL; + if (scan == &cpplM && !copts.cplusplus) + return NULL; + } + break; + } + } + + return scan; +} + +void foundnl() { + if (!tokenstacklevel) { + if (preprocessing_only) + CPrep_PreprocessDumpNewLine(); + linenumber++; + lines++; + if (filesp <= 0) + lineoffset = pos - filestack[0]->textbuffer; + } +} + +void newline() { + foundnl(); + nlflag = 1; + at_linestart = 1; + spaceskip = 1; + if (COS_GetTicks() > linetick) { + if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr) + CError_UserBreak(); + linetick = COS_GetTicks() + 5; + } +} + +static void gotonexttoken() { + char *save_pos; + Macro *macro; + char c; + +loop: + switch ((c = prepskipnextchar())) { + case 0: + if (tokenstacklevel) { + poptokenseq(); + goto loop; + } + if (tokenstacklevel > 0 || pos >= prep_file_end) { + if (filesp > 0) { + popfile(); + goto loop; + } + return; + } + pos = nextcharpos; + goto loop; + case '\r': + newline(); + pos = nextcharpos; + goto loop; + } + + if (macrocheck && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'))) { + pos = ReadIdentifier(save_pos = pos); + if ((macro = ismacroname())) { + prepmacro(macro); + goto loop; + } else { + pos = save_pos; + } + } +} + +short notendofline() { + char *save_pos; + Macro *macro; + char c; + +loop: + switch ((c = prepskipnextchar())) { + case 0: + if (tokenstacklevel) { + poptokenseq(); + goto loop; + } + case '\r': + return 0; + } + + if (macrocheck && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'))) { + pos = ReadIdentifier(save_pos = pos); + if ((macro = ismacroname())) { + prepmacro(macro); + goto loop; + } else { + pos = save_pos; + } + } + + return 1; +} + +static void CPrep_MacroRedefError(char *name, Boolean *flag) { + if (!*flag) { + if (copts.gcc_extensions) { + CPrep_WarningName(108, name); + } else if (copts.cpp_extensions) { + if (copts.pedantic) + CPrep_WarningName(108, name); + } else { + CPrep_ErrorName(108, name); + } + *flag = 1; + } +} + +static void goendofline() { + if (notendofline()) { + CPrep_Error(113); + skipendofline(); + } +} + +static void CPrep_Define() { + Macro *existing_macro; // r31 + HashNameNode *name; // r29 + short r28; // r28 + Boolean r27; // r27 + Macro *macro; // r20 + short t; // r17 + Boolean error_flag; + + macrocheck = 0; + nlflag = 0; + t = lexidentifier(); + if (nlflag) { + CPrep_Error(112); + skipendofline(); + } + if (t != TK_IDENTIFIER) { + CPrep_Error(107); + skipendofline(); + return; + } + + macro = ismacroname3(); + name = tkidentifier; + error_flag = 0; + r27 = 0; + if (prepcurchar() == '(') { + r28 = 1; + pos = nextcharpos; + // fix me + } else { + macro = galloc(sizeof(Macro)); + r28 = 0; + } + + if (existing_macro && (existing_macro->xC & 0x7FFF) != r28) + CPrep_MacroRedefError(name->name, &error_flag); + + macro->name = name; + macro->xC = r27 ? (r28 | 0x8000) : r28; + macro->is_special = 0; + macro->xF = 0; + + if (r28 > 1) { + // fix me + } + + mlist.size = 0; + if (notendofline()) { + // fix me + } else { + // fix me + } +} + +static void prepundefine() { + short t; + Macro *macro; + Macro **scan; + HashNameNode *name; + + nlflag = 0; + t = lexidentifier(); + if (nlflag) { + CPrep_Error(112); + skipendofline(); + } else if (t != TK_IDENTIFIER) { + CPrep_Error(107); + skipendofline(); + } else { + name = tkidentifier; + for (scan = ¯ohashtable[name->hashval], macro = *scan; macro; scan = ¯o->next, macro = *scan) { + if (macro->name == name) { + *scan = macro->next; + macrocheck = 1; + return; + } + } + goendofline(); + } +} + +static Boolean CPrep_CheckTarget() {} +static Boolean CPrep_CheckOption() {} +static char *CPrep_XpandDefinedCheck(char *) {} + +static char *XpandString(Macro *macro, char *somepos) { + // almost matches, r22 and r23 are swapped at the end + short start_level; + char *curpos; + char *tmp; + SInt32 tmplen; + SInt32 i; + char *macro_output; + Macro *macro2; + int c; + char *resultptr; + + pushtokenseq(macro); + macropos = somepos; + macrostart = somepos; + start_level = tokenstacklevel; + pos = somepos; + mlist.size = 0; + + while (tokenstacklevel >= start_level) { + loop: + switch (*(curpos = pos)) { + case 4: + AppendGListByte(&mlist, 4); + pos = ReadIdentifier(somepos = ++pos); + if (cprep_incondexpr && !strcmp(tkidentifier->name, "defined") && (tmp = CPrep_XpandDefinedCheck(pos))) + pos = tmp; + AppendGListData(&mlist, somepos, pos - somepos); + goto loop; + case '"': + case '\'': + somepos = pos++; + CPrep_MatchChar(*somepos, 0); + AppendGListData(&mlist, somepos, pos - somepos); + goto loop; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': + case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': + case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': + case '_': + pos = ReadIdentifier(curpos); + waslockedmacro = 0; + if (cprep_incondexpr && !strcmp(tkidentifier->name, "defined") && (tmp = CPrep_XpandDefinedCheck(pos))) { + pos = tmp; + AppendGListData(&mlist, curpos, pos - curpos); + goto loop; + } else { + if (macro) + macro2 = ismacroname2(pos); + else + macro2 = ismacroname5(pos); + if (macro2) { + AppendGListByte(&mlist, 5); + tmplen = mlist.size; + if (tmplen > 0x20000) { + macropos = pos; + CPrep_Error(111); + return ""; + } + curpos = aalloc(tmplen); + memcpy(curpos, *mlist.data, tmplen); + macro_output = XpandMacro(macro2); + if (tokenstacklevel == start_level) { + for (i = strlen(macro_output) - 1; i > 0; i--) { + switch (macro_output[i]) { + case ' ': + case '"': + case '\'': + case ';': + goto exit_innermost_loop; + } + } + exit_innermost_loop: + if (i > 0) { + mlist.size = 0; + AppendGListName(&mlist, ¯o_output[i + 1]); + AppendGListID(&mlist, pos); + pos = aalloc(mlist.size); + memcpy(pos, *mlist.data, mlist.size); + mlist.size = 0; + AppendGListData(&mlist, curpos, tmplen); + AppendGListData(&mlist, macro_output, i + 1); + } else { + mlist.size = 0; + AppendGListName(&mlist, macro_output); + AppendGListID(&mlist, pos); + macro_output = aalloc(mlist.size); + memcpy(macro_output, *mlist.data, mlist.size); + mlist.size = 0; + pos = macro_output; + AppendGListData(&mlist, curpos, tmplen); + } + } else { + mlist.size = 0; + AppendGListData(&mlist, curpos, tmplen); + AppendGListID(&mlist, macro_output); + if (tokenstacklevel < start_level) + goto skip_null_term; + mlist.size--; + goto loop; + } + } else { + if (waslockedmacro) + AppendGListByte(&mlist, 4); + AppendGListData(&mlist, curpos, pos - curpos); + goto loop; + } + } + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + AppendGListByte(&mlist, *(pos++)); + do { + c = *pos; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9')) { + AppendGListByte(&mlist, c); + pos++; + } else { + break; + } + } while (1); + goto loop; + default: + AppendGListByte(&mlist, *(pos++)); + goto loop; + case 0: + if (tokenstacklevel >= start_level) + poptokenseq(); + } + } + + AppendGListByte(&mlist, 0); +skip_null_term: + if ((tmplen = mlist.size) > 0x20000) { + CPrep_Error(111); + return ""; + } else { + resultptr = aalloc(tmplen); + memcpy(resultptr, *mlist.data, tmplen); + return resultptr; + } +} + +char *CPrep_GetFileName(char *buffer, Boolean flag1, Boolean flag2) { +} + +static char *XpandSpecialMacro(Macro *macro) { + char buf[512]; + char smallbuf[32]; + char *strptr; + struct tm *tm; + + if (macro == &optiM) { + return CPrep_CheckOption() ? "1" : "0"; + } else if (macro == &trgtM) { + return CPrep_CheckTarget() ? "1" : "0"; + } else if (macro == &lineM) { + sprintf(buf, "%ld", linenumber); + do_string: + strptr = aalloc(strlen(buf) + 1); + strcpy(strptr, buf); + return strptr; + } else if (macro == &fileM) { + CPrep_GetFileName(buf, 0, 1); + goto do_string; + } else if (macro == &dateM) { + tm = localtime(&now_time); + strftime(buf, 64, "\"%b ", tm); + strftime(smallbuf, 32, "%d", tm); + if (smallbuf[0] == '0') + smallbuf[0] = ' '; + strcat(buf, smallbuf); + strftime(smallbuf, 32, " %Y\"", tm); + strcat(buf, smallbuf); + goto do_string; + } else if (macro == &timeM) { + strftime(buf, 64, "\"%H:%M:%S\"", localtime(&now_time)); + goto do_string; + } else if (macro == &stdcM) { + return "1"; + } else if (macro == &casmM || macro == &MWRSM) { + return "0x2405"; + } else if (macro == &cpplM) { + return "199711L"; + } else if (macro == &dtsomM) { + return copts.direct_to_som ? "1" : "0"; + } else if (macro == &ecppM) { + return copts.ecplusplus ? "1" : "0"; + } else if (macro == &stcvM) { + return copts.c9x ? "199901L" : "199409L"; + } else if (macro == &stchM) { + return "0"; + } else { + return CodeGen_ExpandSpecialMacro(macro); + } +} + +static char *XpandMacro(Macro *macro) { +} + +static void prepmacro(Macro *macro) { + Boolean save_spaceskip; + char *result; + + macrocheck = 0; + dofreeaheap = 0; + save_spaceskip = spaceskip; + result = XpandMacro(macro); + macrocheck = 1; + pushtokenseq(NULL); + macropos = result; + pos = result; + macrostart = result; + dofreeaheap = 1; + macrocheck = 0; + spaceskip = save_spaceskip; +} + +Boolean macrotest() { + Macro *macro; + if ((macro = ismacroname())) { + prepmacro(macro); + return 1; + } else { + return 0; + } +} + +short CPrep_PragmaLex(Boolean no_err) { + if (notendofline()) + return plex(); + if (!no_err) + CPrep_Error(113); + return 0; +} + +void CPrep_PushOption(SInt32 id, char value) { + struct COptPush *opt; + struct COptPush *newopt; + + opt = coptpush; + do { + if (!opt || (opt->x8 && opt->id == id)) { + newopt = galloc(sizeof(struct COptPush)); + newopt->next = coptpush; + coptpush = opt = newopt; + break; + } + if (!opt->x8) + break; + opt = opt->next; + } while (1); + + opt->value = ((UInt8 *) &copts)[id]; + opt->id = id; + opt->x8 = 1; + ((UInt8 *) &copts)[id] = value; +} + +void CPrep_PopOption(SInt32 id) { + struct COptPush *opt; + + for (opt = coptpush; opt; opt = opt->next) { + if (opt->x8 && opt->id == id) { + ((UInt8 *) &copts)[id] = opt->value; + opt->x8 = 0; + return; + } + } + + ((UInt8 *) &copts)[id] = ((UInt8 *) coptssave)[id]; +} + +static void CPrep_PragmaImExport(int flags) { + // does not match - weirdness with the branching inside the loop + NameSpaceObjectList *list; + + do { + if (!notendofline()) + break; + if (plex() != TK_IDENTIFIER) + break; + + if (!(list = CScope_GetLocalObject(cscope_root, tkidentifier))) { + break; + } else { + while (list) { + if (list->object->otype == OT_OBJECT) { + switch (OBJECT(list->object)->datatype) { + case DDATA: + case DFUNC: + OBJECT(list->object)->flags |= flags; + break; + default: + CPrep_Warning(186); + return; + } + } + list = list->next; + } + } + + if (!notendofline()) + return; + } while (plex() == ',' && notendofline()); + + if (copts.warn_illpragma) + CPrep_Warning(186); +} + +static void pragma_on_off_reset(UInt32 bits) { + Boolean flag = (bits & OPT_FLAG_2000) != 0; + int imex_flags; + + if (notendofline() && plex() == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "on")) { + CPrep_PushOption(bits & OPT_OFFSET_MASK, 1); + return; + } + if (!strcmp(tkidentifier->name, "off")) { + CPrep_PushOption(bits & OPT_OFFSET_MASK, 0); + return; + } + if (!strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(bits & OPT_OFFSET_MASK); + return; + } + if (flag && !strcmp(tkidentifier->name, "list")) { + if (cparamblkptr->isPreprocessing) { + skipendofline(); + return; + } + + macrocheck = 1; + if ((bits & OPT_OFFSET_MASK) == OPT_OFFSET(internal)) + imex_flags = OBJECT_FLAGS_10; + else if ((bits & OPT_OFFSET_MASK) == OPT_OFFSET(import)) + imex_flags = OBJECT_FLAGS_20; + else if ((bits & OPT_OFFSET_MASK) == OPT_OFFSET(export)) + imex_flags = OBJECT_FLAGS_40; + else if ((bits & OPT_OFFSET_MASK) == OPT_OFFSET(lib_export)) + imex_flags = OBJECT_FLAGS_60; + else +#line 3610 + CError_FATAL(); + CPrep_PragmaImExport(imex_flags); + return; + } + } + + if (copts.warn_illpragma) + CPrep_Warning(186); +} + +static HashNameNode *CPrep_PragmaOnceName(StringPtr name, Boolean flag) { + // does not match, can't be bothered to fix it atm + short len; + char myname[256]; + unsigned char *src; + char *dst; + + len = name[0]; + if (len > 250) + len = 250; + + dst = &myname[1]; + src = &name[1]; + while (len-- > 0) { + *(dst++) = tolower(*(src++)); + } + *dst = 0; + + myname[0] = (copts.syspath_once && flag) ? '$' : -'\\'; + return GetHashNameNodeExport(myname); +} + +static void pragma_precompile_target() { + if (!notendofline()) { + CPrep_Error(112); + return; + } + + if (plex() != TK_STRING) { + CPrep_Error(117); + skipendofline(); + return; + } + + if (ispascalstring) { + CPrep_Error(101); + skipendofline(); + return; + } + + precomp_target_str = tkstring; + goendofline(); +} + +static void CPrep_DefinePragmaOnceMacro(StringPtr name, Boolean flag) { + HashNameNode *namenode; + Macro *macro; + + namenode = CPrep_PragmaOnceName(name, flag); + if (!ismacroname4(namenode)) { + macro = galloc(sizeof(Macro)); + memclrw(macro, sizeof(Macro)); + macro->name = namenode; + macro->next = macrohashtable[namenode->hashval]; + macrohashtable[namenode->hashval] = macro; + } +} + +static void CPrep_PragmaOnce() { + if (notendofline()) { + if (plex() == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "on")) { + include_once = 1; + return; + } else if (!strcmp(tkidentifier->name, "off")) { + include_once = 0; + return; + } + } + if (copts.warn_illpragma) + CPrep_Warning(186); + } else { + Str255 filename; + COS_FileGetFSSpecInfo(&prep_file->textfile, NULL, NULL, filename); + CPrep_DefinePragmaOnceMacro(filename, prep_file->unkfield126); + } +} + +static void CPrep_PragmaUnused() { + NameSpace *nspace; + NameSpaceObjectList *list; + short t; + + if (cparamblkptr->isPreprocessing) { + skipendofline(); + return; + } + + if (cscope_currentfunc && notendofline() && plex() == '(' && notendofline()) { + restart: + if (plex() == TK_IDENTIFIER) { + for (nspace = cscope_current; nspace; nspace = nspace->parent) { + if (nspace->is_global) + break; + + list = CScope_GetLocalObject(nspace, tkidentifier); + if (list && list->object->otype == OT_OBJECT && OBJECT(list->object)->datatype == DLOCAL) { + OBJECT(list->object)->flags |= OBJECT_FLAGS_UNUSED; + if (notendofline()) { + t = plex(); + if (t == ')') + return; + if (t == ',' && notendofline()) + goto restart; + } + break; + } + } + } + } + + if (copts.warn_illpragma) + CPrep_Warning(186); +} + +static void CPrep_PragmaInlineDepth() { + int lv; + + if (notendofline() && plex() == '(' && notendofline()) { + switch (plex()) { + case TK_IDENTIFIER: + if (strcmp(tkidentifier->name, "smart")) + CPrep_Warning(186); + else + copts.inlinelevel = 0; + break; + case TK_INTCONST: + lv = CInt64_GetULong(&tkintconst); + if (lv >= 0 && lv <= 1024) + copts.inlinelevel = lv ? lv : -1; + else + CPrep_Warning(186); + break; + default: + CPrep_Warning(186); + skipendofline(); + return; + } + + if (!notendofline() || plex() != ')') { + CPrep_Warning(115); + } + if (notendofline()) { + CPrep_Warning(113); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void CPrep_PragmaInlineMaxSize() { + if (notendofline() && plex() == '(' && notendofline()) { + switch (plex()) { + case TK_INTCONST: + copts.inline_max_size = CInt64_GetULong(&tkintconst); + break; + default: + CPrep_Warning(186); + skipendofline(); + return; + } + + if (!notendofline() || plex() != ')') { + CPrep_Warning(115); + } + if (notendofline()) { + CPrep_Warning(113); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void CPrep_PragmaInlineMaxTotalSize() { + if (notendofline() && plex() == '(' && notendofline()) { + switch (plex()) { + case TK_INTCONST: + copts.inline_max_total_size = CInt64_GetULong(&tkintconst); + break; + default: + CPrep_Warning(186); + skipendofline(); + return; + } + + if (!notendofline() || plex() != ')') { + CPrep_Warning(115); + } + if (notendofline()) { + CPrep_Warning(113); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void pragma_segment() { + short i; + short t; + char name[256]; + + if (notendofline()) { + for (i = 0; i < 255; i++) { + spaceskip = 0; + t = prepskipnextchar(); + if (spaceskip) + break; + if (t <= ' ') + break; + name[i] = t; + pos = nextcharpos; + } + name[i] = 0; + + if (!i || i >= 255) + CPrep_Warning(186); + + copts.forcedSegment = GetHashNameNodeExport(name); + ObjGen_SegmentName(); + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void pragma_options() { + if (notendofline() && plex() == TK_IDENTIFIER && !strcmp(tkidentifier->name, "align") && notendofline() && plex() == '=' && notendofline() && plex() == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(OPT_OFFSET(align_mode)); + goto done; + } else if (!strcmp(tkidentifier->name, "native")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode2_PPC); + goto done; + } else if (!strcmp(tkidentifier->name, "mac68k")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode0_Mac68k); + goto done; + } else if (!strcmp(tkidentifier->name, "mac68k4byte")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode1_Mac68k4byte); + goto done; + } else if (!strcmp(tkidentifier->name, "power")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode2_PPC); + goto done; + } else if (!strcmp(tkidentifier->name, "packed")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode8_Packed); + goto done; + } + } + + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + +done: + if (notendofline()) { + CPrep_Error(113); + skipendofline(); + } +} + +static void pragma_push() { + struct COptsPush *push; + + push = galloc(sizeof(struct COptsPush)); + push->next = coptpushs; + coptpushs = push; + + push->opts = copts; +} + +static void pragma_pop() { + if (coptpushs) { + copts = coptpushs->opts; + coptpushs = coptpushs->next; + CMach_Configure(); + } else { + CPrep_Error(237); + } +} + +static void pragma_overload() { + Object *obj; + + if (cparamblkptr->isPreprocessing) { + skipendofline(); + return; + } + + nlflag = 0; + tk = lex(); + if ((obj = CParser_ParseObject())) { + if (obj->sclass && obj->sclass != 0x103) + CPrep_Error(177); + obj->qual |= Q_OVERLOAD; + } else { + CPrep_Error(186); + } + + if (nlflag) + CPrep_Error(112); + if (tk != ';') + CPrep_Error(123); +} + +static void pragma_optimization_level() { + short t; + int lv; + + if (notendofline()) { + t = plex(); + if (t == TK_INTCONST) { + lv = CInt64_GetULong(&tkintconst); + if (lv >= 0 && lv <= 4) { + if (copts.crippled && lv > 1) { + CPrep_Warning(385); + lv = 1; + } + CPrep_PushOption(OPT_OFFSET(optimizationlevel), lv); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(154); + skipendofline(); + } + } else if (t == TK_IDENTIFIER && !strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(OPT_OFFSET(optimizationlevel)); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(105); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } +} + +static void pragma_opt_unroll_count() { + short t; + int lv; + + if (notendofline()) { + t = plex(); + if (t == TK_INTCONST) { + lv = CInt64_GetULong(&tkintconst); + if (lv >= 0 && lv <= 127) { + CPrep_PushOption(OPT_OFFSET(loop_unroll_count), lv); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(154); + skipendofline(); + } + } else if (t == TK_IDENTIFIER && !strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(OPT_OFFSET(loop_unroll_count)); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(105); + skipendofline(); + } + } else { + if (copts.warn_illpragma) CPrep_Warning(186); + skipendofline(); + } +} - copts.forcedSegment = GetHashNameNodeExport(name); - ObjGen_SegmentName(); +static void pragma_opt_unroll_instr_count() { + short t; + int lv; + + if (notendofline()) { + t = plex(); + if (t == TK_INTCONST) { + lv = CInt64_GetULong(&tkintconst); + if (lv >= 0 && lv <= 127) { + CPrep_PushOption(OPT_OFFSET(loop_unroll_size_threshold), lv); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(154); + skipendofline(); + } + } else if (t == TK_IDENTIFIER && !strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(OPT_OFFSET(loop_unroll_size_threshold)); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(105); + skipendofline(); + } } else { if (copts.warn_illpragma) CPrep_Warning(186); + skipendofline(); } } -static void pragma_options() {} +static void pragma_pack() { + int t; + int i; + Boolean did_push; + Boolean did_pop; -static void pragma_push() { - struct COptsPush *push; + if (notendofline() && plex() == '(') { + macrocheck = 1; + if (notendofline() && ((t = plex()) == ')')) { + copts.align_mode = coptssave->align_mode; + } else { + did_push = did_pop = 0; + do { + if (t == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "push")) { + if (cprep_packstackp) { + cprep_packstackp--; + cprep_packstack[cprep_packstackp].identifier = NULL; + cprep_packstack[cprep_packstackp].align_mode = copts.align_mode; + did_push = 1; + } else { + CPrep_Warning(186); + } + } else if (!strcmp(tkidentifier->name, "pop")) { + if (cprep_packstackp < 128) { + copts.align_mode = cprep_packstack[cprep_packstackp].align_mode; + cprep_packstackp++; + did_pop = 1; + } else { + CPrep_Warning(186); + } + } else { + if (did_push) { + cprep_packstack[cprep_packstackp].identifier = tkidentifier; + } else if (did_pop) { + for (i = cprep_packstackp - 1; i < 128; i++) { + if (cprep_packstack[i].identifier == tkidentifier) + break; + } + if (i < 128) { + copts.align_mode = cprep_packstack[i].align_mode; + cprep_packstackp = i + 1; + } else { + CPrep_Warning(186); + } + } else { + CPrep_Warning(186); + } + did_pop = 0; + did_push = 0; + } + } else { + if (t == TK_INTCONST) { + switch (CInt64_GetULong(&tkintconst)) { + case 0: + copts.align_mode = coptssave->align_mode; + break; + case 1: + copts.align_mode = AlignMode3_1Byte; + break; + case 2: + copts.align_mode = AlignMode4_2Byte; + break; + case 4: + copts.align_mode = AlignMode5_4Byte; + break; + case 8: + copts.align_mode = AlignMode6_8Byte; + break; + case 16: + copts.align_mode = AlignMode7_16Byte; + break; + default: + if (copts.warn_illpragma) + CPrep_Warning(186); + } + } + did_pop = 0; + did_push = 0; + } - push = galloc(sizeof(struct COptsPush)); - push->next = coptpushs; - coptpushs = push; + if (notendofline()) + t = plex(); + if (t != ',') + break; + t = plex(); + } while (1); + } + if (t != ')' && copts.warn_illpragma) + CPrep_Warning(186); + macrocheck = 0; + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} - push->opts = copts; +static void pragma_comment() { + int t; + short start_tokenstacklevel = tokenstacklevel; + + if (notendofline() && plex() == '(') { + if (notendofline()) { + t = plex(); + if (t == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "compiler")) { + t = plex(); + } else if (!strcmp(tkidentifier->name, "exestr") || !strcmp(tkidentifier->name, "linker") || !strcmp(tkidentifier->name, "user")) { + if (plex() == ',') { + macrocheck = 1; + t = plex(); + macrocheck = 0; + if (t == TK_STRING) { + while (t == TK_STRING) { + macrocheck = 1; + if (tokenstacklevel == start_tokenstacklevel && !notendofline()) + break; + macrocheck = 1; + t = plex(); + macrocheck = 0; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else if (!strcmp(tkidentifier->name, "lib")) { + if (plex() == ',') { + macrocheck = 1; + t = plex(); + macrocheck = 0; + if (t == TK_STRING) { + while (t == TK_STRING) { + macrocheck = 1; + if (tokenstacklevel == start_tokenstacklevel && !notendofline()) + break; + macrocheck = 1; + t = plex(); + macrocheck = 0; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } + + if (t != ')') { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } } -static void pragma_pop() { - if (coptpushs) { - copts = coptpushs->opts; - coptpushs = coptpushs->next; - CMach_Configure(); +static void pragma_message() { + int t; + short start_tokenstacklevel; + char str[128]; + char *ptr; + + if (notendofline() && plex() == '(') { + if (notendofline()) { + start_tokenstacklevel = tokenstacklevel; + ptr = str; + str[0] = 0; + macrocheck = 1; + t = plex(); + macrocheck = 0; + if (t == TK_STRING) { + while (t == TK_STRING) { + strncpy(ptr, tkstring, sizeof(str) - (ptr - str)); + str[sizeof(str) - 1] = 0; + ptr = str + strlen(str); + + macrocheck = 1; + if (tokenstacklevel == start_tokenstacklevel && !notendofline()) + break; + macrocheck = 1; + t = plex(); + macrocheck = 0; + } + + CWReportMessage(cparamblkptr->context, NULL, str, NULL, messagetypeInfo, 337); + skipendofline(); + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } + } else if (plex() != ')') { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } } else { - CPrep_Error(237); + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } +} + +static void preppragma() { + struct CompilerOption *opt; + Boolean save_eoltokens; + + if (notendofline()) { + macrocheck = 0; + if (lexidentifier() == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "pack")) { + pragma_pack(); + } else if (!strcmp(tkidentifier->name, "optimization_level")) { + pragma_optimization_level(); + } else if (!strcmp(tkidentifier->name, "once")) { + CPrep_PragmaOnce(); + } else if (!strcmp(tkidentifier->name, "unused")) { + CPrep_PragmaUnused(); + } else if (!strcmp(tkidentifier->name, "inline_depth")) { + CPrep_PragmaInlineDepth(); + } else if (!strcmp(tkidentifier->name, "inline_max_size")) { + CPrep_PragmaInlineMaxSize(); + } else if (!strcmp(tkidentifier->name, "inline_max_total_size")) { + CPrep_PragmaInlineMaxTotalSize(); + } else if (!strcmp(tkidentifier->name, "opt_pointer_analysis_mode")) { + PointerAnalysis_PragmaMode(); + } else if (!strcmp(tkidentifier->name, "options")) { + pragma_options(); + macrocheck = 1; + return; + } else if (!strcmp(tkidentifier->name, "segment")) { + pragma_segment(); + } else if (!strcmp(tkidentifier->name, "push")) { + pragma_push(); + } else if (!strcmp(tkidentifier->name, "pop")) { + pragma_pop(); + } else if (!strcmp(tkidentifier->name, "parameter")) { + macrocheck = 1; + CMach_PragmaParams(); + } else if (!strcmp(tkidentifier->name, "overload")) { + macrocheck = 1; + pragma_overload(); + } else if (!strcmp(tkidentifier->name, "mark")) { + skipendofline(); + macrocheck = 1; + return; + } else if (!strcmp(tkidentifier->name, "precompile_target")) { + pragma_precompile_target(); + } else if (!strcmp(tkidentifier->name, "message")) { + pragma_message(); + } else if (!strcmp(tkidentifier->name, "opt_unroll_count")) { + pragma_opt_unroll_count(); + } else if (!strcmp(tkidentifier->name, "opt_unroll_instr_count")) { + pragma_opt_unroll_instr_count(); + } else if (!strcmp(tkidentifier->name, "exception_terminate")) { + if (!preprocessing_only) + CExcept_Terminate(); + } else if (!strcmp(tkidentifier->name, "exception_arrayinit")) { + if (!preprocessing_only) + CExcept_ArrayInit(); + } else if (!strcmp(tkidentifier->name, "exception_magic")) { + if (!preprocessing_only) + CExcept_Magic(); + } else if (!strcmp(tkidentifier->name, "SOMReleaseOrder")) { + macrocheck = 1; + CSOM_PragmaReleaseOrder(); + } else if (!strcmp(tkidentifier->name, "SOMClassVersion")) { + macrocheck = 1; + CSOM_PragmaClassVersion(); + } else if (!strcmp(tkidentifier->name, "SOMMetaClass")) { + macrocheck = 1; + CSOM_PragmaMetaClass(); + } else if (!strcmp(tkidentifier->name, "SOMCallStyle")) { + CSOM_PragmaCallStyle(); + } else { + for (opt = compileroptions; opt->name; opt++) { + if (!strcmp(tkidentifier->name, opt->name) && !(opt->bits & OPT_FLAG_4000)) { + pragma_on_off_reset(opt->bits); + if (opt->bits & OPT_FLAG_8000) + CMach_Configure(); + goto foundOption; + } + } + + save_eoltokens = cprep_eoltokens; + cprep_eoltokens = 1; + CodeGen_ParsePragma(tkidentifier); + cprep_eoltokens = save_eoltokens; + macrocheck = 1; + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + macrocheck = 1; + return; + } + foundOption: + if (notendofline()) { + CPrep_Error(113); + skipendofline(); + } + CPrep_Reconfig(); + macrocheck = 1; + } +} + +static void prepinclude(Boolean flag) { + // mostly ok but registers need to be rearranged + short t; + Boolean r29; + short len; + short i; + char *save_pos; + char buf[256]; + short start_tokenstacklevel; + StringPtr ptr; + + if (!notendofline()) { + CPrep_Error(112); + return; + } + + t = prepcurchar(); + if (t != '"' && t != '<') { + CPrep_Error(117); + skipendofline(); + return; + } + + r29 = 1; + save_pos = pos; + if (t == '<') { + prepnextchar(); + if (!copts.flat_include) + r29 = 0; + len = 0; + while ((t = prepnextstringchar(save_pos, 1)) != '>') { + if (t != 5) { + if (len > 254) { + CPrep_Error(106); + skipendofline(); + return; + } + buf[++len] = t; + } + } + buf[0] = len; + ptr = (StringPtr) buf; + } else { + start_tokenstacklevel = tokenstacklevel; + macrocheck = 1; + t = plex(); + macrocheck = 0; + buf[1] = 0; + if (t != TK_STRING) { + CPrep_Error(117); + skipendofline(); + return; + } + + while (t == TK_STRING) { + strncat(&buf[1], tkstring, 254 - strlen(&buf[1])); + buf[255] = 0; + if (tokenstacklevel == start_tokenstacklevel && !notendofline()) + break; + macrocheck = 1; + t = plex(); + macrocheck = 0; + } + buf[0] = strlen(&buf[1]); + ptr = (StringPtr) buf; + } + + goendofline(); + if (ismacroname4(CPrep_PragmaOnceName((StringPtr) buf, !r29))) + return; + if (flag || copts.always_import) + CPrep_DefinePragmaOnceMacro((StringPtr) buf, !r29); + + if (copts.flat_include) { + for (i = len; i > 0; i--) { + switch (buf[i]) { + case ':': + case '/': + case '\\': + ptr = (StringPtr) buf; + ptr += i; + buf[i] = len - i; + goto all_done; + } + } + } + +all_done: + setupfile(ptr, r29, flag); +} + +static void prepline() { + short t; + short len; + char buf[256]; + + cprep_hasprepline = 1; + if (!notendofline()) { + CPrep_Error(112); + return; + } + + if (plex() != TK_INTCONST) { + CPrep_Error(117); + skipendofline(); + return; + } + + linenumber = CInt64_GetULong(&tkintconst) - 1; + if (notendofline()) { + if (prepnextchar() != '"') { + CPrep_Error(117); + skipendofline(); + return; + } + + len = 0; + while ((t = prepnextchar()) != '"') { + if (!t) + break; + if (len > 252) { + CPrep_Error(106); + skipendofline(); + return; + } + buf[len] = t; + len++; + } + buf[len] = 0; + + CTool_CtoPstr(buf); + filestack[filesp]->nameNode = CPrep_GetSourceFilePath(filestack[filesp]); + COS_FileSetFSSpec(&filestack[filesp]->textfile, (StringPtr) buf); + goendofline(); + if (preprocessing_only && !copts.simple_prepdump) + CPrep_PreprocessDumpFileInfo(0); + } +} + +static TypeIntegral *CPrep_GetPrepType(PrepValue *pv) { + if (copts.longlong_prepeval || copts.c9x) { + if (pv->is_unsigned) + return &stunsignedlonglong; + else + return &stsignedlonglong; + } else { + if (pv->is_unsigned) + return &stunsignedlong; + else + return &stsignedlong; + } +} + +static PrepValue CPrep_ParseUnary() { + +} + +static PrepValue CPrep_ParseBinary(PrepValue *rhs, short op) { + // i need a lot of fixing :( + PrepValue a; + PrepValue b; + short t; + short op2; + short op3; + short prec2; + short prec3; + + if (!rhs) { + a = CPrep_ParseUnary(); + } else { + a = *rhs; + } + + op2 = op; +restart: + op3 = exprtk; + prec3 = GetPrec(op3); + if (!prec3) { + return a; + } + if (!notendofline()) { + CPrep_Error(112); + return a; + } + b = CPrep_ParseUnary(); + prec3 = prec3; // variable change situation? + do { + if (exprtk == ')' || !notendofline()) { + if (b.is_unsigned) + a.is_unsigned = 1; + a.val = CMach_CalcIntDiadic((Type *) CPrep_GetPrepType(&a), a.val, t, b.val); + return a; + } + + op = GetPrec(exprtk); + if (!op) { + CPrep_Error(141); + return a; + } + if (prec3 >= prec2) { + if (b.is_unsigned) + a.is_unsigned = 1; + a.val = CMach_CalcIntDiadic((Type *) CPrep_GetPrepType(&a), a.val, t, b.val); + if (GetPrec(op) > op2) + goto restart; + return a; + } + b = CPrep_ParseBinary(&b, prec3); + } while (1); +} + +static PrepValue CPrep_ParseCond() { + PrepValue a; + PrepValue b; + PrepValue c; + + a = CPrep_ParseBinary(NULL, -1); + if (exprtk == '?') { + b = CPrep_ParseCond(); + if (!notendofline()) { + CPrep_Error(112); + return a; + } + if (exprtk != ':') { + CPrep_Error(170); + return a; + } + if (!notendofline()) { + CPrep_Error(112); + return a; + } + c = CPrep_ParseCond(); + a = !CInt64_IsZero(&a.val) ? b : c; + } + + return a; +} + +static void doevalconstexpr() { + PrepValue v; + + macrocheck = 1; + nlflag = 0; + cprep_incondexpr = 1; + v = CPrep_ParseCond(); + if (exprtk) + CPrep_Error(141); + cprep_incondexpr = 0; + if (nlflag) + CPrep_Error(112); + else + goendofline(); + tkintconst = v.val; +} + +static void pushifstate(SInt16 state) { + if (iflevel >= 64) { + CPrep_Error(215); + } else { + ifstack[iflevel].state = state; + ifstack[iflevel].file = prep_file; + ifstack[iflevel].pos = pos - prep_file_start; + iflevel++; + } +} + +static void popifstate() { + if (iflevel <= 0) { + CPrep_Error(117); + } else { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + iflevel--; + return; + } + + iflevel--; + if (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + prepifskip(); + } + } + } +} + +static void positiveif() { + pushifstate(IfState_0); +} + +static void negativeif(Boolean flag) { + if (flag) { + pushifstate(IfState_1); + prepifskip(); + } else { + pushifstate(IfState_3); + } +} + +static void prepif() { + if (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + skipendofline(); + negativeif(0); + return; + } + } + + doevalconstexpr(); + if (CInt64_IsZero(&tkintconst)) + negativeif(1); + else + positiveif(); +} + +static void prepifdef() { + if (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + skipendofline(); + negativeif(0); + return; + } + } + + macrocheck = 0; + if (!notendofline()) { + CPrep_Error(112); + negativeif(1); + return; + } + + if (lexidentifier() != TK_IDENTIFIER) { + CPrep_Error(107); + negativeif(1); + return; + } + + macrocheck = 1; + goendofline(); + if (ismacroname3()) + positiveif(); + else + negativeif(1); +} + +static void prepifndef() { + if (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + skipendofline(); + negativeif(0); + return; + } + } + + macrocheck = 0; + if (!notendofline()) { + CPrep_Error(112); + negativeif(1); + return; + } + + if (lexidentifier() != TK_IDENTIFIER) { + CPrep_Error(107); + negativeif(1); + return; + } + + macrocheck = 1; + goendofline(); + if (!ismacroname3()) + positiveif(); + else + negativeif(1); +} + +static void prepelif() { + if (iflevel <= 0 || ifstack[iflevel - 1].state == IfState_2 || ifstack[iflevel - 1].state == IfState_4) { + CPrep_Error(118); + skipendofline(); + return; + } + + switch (ifstack[iflevel - 1].state) { + case IfState_1: + doevalconstexpr(); + if (!CInt64_IsZero(&tkintconst)) + ifstack[iflevel - 1].state = IfState_0; + break; + case IfState_3: + skipendofline(); + break; + case IfState_0: + ifstack[iflevel - 1].state = IfState_3; + skipendofline(); + prepifskip(); + break; + default: +#line 5700 + CError_FATAL(); + } +} + +static void prepelse() { + if (iflevel <= 0 || ifstack[iflevel - 1].state == IfState_2 || ifstack[iflevel - 1].state == IfState_4) { + CPrep_Error(118); + skipendofline(); + return; + } + + if (!copts.ANSI_strict) + skipendofline(); + else + goendofline(); + + switch (ifstack[iflevel - 1].state) { + case IfState_1: + ifstack[iflevel - 1].state = IfState_2; + break; + case IfState_0: + ifstack[iflevel - 1].state = IfState_4; + prepifskip(); + break; + case IfState_3: + ifstack[iflevel - 1].state = IfState_4; + break; + default: +#line 5738 + CError_FATAL(); + } +} + +static void prependif() { + if (iflevel <= 0) { + CPrep_Error(118); + skipendofline(); + return; + } + + macrocheck = 0; + if (!copts.ANSI_strict) + skipendofline(); + else + goendofline(); + + macrocheck = 1; + popifstate(); +} + +static void prepifskip() { + // this function does something very weird with its code generation that i can't match + TStreamElement ts; + short t; + + while (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + restart: + t = prepskipnextchar(); + pos = nextcharpos; + switch (t) { + case 0: + if (tokenstacklevel > 0) { + poptokenseq(); + } else if (tokenstacklevel > 0 || pos >= prep_file_end) { + if (filesp > 0) { + popfile(); + } else { + was_prep_error = 0; + ts.tokenfile = ifstack[iflevel - 1].file; + ts.tokenoffset = ifstack[iflevel - 1].pos; + CError_SetErrorToken(&ts); + CError_ErrorTerm(119); + iflevel = 0; + return; + } + } else { + CPrep_Error(105); + } + goto restart; + case '\r': + newline(); + goto restart; + case '"': + skipendoflinematch(pos, '"'); + goto restart; + case '\'': + skipendoflinematch(pos, '"'); + goto restart; + case '#': + t = prepskipnextchar(); + pos = nextcharpos; + switch (t) { + case '\r': + goto restart; + case 0: + CPrep_Error(102); + default: + pos = ReadIdentifier(pos - 1); + if (!strcmp("if", tkidentifier->name)) { + prepif(); + } else if (!strcmp("ifdef", tkidentifier->name)) { + prepifdef(); + } else if (!strcmp("ifndef", tkidentifier->name)) { + prepifndef(); + } else if (!strcmp("elif", tkidentifier->name)) { + prepelif(); + } else if (!strcmp("else", tkidentifier->name)) { + prepelse(); + } else if (!strcmp("endif", tkidentifier->name)) { + prependif(); + } else { + skipendofline(); + goto restart; + } + } + break; + default: + skipendofline(); + goto restart; + } + default: + return; + } + return; + } +} + +void preprocessor() { + short t; + + gDirectiveStart = pos - prep_file_start; + t = prepskipnextchar(); + pos = nextcharpos; + + switch (t) { + case 0: + CPrep_Error(102); + case '\r': + return; + } + + pos = ReadIdentifier(pos - 1); + if (!strcmp("define", tkidentifier->name)) { + CPrep_Define(); + macrocheck = 1; + return; + } + if (!strcmp("undef", tkidentifier->name)) { + prepundefine(); + macrocheck = 1; + return; + } + if (!strcmp("include", tkidentifier->name)) { + prepinclude(0); + macrocheck = 1; + return; + } + if (!strcmp("line", tkidentifier->name)) { + prepline(); + macrocheck = 1; + return; + } + if (!strcmp("error", tkidentifier->name)) { + CPrep_Error(318); + CError_ResetErrorSkip(); + skipendofline(); + macrocheck = 1; + return; + } + if (!strcmp("pragma", tkidentifier->name)) { + preppragma(); + macrocheck = 1; + return; } + if (!copts.ANSI_strict) { + if (!strcmp("warning", tkidentifier->name)) { + CPrep_Warning(337); + skipendofline(); + macrocheck = 1; + return; + } + if (!strcmp(tkidentifier->name, "ident")) { + skipendofline(); + macrocheck = 1; + return; + } + } + if (!strcmp("if", tkidentifier->name)) { + macrocheck = 1; + prepif(); + return; + } + if (!strcmp("ifdef", tkidentifier->name)) { + macrocheck = 1; + prepifdef(); + return; + } + if (!strcmp("ifndef", tkidentifier->name)) { + macrocheck = 1; + prepifndef(); + return; + } + if (!strcmp("elif", tkidentifier->name)) { + macrocheck = 1; + prepelif(); + return; + } + if (!strcmp("else", tkidentifier->name)) { + macrocheck = 1; + prepelse(); + return; + } + if (!strcmp("endif", tkidentifier->name)) { + macrocheck = 1; + prependif(); + return; + } + if (copts.objective_c || !copts.ANSI_strict) { + if (!strcmp("import", tkidentifier->name)) { + prepinclude(1); + macrocheck = 1; + return; + } + } + CPrep_Error(104); + skipendofline(); + macrocheck = 1; } -static void pragma_overload() {} -static void pragma_optimization_level() {} -static void pragma_opt_unroll_count() {} -static void pragma_opt_unroll_instr_count() {} -static void pragma_pack() {} -static void pragma_comment() {} -static void pragma_message() {} -static void preppragma() {} -static void prepinclude() {} -static void prepline() {} -static void CPrep_GetPrepType() {} -static void CPrep_ParseUnary() {} -static void CPrep_ParseBinary() {} -static void CPrep_ParseCond() {} -static void doevalconstexpr() {} -static void pushifstate() {} -static void popifstate() {} -static void positiveif() {} -static void negativeif() {} -static void prepif() {} -static void prepifdef() {} -static void prepifndef() {} -static void prepelif() {} -static void prepelse() {} -static void prependif() {} -static void prepifskip() {} -void preprocessor() {} -void CPrep_BrowserTokenOffset() {} -void CPrep_BrowserFileOffset() {} +SInt32 CPrep_BrowserTokenOffset(FileOffsetInfo *foi) { + return foi->tokenoffset; +} + +SInt32 CPrep_BrowserFileOffset() { + if (ts_first < ts_current) + return ts_current[-1].tokenoffset + 1; + else if (tokenstacklevel) + return tokenstack[0].pos - filestack[filesp]->textbuffer; + else + return pos - filestack[filesp]->textbuffer; +} void CPrep_BrowserFilePosition(CPrepFileInfo **fileinfo, SInt32 *offset) { CPrepFileInfo *file; -- cgit v1.2.3