summaryrefslogtreecommitdiff
path: root/compiler_and_linker/FrontEnd/C/CPrep.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler_and_linker/FrontEnd/C/CPrep.c2984
1 files changed, 2885 insertions, 99 deletions
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,24 +1569,504 @@ 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 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 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 (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 Macro *ismacroname2(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 != '(' && !is_nextchar('('))
+ return NULL;
+ }
+
+ return scan;
+ }
+ }
+
+ 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 = &macrohashtable[name->hashval], macro = *scan; macro; scan = &macro->next, macro = *scan) {
+ if (macro->name == name) {
+ *scan = macro->next;
+ macrocheck = 1;
+ return;
+ }
+ }
+ goendofline();
+ }
+}
+
static Boolean CPrep_CheckTarget() {}
static Boolean CPrep_CheckOption() {}
-static void CPrep_XpandDefinedCheck() {}
-static void XpandString() {}
+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, &macro_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) {
}
@@ -795,22 +2121,364 @@ static char *XpandSpecialMacro(Macro *macro) {
}
}
-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 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;
@@ -841,7 +2509,40 @@ static void pragma_segment() {
}
}
-static void pragma_options() {}
+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;
@@ -863,35 +2564,1120 @@ static void pragma_pop() {
}
}
-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() {}
+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();
+ }
+}
+
+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_pack() {
+ int t;
+ int i;
+ Boolean did_push;
+ Boolean did_pop;
+
+ 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;
+ }
+
+ 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);
+ }
+}
+
+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_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 {
+ 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;
+}
+
+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;