mirror of
https://git.wuffs.org/MWCC
synced 2025-07-23 11:35:53 +00:00
first very unfinished commit lol
This commit is contained in:
commit
97f6a2438d
604
Arguments.c
Normal file
604
Arguments.c
Normal file
@ -0,0 +1,604 @@
|
||||
#include "mwcc_decomp.h"
|
||||
|
||||
char compat;
|
||||
char *MAINOPTCHAR;
|
||||
char *FIRSTARGCHAR;
|
||||
char *SEPOPTSTR;
|
||||
char SEPOPTCHAR;
|
||||
char SEP1;
|
||||
char SEP2;
|
||||
char SEP3;
|
||||
char RESPFILECHAR;
|
||||
char *RESPFILESTR;
|
||||
static ArgToken *argtoks;
|
||||
static int numargtoks;
|
||||
static int maxargtoks;
|
||||
unsigned char parserDebug;
|
||||
static unsigned char in_response_file;
|
||||
static int margc;
|
||||
static int margind;
|
||||
static char **margv;
|
||||
static OSFileHandle respfilehandle;
|
||||
static char *respfile;
|
||||
static char *respfilestart;
|
||||
static unsigned long respfilesize;
|
||||
static int scantok;
|
||||
anon0_50 linkargs;
|
||||
anon0_50 prelinkargs;
|
||||
anon0_50 postlinkargs;
|
||||
|
||||
// TODO move me
|
||||
/*extern int OS_MakeFileSpec(const char *name, struct OSSpec *spec);
|
||||
extern int OS_NewFileHandle(struct OSSpec *spec, int a, int b, OSFileHandle *fh);
|
||||
extern int OS_AppendHandle(struct OSHandle *h, const void *, long);
|
||||
extern int OS_LockFileHandle(OSFileHandle *fh, char **h, unsigned long *size);
|
||||
extern void OS_FreeFileHandle(OSFileHandle *fh);
|
||||
extern void CLPOSAlert(short code, short code2, ...);
|
||||
extern void CLPReportError(short code, ...);
|
||||
extern void CLPReportWarning(short code, ...);
|
||||
extern void CLPFatalError(const char *format, ...);
|
||||
extern int ustrncmp(const char *a, const char *b, int len);*/
|
||||
// TODO move me
|
||||
|
||||
static void Arg_AddToken(short val, char *text);
|
||||
static void Arg_Setup(int argc, char **argv);
|
||||
static void Arg_SkipRespFileWS();
|
||||
static unsigned char Arg_OpenRespFile(const char *name);
|
||||
static void Arg_CloseRespFile();
|
||||
static char *Arg_GetRespFileToken();
|
||||
static char *Arg_GetNext(unsigned char allow_resp);
|
||||
static unsigned char Arg_GotMore();
|
||||
static void Arg_Parse();
|
||||
static void Arg_GrowArgs(anon0_50 *ta);
|
||||
static void Arg_GrowArg(anon0_50 *ta, char *txt);
|
||||
|
||||
static void Arg_AddToken(short val, char *text) {
|
||||
ArgToken *cur;
|
||||
ArgToken *prev;
|
||||
ArgToken *pprev;
|
||||
ArgToken *ppprev;
|
||||
ArgToken *pppprev;
|
||||
|
||||
if (numargtoks > 0)
|
||||
prev = &argtoks[numargtoks - 1];
|
||||
else
|
||||
prev = 0;
|
||||
|
||||
if (prev && prev->val == ATK_2 && prev->text[0] == 0) {
|
||||
pppprev = ppprev = pprev = 0;
|
||||
if (numargtoks > 3)
|
||||
pppprev = &argtoks[numargtoks - 4];
|
||||
if (numargtoks > 2)
|
||||
ppprev = &argtoks[numargtoks - 3];
|
||||
if (numargtoks > 1)
|
||||
pprev = &argtoks[numargtoks - 2];
|
||||
|
||||
if (pprev) {
|
||||
if ((int) val == ATK_1 && (pprev->val == ATK_5 || pprev->val == ATK_4) && (ppprev->val != ATK_2 || pppprev->val != ATK_3)) {
|
||||
if (parserDebug)
|
||||
printf("Coalescing args with '%s'\n", Arg_GetTokenName(pprev));
|
||||
val = pprev->val;
|
||||
numargtoks -= 2;
|
||||
} else if (pprev->val == ATK_1 && ((int) val == ATK_5 || (int) val == ATK_4)) {
|
||||
if (parserDebug)
|
||||
printf("Coalescing args, removing '%s'\n", Arg_GetTokenName(pprev));
|
||||
numargtoks -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numargtoks >= maxargtoks) {
|
||||
argtoks = (ArgToken *) xrealloc("argument list", argtoks, sizeof(ArgToken) * (maxargtoks + 16));
|
||||
maxargtoks += 16;
|
||||
}
|
||||
|
||||
cur = &argtoks[numargtoks];
|
||||
cur->val = val;
|
||||
if (text)
|
||||
cur->text = xstrdup(text);
|
||||
else
|
||||
cur->text = 0;
|
||||
numargtoks++;
|
||||
}
|
||||
|
||||
static void Arg_Setup(int argc, char **argv) {
|
||||
in_response_file = 0;
|
||||
respfile = 0;
|
||||
margc = argc;
|
||||
margv = argv;
|
||||
margind = 1;
|
||||
}
|
||||
|
||||
static void Arg_SkipRespFileWS() {
|
||||
restart:
|
||||
while (respfile[0] && isspace(respfile[0]))
|
||||
++respfile;
|
||||
|
||||
if (respfile[0] == '\\' && respfile[1] == '#') {
|
||||
++respfile;
|
||||
return;
|
||||
}
|
||||
|
||||
if (respfile[0] == '#') {
|
||||
if ((respfile > respfilestart) ? (respfile[-1] != '\\') : 1) {
|
||||
while (respfile[0] && respfile[0] != 10 && respfile[0] != 13)
|
||||
++respfile;
|
||||
|
||||
while (respfile[0] == 13 || respfile[0] == 10)
|
||||
++respfile;
|
||||
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char Arg_OpenRespFile(const char *name) {
|
||||
struct OSSpec spec;
|
||||
int err;
|
||||
|
||||
if (
|
||||
(err = OS_MakeFileSpec(name, &spec))
|
||||
|| (err = OS_NewFileHandle(&spec, 0, 0, &respfilehandle))
|
||||
|| (err = OS_AppendHandle(&respfilehandle.hand, "", 1))
|
||||
|| (err = OS_LockFileHandle(&respfilehandle, &respfile, &respfilesize))
|
||||
) {
|
||||
CLPOSAlert(74, (short) err, "response ", name);
|
||||
return 0;
|
||||
} else {
|
||||
respfilestart = respfile;
|
||||
Arg_SkipRespFileWS();
|
||||
in_response_file = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void Arg_CloseRespFile() {
|
||||
in_response_file = 0;
|
||||
OS_FreeFileHandle(&respfilehandle);
|
||||
}
|
||||
|
||||
static char *Arg_GetRespFileToken() {
|
||||
char *start;
|
||||
char *ptr;
|
||||
int quoting;
|
||||
|
||||
quoting = 0;
|
||||
if (respfile[0] == 0)
|
||||
return 0;
|
||||
|
||||
start = ptr = respfile;
|
||||
while (respfile[0]) {
|
||||
if (!quoting && isspace(respfile[0]))
|
||||
break;
|
||||
|
||||
if (respfile[0] == '"') {
|
||||
quoting = !quoting;
|
||||
respfile++;
|
||||
} else if (respfile[0] == '\\' && respfile[1] == '"') {
|
||||
*ptr = '"';
|
||||
respfile += 2;
|
||||
ptr++;
|
||||
} else {
|
||||
*(ptr++) = *(respfile++);
|
||||
}
|
||||
}
|
||||
|
||||
if (respfile[0])
|
||||
Arg_SkipRespFileWS();
|
||||
*ptr = 0;
|
||||
return start;
|
||||
}
|
||||
|
||||
static char *Arg_GetNext(unsigned char allow_resp) {
|
||||
char *ret;
|
||||
int rfclen;
|
||||
char *rfcequ;
|
||||
|
||||
restart:
|
||||
if (!in_response_file) {
|
||||
rfclen = 1;
|
||||
ret = margv[margind++];
|
||||
if (ret[0] == '\\' && ret[1] == RESPFILECHAR) {
|
||||
ret++;
|
||||
} else if (allow_resp) {
|
||||
if (ret[0] == RESPFILECHAR || (RESPFILESTR[0] && !ustrncmp(ret, RESPFILESTR, rfclen = strlen(RESPFILESTR))) && ret[rfclen]) {
|
||||
rfcequ = strchr(ret + rfclen, '=');
|
||||
if (rfcequ)
|
||||
rfclen = (rfcequ + 1) - ret;
|
||||
if (Arg_OpenRespFile(ret + rfclen))
|
||||
goto restart;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = Arg_GetRespFileToken();
|
||||
if (!ret) {
|
||||
Arg_CloseRespFile();
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
if (parserDebug)
|
||||
fprintf(stderr, "Got arg = '%s'\n", ret ? ret : "<NULL>");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned char Arg_GotMore() {
|
||||
if (!in_response_file)
|
||||
return margind < margc;
|
||||
else if (respfile[0])
|
||||
return 1;
|
||||
else
|
||||
return margind < margc;
|
||||
}
|
||||
|
||||
static void Arg_Parse() {
|
||||
unsigned char isOpt;
|
||||
unsigned char isList;
|
||||
char *arg;
|
||||
char *argstart;
|
||||
char buffer[4096];
|
||||
char *bufptr;
|
||||
char ch;
|
||||
|
||||
isOpt = 0;
|
||||
isList = 0;
|
||||
while (Arg_GotMore()) {
|
||||
argstart = arg = Arg_GetNext(1);
|
||||
if (!arg)
|
||||
break;
|
||||
|
||||
bufptr = buffer;
|
||||
buffer[0] = 0;
|
||||
isList = 0;
|
||||
|
||||
if (arg[0] && arg[1] && strchr(MAINOPTCHAR, arg[0])) {
|
||||
if (isOpt)
|
||||
Arg_AddToken(ATK_1, 0);
|
||||
buffer[0] = arg[1];
|
||||
buffer[1] = 0;
|
||||
isOpt = 1;
|
||||
isList = 0;
|
||||
bufptr++;
|
||||
arg += 2;
|
||||
} else {
|
||||
isOpt = 0;
|
||||
}
|
||||
|
||||
while (arg && arg[0]) {
|
||||
ch = arg[0];
|
||||
if (arg[0] == '\\' && (arg[1] == SEP1 || arg[1] == SEP2 || arg[1] == SEP3)) {
|
||||
ch = 0x80 | *(++arg);
|
||||
} else if (compat == 1 && arg[0] == ':' && arg[1] == '\\') {
|
||||
ch |= 0x80;
|
||||
}
|
||||
|
||||
if (ch != SEP1 && ch != SEP2 && ch != SEP3) {
|
||||
if ((ch & 0x7F) == SEP1 || (ch & 0x7F) == SEP2 || (ch & 0x7F) == SEP3)
|
||||
ch &= 0x7F;
|
||||
*(bufptr++) = ch;
|
||||
if (bufptr >= &buffer[sizeof(buffer)]) {
|
||||
CLPReportError(2, argstart, argstart + strlen(argstart) - 15, sizeof(buffer));
|
||||
}
|
||||
*bufptr = 0;
|
||||
} else {
|
||||
if (isOpt) {
|
||||
Arg_AddToken(ATK_3, buffer);
|
||||
Arg_AddToken(ATK_2, buffer);
|
||||
} else {
|
||||
Arg_AddToken(ATK_2, buffer);
|
||||
}
|
||||
|
||||
Arg_AddToken(
|
||||
(unsigned char) ((ch == ',') ? ATK_5 : (((ch == '=') || (ch == SEP3)) ? ATK_4 : ATK_0)),
|
||||
0
|
||||
);
|
||||
|
||||
bufptr = buffer;
|
||||
buffer[0] = 0;
|
||||
|
||||
if (ch == SEP1 || ch == SEP2 || ch == SEP3)
|
||||
isOpt = 0;
|
||||
isList = 1;
|
||||
}
|
||||
|
||||
arg++;
|
||||
}
|
||||
|
||||
// 1799C8
|
||||
if (isOpt && bufptr > &buffer[0]) {
|
||||
Arg_AddToken(ATK_3, buffer + (isList && strchr(MAINOPTCHAR, buffer[0])));
|
||||
Arg_AddToken(ATK_2, buffer + (isList && strchr(MAINOPTCHAR, buffer[0])) + 1);
|
||||
} else {
|
||||
Arg_AddToken(ATK_2, buffer);
|
||||
Arg_AddToken(ATK_1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (isOpt || isList)
|
||||
Arg_AddToken(ATK_1, 0);
|
||||
Arg_AddToken(ATK_0, 0);
|
||||
}
|
||||
|
||||
enum {
|
||||
COMPAT_0,
|
||||
COMPAT_1,
|
||||
COMPAT_2
|
||||
};
|
||||
|
||||
void Arg_Init(int theargc, char **theargv) {
|
||||
int p;
|
||||
int x;
|
||||
|
||||
maxargtoks = 0;
|
||||
numargtoks = 0;
|
||||
parserDebug = 0;
|
||||
if (theargc > 1 && !strcmp(theargv[1], "--parser-debug")) {
|
||||
parserDebug = 1;
|
||||
memmove(&theargv[1], &theargv[2], sizeof(char *) * (theargc - 1));
|
||||
theargc--;
|
||||
}
|
||||
|
||||
if ((int) compat == COMPAT_0) {
|
||||
MAINOPTCHAR = "-";
|
||||
FIRSTARGCHAR = "=";
|
||||
SEPOPTSTR = " ";
|
||||
SEP1 = ',';
|
||||
SEP2 = '=';
|
||||
SEP3 = '=';
|
||||
RESPFILECHAR = '@';
|
||||
RESPFILESTR = "";
|
||||
} else if ((int) compat == COMPAT_1) {
|
||||
MAINOPTCHAR = "/-";
|
||||
FIRSTARGCHAR = ":";
|
||||
SEPOPTSTR = ":";
|
||||
SEP1 = ',';
|
||||
SEP2 = '=';
|
||||
SEP3 = ':';
|
||||
RESPFILECHAR = '@';
|
||||
RESPFILESTR = "";
|
||||
} else if ((int) compat == COMPAT_2) {
|
||||
if (!MAINOPTCHAR)
|
||||
MAINOPTCHAR = "-";
|
||||
if (!FIRSTARGCHAR)
|
||||
FIRSTARGCHAR = "=";
|
||||
if (!SEPOPTSTR)
|
||||
SEPOPTSTR = " ";
|
||||
if (!SEP1)
|
||||
SEP1 = ',';
|
||||
if (!SEP2)
|
||||
SEP2 = '=';
|
||||
if (!SEP3)
|
||||
SEP3 = '=';
|
||||
if (!RESPFILECHAR)
|
||||
RESPFILECHAR = '@';
|
||||
if (!RESPFILESTR)
|
||||
RESPFILESTR = "";
|
||||
} else {
|
||||
CLPFatalError("Unknown parser compatibility type (%d)\n", (int) compat);
|
||||
}
|
||||
|
||||
if (parserDebug) {
|
||||
printf("Incoming arguments: \n");
|
||||
for (p = 0; p < theargc; p++) {
|
||||
printf("[%s] ", theargv[p]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
Arg_Setup(theargc, theargv);
|
||||
Arg_Parse();
|
||||
Arg_Reset();
|
||||
|
||||
if (parserDebug) {
|
||||
for (x = 0; x < numargtoks; x++) {
|
||||
printf("TOKEN: '%s'\n", Arg_GetTokenName(&argtoks[x]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Arg_Terminate() {
|
||||
ArgToken *cur;
|
||||
|
||||
while (numargtoks > 0) {
|
||||
cur = &argtoks[--numargtoks];
|
||||
if (cur->text)
|
||||
free(cur->text);
|
||||
}
|
||||
|
||||
if (maxargtoks)
|
||||
free(argtoks);
|
||||
maxargtoks = 0;
|
||||
}
|
||||
|
||||
void Arg_Reset() {
|
||||
scantok = 0;
|
||||
}
|
||||
|
||||
void Arg_Stop(ArgToken *where) {
|
||||
ArgToken *cur;
|
||||
|
||||
while (&argtoks[numargtoks] > where) {
|
||||
cur = &argtoks[--numargtoks];
|
||||
if (cur->text)
|
||||
free(cur->text);
|
||||
cur->val = ATK_0;
|
||||
cur->text = 0;
|
||||
}
|
||||
|
||||
argtoks[numargtoks++].val = ATK_1;
|
||||
argtoks[numargtoks++].val = ATK_0;
|
||||
scantok = numargtoks - 2;
|
||||
}
|
||||
|
||||
ArgToken *Arg_PeekToken() {
|
||||
if (scantok >= numargtoks)
|
||||
return 0;
|
||||
else
|
||||
return &argtoks[scantok];
|
||||
}
|
||||
|
||||
ArgToken *Arg_UsedToken() {
|
||||
if (scantok < numargtoks)
|
||||
scantok++;
|
||||
return Arg_PeekToken();
|
||||
}
|
||||
|
||||
int Arg_IsEmpty() {
|
||||
ArgToken *tok;
|
||||
|
||||
tok = Arg_PeekToken();
|
||||
return (tok == 0 || tok->val == ATK_0);
|
||||
}
|
||||
|
||||
ArgToken *Arg_GetToken() {
|
||||
ArgToken *ret;
|
||||
|
||||
ret = Arg_PeekToken();
|
||||
if (ret)
|
||||
scantok++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ArgToken *Arg_UndoToken() {
|
||||
if (scantok > 0) {
|
||||
scantok--;
|
||||
return Arg_PeekToken();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char *Arg_GetTokenName(ArgToken *tok) {
|
||||
if ((int) tok->val == ATK_2)
|
||||
return tok->text;
|
||||
|
||||
return
|
||||
((int) tok->val == ATK_3) ? "option" :
|
||||
((int) tok->val == ATK_5) ? "comma" :
|
||||
(((int) compat == COMPAT_1 && (int) tok->val == ATK_4)) ? "colon or equals" :
|
||||
(((int) compat != COMPAT_1 && (int) tok->val == ATK_4)) ? "equals" :
|
||||
((int) tok->val == ATK_1) ? "end of argument" :
|
||||
((int) tok->val == ATK_0) ? "end of command line" :
|
||||
"<error>";
|
||||
}
|
||||
|
||||
const char *Arg_GetTokenText(ArgToken *tok, char *buffer, int maxlen, unsigned char warn) {
|
||||
const char *ptr;
|
||||
char *bptr;
|
||||
int curlen;
|
||||
|
||||
bptr = buffer;
|
||||
curlen = 0;
|
||||
if (tok->val == ATK_2 || tok->val == ATK_3)
|
||||
ptr = tok->text;
|
||||
else
|
||||
ptr = Arg_GetTokenName(tok);
|
||||
|
||||
while (*ptr && curlen++ < maxlen) {
|
||||
*(bptr++) = *(ptr++);
|
||||
}
|
||||
|
||||
if (curlen < maxlen) {
|
||||
bptr[0] = 0;
|
||||
} else {
|
||||
bptr[-1] = 0;
|
||||
if (warn)
|
||||
CLPReportWarning(56, buffer, ptr + strlen(ptr) - ((maxlen <= 32) ? maxlen : 32), maxlen);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void Arg_GrowArgs(anon0_50 *ta) {
|
||||
int len;
|
||||
|
||||
if (!ta->argv || (ta->argc + 1) >= ta->nargv) {
|
||||
len = ta->nargv;
|
||||
ta->nargv = len + 16;
|
||||
ta->argv = xrealloc("argument list", ta->argv, sizeof(char *) * (ta->nargv + 1));
|
||||
while (len <= ta->nargv) {
|
||||
ta->argv[len++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ta->argc++;
|
||||
}
|
||||
|
||||
static void Arg_GrowArg(anon0_50 *ta, char *txt) {
|
||||
char **ptr;
|
||||
int ptrlen;
|
||||
|
||||
ptr = &ta->argv[ta->argc];
|
||||
|
||||
if (*ptr == 0) {
|
||||
*ptr = xstrdup(txt);
|
||||
} else {
|
||||
ptrlen = strlen(*ptr);
|
||||
*ptr = xrealloc("command line", *ptr, ptrlen + strlen(txt) + 1);
|
||||
strcpy(*ptr + ptrlen, txt);
|
||||
}
|
||||
}
|
||||
|
||||
void Arg_InitToolArgs(anon0_50 *ta) {
|
||||
ta->argc = 0;
|
||||
ta->nargv = 0;
|
||||
ta->argv = 0;
|
||||
Arg_GrowArgs(ta);
|
||||
}
|
||||
|
||||
void Arg_AddToToolArgs(anon0_50 *ta, short tokval, char *toktxt) {
|
||||
switch (tokval) {
|
||||
case ATK_0:
|
||||
Arg_FinishToolArgs(ta);
|
||||
break;
|
||||
case ATK_1:
|
||||
if (ta->argv && ta->argv[ta->argc])
|
||||
Arg_GrowArgs(ta);
|
||||
break;
|
||||
case ATK_2:
|
||||
Arg_GrowArg(ta, toktxt);
|
||||
break;
|
||||
case ATK_3:
|
||||
Arg_GrowArg(ta, "-");
|
||||
break;
|
||||
case ATK_4:
|
||||
Arg_GrowArg(ta, "=");
|
||||
break;
|
||||
case ATK_5:
|
||||
Arg_GrowArg(ta, ",");
|
||||
break;
|
||||
default:
|
||||
#line 787
|
||||
CLPFatalError(__FILE__, __LINE__, "Unknown token (%d)", tokval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Arg_FinishToolArgs(anon0_50 *ta) {
|
||||
Arg_GrowArgs(ta);
|
||||
ta->argv[ta->argc] = 0;
|
||||
}
|
||||
|
||||
void Arg_ToolArgsForPlugin(anon0_50 *ta, struct CWCommandLineArgs *args) {
|
||||
args->argc = 1;
|
||||
args->argv = ta->argv;
|
||||
|
||||
while (args->argv[args->argc])
|
||||
args->argc++;
|
||||
|
||||
args->envp = 0;
|
||||
}
|
||||
|
||||
void Arg_FreeToolArgs(anon0_50 *ta) {
|
||||
int x;
|
||||
|
||||
if (ta->argv) {
|
||||
for (x = 1; x < ta->argc; x++) {
|
||||
if (ta->argv[x])
|
||||
free(ta->argv[x]);
|
||||
}
|
||||
free(ta->argv);
|
||||
}
|
||||
}
|
319
CError.c
Normal file
319
CError.c
Normal file
@ -0,0 +1,319 @@
|
||||
#include "CError.h"
|
||||
#include "CompilerTools.h"
|
||||
|
||||
// TODO MOVE ME
|
||||
extern char *CMangler_GetOperator(StringNode *str);
|
||||
extern jmp_buf errorreturn;
|
||||
extern unsigned char cprep_nomem_exit;
|
||||
extern unsigned char anyerrors;
|
||||
extern unsigned char fatalerrors;
|
||||
extern char string[256];
|
||||
// TODO MOVE ME
|
||||
|
||||
Token *cerror_locktoken;
|
||||
static Token *cerror_token;
|
||||
static short cerror_errorcount;
|
||||
static int cerror_lasterrorline;
|
||||
// cerror_synchdata
|
||||
// cerror_synchoffset
|
||||
int CError_BreakPointcount;
|
||||
|
||||
void CError_Init() {
|
||||
cerror_errorcount = 0;
|
||||
cerror_lasterrorline = -1;
|
||||
cerror_token = 0;
|
||||
cerror_locktoken = 0;
|
||||
}
|
||||
|
||||
void CError_SetErrorToken(Token *token) {
|
||||
if (token && token->x4)
|
||||
cerror_token = token;
|
||||
}
|
||||
|
||||
void CError_SetNullErrorToken() {
|
||||
cerror_token = (Token *) -1;
|
||||
}
|
||||
|
||||
void CError_LockErrorPos(Token *token, Token **saved) {
|
||||
*saved = cerror_locktoken;
|
||||
if (token && token->x4)
|
||||
cerror_locktoken = token;
|
||||
}
|
||||
|
||||
void CError_UnlockErrorPos(Token **saved) {
|
||||
cerror_locktoken = *saved;
|
||||
}
|
||||
|
||||
void CError_ResetErrorSkip() {
|
||||
cerror_lasterrorline = -1;
|
||||
}
|
||||
|
||||
void CError_GetErrorString(char *buf, short code) {
|
||||
// This feels dirty, surely this can't have been the solution...
|
||||
int code_ = code;
|
||||
#line 142
|
||||
CError_ASSERT(code_ >= 100 && code_ < 393);
|
||||
COS_GetString(buf, 10000, (short) (code_ - 99));
|
||||
}
|
||||
|
||||
void CError_BufferInit(CErrorBuffer *eb, char *buf, long bufSize) {
|
||||
eb->start = eb->end = buf;
|
||||
eb->size = eb->remaining = bufSize - 1;
|
||||
}
|
||||
|
||||
void CError_BufferGrow(CErrorBuffer *eb, long amount) {
|
||||
char *newBuf;
|
||||
|
||||
newBuf = lalloc(eb->size + amount);
|
||||
memcpy(newBuf, eb->start, eb->size);
|
||||
eb->start = newBuf;
|
||||
eb->end = newBuf + eb->size - eb->remaining;
|
||||
eb->size += amount;
|
||||
eb->remaining += amount;
|
||||
}
|
||||
|
||||
void CError_BufferAppendChar(CErrorBuffer *eb, char ch) {
|
||||
if (eb) {
|
||||
if (!eb->remaining)
|
||||
CError_BufferGrow(eb, 256);
|
||||
*(eb->end++) = ch;
|
||||
eb->remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
void CError_BufferAppendString(CErrorBuffer *eb, const char *str) {
|
||||
size_t len;
|
||||
|
||||
if (eb) {
|
||||
len = strlen(str);
|
||||
if (eb->remaining < len)
|
||||
CError_BufferGrow(eb, len);
|
||||
memcpy(eb->end, str, len);
|
||||
eb->end += len;
|
||||
eb->remaining -= len;
|
||||
}
|
||||
}
|
||||
|
||||
void CError_BufferTerminate(CErrorBuffer *eb) {
|
||||
if (eb->remaining == 0)
|
||||
CError_BufferGrow(eb, 1);
|
||||
*eb->end = 0;
|
||||
eb->remaining = 0;
|
||||
}
|
||||
|
||||
void CError_BufferAppendQualifier(CErrorBuffer *eb, int quals) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, void *targExpr) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendTemplArg(CErrorBuffer *eb, void *targ) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendTemplArgs(CErrorBuffer *eb, void *targs) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendNameSpace(CErrorBuffer *eb, void *ns) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendPType(CErrorBuffer *eb, void *ty) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendTemplDepType(CErrorBuffer *eb, void *ty) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendFuncArgs(CErrorBuffer *eb, void *args, unsigned char flag) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendType(CErrorBuffer *eb, void *ty, int quals) {
|
||||
|
||||
}
|
||||
|
||||
char *CError_GetTypeName(void *ty, int quals, unsigned char useGlobalHeap) {
|
||||
CErrorBuffer eb;
|
||||
char buf[256];
|
||||
char *ptr;
|
||||
|
||||
CError_BufferInit(&eb, buf, sizeof(buf));
|
||||
CError_BufferAppendType(&eb, ty, quals);
|
||||
CError_BufferTerminate(&eb);
|
||||
|
||||
if (useGlobalHeap)
|
||||
ptr = galloc(eb.size + 1);
|
||||
else
|
||||
ptr = lalloc(eb.size + 1);
|
||||
|
||||
return strcpy(ptr, eb.start);
|
||||
}
|
||||
|
||||
void CError_AppendUnqualFunctionName(CErrorBuffer *eb, void *unk1, void *unk2, void *unk3) {
|
||||
|
||||
}
|
||||
|
||||
void CError_AppendFunctionName(CErrorBuffer *eb, void *unk1, void *unk2, void *unk3, void *unk4) {
|
||||
|
||||
}
|
||||
|
||||
void CError_AppendObjectName(CErrorBuffer *eb, void *obj) {
|
||||
|
||||
}
|
||||
|
||||
void CError_AppendMethodName(CErrorBuffer *eb, void *obj) {
|
||||
|
||||
}
|
||||
|
||||
char *CError_GetQualifiedName(void *ns, StringNode *name) {
|
||||
CErrorBuffer eb;
|
||||
char buf[256];
|
||||
char *ptr;
|
||||
|
||||
CError_BufferInit(&eb, buf, sizeof(buf));
|
||||
CError_BufferAppendNameSpace(&eb, ns);
|
||||
CError_BufferAppendString(&eb, name->data);
|
||||
CError_BufferTerminate(&eb);
|
||||
|
||||
ptr = lalloc(eb.size + 1);
|
||||
return strcpy(ptr, eb.start);
|
||||
}
|
||||
|
||||
char *CError_GetFunctionName(void *a, void *b, void *c) {
|
||||
CErrorBuffer eb;
|
||||
char buf[256];
|
||||
char *ptr;
|
||||
|
||||
CError_BufferInit(&eb, buf, sizeof(buf));
|
||||
CError_AppendFunctionName(&eb, a, b, 0, c);
|
||||
CError_BufferTerminate(&eb);
|
||||
|
||||
ptr = lalloc(eb.size + 1);
|
||||
return strcpy(ptr, eb.start);
|
||||
}
|
||||
|
||||
char *CError_GetObjectName(void *obj) {
|
||||
CErrorBuffer eb;
|
||||
char buf[256];
|
||||
char *ptr;
|
||||
|
||||
CError_BufferInit(&eb, buf, sizeof(buf));
|
||||
CError_AppendObjectName(&eb, obj);
|
||||
CError_BufferTerminate(&eb);
|
||||
|
||||
ptr = lalloc(eb.size + 1);
|
||||
return strcpy(ptr, eb.start);
|
||||
}
|
||||
|
||||
char *CError_GetNameString(void *obj, StringNode *operatorName) {
|
||||
CErrorBuffer eb;
|
||||
char buf[256];
|
||||
char *ptr;
|
||||
char *opStr;
|
||||
|
||||
CError_ASSERT(operatorName);
|
||||
|
||||
// TODO lolol
|
||||
CError_BufferInit(&eb, buf, sizeof(buf));
|
||||
CError_AppendObjectName(&eb, obj);
|
||||
CError_BufferTerminate(&eb);
|
||||
|
||||
ptr = lalloc(eb.size + 1);
|
||||
return strcpy(ptr, eb.start);
|
||||
}
|
||||
|
||||
void CError_ErrorMessage(int errTable, char *buf, unsigned char flag1, unsigned char flag2) {
|
||||
|
||||
}
|
||||
|
||||
void CError_BufferAppendTemplateStack(CErrorBuffer *eb) {
|
||||
|
||||
}
|
||||
|
||||
void CError_ErrorMessageVA(short code, char *buf, va_list list, unsigned char flag1, unsigned char flag2) {
|
||||
|
||||
}
|
||||
|
||||
void CError_VAErrorMessage(short code, va_list list, unsigned char flag1, unsigned char flag2) {
|
||||
char buf[256];
|
||||
|
||||
CError_GetErrorString(buf, code);
|
||||
CError_ErrorMessageVA(code + 10000, buf, list, flag1, flag2);
|
||||
}
|
||||
|
||||
void CError_Error(short code, ...) {
|
||||
|
||||
}
|
||||
|
||||
void CError_ErrorTerm(short code) {
|
||||
CError_GetErrorString(string, code);
|
||||
CError_ErrorMessage(code + 10000, string, 0, 0);
|
||||
longjmp(errorreturn, 1);
|
||||
}
|
||||
|
||||
void CError_ErrorSkip(short code, ...) {
|
||||
// TODO trychain, tk
|
||||
}
|
||||
|
||||
void CError_ErrorFuncCall(short code, void *aa, void *bb) {
|
||||
|
||||
}
|
||||
|
||||
void CError_OverloadedFunctionError2(void *aa, void *bb, void *cc) {
|
||||
|
||||
}
|
||||
|
||||
void CError_OverloadedFunctionError(void *aa, void *bb) {
|
||||
|
||||
}
|
||||
|
||||
void CError_AbstractClassError() {
|
||||
// TODO CClass
|
||||
}
|
||||
|
||||
void CError_Warning(short code, ...) {
|
||||
// TODO lol
|
||||
}
|
||||
|
||||
void CError_BreakPoint(const char *a, const char *b) {
|
||||
if (!a || !strcmp(a, b))
|
||||
CError_BreakPointcount++;
|
||||
}
|
||||
|
||||
void CError_Internal(char *filename, int line) {
|
||||
char tmp[128];
|
||||
CompilerGetCString(5, tmp);
|
||||
sprintf(string, tmp, filename, line);
|
||||
CError_ErrorMessage(10001, string, 1, 0);
|
||||
longjmp(errorreturn, 1);
|
||||
CError_BreakPoint(0, 0);
|
||||
}
|
||||
|
||||
void CError_ExpressionTooComplex() {
|
||||
CompilerGetCString(6, string);
|
||||
CError_ErrorMessage(10002, string, 1, 0);
|
||||
longjmp(errorreturn, 1);
|
||||
}
|
||||
|
||||
void CError_NoMem() {
|
||||
cprep_nomem_exit = 1;
|
||||
longjmp(errorreturn, 1);
|
||||
}
|
||||
|
||||
void CError_UserBreak() {
|
||||
CompilerGetCString(8, string);
|
||||
longjmp(errorreturn, 1);
|
||||
}
|
||||
|
||||
void CError_CannotOpen() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CError_QualifierCheck(int quals) {
|
||||
|
||||
}
|
893
CInt64.c
Normal file
893
CInt64.c
Normal file
@ -0,0 +1,893 @@
|
||||
#include <MacHeadersMach-O>
|
||||
#include "CInt64.h"
|
||||
|
||||
const CInt64 cint64_negone = {0xFFFFFFFF, 0xFFFFFFFF};
|
||||
const CInt64 cint64_zero = {0, 0};
|
||||
const CInt64 cint64_one = {0, 1};
|
||||
const CInt64 cint64_max = {0x7FFFFFFF, 0xFFFFFFFF};
|
||||
const CInt64 cint64_min = {0x80000000, 0};
|
||||
|
||||
#define SHIFT_LEFT_ONE(a, b) do { a <<= 1; if (b & 0x80000000) { a |= 1; } b <<= 1; } while(0)
|
||||
|
||||
void CInt64_Init() {
|
||||
}
|
||||
|
||||
CInt64 CInt64_Not(CInt64 input) {
|
||||
CInt64 output;
|
||||
unsigned char c;
|
||||
|
||||
c = (input.a == 0 && input.b == 0);
|
||||
CInt64_SetLong(&output, c);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Inv(CInt64 input) {
|
||||
CInt64 output;
|
||||
output.a = ~input.a;
|
||||
output.b = ~input.b;
|
||||
return output;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Add(CInt64 lhs, CInt64 rhs) {
|
||||
if (lhs.b & 0x80000000) {
|
||||
if (rhs.b & 0x80000000) {
|
||||
lhs.b += rhs.b;
|
||||
lhs.a += 1;
|
||||
} else {
|
||||
lhs.b += rhs.b;
|
||||
if (!(lhs.b & 0x80000000))
|
||||
lhs.a += 1;
|
||||
}
|
||||
} else {
|
||||
if (rhs.b & 0x80000000) {
|
||||
lhs.b += rhs.b;
|
||||
if (!(lhs.b & 0x80000000))
|
||||
lhs.a += 1;
|
||||
} else {
|
||||
lhs.b += rhs.b;
|
||||
}
|
||||
}
|
||||
lhs.a += rhs.a;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Neg(CInt64 input) {
|
||||
CInt64 result;
|
||||
result = CInt64_Add(CInt64_Inv(input), cint64_one);
|
||||
return result;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Sub(CInt64 lhs, CInt64 rhs) {
|
||||
lhs = CInt64_Add(lhs, CInt64_Neg(rhs));
|
||||
return lhs;
|
||||
}
|
||||
|
||||
CInt64 CInt64_MulU(CInt64 lhs, CInt64 rhs) {
|
||||
CInt64 result;
|
||||
CInt64 work1;
|
||||
unsigned long aaaa;
|
||||
unsigned long bbbb;
|
||||
unsigned long cccc;
|
||||
unsigned long dddd;
|
||||
unsigned long eeee;
|
||||
|
||||
aaaa = rhs.b;
|
||||
result.a = result.b = 0;
|
||||
bbbb = lhs.b;
|
||||
cccc = rhs.a;
|
||||
dddd = rhs.b;
|
||||
|
||||
while (bbbb != 0) {
|
||||
if (bbbb & 1) {
|
||||
work1.a = cccc;
|
||||
work1.b = dddd;
|
||||
result = CInt64_Add(result, work1);
|
||||
}
|
||||
cccc <<= 1;
|
||||
if (dddd & 0x80000000)
|
||||
cccc |= 1;
|
||||
dddd <<= 1;
|
||||
bbbb >>= 1;
|
||||
}
|
||||
|
||||
eeee = lhs.a;
|
||||
while (eeee != 0 && aaaa != 0) {
|
||||
if (eeee & 1)
|
||||
result.a += aaaa;
|
||||
aaaa <<= 1;
|
||||
eeee >>= 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Mul(CInt64 lhs, CInt64 rhs) {
|
||||
if (CInt64_IsNegative(&rhs)) {
|
||||
if (CInt64_IsNegative(&lhs)) {
|
||||
return CInt64_MulU(CInt64_Neg(lhs), CInt64_Neg(rhs));
|
||||
}
|
||||
return CInt64_Neg(CInt64_MulU(lhs, CInt64_Neg(rhs)));
|
||||
}
|
||||
if (CInt64_IsNegative(&lhs)) {
|
||||
return CInt64_Neg(CInt64_MulU(CInt64_Neg(lhs), rhs));
|
||||
}
|
||||
return CInt64_MulU(lhs, rhs);
|
||||
}
|
||||
|
||||
void CInt64_DivMod(const CInt64 *lhs, const CInt64 *rhs, CInt64 *pDiv, CInt64 *pMod) {
|
||||
unsigned char bad;
|
||||
unsigned long workA;
|
||||
unsigned long workB;
|
||||
unsigned long leftA;
|
||||
unsigned long leftB;
|
||||
unsigned long rightA;
|
||||
unsigned long rightB;
|
||||
unsigned long outA;
|
||||
unsigned long outB;
|
||||
CInt64 work;
|
||||
int counter;
|
||||
|
||||
bad = (rhs->a == 0) && (rhs->b == 0);
|
||||
if (!bad) {
|
||||
workA = 0;
|
||||
workB = 0;
|
||||
leftA = lhs->a;
|
||||
leftB = lhs->b;
|
||||
rightA = rhs->a;
|
||||
rightB = rhs->b;
|
||||
outA = 0;
|
||||
outB = 0;
|
||||
counter = 0;
|
||||
|
||||
do {
|
||||
workA <<= 1;
|
||||
if (workB & 0x80000000)
|
||||
workA |= 1;
|
||||
workB <<= 1;
|
||||
if (leftA & 0x80000000)
|
||||
workB |= 1;
|
||||
leftA <<= 1;
|
||||
if (leftB & 0x80000000)
|
||||
leftA |= 1;
|
||||
leftB <<= 1;
|
||||
|
||||
outA <<= 1;
|
||||
if (outB & 0x80000000)
|
||||
outA |= 1;
|
||||
outB <<= 1;
|
||||
|
||||
if (workA <= rightA) {
|
||||
if (workA != rightA)
|
||||
continue;
|
||||
if (workB < rightB)
|
||||
continue;
|
||||
}
|
||||
|
||||
outB |= 1;
|
||||
|
||||
work.a = workA;
|
||||
work.b = workB;
|
||||
work = CInt64_Sub(work, *rhs);
|
||||
workA = work.a;
|
||||
workB = work.b;
|
||||
} while (++counter < 64);
|
||||
|
||||
if (pDiv) {
|
||||
pDiv->a = outA;
|
||||
pDiv->b = outB;
|
||||
}
|
||||
if (pMod) {
|
||||
pMod->a = workA;
|
||||
pMod->b = workB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CInt64 CInt64_Div(CInt64 lhs, CInt64 rhs) {
|
||||
CInt64 result;
|
||||
if (CInt64_IsNegative(&rhs)) {
|
||||
rhs = CInt64_Neg(rhs);
|
||||
if (CInt64_IsNegative(&lhs)) {
|
||||
lhs = CInt64_Neg(lhs);
|
||||
CInt64_DivMod(&lhs, &rhs, &result, 0);
|
||||
return result;
|
||||
} else {
|
||||
CInt64_DivMod(&lhs, &rhs, &result, 0);
|
||||
return CInt64_Neg(result);
|
||||
}
|
||||
} else {
|
||||
if (CInt64_IsNegative(&lhs)) {
|
||||
lhs = CInt64_Neg(lhs);
|
||||
CInt64_DivMod(&lhs, &rhs, &result, 0);
|
||||
return CInt64_Neg(result);
|
||||
} else {
|
||||
CInt64_DivMod(&lhs, &rhs, &result, 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CInt64 CInt64_DivU(CInt64 lhs, CInt64 rhs) {
|
||||
CInt64 result;
|
||||
CInt64_DivMod(&lhs, &rhs, &result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Mod(CInt64 lhs, CInt64 rhs) {
|
||||
CInt64 result;
|
||||
if (CInt64_IsNegative(&lhs)) {
|
||||
lhs = CInt64_Neg(lhs);
|
||||
if (CInt64_IsNegative(&rhs))
|
||||
rhs = CInt64_Neg(rhs);
|
||||
CInt64_DivMod(&lhs, &rhs, 0, &result);
|
||||
return CInt64_Neg(result);
|
||||
} else {
|
||||
if (CInt64_IsNegative(&rhs))
|
||||
rhs = CInt64_Neg(rhs);
|
||||
CInt64_DivMod(&lhs, &rhs, 0, &result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
CInt64 CInt64_ModU(CInt64 lhs, CInt64 rhs) {
|
||||
CInt64 result;
|
||||
CInt64_DivMod(&lhs, &rhs, 0, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Shl(CInt64 lhs, CInt64 rhs) {
|
||||
int counter;
|
||||
unsigned long a;
|
||||
unsigned long b;
|
||||
|
||||
if (rhs.a == 0 && rhs.b < 64) {
|
||||
a = lhs.a;
|
||||
b = lhs.b;
|
||||
for (counter = rhs.b; counter != 0; --counter) {
|
||||
a <<= 1;
|
||||
if (b & 0x80000000)
|
||||
a |= 1;
|
||||
b <<= 1;
|
||||
}
|
||||
lhs.a = a;
|
||||
lhs.b = b;
|
||||
} else {
|
||||
lhs.a = 0;
|
||||
lhs.b = 0;
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Shr(CInt64 lhs, CInt64 rhs) {
|
||||
int counter;
|
||||
long a;
|
||||
unsigned long b;
|
||||
|
||||
if (rhs.a == 0 && rhs.b < 64) {
|
||||
a = lhs.a;
|
||||
b = lhs.b;
|
||||
for (counter = rhs.b; counter != 0; --counter) {
|
||||
b >>= 1;
|
||||
if (a & 1)
|
||||
b |= 0x80000000;
|
||||
a >>= 1;
|
||||
}
|
||||
lhs.a = a;
|
||||
lhs.b = b;
|
||||
} else {
|
||||
if (lhs.a & 0x80000000) {
|
||||
lhs.a = 0xFFFFFFFF;
|
||||
lhs.b = 0xFFFFFFFF;
|
||||
} else {
|
||||
lhs.a = 0;
|
||||
lhs.b = 0;
|
||||
}
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
|
||||
CInt64 CInt64_ShrU(CInt64 lhs, CInt64 rhs) {
|
||||
int counter;
|
||||
unsigned long a;
|
||||
unsigned long b;
|
||||
|
||||
if (rhs.a == 0 && rhs.b < 64) {
|
||||
a = lhs.a;
|
||||
b = lhs.b;
|
||||
for (counter = rhs.b; counter != 0; --counter) {
|
||||
b >>= 1;
|
||||
if (a & 1)
|
||||
b |= 0x80000000;
|
||||
a >>= 1;
|
||||
}
|
||||
lhs.a = a;
|
||||
lhs.b = b;
|
||||
} else {
|
||||
lhs.a = 0;
|
||||
lhs.b = 0;
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
|
||||
int CInt64_UnsignedCompare(const CInt64 *lhs, const CInt64 *rhs) {
|
||||
if (lhs->a == rhs->a) {
|
||||
if (lhs->b < rhs->b)
|
||||
return -1;
|
||||
else
|
||||
return lhs->b > rhs->b;
|
||||
} else {
|
||||
return ((unsigned long) lhs->a < rhs->a) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
int CInt64_SignedCompare(const CInt64 *lhs, const CInt64 *rhs) {
|
||||
CInt64 lhs_;
|
||||
CInt64 rhs_;
|
||||
|
||||
lhs_ = CInt64_Xor(*lhs, cint64_min);
|
||||
rhs_ = CInt64_Xor(*rhs, cint64_min);
|
||||
return CInt64_UnsignedCompare(&lhs_, &rhs_);
|
||||
}
|
||||
|
||||
unsigned char CInt64_Less(CInt64 lhs, CInt64 rhs) {
|
||||
return CInt64_SignedCompare(&lhs, &rhs) < 0;
|
||||
}
|
||||
|
||||
unsigned char CInt64_LessU(CInt64 lhs, CInt64 rhs) {
|
||||
return CInt64_UnsignedCompare(&lhs, &rhs) < 0;
|
||||
}
|
||||
|
||||
unsigned char CInt64_Greater(CInt64 lhs, CInt64 rhs) {
|
||||
return CInt64_SignedCompare(&lhs, &rhs) > 0;
|
||||
}
|
||||
|
||||
unsigned char CInt64_GreaterU(CInt64 lhs, CInt64 rhs) {
|
||||
return CInt64_UnsignedCompare(&lhs, &rhs) > 0;
|
||||
}
|
||||
|
||||
unsigned char CInt64_LessEqual(CInt64 lhs, CInt64 rhs) {
|
||||
return CInt64_SignedCompare(&lhs, &rhs) <= 0;
|
||||
}
|
||||
|
||||
unsigned char CInt64_LessEqualU(CInt64 lhs, CInt64 rhs) {
|
||||
return CInt64_UnsignedCompare(&lhs, &rhs) <= 0;
|
||||
}
|
||||
|
||||
unsigned char CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs) {
|
||||
return CInt64_SignedCompare(&lhs, &rhs) >= 0;
|
||||
}
|
||||
|
||||
unsigned char CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs) {
|
||||
return CInt64_UnsignedCompare(&lhs, &rhs) >= 0;
|
||||
}
|
||||
|
||||
unsigned char CInt64_Equal(CInt64 lhs, CInt64 rhs) {
|
||||
return lhs.a == rhs.a && lhs.b == rhs.b;
|
||||
}
|
||||
|
||||
unsigned char CInt64_NotEqual(CInt64 lhs, CInt64 rhs) {
|
||||
return lhs.a != rhs.a || lhs.b != rhs.b;
|
||||
}
|
||||
|
||||
unsigned char CInt64_IsInRange(CInt64 value, short len) {
|
||||
CInt64 bound;
|
||||
|
||||
if (value.a & 0x80000000) {
|
||||
switch (len) {
|
||||
case 1:
|
||||
bound.b = 0xFFFFFF80;
|
||||
bound.a = 0xFFFFFFFF;
|
||||
break;
|
||||
case 2:
|
||||
bound.b = 0xFFFF8000;
|
||||
bound.a = 0xFFFFFFFF;
|
||||
break;
|
||||
case 4:
|
||||
bound.b = 0x80000000;
|
||||
bound.a = 0xFFFFFFFF;
|
||||
break;
|
||||
case 8:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return CInt64_GreaterEqual(value, bound);
|
||||
} else {
|
||||
switch (len) {
|
||||
case 1:
|
||||
bound.b = 0x7F;
|
||||
bound.a = 0;
|
||||
break;
|
||||
case 2:
|
||||
bound.b = 0x7FFF;
|
||||
bound.a = 0;
|
||||
break;
|
||||
case 4:
|
||||
bound.b = 0x7FFFFFFF;
|
||||
bound.a = 0;
|
||||
break;
|
||||
case 8:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return CInt64_LessEqual(value, bound);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char CInt64_IsInURange(CInt64 value, short len) {
|
||||
switch (len) {
|
||||
case 1:
|
||||
return value.a == 0 && (value.b & 0xFFFFFF00) == 0;
|
||||
case 2:
|
||||
return value.a == 0 && (value.b & 0xFFFF0000) == 0;
|
||||
case 4:
|
||||
return value.a == 0;
|
||||
case 8:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
CInt64 CInt64_And(CInt64 lhs, CInt64 rhs) {
|
||||
lhs.a &= rhs.a;
|
||||
lhs.b &= rhs.b;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Xor(CInt64 lhs, CInt64 rhs) {
|
||||
lhs.a ^= rhs.a;
|
||||
lhs.b ^= rhs.b;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
CInt64 CInt64_Or(CInt64 lhs, CInt64 rhs) {
|
||||
lhs.a |= rhs.a;
|
||||
lhs.b |= rhs.b;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
void CInt64_ConvertInt32(CInt64 *i) {
|
||||
CInt64_Extend32(i);
|
||||
}
|
||||
|
||||
void CInt64_ConvertUInt32(CInt64 *i) {
|
||||
CInt64_SetULong(i, (unsigned long) i->b);
|
||||
}
|
||||
|
||||
void CInt64_ConvertInt16(CInt64 *i) {
|
||||
i->b = (short) i->b;
|
||||
CInt64_Extend32(i);
|
||||
}
|
||||
|
||||
void CInt64_ConvertUInt16(CInt64 *i) {
|
||||
CInt64_SetULong(i, (unsigned short) i->b);
|
||||
}
|
||||
|
||||
void CInt64_ConvertInt8(CInt64 *i) {
|
||||
i->b = (char) i->b;
|
||||
CInt64_Extend32(i);
|
||||
}
|
||||
|
||||
void CInt64_ConvertUInt8(CInt64 *i) {
|
||||
CInt64_SetULong(i, (unsigned char) i->b);
|
||||
}
|
||||
|
||||
void CInt64_ConvertUFromLongDouble(CInt64 *pResult, double value) {
|
||||
union { float f; unsigned long l; } cvt;
|
||||
unsigned long a, b;
|
||||
float threshold;
|
||||
int bits;
|
||||
|
||||
if (value <= 0.0) {
|
||||
pResult->a = 0;
|
||||
pResult->b = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
cvt.l = 0x5F800000;
|
||||
if (value >= cvt.f) {
|
||||
pResult->a = 0xFFFFFFFF;
|
||||
pResult->b = 0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
|
||||
a = b = 0;
|
||||
for (bits = 63; bits >= 0; bits--) {
|
||||
a <<= 1;
|
||||
if (b & 0x80000000)
|
||||
a |= 1;
|
||||
b <<= 1;
|
||||
|
||||
if ((short) bits == 0) {
|
||||
threshold = 1.0f;
|
||||
} else {
|
||||
cvt.l = (((short) bits + 127) & 255) << 23;
|
||||
threshold = cvt.f;
|
||||
}
|
||||
|
||||
if (threshold <= value) {
|
||||
b |= 1;
|
||||
value -= threshold;
|
||||
}
|
||||
}
|
||||
|
||||
pResult->a = a;
|
||||
pResult->b = b;
|
||||
}
|
||||
|
||||
void CInt64_ConvertFromLongDouble(CInt64 *pResult, double value) {
|
||||
if (value < 0.0) {
|
||||
CInt64_ConvertUFromLongDouble(pResult, -value);
|
||||
*pResult = CInt64_Neg(*pResult);
|
||||
} else {
|
||||
CInt64_ConvertUFromLongDouble(pResult, value);
|
||||
}
|
||||
}
|
||||
|
||||
double CInt64_ConvertUToLongDouble(const CInt64 *value) {
|
||||
unsigned char bad;
|
||||
unsigned long work;
|
||||
int counter;
|
||||
double result;
|
||||
|
||||
bad = (value->a == 0) && (value->b == 0);
|
||||
if (bad) {
|
||||
return 0.0;
|
||||
} else {
|
||||
result = 0.0;
|
||||
|
||||
work = value->a;
|
||||
if (work != 0) {
|
||||
for (counter = 0; counter < 32; counter++) {
|
||||
result += result;
|
||||
if (work & 0x80000000)
|
||||
result += 1.0;
|
||||
work <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
work = value->b;
|
||||
for (; counter < 32; counter++) {
|
||||
result += result;
|
||||
if (work & 0x80000000)
|
||||
result += 1.0;
|
||||
work <<= 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
double CInt64_ConvertToLongDouble(const CInt64 *value) {
|
||||
CInt64 tmp;
|
||||
if (value->a & 0x80000000) {
|
||||
tmp = CInt64_Neg(*value);
|
||||
return -CInt64_ConvertUToLongDouble(&tmp);
|
||||
} else {
|
||||
return CInt64_ConvertUToLongDouble(value);
|
||||
}
|
||||
}
|
||||
|
||||
char *CInt64_ScanOctString(CInt64 *pResult, char *str, unsigned char *pFail) {
|
||||
int ch;
|
||||
CInt64 tmp;
|
||||
unsigned long a;
|
||||
unsigned long b;
|
||||
|
||||
*pFail = 0;
|
||||
pResult->a = pResult->b = 0;
|
||||
|
||||
while ((ch = *str) >= '0' && *str <= '7') {
|
||||
a = pResult->a;
|
||||
b = pResult->b;
|
||||
if (a & 0xE0000000)
|
||||
*pFail = 1;
|
||||
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
|
||||
pResult->a = a;
|
||||
pResult->b = b;
|
||||
|
||||
CInt64_SetLong(&tmp, ch - '0');
|
||||
*pResult = CInt64_Add(*pResult, tmp);
|
||||
++str;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char *CInt64_ScanDecString(CInt64 *pResult, char *str, unsigned char *pFail) {
|
||||
int ch;
|
||||
CInt64 tmp;
|
||||
unsigned long a;
|
||||
unsigned long b;
|
||||
|
||||
*pFail = 0;
|
||||
pResult->a = pResult->b = 0;
|
||||
|
||||
while ((ch = *str) >= '0' && *str <= '9') {
|
||||
a = pResult->a;
|
||||
b = pResult->b;
|
||||
if (a & 0xE0000000)
|
||||
*pFail = 1;
|
||||
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
tmp.a = a;
|
||||
tmp.b = b;
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
pResult->a = a;
|
||||
pResult->b = b;
|
||||
|
||||
if (CInt64_IsNegative(pResult)) {
|
||||
*pResult = CInt64_Add(*pResult, tmp);
|
||||
if (!CInt64_IsNegative(pResult))
|
||||
*pFail = 1;
|
||||
} else {
|
||||
*pResult = CInt64_Add(*pResult, tmp);
|
||||
}
|
||||
|
||||
CInt64_SetLong(&tmp, ch - '0');
|
||||
if (CInt64_IsNegative(pResult)) {
|
||||
*pResult = CInt64_Add(*pResult, tmp);
|
||||
if (!CInt64_IsNegative(pResult))
|
||||
*pFail = 1;
|
||||
} else {
|
||||
*pResult = CInt64_Add(*pResult, tmp);
|
||||
}
|
||||
|
||||
++str;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char *CInt64_ScanHexString(CInt64 *pResult, char *str, unsigned char *pFail) {
|
||||
/* NOT MATCHING */
|
||||
int digit;
|
||||
CInt64 tmp;
|
||||
unsigned long a;
|
||||
unsigned long b;
|
||||
|
||||
*pFail = 0;
|
||||
pResult->a = pResult->b = 0;
|
||||
|
||||
for (;;) {
|
||||
if ((digit = str[0]) >= '0' && digit <= '9')
|
||||
digit = digit - '0';
|
||||
else if (digit >= 'A' && digit <= 'F')
|
||||
digit = digit - 'A' + 10;
|
||||
else if (digit >= 'a' && digit <= 'f')
|
||||
digit = digit - 'a' + 10;
|
||||
else
|
||||
break;
|
||||
|
||||
a = pResult->a;
|
||||
b = pResult->b;
|
||||
++str;
|
||||
|
||||
if (a & 0xF0000000)
|
||||
*pFail = 1;
|
||||
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
|
||||
pResult->a = a;
|
||||
pResult->b = b;
|
||||
|
||||
CInt64_SetLong(&tmp, (char) digit);
|
||||
*pResult = CInt64_Add(*pResult, tmp);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char *CInt64_ScanBinString(CInt64 *pResult, char *str, unsigned char *pFail) {
|
||||
char digit;
|
||||
unsigned long a;
|
||||
unsigned long b;
|
||||
|
||||
*pFail = 0;
|
||||
pResult->a = pResult->b = 0;
|
||||
|
||||
for (;;) {
|
||||
if (*str == '0')
|
||||
digit = 0;
|
||||
else if (*str == '1')
|
||||
digit = 1;
|
||||
else
|
||||
break;
|
||||
|
||||
a = pResult->a;
|
||||
b = pResult->b;
|
||||
++str;
|
||||
|
||||
if (a & 0x80000000)
|
||||
*pFail = 1;
|
||||
|
||||
SHIFT_LEFT_ONE(a, b);
|
||||
|
||||
pResult->a = a;
|
||||
pResult->b = b;
|
||||
|
||||
if (digit == 1)
|
||||
*pResult = CInt64_Add(*pResult, cint64_one);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, unsigned char *pFail) {
|
||||
unsigned char isMaybeBin;
|
||||
unsigned char isOct;
|
||||
unsigned char isMaybeDec;
|
||||
unsigned char isBin;
|
||||
char *p;
|
||||
|
||||
isMaybeBin = 1;
|
||||
isOct = *str == '0';
|
||||
isMaybeDec = 1;
|
||||
isBin = 0;
|
||||
p = str;
|
||||
|
||||
for (;;) {
|
||||
if (*p == 0)
|
||||
break;
|
||||
|
||||
if (strchr("01", p[0])) {
|
||||
if (isBin)
|
||||
isMaybeBin = 0;
|
||||
} else if (strchr("bB", p[0])) {
|
||||
isBin = 1;
|
||||
isMaybeDec = 0;
|
||||
isOct = 0;
|
||||
} else if (strchr("234567", p[0])) {
|
||||
isMaybeBin = 0;
|
||||
} else if (strchr("89", p[0])) {
|
||||
isOct = 0;
|
||||
isMaybeBin = 0;
|
||||
} else if (strchr("acdefACEDF", p[0])) {
|
||||
isMaybeDec = 0;
|
||||
isMaybeBin = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
if (isMaybeBin && isBin) {
|
||||
return CInt64_ScanBinString(pResult, str, pFail) + 1;
|
||||
} else if (p[0] == 'h' || p[0] == 'H') {
|
||||
return CInt64_ScanHexString(pResult, str, pFail) + 1;
|
||||
} else if (isOct) {
|
||||
return CInt64_ScanOctString(pResult, str, pFail);
|
||||
} else if (isMaybeDec) {
|
||||
return CInt64_ScanDecString(pResult, str, pFail);
|
||||
} else {
|
||||
*pFail = 1;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
int CInt64_PrintDec(char *output, CInt64 value) {
|
||||
int length;
|
||||
CInt64 rem;
|
||||
CInt64 divisor;
|
||||
char buf[40];
|
||||
char *bufp;
|
||||
|
||||
length = 0;
|
||||
if (CInt64_IsNegative(&value)) {
|
||||
value = CInt64_Neg(value);
|
||||
*output = '-';
|
||||
length++;
|
||||
output++;
|
||||
}
|
||||
|
||||
if (!CInt64_IsZero(&value)) {
|
||||
divisor.b = 10;
|
||||
divisor.a = 0;
|
||||
|
||||
bufp = buf;
|
||||
for (;;) {
|
||||
rem = CInt64_ModU(value, divisor);
|
||||
*(bufp++) = rem.b + '0';
|
||||
value = CInt64_DivU(value, divisor);
|
||||
if (CInt64_IsZero(&value) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
while (--bufp >= buf) {
|
||||
*(output++) = *bufp;
|
||||
length++;
|
||||
}
|
||||
} else {
|
||||
*(output++) = '0';
|
||||
length++;
|
||||
}
|
||||
|
||||
*output = 0;
|
||||
return length;
|
||||
}
|
||||
|
||||
int CInt64_PrintHex(char *output, CInt64 value) {
|
||||
int length;
|
||||
CInt64 rem;
|
||||
CInt64 shift;
|
||||
CInt64 mask;
|
||||
char buf[32];
|
||||
char *bufp;
|
||||
|
||||
length = 0;
|
||||
if (!CInt64_IsZero(&value)) {
|
||||
shift.b = 4;
|
||||
shift.a = 0;
|
||||
mask.b = 0xF;
|
||||
mask.a = 0;
|
||||
|
||||
bufp = buf;
|
||||
for (;;) {
|
||||
rem = CInt64_And(value, mask);
|
||||
if ((long) rem.b >= 10)
|
||||
*(bufp++) = rem.b + 'A';
|
||||
else
|
||||
*(bufp++) = rem.b + '0';
|
||||
value = CInt64_ShrU(value, shift);
|
||||
if (CInt64_IsZero(&value) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
while (--bufp >= buf) {
|
||||
*(output++) = *bufp;
|
||||
length++;
|
||||
}
|
||||
} else {
|
||||
*(output++) = '0';
|
||||
length++;
|
||||
}
|
||||
|
||||
*output = 0;
|
||||
return length;
|
||||
}
|
||||
|
||||
int CInt64_PrintBin(char *output, CInt64 value) {
|
||||
int length;
|
||||
CInt64 rem;
|
||||
char buf[64];
|
||||
char *bufp;
|
||||
|
||||
length = 0;
|
||||
if (!CInt64_IsZero(&value)) {
|
||||
bufp = buf;
|
||||
for (;;) {
|
||||
rem = CInt64_And(value, cint64_one);
|
||||
if (CInt64_Equal(rem, cint64_one))
|
||||
*(bufp++) = '1';
|
||||
else
|
||||
*(bufp++) = '0';
|
||||
value = CInt64_ShrU(value, cint64_one);
|
||||
if (CInt64_IsZero(&value) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
while (--bufp >= buf) {
|
||||
*(output++) = *bufp;
|
||||
length++;
|
||||
}
|
||||
} else {
|
||||
*(output++) = '0';
|
||||
length++;
|
||||
}
|
||||
|
||||
*output = 0;
|
||||
return length;
|
||||
}
|
85
CInt64.h
Normal file
85
CInt64.h
Normal file
@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct _CInt64 {
|
||||
long a;
|
||||
unsigned long b;
|
||||
} CInt64;
|
||||
|
||||
// make sure this is in the right place
|
||||
extern const CInt64 cint64_negone;
|
||||
extern const CInt64 cint64_zero;
|
||||
extern const CInt64 cint64_one;
|
||||
extern const CInt64 cint64_max;
|
||||
extern const CInt64 cint64_min;
|
||||
|
||||
inline int CInt64_IsNegative(const CInt64 *n) {
|
||||
return (n->a & 0x80000000) != 0;
|
||||
}
|
||||
inline void CInt64_SetLong(CInt64 *pN, long n) {
|
||||
pN->b = n;
|
||||
pN->a = (n < 0) ? 0xFFFFFFFF : 0;
|
||||
}
|
||||
inline void CInt64_SetULong(CInt64 *pN, unsigned long n) {
|
||||
pN->b = n;
|
||||
pN->a = 0;
|
||||
}
|
||||
|
||||
// i don't think this one is real lol
|
||||
inline int CInt64_IsZero(CInt64 *n) {
|
||||
return n->a == 0 && n->b == 0;
|
||||
}
|
||||
inline void CInt64_Extend32(CInt64 *n) { // assumed name
|
||||
n->a = (n->b >> 31) ? 0xFFFFFFFF : 0;
|
||||
}
|
||||
|
||||
extern void CInt64_Init();
|
||||
extern CInt64 CInt64_Not(CInt64 input);
|
||||
extern CInt64 CInt64_Inv(CInt64 input);
|
||||
extern CInt64 CInt64_Add(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_Neg(CInt64 input);
|
||||
extern CInt64 CInt64_Sub(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_MulU(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_Mul(CInt64 lhs, CInt64 rhs);
|
||||
extern void CInt64_DivMod(const CInt64 *lhs, const CInt64 *rhs, CInt64 *pDiv, CInt64 *pMod);
|
||||
extern CInt64 CInt64_Div(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_DivU(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_Mod(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_ModU(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_Shl(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_Shr(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_ShrU(CInt64 lhs, CInt64 rhs);
|
||||
extern int CInt64_UnsignedCompare(const CInt64 *lhs, const CInt64 *rhs);
|
||||
extern int CInt64_SignedCompare(const CInt64 *lhs, const CInt64 *rhs);
|
||||
extern unsigned char CInt64_Less(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_LessU(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_Greater(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_GreaterU(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_LessEqual(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_LessEqualU(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_Equal(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_NotEqual(CInt64 lhs, CInt64 rhs);
|
||||
extern unsigned char CInt64_IsInRange(CInt64 value, short len);
|
||||
extern unsigned char CInt64_IsInURange(CInt64 value, short len);
|
||||
extern CInt64 CInt64_And(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_Xor(CInt64 lhs, CInt64 rhs);
|
||||
extern CInt64 CInt64_Or(CInt64 lhs, CInt64 rhs);
|
||||
extern void CInt64_ConvertInt32(CInt64 *i);
|
||||
extern void CInt64_ConvertUInt32(CInt64 *i);
|
||||
extern void CInt64_ConvertInt16(CInt64 *i);
|
||||
extern void CInt64_ConvertUInt16(CInt64 *i);
|
||||
extern void CInt64_ConvertInt8(CInt64 *i);
|
||||
extern void CInt64_ConvertUInt8(CInt64 *i);
|
||||
extern void CInt64_ConvertUFromLongDouble(CInt64 *pResult, double value);
|
||||
extern void CInt64_ConvertFromLongDouble(CInt64 *pResult, double value);
|
||||
extern double CInt64_ConvertUToLongDouble(const CInt64 *value);
|
||||
extern double CInt64_ConvertToLongDouble(const CInt64 *value);
|
||||
extern char *CInt64_ScanOctString(CInt64 *pResult, char *str, unsigned char *pFail);
|
||||
extern char *CInt64_ScanDecString(CInt64 *pResult, char *str, unsigned char *pFail);
|
||||
extern char *CInt64_ScanHexString(CInt64 *pResult, char *str, unsigned char *pFail);
|
||||
extern char *CInt64_ScanBinString(CInt64 *pResult, char *str, unsigned char *pFail);
|
||||
extern char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, unsigned char *pFail);
|
||||
extern int CInt64_PrintDec(char *output, CInt64 value);
|
||||
extern int CInt64_PrintHex(char *output, CInt64 value);
|
||||
extern int CInt64_PrintBin(char *output, CInt64 value);
|
1230
CompilerTools.c
Normal file
1230
CompilerTools.c
Normal file
File diff suppressed because it is too large
Load Diff
134
CompilerTools.h
Normal file
134
CompilerTools.h
Normal file
@ -0,0 +1,134 @@
|
||||
#include "mwcc_decomp.h"
|
||||
#pragma once
|
||||
|
||||
extern void CompilerGetPString(short index, unsigned char *str);
|
||||
extern void CompilerGetCString(short index, char *str);
|
||||
extern unsigned char *CTool_CtoPstr(char *input);
|
||||
|
||||
typedef struct _AllocatorBlock {
|
||||
struct _AllocatorBlock *nextBlock;
|
||||
char **handle;
|
||||
long size;
|
||||
long remaining;
|
||||
} AllocatorBlock;
|
||||
|
||||
typedef struct _Allocator {
|
||||
AllocatorBlock *blockList;
|
||||
long paddingSize;
|
||||
AllocatorBlock *lastBlockUsed;
|
||||
void *ptrToFreeArea;
|
||||
long remaining;
|
||||
} Allocator;
|
||||
|
||||
typedef struct _HeapInfo {
|
||||
long _0;
|
||||
long _4;
|
||||
long _8;
|
||||
long xx_C;
|
||||
long _10;
|
||||
long _14;
|
||||
long _18;
|
||||
} HeapInfo;
|
||||
|
||||
typedef struct _StringNode {
|
||||
struct _StringNode *next;
|
||||
long index;
|
||||
short hash;
|
||||
char data[1];
|
||||
} StringNode;
|
||||
|
||||
typedef struct _GList {
|
||||
char **data;
|
||||
long size;
|
||||
long capacity;
|
||||
long expansion;
|
||||
} GList;
|
||||
|
||||
extern long hash_name_id;
|
||||
extern StringNode **name_hash_nodes;
|
||||
extern void (*GListErrorProc)();
|
||||
|
||||
// extern void GListError();
|
||||
extern int InitGList(GList *list, long capacity);
|
||||
extern void FreeGList(GList *list);
|
||||
extern void LockGList(GList *list);
|
||||
extern void UnlockGList(GList *list);
|
||||
extern void ShrinkGList(GList *list);
|
||||
extern void AppendGListData(GList *list, const void *data, long size);
|
||||
extern void AppendGListNoData(GList *list, long size);
|
||||
extern void AppendGListByte(GList *list, char v);
|
||||
extern void AppendGListWord(GList *list, short v);
|
||||
extern void AppendGListTargetEndianWord(GList *list, short v);
|
||||
extern void AppendGListLong(GList *list, long v);
|
||||
extern void AppendGListTargetEndianLong(GList *list, long v);
|
||||
extern void AppendGListID(GList *list, const char *str);
|
||||
extern void AppendGListName(GList *list, const char *str);
|
||||
extern void RemoveGListData(GList *list, long size);
|
||||
extern char GetGListByte(GList *list);
|
||||
extern short GetGListWord(GList *list);
|
||||
extern long GetGListLong(GList *list);
|
||||
extern short GetGListID(GList *list, char *buf);
|
||||
extern void GetGListData(GList *list, char *buf, long size);
|
||||
// extern long hashpjw(const char *str);
|
||||
// extern short PHash(const unsigned char *str);
|
||||
extern short CHash(const char *str);
|
||||
extern StringNode *GetHashNameNode(const char *str);
|
||||
extern StringNode *GetHashNameNodeHash(const char *str, short hash);
|
||||
extern StringNode *GetHashNameNodeHash2(const char *str, short hash);
|
||||
extern StringNode *GetHashNameNodeExport(const char *str);
|
||||
extern long GetHashNameNodeExportID(StringNode *node);
|
||||
extern StringNode *GetHashNameNodeByID(long id);
|
||||
extern void NameHashExportReset();
|
||||
extern void NameHashWriteNameTable(GList *list);
|
||||
extern void NameHashWriteTargetEndianNameTable(GList *list);
|
||||
extern void InitNameHash();
|
||||
|
||||
typedef void (*heaperror_t)();
|
||||
|
||||
extern long CTool_TotalHeapSize();
|
||||
// extern void getheapinfo(HeapInfo *result, Allocator *heap);
|
||||
extern void CTool_GetHeapInfo(HeapInfo *result, unsigned char heapID);
|
||||
// extern void MoreHeapSpace(Allocator *alloc, long size);
|
||||
extern int initheaps(heaperror_t failureCallback);
|
||||
extern int initgheap(heaperror_t failureCallback);
|
||||
extern heaperror_t getheaperror();
|
||||
extern void setheaperror(heaperror_t failureCallback);
|
||||
// extern void relheap(Allocator *alloc);
|
||||
extern void releaseheaps();
|
||||
extern void releasegheap();
|
||||
extern void releaseoheap();
|
||||
extern char *galloc(long size);
|
||||
extern char *lalloc(long size);
|
||||
extern char *aalloc(long size);
|
||||
extern char *oalloc(long size);
|
||||
extern char *balloc(long size);
|
||||
|
||||
extern void locklheap();
|
||||
extern void unlocklheap();
|
||||
extern void freelheap();
|
||||
extern void freeaheap();
|
||||
extern void freeoheap();
|
||||
extern void freebheap();
|
||||
|
||||
extern char *ScanHex(char *str, long *output, Boolean *overflow);
|
||||
extern char *ScanOct(char *str, long *output, Boolean *overflow);
|
||||
extern char *ScanDec(char *str, long *output, Boolean *overflow);
|
||||
|
||||
// extern char *UnmangleClassname(char *work, char **pNameStart, short *pNameLength, char **a4, short *a5, Boolean a6);
|
||||
// extern char *UnmangleAppend(char *src, char srcLen, char **pOutput, short *pOutputLen);
|
||||
extern void OldUnmangle(char *input, char *output, Boolean flag);
|
||||
|
||||
extern short hash(char *str);
|
||||
extern void memclr(void *buffer, long size);
|
||||
extern void memclrw(void *buffer, long size);
|
||||
extern void CToLowercase(char *src, char *dst);
|
||||
extern int getbit(long v);
|
||||
typedef struct {
|
||||
unsigned long a, b;
|
||||
} WtfWord64; // this has to make sense, somehow... but how?
|
||||
extern void CTool_EndianConvertWord64(WtfWord64 value, unsigned long long *p);
|
||||
extern unsigned short CTool_EndianConvertInPlaceWord16Ptr(unsigned short *p);
|
||||
extern unsigned long CTool_EndianConvertInPlaceWord32Ptr(unsigned long *p);
|
||||
extern void CTool_EndianConvertVector128(); // not correct but idc
|
||||
extern StringNode *CTool_GetPathName(const FSSpec *spec, long *mdDat);
|
||||
extern Boolean strcat_safe(char *dst, const char *src, int maxLen);
|
564
Help.c
Normal file
564
Help.c
Normal file
@ -0,0 +1,564 @@
|
||||
#include "mwcc_decomp.h"
|
||||
typedef struct _Side {
|
||||
short offset;
|
||||
short width;
|
||||
char buffer[1024];
|
||||
short bptr;
|
||||
short blen;
|
||||
short indent;
|
||||
short vrow;
|
||||
short vcol;
|
||||
unsigned char atEOL;
|
||||
unsigned char impInd;
|
||||
} Side;
|
||||
|
||||
short helpExtras;
|
||||
unsigned char showedHelp;
|
||||
Side left;
|
||||
Side right;
|
||||
Side all;
|
||||
char **helptext;
|
||||
static char outLine[256];
|
||||
|
||||
static void Help_Output(Side *left, Side *right);
|
||||
static void Help_OutputSingle(Side *all);
|
||||
static void Help_Flush();
|
||||
|
||||
static void Side_Init(Side *s, short offset, short width) {
|
||||
memset(s, 0, sizeof(Side));
|
||||
s->offset = offset;
|
||||
s->width = width;
|
||||
}
|
||||
|
||||
static void Side_Print(Side *s, const char *format, ...) {
|
||||
char c;
|
||||
char *text;
|
||||
char buffer[1024];
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(buffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
text = buffer;
|
||||
while (*text) {
|
||||
if (s->blen < 1024) {
|
||||
c = *(text++);
|
||||
if (c == '~' && *text == '~') {
|
||||
c = *MAINOPTCHAR;
|
||||
text++;
|
||||
}
|
||||
|
||||
s->buffer[(s->bptr + s->blen) & 1023] = c;
|
||||
s->blen++;
|
||||
} else {
|
||||
if (s == &left)
|
||||
Help_Output(&left, &right);
|
||||
else
|
||||
Help_OutputSingle(&all);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Side_NewLine(Side *s) {
|
||||
Side_Print(s, "\n");
|
||||
}
|
||||
|
||||
static void Side_Indent(Side *s, short how) {
|
||||
if ((s->width - s->indent - how) > (parseopts.ioCols / 8))
|
||||
s->indent += how;
|
||||
else if ((s->width - s->indent - 1) > (parseopts.ioCols / 10))
|
||||
s->indent++;
|
||||
}
|
||||
|
||||
static void Side_Outdent(Side *s, short how) {
|
||||
if ((s->width - s->indent) < (parseopts.ioCols / 8))
|
||||
s->indent++;
|
||||
else if (s->indent >= how)
|
||||
s->indent -= how;
|
||||
}
|
||||
|
||||
static unsigned char isBreaker(char c) {
|
||||
return (c == 10) || (c == 13) || (c == 32) || (c == 9) || (c == 8) || (c == '|');
|
||||
}
|
||||
|
||||
static void Side_DumpLine(Side *s) {
|
||||
short col;
|
||||
short len;
|
||||
short afterspace;
|
||||
short eol;
|
||||
short ind;
|
||||
char c;
|
||||
|
||||
eol = 0;
|
||||
ind = 0;
|
||||
col = s->offset + s->indent;
|
||||
s->vcol = s->indent;
|
||||
len = 0;
|
||||
afterspace = s->width - s->indent;
|
||||
|
||||
while (s->blen > 0 && s->vcol < s->width && !eol && !ind) {
|
||||
c = s->buffer[s->bptr];
|
||||
outLine[col + len] = c;
|
||||
s->vcol++;
|
||||
len++;
|
||||
|
||||
if (isBreaker(c)) {
|
||||
afterspace = len;
|
||||
eol = (c == '\n') || (c == '\r');
|
||||
eol += (c == '\r');
|
||||
ind = (c == '\b') || (c == '\t');
|
||||
ind += (c == '\b');
|
||||
}
|
||||
|
||||
s->bptr = (s->bptr + 1) & 1023;
|
||||
s->blen--;
|
||||
}
|
||||
|
||||
if (s->blen || eol || ind) {
|
||||
s->blen += len - afterspace;
|
||||
s->bptr = (s->bptr - (len - afterspace)) & 1023;
|
||||
if (eol || ind) {
|
||||
len++;
|
||||
afterspace--;
|
||||
}
|
||||
|
||||
while (len > afterspace) {
|
||||
outLine[col + --len] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
s->vcol = 0;
|
||||
s->vrow++;
|
||||
s->atEOL = (eol == 1) || ind || !s->blen;
|
||||
if ((s->atEOL || ind) && s->impInd) {
|
||||
Side_Outdent(s, parseopts.ioCols / 40);
|
||||
s->impInd = 0;
|
||||
}
|
||||
if (ind) {
|
||||
if (ind == 1)
|
||||
Side_Indent(s, parseopts.ioCols / 25);
|
||||
else
|
||||
Side_Outdent(s, parseopts.ioCols / 25);
|
||||
} else if (!s->atEOL && s != &all && !s->impInd) {
|
||||
Side_Indent(s, parseopts.ioCols / 40);
|
||||
s->impInd = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void Help_PrintLine() {
|
||||
HPrintF(helptext, "%.*s\n", parseopts.ioCols - 1, outLine);
|
||||
}
|
||||
|
||||
static void Help_Output(Side *left, Side *right) {
|
||||
while (left->blen || right->blen) {
|
||||
memset(outLine, ' ', parseopts.ioCols);
|
||||
outLine[left->offset + left->width + 1] = '#';
|
||||
if (left->atEOL && right->atEOL)
|
||||
left->atEOL = right->atEOL = 0;
|
||||
if (!left->atEOL)
|
||||
Side_DumpLine(left);
|
||||
if (!right->atEOL)
|
||||
Side_DumpLine(right);
|
||||
Help_PrintLine();
|
||||
}
|
||||
}
|
||||
|
||||
static void Help_OutputSingle(Side *all) {
|
||||
while (all->blen) {
|
||||
memset(outLine, ' ', parseopts.ioCols);
|
||||
if (all->atEOL)
|
||||
all->atEOL = 0;
|
||||
if (!all->atEOL)
|
||||
Side_DumpLine(all);
|
||||
Help_PrintLine();
|
||||
}
|
||||
}
|
||||
|
||||
static void Help_Flush() {
|
||||
Help_Output(&left, &right);
|
||||
}
|
||||
|
||||
static void Help_NewLine() {
|
||||
Side_NewLine(&left);
|
||||
Side_NewLine(&right);
|
||||
}
|
||||
|
||||
int Help_Option(struct OptionList *lst, struct Option *opt, int subprint, const char *keyword) {
|
||||
char pfbuf[512];
|
||||
char slflags;
|
||||
int listFlags;
|
||||
Boolean allNoArgs;
|
||||
PARAM_T *lastparam;
|
||||
Boolean print;
|
||||
Boolean printMe;
|
||||
|
||||
if (!opt->names[0] && !(lst->flags & LISTFLAGS_4))
|
||||
return 0;
|
||||
|
||||
if (keyword && keyword[0] && !strstr(opt->names, keyword) && (!opt->help || !strstr(opt->help, keyword)))
|
||||
return 0;
|
||||
|
||||
if ((opt->avail & OTF_SECRET) && !(parseopts.helpFlags & HELPFLAGS_SECRET))
|
||||
return 0;
|
||||
|
||||
if ((opt->avail & OTF_OBSOLETE) && !(parseopts.helpFlags & HELPFLAGS_OBSOLETE))
|
||||
return 0;
|
||||
|
||||
if ((opt->avail & OTF_DEPRECATED) && !(parseopts.helpFlags & HELPFLAGS_DEPRECATED))
|
||||
return 0;
|
||||
|
||||
if ((opt->avail & OTF_IGNORED) && !(parseopts.helpFlags & HELPFLAGS_IGNORED))
|
||||
return 0;
|
||||
|
||||
if ((opt->avail & OTF_MEANINGLESS) && !(parseopts.helpFlags & HELPFLAGS_MEANINGLESS))
|
||||
return 0;
|
||||
|
||||
if (!(parseopts.helpFlags & HELPFLAGS_NORMAL) && !(opt->avail & OTF_ALL_HIDDEN_BY_DEFAULT))
|
||||
return 0;
|
||||
|
||||
if (opt->help || (opt->avail & OTF8000)) {
|
||||
allNoArgs = 1;
|
||||
lastparam = 0;
|
||||
if (parseopts.helpFlags & HELPFLAGS_SPACES)
|
||||
Help_NewLine();
|
||||
if ((opt->avail & OTF_GLOBAL) && !subprint)
|
||||
Side_Print(&right, "global; ");
|
||||
if (compat != 1 && (opt->avail & OTF_CASED))
|
||||
Side_Print(&right, "cased; ");
|
||||
|
||||
slflags = (subprint == 0) ? SLFLAGS_1 : SLFLAGS_2;
|
||||
switch (opt->avail & OTF_SLFLAGS_MASK) {
|
||||
case OTF_SLFLAGS_8:
|
||||
slflags = slflags | SLFLAGS_8;
|
||||
break;
|
||||
case OTF_SLFLAGS_10:
|
||||
slflags = slflags | SLFLAGS_10;
|
||||
break;
|
||||
case OTF_SLFLAGS_20:
|
||||
slflags = slflags | SLFLAGS_20;
|
||||
break;
|
||||
}
|
||||
if (opt->avail & OTF2)
|
||||
slflags = slflags | SLFLAGS_40;
|
||||
|
||||
Utils_SpellList(opt->names[0] ? opt->names : "...", pfbuf, slflags);
|
||||
Side_Print(&left, pfbuf);
|
||||
|
||||
if (opt->avail & OTF_OBSOLETE)
|
||||
Side_Print(&right, "obsolete;\r");
|
||||
if (opt->avail & OTF_COMPATIBILITY)
|
||||
Side_Print(&right, "compatibility;\r");
|
||||
if (opt->avail & OTF_IGNORED)
|
||||
Side_Print(&right, "ignored;\r");
|
||||
|
||||
listFlags = ((lst->flags & LISTFLAGS_COMPILER) ? OTF_TOOL_COMPILER : 0) | ((lst->flags & LISTFLAGS_LINKER) ? OTF_TOOL_LINKER : 0) | ((lst->flags & LISTFLAGS_DISASSEMBLER) ? OTF_TOOL_DISASSEMBLER : 0);
|
||||
if (!Option_ForThisTool(opt) || Option_AlsoPassedFromThisTool(opt) || listFlags != Option_ThisTool()) {
|
||||
print = 0;
|
||||
printMe = 1;
|
||||
if ((opt->avail & OTF_TOOL_MASK) != (unsigned int) listFlags)
|
||||
print = 1;
|
||||
if (Option_ForThisTool(opt) && Option_AlsoPassedFromThisTool(opt))
|
||||
printMe = 0;
|
||||
|
||||
if (print) {
|
||||
char opttool[64] = ""; // stack 0x44
|
||||
if ((opt->avail & OTF_TOOL_MASK) == (unsigned int) OTF_TOOL_MASK) {
|
||||
strcat(opttool, "all tools");
|
||||
} else {
|
||||
if (Option_ForTool(opt, OTF_TOOL_COMPILER) && ((Option_ThisTool() != (unsigned int) OTF_TOOL_COMPILER) || printMe)) {
|
||||
strcat(opttool, "this tool");
|
||||
}
|
||||
if (Option_ForTool(opt, OTF_TOOL_LINKER) && ((Option_ThisTool() != (unsigned int) OTF_TOOL_LINKER) || printMe)) {
|
||||
if (opttool[0])
|
||||
strcat(opttool, ", ");
|
||||
strcat(opttool, "linker");
|
||||
}
|
||||
if (Option_ForTool(opt, OTF_TOOL_DISASSEMBLER) && ((Option_ThisTool() != (unsigned int) OTF_TOOL_DISASSEMBLER) || printMe)) {
|
||||
if (opttool[0])
|
||||
strcat(opttool, ", ");
|
||||
strcat(opttool, "disassembler");
|
||||
}
|
||||
if (!Option_ForTool(opt, OTF_TOOL_MASK))
|
||||
strcat(opttool, "another tool");
|
||||
}
|
||||
|
||||
if (printMe || !Option_ForThisTool(opt)) {
|
||||
Side_Print(&right, "for %s;\r", opttool);
|
||||
} else if (parseopts.passingArgs) {
|
||||
Side_Print(&right, "passed to %s;\r", opttool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opt->avail & OTF_WARNING)
|
||||
Side_Print(&right, "warning:\r");
|
||||
|
||||
if (opt->avail & OTF_DEPRECATED)
|
||||
Side_Print(&right, "deprecated;\rinstead use ");
|
||||
else if (opt->avail & OTF_SUBSTITUTED)
|
||||
Side_Print(&right, "substituted with ");
|
||||
|
||||
if (opt->help)
|
||||
Side_Print(&right, "%s", opt->help);
|
||||
|
||||
if (opt->param && !(opt->avail & OTF_IGNORED)) {
|
||||
PARAM_T *scan = opt->param;
|
||||
PARAM_T *firstparam = 0;
|
||||
const char *desc;
|
||||
const char *help;
|
||||
const char *defaul;
|
||||
while (scan) {
|
||||
if ((scan->flags & PARAMFLAGS_3) != PARAMFLAGS_1) {
|
||||
if (!firstparam)
|
||||
firstparam = scan;
|
||||
|
||||
allNoArgs = 0;
|
||||
Param_DescHelp(scan, &desc, &help, &defaul);
|
||||
if (desc) {
|
||||
if (((scan->flags & PARAMFLAGS_3) == PARAMFLAGS_2) && scan->which != PARAMWHICH_Setting && scan->which != PARAMWHICH_IfArg) {
|
||||
if (SEPOPTSTR[0] == ' ') {
|
||||
Side_Print(&left, (scan != firstparam) ? "[," : subprint ? "[=" : " [");
|
||||
} else {
|
||||
Side_Print(&left, "[%s", (scan != firstparam) ? "," : subprint ? "=" : SEPOPTSTR);
|
||||
}
|
||||
} else {
|
||||
Side_Print(&left, (scan != firstparam) ? "," : subprint ? "=" : ((opt->avail & OTF2) && !strchr(opt->names, '|')) ? "" : SEPOPTSTR);
|
||||
}
|
||||
Side_Print(&left, "%s", desc);
|
||||
if (((scan->flags & PARAMFLAGS_3) == PARAMFLAGS_2) && scan->which != PARAMWHICH_Setting && scan->which != PARAMWHICH_IfArg) {
|
||||
Side_Print(&left, "]");
|
||||
}
|
||||
if (help) {
|
||||
if ((scan->flags & PARAMFLAGS_3) != PARAMFLAGS_2)
|
||||
Side_Print(&right, "; for '%s', %s", desc, help);
|
||||
else
|
||||
Side_Print(&right, "; if parameter specified, %s", help);
|
||||
}
|
||||
if (defaul && !(opt->avail & OTF2000)) {
|
||||
if (firstparam == scan)
|
||||
Side_Print(&right, "; default is %s", defaul);
|
||||
else
|
||||
Side_Print(&right, ",%s", defaul);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastparam = scan;
|
||||
scan = scan->next;
|
||||
}
|
||||
|
||||
if (allNoArgs && !(opt->avail & OTF2000)) {
|
||||
PARAM_T *scan = opt->param;
|
||||
Boolean isdefault = scan ? 1 : 0;
|
||||
while (scan && isdefault) {
|
||||
isdefault &= Param_Compare(scan);
|
||||
scan = scan->next;
|
||||
}
|
||||
|
||||
if (isdefault)
|
||||
Side_Print(&right, "; default");
|
||||
}
|
||||
}
|
||||
|
||||
if (opt->avail & OTF_MEANINGLESS)
|
||||
Side_Print(&right, "; meaningless for this target");
|
||||
|
||||
if ((opt->avail & OTF8000) && opt->sub) {
|
||||
if (!allNoArgs) {
|
||||
Side_Print(
|
||||
&left,
|
||||
"%s",
|
||||
(opt->avail & OTF10000) ? ((lastparam->flags & PARAMFLAGS_8) ? "[=" : "[,") : ((lastparam->flags & PARAMFLAGS_8) ? "," : "=")
|
||||
);
|
||||
} else if (!(opt->avail & OTF2)) {
|
||||
if (opt->avail & OTF10000) {
|
||||
if (SEPOPTSTR[0] == ' ')
|
||||
Side_Print(&left, subprint ? "[=" : " [");
|
||||
else
|
||||
Side_Print(&left, "[%s", subprint ? "=" : SEPOPTSTR);
|
||||
} else {
|
||||
Side_Print(&left, "%c", subprint ? '=' : SEPOPTSTR[0]);
|
||||
}
|
||||
} else {
|
||||
if (opt->avail & OTF10000) {
|
||||
Side_Print(&left, subprint ? "[" : (SEPOPTSTR[0] == ' ') ? " [" : "[");
|
||||
}
|
||||
}
|
||||
|
||||
Side_Print(
|
||||
&left,
|
||||
"%s%s%s",
|
||||
opt->sub->help ? opt->sub->help : "keyword",
|
||||
(opt->sub->flags & PARAMFLAGS_1) ? "" : "[,...]",
|
||||
(opt->avail & OTF10000) ? "]" : ""
|
||||
);
|
||||
|
||||
Side_Print(&left, "\t");
|
||||
Side_Print(&right, "\t");
|
||||
Help_Options(opt->sub, 1, "");
|
||||
Side_Print(&left, "\b");
|
||||
Side_Print(&right, "\b");
|
||||
} else {
|
||||
Side_Print(&left, "\n");
|
||||
Side_Print(&right, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
Help_Flush();
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int IsCompiler() {
|
||||
return (Option_ThisTool() == (unsigned int) OTF_TOOL_COMPILER) ? LISTFLAGS_COMPILER : LISTFLAGS_LINKER;
|
||||
}
|
||||
|
||||
void Help_Options(struct OptionList *lst, int subprint, const char *keyword) {
|
||||
Option **opts;
|
||||
int toolflags;
|
||||
Boolean show;
|
||||
|
||||
opts = lst->list;
|
||||
toolflags = 0;
|
||||
if (Option_ThisTool() == (unsigned int) OTF_TOOL_COMPILER) {
|
||||
toolflags |= LISTFLAGS_COMPILER;
|
||||
} else {
|
||||
toolflags |= LISTFLAGS_LINKER;
|
||||
}
|
||||
|
||||
// review me maybe?
|
||||
if (!subprint && (parseopts.helpFlags & HELPFLAGS_TOOL)) {
|
||||
if ((parseopts.helpFlags & HELPFLAGS_TOOL_BOTH) == HELPFLAGS_TOOL_THIS && (lst->flags & LISTFLAGS_TOOL_MASK) && !(lst->flags & toolflags))
|
||||
return;
|
||||
if ((parseopts.helpFlags & HELPFLAGS_TOOL_BOTH) == HELPFLAGS_TOOL_OTHER && (((lst->flags & LISTFLAGS_TOOL_MASK) == (unsigned int) toolflags) || ((lst->flags & LISTFLAGS_TOOL_MASK) == (unsigned int) LISTFLAGS_NONE)))
|
||||
return;
|
||||
}
|
||||
|
||||
if (lst->help && !subprint && opts[0]) {
|
||||
Help_Line('-');
|
||||
Side_Print(&all, "%s", lst->help);
|
||||
Help_OutputSingle(&all);
|
||||
Help_Line('-');
|
||||
}
|
||||
|
||||
while (*opts) {
|
||||
show = 0;
|
||||
if (!(parseopts.helpFlags & HELPFLAGS_TOOL)) {
|
||||
if (((parseopts.helpFlags & HELPFLAGS_TOOL_BOTH) == HELPFLAGS_TOOL_BOTH) && (parseopts.passingArgs ? (Option_ForTool(*opts, OTF_TOOL_LINKER) || Option_ForTool(*opts, OTF_TOOL_DISASSEMBLER)) : 1) && Option_ForThisTool(*opts))
|
||||
show = 1;
|
||||
} else if ((parseopts.helpFlags & HELPFLAGS_TOOL_BOTH) == HELPFLAGS_TOOL_BOTH) {
|
||||
show = 1;
|
||||
} else if ((parseopts.helpFlags & HELPFLAGS_TOOL_THIS) && Option_ForThisTool(*opts)) {
|
||||
show = 1;
|
||||
} else if ((parseopts.helpFlags & HELPFLAGS_TOOL_OTHER) && !Option_ForThisTool(*opts)) {
|
||||
show = 1;
|
||||
} else if ((parseopts.helpFlags & HELPFLAGS_TOOL_OTHER) && Option_ForTool(*opts, ~Option_ThisTool() & OTF_TOOL_MASK)) {
|
||||
show = 1;
|
||||
}
|
||||
|
||||
if (show)
|
||||
Help_Option(lst, *opts, subprint, keyword);
|
||||
|
||||
++opts;
|
||||
}
|
||||
|
||||
if (subprint && (parseopts.helpFlags & HELPFLAGS_SPACES))
|
||||
Help_NewLine();
|
||||
Help_Flush();
|
||||
if (!subprint)
|
||||
HPrintF(helptext, "\n");
|
||||
}
|
||||
|
||||
void Help_Usage() {
|
||||
Side_Print(
|
||||
&all,
|
||||
"\tGuide to help:\b"
|
||||
"\tWhen an option is specified as '~~xxx | yy[y] | zzz', then either '~~xxx', '~~yy', '~~yyy', or '~~zzz' matches the option.\b"
|
||||
"\tAn option given as '~~[no]xxx' may be given as '~~xxx' or '~~noxxx'; '~~noxxx' reverses the meaning of the option.\b"
|
||||
);
|
||||
Help_OutputSingle(&all);
|
||||
|
||||
Side_Print(
|
||||
&all,
|
||||
"\tFor most options, the option and the parameters are separated by a %sspace. When the option's name is '~~xxx+', however, the parameter must directly follow the option, without the '+' (as in '~~xxx45').\b",
|
||||
(compat != 1) ? "" : "colon or "
|
||||
);
|
||||
Side_Print(
|
||||
&all,
|
||||
"\tA parameter included in brackets '[]' is optional. An ellipsis '...' indicates that the previous type of parameter may be repeated as a list.\b"
|
||||
);
|
||||
Help_OutputSingle(&all);
|
||||
|
||||
Side_Print(
|
||||
&all,
|
||||
"\t%s-- \"compatability\" indicates that the option is borrowed from another vendor's tool and may only approximate its counterpart.\r"
|
||||
"-- \"global\" indicates that the option has an effect over the entire command line and is parsed before any other options. When several global options are specified, they are interpreted in order.\r"
|
||||
"-- \"deprecated\" indicates that the option will be eliminated in the future and should not be used any longer. An alternative form is supplied.\r",
|
||||
(compat != 1) ? "-- \"cased\" indicates that the option is case-sensitive. By default, no options are case-sensitive.\r" : "");
|
||||
Help_OutputSingle(&all);
|
||||
|
||||
Side_Print(
|
||||
&all,
|
||||
"-- \"ignored\" means the option will be accepted but has no effect on the tool.\r"
|
||||
"-- \"meaningless\" means the option is accepted but probably has no meaning for the target OS.\r"
|
||||
"-- \"obsolete\" means the option was once deprecated and is now gone.\r"
|
||||
"-- \"substituted\" means the option has the same effect as another. This points out a preferred form and prevents confusion when similar options appear in the help.\r"
|
||||
"-- \"default\" in the help text indicates that the given value or variation of an option will be used unless otherwise overridden. \b"
|
||||
);
|
||||
Help_OutputSingle(&all);
|
||||
|
||||
Side_Print(
|
||||
&all,
|
||||
"\tThe symbols ',' %s separate options and parameters unconditionally; to include one of these symbols in a parameter or filename, escape it (e.g., as '\\,' in mwcc file.c\\,v).\b\n",
|
||||
(compat != 1) ? "and '='" : ", ':', and '='"
|
||||
);
|
||||
Help_OutputSingle(&all);
|
||||
|
||||
if (parseopts.passingArgs && pTool->TYPE == CWDROPINCOMPILERTYPE)
|
||||
Side_Print(
|
||||
&all,
|
||||
"\tThis tool calls the linker (unless a compiler option such as ~~c prevents it) and understands linker options -- use '~~help tool=other' to see them. Options marked \"passed to linker\" are used by the compiler and the linker; options marked \"for linker\" are used only by the linker. When using the compiler and linker separately, you must pass the common options to both.\b\n"
|
||||
);
|
||||
Help_OutputSingle(&all);
|
||||
}
|
||||
|
||||
void Help_Null() {
|
||||
Side_Print(&all,
|
||||
"%s [options, filenames...]\n\nExecute '%s %shelp' for more information.",
|
||||
OS_GetFileNamePtr(parseopts.args->argv[0]),
|
||||
OS_GetFileNamePtr(parseopts.args->argv[0]),
|
||||
MAINOPTCHAR
|
||||
);
|
||||
Help_OutputSingle(&all);
|
||||
}
|
||||
|
||||
void Help_Init() {
|
||||
short lb;
|
||||
short le;
|
||||
short rb;
|
||||
short re;
|
||||
|
||||
if (!(helptext = NewHandle(0))) {
|
||||
fprintf(stderr, "\n*** Out of memory\n");
|
||||
exit(-23);
|
||||
}
|
||||
|
||||
lb = parseopts.ioCols / 40;
|
||||
le = (parseopts.ioCols / 3) + lb;
|
||||
rb = le + 3 + ((parseopts.ioCols / 60) & ~1);
|
||||
re = parseopts.ioCols - 1;
|
||||
Side_Init(&left, lb, le - lb);
|
||||
Side_Init(&right, rb, re - rb);
|
||||
Side_Init(&all, 0, re);
|
||||
}
|
||||
|
||||
void Help_Line(char ch) {
|
||||
char line[256];
|
||||
memset(line, ch, 255);
|
||||
line[255] = 0;
|
||||
HPrintF(helptext, "%.*s\n", parseopts.ioCols - 1, line);
|
||||
}
|
||||
|
||||
void Help_Term() {
|
||||
ShowTextHandle(0, helptext);
|
||||
DisposeHandle(helptext);
|
||||
}
|
630
Option.c
Normal file
630
Option.c
Normal file
@ -0,0 +1,630 @@
|
||||
#include "mwcc_decomp.h"
|
||||
|
||||
#define OPTION_ASSERT(cond) do { if (!(cond)) { printf("%s:%u: failed assertion\n", __FILE__, __LINE__); abort(); } } while(0)
|
||||
|
||||
#define MAXSTACK 8
|
||||
|
||||
int oStackPtr;
|
||||
Opt48 oStack[8];
|
||||
char curopt[1024];
|
||||
int maxlegalset;
|
||||
int numlegalset;
|
||||
int numinternalset;
|
||||
static OptionList legalset;
|
||||
static OptionList internalset;
|
||||
int numoptionlists;
|
||||
static OptionList *optionlists[32];
|
||||
|
||||
enum {
|
||||
ARGFLAG_1 = 1,
|
||||
ARGFLAG_2 = 2,
|
||||
ARGFLAG_4 = 4,
|
||||
ARGFLAG_8 = 8,
|
||||
ARGFLAG_10 = 0x10,
|
||||
ARGFLAG_20 = 0x20,
|
||||
ARGFLAG_40 = 0x40,
|
||||
ARGFLAG_80 = 0x80
|
||||
};
|
||||
|
||||
enum {
|
||||
ARGSPELLFLAG_1 = 1,
|
||||
ARGSPELLFLAG_2 = 2,
|
||||
ARGSPELLFLAG_4 = 4,
|
||||
ARGSPELLFLAG_8 = 8,
|
||||
ARGSPELLFLAG_10 = 0x10,
|
||||
ARGSPELLFLAG_20 = 0x20,
|
||||
ARGSPELLFLAG_40 = 0x40,
|
||||
ARGSPELLFLAG_80 = 0x80
|
||||
};
|
||||
|
||||
enum {
|
||||
OPTSPELLFLAG_1 = 1,
|
||||
OPTSPELLFLAG_2 = 2,
|
||||
OPTSPELLFLAG_4 = 4,
|
||||
OPTSPELLFLAG_8 = 8,
|
||||
OPTSPELLFLAG_10 = 0x10,
|
||||
OPTSPELLFLAG_20 = 0x20,
|
||||
OPTSPELLFLAG_40 = 0x40,
|
||||
OPTSPELLFLAG_80 = 0x80
|
||||
};
|
||||
|
||||
static void Option_PushList(OptionList *lst) {
|
||||
Args_Push(1, lst, 0);
|
||||
}
|
||||
|
||||
static void Option_PushOpt(Option *opt, const char *optname) {
|
||||
char *cpy;
|
||||
short flags = ARGFLAG_2;
|
||||
if (opt && (opt->avail & OTF2)) {
|
||||
if (Utils_CompareOptionString(opt->names, optname, opt->avail & OTF_CASED, OTF2)) {
|
||||
flags |= ARGFLAG_80;
|
||||
}
|
||||
}
|
||||
cpy = xstrdup(optname);
|
||||
Args_Push(flags, opt, cpy);
|
||||
}
|
||||
|
||||
static void Option_PopOpt(char *optname) {
|
||||
Opt48 *os = Args_Pop(ARGFLAG_2);
|
||||
if (optname)
|
||||
strcpy(optname, os->e.o.curopt);
|
||||
free(os->e.o.curopt);
|
||||
}
|
||||
|
||||
static void Option_PopList() {
|
||||
Args_Pop(ARGFLAG_1);
|
||||
}
|
||||
|
||||
void Args_InitStack() {
|
||||
oStackPtr = 0;
|
||||
}
|
||||
int Args_StackSize() {
|
||||
return oStackPtr;
|
||||
}
|
||||
|
||||
void Args_Push(short flags, void *first, void *second) {
|
||||
#line 104
|
||||
OPTION_ASSERT(oStackPtr<MAXSTACK);
|
||||
if (oStackPtr > 0)
|
||||
{
|
||||
short prev =
|
||||
(flags & ARGFLAG_1) ? ARGFLAG_2 :
|
||||
(flags & ARGFLAG_2) ? ARGFLAG_1 :
|
||||
(flags & ARGFLAG_4) ? ARGFLAG_2 : -1;
|
||||
OPTION_ASSERT(oStack[oStackPtr-1].flags & prev);
|
||||
}
|
||||
|
||||
oStack[oStackPtr].e.v.first = first;
|
||||
oStack[oStackPtr].e.v.second = second;
|
||||
oStack[oStackPtr].flags = flags;
|
||||
oStackPtr++;
|
||||
}
|
||||
|
||||
Opt48 *Args_Pop(short flags)
|
||||
{
|
||||
OPTION_ASSERT(oStackPtr>0);
|
||||
--oStackPtr;
|
||||
OPTION_ASSERT(oStack[oStackPtr].flags & flags);
|
||||
return &oStack[oStackPtr];
|
||||
}
|
||||
|
||||
void Args_SpellStack(char *buffer, short flags) {
|
||||
char *bptr;
|
||||
Opt48 *os;
|
||||
int sp;
|
||||
int level;
|
||||
|
||||
bptr = buffer;
|
||||
sp = 0;
|
||||
level = 0;
|
||||
os = &oStack[sp];
|
||||
|
||||
while (sp < oStackPtr) {
|
||||
if (!flags || !(os->flags & ARGFLAG_20)) {
|
||||
if (os->flags & ARGFLAG_4) {
|
||||
Opt48 *po = os - 1;
|
||||
if (!(os[-1].flags & ARGFLAG_40)) {
|
||||
if ((level == 1 || level == 2) && !(po->flags & ARGFLAG_80))
|
||||
*(bptr++) = (flags & ARGSPELLFLAG_20) ? '\n' : ' ';
|
||||
os[-1].flags |= ARGFLAG_40;
|
||||
} else if (level == 2) {
|
||||
*(bptr++) = ',';
|
||||
} else if (level == 3) {
|
||||
*(bptr++) = '=';
|
||||
}
|
||||
strcpy(bptr, os->e.param);
|
||||
bptr += strlen(bptr);
|
||||
} else if (os->flags & ARGFLAG_2) {
|
||||
if (level == 1) {
|
||||
*(bptr++) = MAINOPTCHAR[0];
|
||||
} else if (level == 2) {
|
||||
Opt48 *po = os - 2;
|
||||
if (!(os[-1].flags & ARGFLAG_40) && !(po->flags & ARGFLAG_80))
|
||||
*(bptr++) = (flags & ARGSPELLFLAG_20) ? '\n' : ' ';
|
||||
}
|
||||
|
||||
if (os[-1].flags & ARGFLAG_40) {
|
||||
if (level == 2) {
|
||||
if (flags & ARGSPELLFLAG_20)
|
||||
*(bptr++) = ',';
|
||||
else
|
||||
*(bptr++) = ' ';
|
||||
}
|
||||
} else {
|
||||
if (level == 3) {
|
||||
*(bptr++) = '=';
|
||||
}
|
||||
}
|
||||
|
||||
os[-1].flags |= ARGFLAG_40;
|
||||
strcpy(bptr, os->e.o.curopt);
|
||||
bptr += strlen(bptr);
|
||||
}
|
||||
|
||||
if (flags & ARGSPELLFLAG_20)
|
||||
os->flags |= ARGFLAG_20;
|
||||
}
|
||||
|
||||
if (os->flags & ARGFLAG_1)
|
||||
level++;
|
||||
|
||||
++sp;
|
||||
++os;
|
||||
}
|
||||
}
|
||||
|
||||
void Args_AddToToolArgs(anon0_50 *ta) {
|
||||
char buffer[4096];
|
||||
char *nptr;
|
||||
|
||||
Args_SpellStack(buffer, ARGSPELLFLAG_20);
|
||||
nptr = strchr(buffer, '\n');
|
||||
if (nptr) {
|
||||
*(nptr++) = 0;
|
||||
Arg_AddToToolArgs(ta, 2, buffer);
|
||||
Arg_AddToToolArgs(ta, 1, 0);
|
||||
} else {
|
||||
nptr = buffer;
|
||||
}
|
||||
Arg_AddToToolArgs(ta, 2, nptr);
|
||||
}
|
||||
|
||||
void Options_Init() {
|
||||
numoptionlists = 0;
|
||||
maxlegalset = 0;
|
||||
numlegalset = 0;
|
||||
numinternalset = 0;
|
||||
|
||||
if (legalset.list)
|
||||
free(legalset.list);
|
||||
if (internalset.list)
|
||||
free(internalset.list);
|
||||
|
||||
legalset.list = 0;
|
||||
legalset.flags =
|
||||
((Option_ThisTool() & OTF_TOOL_COMPILER) ? LISTFLAGS_COMPILER : 0) |
|
||||
((Option_ThisTool() & OTF_TOOL_LINKER) ? LISTFLAGS_LINKER : 0) |
|
||||
((Option_ThisTool() & OTF_TOOL_DISASSEMBLER) ? LISTFLAGS_DISASSEMBLER : 0);
|
||||
internalset.list = 0;
|
||||
internalset.flags =
|
||||
((Option_ThisTool() & OTF_TOOL_COMPILER) ? LISTFLAGS_COMPILER : 0) |
|
||||
((Option_ThisTool() & OTF_TOOL_LINKER) ? LISTFLAGS_LINKER : 0) |
|
||||
((Option_ThisTool() & OTF_TOOL_DISASSEMBLER) ? LISTFLAGS_DISASSEMBLER : 0);
|
||||
|
||||
Args_InitStack();
|
||||
}
|
||||
|
||||
OptionList *Options_GetOptions() {
|
||||
return &legalset;
|
||||
}
|
||||
|
||||
void Options_SortOptions() {
|
||||
int r;
|
||||
|
||||
if (numinternalset > 0) {
|
||||
legalset.list = (Option **) xrealloc("options", legalset.list, sizeof(Option *) * (numinternalset + 1));
|
||||
for (r = 0; r < numinternalset; r++) {
|
||||
if (internalset.list[r]->avail & (OTF2 | OTF_CASED))
|
||||
legalset.list[numlegalset++] = internalset.list[r];
|
||||
}
|
||||
for (r = 0; r < numinternalset; r++) {
|
||||
if (!(internalset.list[r]->avail & (OTF2 | OTF_CASED)))
|
||||
legalset.list[numlegalset++] = internalset.list[r];
|
||||
}
|
||||
legalset.list[numlegalset] = 0;
|
||||
|
||||
if (internalset.list)
|
||||
free(internalset.list);
|
||||
internalset.list = 0;
|
||||
numinternalset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void Options_AddOption(Option *opt) {
|
||||
if (numinternalset >= maxlegalset) {
|
||||
maxlegalset += 32;
|
||||
internalset.list = (Option **) xrealloc("options", internalset.list, sizeof(Option *) * (maxlegalset + 1));
|
||||
}
|
||||
|
||||
internalset.list[numinternalset++] = opt;
|
||||
internalset.list[numinternalset] = 0;
|
||||
}
|
||||
|
||||
int Options_AddList(OptionList *optlst) {
|
||||
Option **ptr;
|
||||
|
||||
if (numoptionlists >= 32)
|
||||
CLPFatalError("Too many option lists defined!");
|
||||
|
||||
optionlists[numoptionlists++] = optlst;
|
||||
for (ptr = optlst->list; *ptr; ptr++)
|
||||
Options_AddOption(*ptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Options_AddLists(OptionList **optlst) {
|
||||
int ret = 1;
|
||||
OptionList **ptr;
|
||||
|
||||
for (ptr = optlst; *ptr; ptr++) {
|
||||
ret = Options_AddList(*ptr);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void Options_Reset(OptionList *optlst) {
|
||||
Option **os;
|
||||
|
||||
os = optlst->list;
|
||||
if (os) {
|
||||
for (; *os; os++) {
|
||||
(*os)->avail &= ~(OTF80000000 | OTF40000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Option_SpellList(char *buffer, OptionList *conflicts, int flags) {
|
||||
// r25: buffer
|
||||
// r0: conflicts
|
||||
// r26: flags
|
||||
|
||||
Option **scan; // r30
|
||||
Boolean first; // r29
|
||||
int total; // r28
|
||||
char tmp[256]; // stack 0x58
|
||||
Option **next; // r27
|
||||
int slflags; // r6
|
||||
|
||||
scan = conflicts->list;
|
||||
first = 1;
|
||||
total = 0;
|
||||
while (*scan) {
|
||||
next = scan + 1;
|
||||
if (!((*scan)->avail & (((parseopts.helpFlags & HELPFLAGS_SECRET) ? 0 : OTF_SECRET) | ((parseopts.helpFlags & HELPFLAGS_DEPRECATED) ? 0 : OTF_DEPRECATED) | OTF_SUBSTITUTED)) && (*scan)->names[0]) {
|
||||
// 17C1BC
|
||||
if (!first)
|
||||
buffer += sprintf(buffer, ", ");
|
||||
if (first)
|
||||
first = 0;
|
||||
|
||||
if (total > 1) {
|
||||
while (*next && (((*next)->avail & (((parseopts.helpFlags & HELPFLAGS_SECRET) ? 0 : OTF_SECRET) | ((parseopts.helpFlags & HELPFLAGS_DEPRECATED) ? 0 : OTF_DEPRECATED) | OTF_SUBSTITUTED)) || !(*next)->names[0])) {
|
||||
++next;
|
||||
}
|
||||
|
||||
if (!*next)
|
||||
buffer += sprintf(buffer, "or ");
|
||||
}
|
||||
|
||||
slflags = (flags & OPTSPELLFLAG_2) ? SLFLAGS_2 : SLFLAGS_1;
|
||||
switch ((*scan)->avail & OTF_SLFLAGS_MASK) {
|
||||
case OTF_SLFLAGS_8:
|
||||
slflags |= SLFLAGS_8;
|
||||
break;
|
||||
case OTF_SLFLAGS_20:
|
||||
slflags |= SLFLAGS_20;
|
||||
break;
|
||||
case OTF_SLFLAGS_10:
|
||||
slflags |= SLFLAGS_10;
|
||||
break;
|
||||
}
|
||||
|
||||
Utils_SpellList((*scan)->names, tmp, slflags);
|
||||
total++;
|
||||
buffer += sprintf(buffer, "%s", tmp);
|
||||
|
||||
if ((*scan)->avail & OTF8000)
|
||||
buffer += sprintf(buffer, " ...");
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
}
|
||||
|
||||
int Option_ForTool(Option *opt, int which) {
|
||||
return !which || (opt->avail & which);
|
||||
}
|
||||
|
||||
int Option_ThisTool() {
|
||||
return (pTool->TYPE == CWDROPINCOMPILERTYPE) ? OTF_TOOL_COMPILER : OTF_TOOL_LINKER;
|
||||
}
|
||||
|
||||
int Option_ForThisTool(Option *opt) {
|
||||
return !Option_ForTool(opt, OTF_TOOL_MASK) || Option_ForTool(opt, Option_ThisTool());
|
||||
}
|
||||
|
||||
int Option_AlsoPassedToTool(Option *opt, int which) {
|
||||
return Option_ForThisTool(opt) && Option_ForTool(opt, which);
|
||||
}
|
||||
|
||||
int Option_AlsoPassedFromThisTool(Option *opt) {
|
||||
return Option_ForThisTool(opt) && Option_ForTool(opt, ~Option_ThisTool() & OTF_TOOL_MASK);
|
||||
}
|
||||
|
||||
static Boolean Option_ContinuesThisLevel(int level, ArgToken *tok) {
|
||||
// tok: r30
|
||||
ArgToken *tmp; // r0
|
||||
int ret; // not in stabs but i think this exists
|
||||
|
||||
if (level == 1) {
|
||||
return (tok->val == ATK_1) || (tok->val == ATK_3) || (tok->val == ATK_2);
|
||||
} else if (level == 2) {
|
||||
tmp = Arg_UsedToken();
|
||||
ret = (tok->val == ATK_5 && tmp->val != ATK_3) || (tok->val == ATK_2 && tmp->val != ATK_1);
|
||||
Arg_UndoToken();
|
||||
return ret;
|
||||
} else if (level == 3) {
|
||||
return (tok->val == ATK_4) || (tok->val == ATK_2);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static short endingStack[5][3];
|
||||
static Boolean Option_IsEndingThisLevel(int level, ArgToken *tok) {
|
||||
// level, tok: r0
|
||||
ArgToken *tmp; // r0
|
||||
|
||||
if (!tok)
|
||||
return 0;
|
||||
// todo
|
||||
}
|
||||
|
||||
static Boolean Option_IsEndingLevel(int level, ArgToken *tok) {
|
||||
// level: r30
|
||||
// tok: r31
|
||||
}
|
||||
|
||||
int Option_Parse(Option *opt, int oflags) {
|
||||
// opt: r24
|
||||
// oflags: r25
|
||||
int ret; // r29
|
||||
int pushed; // r28
|
||||
int samelevel; // r30
|
||||
int subparse; // r27
|
||||
int flags; // r26
|
||||
char errstr[1024]; // stack 0x3C
|
||||
Option **cscan; // r30
|
||||
Option **scan; // r5
|
||||
int goingtosubparse; // r30
|
||||
ArgToken *tok; // r0
|
||||
}
|
||||
|
||||
static int Option_MatchString(char *list, char *str, int flags, int *result) {
|
||||
// list: r26
|
||||
// str: r27
|
||||
// flags: r0
|
||||
// result: r28
|
||||
int str_len; // r0
|
||||
char cpy[64]; // stack 0x3C
|
||||
}
|
||||
|
||||
static Option *Option_Lookup(OptionList *search, int unk, int *flags) {
|
||||
// search: r0
|
||||
// flags: r25
|
||||
Option **os; // r29
|
||||
Option *stickyopt; // r28
|
||||
int stickyflags; // r27
|
||||
Boolean matched; // r0
|
||||
char *names; // r26
|
||||
}
|
||||
|
||||
static int Options_DoParse(OptionList *search, int flags) {
|
||||
// search: r26
|
||||
// flags: r28
|
||||
int haderrors; // r30
|
||||
int parsedany; // r23
|
||||
int failed; // r24
|
||||
int matchflags; // stack 0x3C
|
||||
int subparse; // r20
|
||||
ArgToken *starttok; // r0
|
||||
ArgToken *tok; // r25
|
||||
ArgToken *opttok; // r27
|
||||
Option *opt; // r16
|
||||
Boolean isOpt; // r0
|
||||
char *lptr; // r17
|
||||
char *optname; // r16
|
||||
char saveopt[1024]; // stack 0xBC
|
||||
// Option *opt; // r3
|
||||
// char saveopt[64]; // stack 0x7C
|
||||
// ArgToken *prev; // r0
|
||||
// char sticky[64]; // stack 0x3C
|
||||
// ArgToken *prev; // r16
|
||||
}
|
||||
|
||||
int Options_Parse(OptionList *options, int flags) {
|
||||
// options: r30
|
||||
// flags: r31
|
||||
int ret; // r31
|
||||
char savecuropt[64]; // stack 0x3C
|
||||
|
||||
Options_Reset(options);
|
||||
Option_PushList(options);
|
||||
|
||||
if (!(flags & 2)) {
|
||||
ret = Options_DoParse(options, flags);
|
||||
if (Option_ThisTool() == OTF_TOOL_COMPILER)
|
||||
Arg_AddToToolArgs(&linkargs, 1, 0);
|
||||
} else {
|
||||
strcpy(savecuropt, curopt);
|
||||
ret = Options_DoParse(options, flags);
|
||||
strcpy(curopt, savecuropt);
|
||||
}
|
||||
|
||||
Option_PopList();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Option_ParseDefaultOption(OptionList *options) {
|
||||
// options: r31
|
||||
int ret; // r31
|
||||
Option *dopt; // r0
|
||||
int matchflags; // 0x3C
|
||||
|
||||
Options_Reset(options);
|
||||
Option_PushList(options);
|
||||
|
||||
strcpy(curopt, "defaultoptions");
|
||||
dopt = Option_Lookup(options, 0, &matchflags);
|
||||
if (!dopt) {
|
||||
CLPFatalError("Default options not defined");
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = Option_Parse(dopt, 0);
|
||||
}
|
||||
|
||||
Option_PopList();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Option_ParamError(short id, va_list ap) {
|
||||
char buf[4096];
|
||||
|
||||
CLPGetErrorString(id, buf);
|
||||
sprintf(&buf[strlen(buf)], "\nwhile parsing option '");
|
||||
Args_SpellStack(&buf[strlen(buf)], 0);
|
||||
sprintf(&buf[strlen(buf)], "'");
|
||||
CLPReportError_V(buf, ap);
|
||||
}
|
||||
|
||||
void Option_ParamWarning(short id, va_list ap) {
|
||||
char buf[1024];
|
||||
|
||||
CLPGetErrorString(id, buf);
|
||||
sprintf(&buf[strlen(buf)], "\nwhile parsing option '");
|
||||
Args_SpellStack(&buf[strlen(buf)], 0);
|
||||
sprintf(&buf[strlen(buf)], "'");
|
||||
CLPReportWarning_V(buf, ap);
|
||||
}
|
||||
|
||||
void Option_OptionError(short id, va_list ap) {
|
||||
char buf[1024];
|
||||
|
||||
CLPGetErrorString(id, buf);
|
||||
if (Args_StackSize() >= 2) {
|
||||
sprintf(&buf[strlen(buf)], "\nwhile parsing option '");
|
||||
Args_SpellStack(&buf[strlen(buf)], 0);
|
||||
sprintf(&buf[strlen(buf)], "'");
|
||||
}
|
||||
CLPReportError_V(buf, ap);
|
||||
}
|
||||
|
||||
void Option_OptionWarning(short id, va_list ap) {
|
||||
char buf[1024];
|
||||
|
||||
CLPGetErrorString(id, buf);
|
||||
if (Args_StackSize() >= 2) {
|
||||
sprintf(&buf[strlen(buf)], "\nwhile parsing option '");
|
||||
Args_SpellStack(&buf[strlen(buf)], 0);
|
||||
sprintf(&buf[strlen(buf)], "'");
|
||||
}
|
||||
CLPReportWarning_V(buf, ap);
|
||||
}
|
||||
|
||||
void Option_Error(short id, ...) {
|
||||
va_list va;
|
||||
va_start(va, id);
|
||||
Option_OptionError(id, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void Option_Warning(short id, ...) {
|
||||
va_list va;
|
||||
va_start(va, id);
|
||||
Option_OptionWarning(id, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
int Options_Help(const char *keyword) {
|
||||
// keyword: r31
|
||||
int scan; // r26
|
||||
OptionList *lst; // r25
|
||||
|
||||
Help_Init();
|
||||
|
||||
if (parseopts.helpFlags & HELPFLAGS_USAGE) {
|
||||
ShowVersion(1);
|
||||
Help_Line('=');
|
||||
Help_Usage();
|
||||
} else {
|
||||
ShowVersion(1);
|
||||
for (scan = 0; scan < numoptionlists; scan++) {
|
||||
if ((lst = optionlists[scan])) {
|
||||
if (parseopts.helpFlags & HELPFLAGS_8000) {
|
||||
if (keyword && keyword[0] && lst->help && strstr(lst->help, keyword))
|
||||
Help_Options(lst, 0, "");
|
||||
} else {
|
||||
Help_Options(lst, 0, keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Help_Term();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Option_Help(const char *opt) {
|
||||
// opt: r31
|
||||
Option *find; // r29
|
||||
int matchflags; // stack 0x3C
|
||||
int ret; // r29
|
||||
|
||||
find = 0;
|
||||
Option_PushList(Options_GetOptions());
|
||||
Option_PushOpt(0, "help");
|
||||
if (opt[0] == MAINOPTCHAR[0])
|
||||
strcpy(curopt, opt + 1);
|
||||
else
|
||||
strcpy(curopt, opt);
|
||||
|
||||
if (!curopt[1])
|
||||
find = Option_Lookup(Options_GetOptions(), 0x700002, &matchflags);
|
||||
if (!find)
|
||||
find = Option_Lookup(Options_GetOptions(), 0x700000, &matchflags);
|
||||
|
||||
if (find) {
|
||||
Help_Init();
|
||||
if (!Help_Option(Options_GetOptions(), find, 0, ""))
|
||||
CLPReportWarning(38, opt);
|
||||
Help_Term();
|
||||
ret = 1;
|
||||
} else {
|
||||
Option_Error(19, opt);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
Option_PopOpt(curopt);
|
||||
Option_PopList();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Options_DisplayHelp() {
|
||||
if (parseopts.helpFlags & HELPFLAGS_1)
|
||||
Option_Help(parseopts.helpKey);
|
||||
else
|
||||
Options_Help(parseopts.helpKey);
|
||||
}
|
286
PCode.c
Normal file
286
PCode.c
Normal file
@ -0,0 +1,286 @@
|
||||
#include "CompilerTools.h"
|
||||
#include "PCode.h"
|
||||
|
||||
// TODO RESOLVE ME
|
||||
extern void initialize_aliases();
|
||||
extern void *current_statement;
|
||||
extern PCode *vformatpcode(short op, va_list args);
|
||||
|
||||
PCBlock *pcbasicblocks;
|
||||
PCBlock *pclastblock;
|
||||
void *prologue;
|
||||
void *epilogue;
|
||||
PCBlock **depthfirstordering;
|
||||
int pcblockcount;
|
||||
int pcloopweight;
|
||||
static unsigned short pclabelcount;
|
||||
|
||||
void initpcode() {
|
||||
pclastblock = 0;
|
||||
pcbasicblocks = 0;
|
||||
pcblockcount = 0;
|
||||
pclabelcount = 0;
|
||||
pcloopweight = 1;
|
||||
initialize_aliases();
|
||||
}
|
||||
|
||||
PCode *makepcode(short op, ...) {
|
||||
PCode *pcode;
|
||||
va_list list;
|
||||
|
||||
va_start(list, op);
|
||||
pcode = vformatpcode(op, list);
|
||||
// TODO
|
||||
return pcode;
|
||||
}
|
||||
|
||||
void emitpcode(short op, ...) {
|
||||
PCode *pcode;
|
||||
va_list list;
|
||||
|
||||
va_start(list, op);
|
||||
pcode = vformatpcode(op, list);
|
||||
// TODO
|
||||
appendpcode(pclastblock, pcode);
|
||||
}
|
||||
|
||||
PCode *copypcode(PCode *pcode) {
|
||||
PCode *newpc;
|
||||
int flag;
|
||||
|
||||
flag = 0;
|
||||
// TODO
|
||||
|
||||
return newpc;
|
||||
}
|
||||
|
||||
PCLabel *makepclabel() {
|
||||
PCLabel *label;
|
||||
|
||||
label = (PCLabel *) lalloc(sizeof(PCLabel));
|
||||
memclrw(label, sizeof(PCLabel));
|
||||
label->index = pclabelcount++;
|
||||
return label;
|
||||
}
|
||||
|
||||
PCBlock *makepcblock() {
|
||||
PCBlock *block;
|
||||
|
||||
block = (PCBlock *) lalloc(sizeof(PCBlock));
|
||||
memclrw(block, sizeof(PCBlock));
|
||||
block->loopWeight = pcloopweight;
|
||||
block->blockIndex = pcblockcount++;
|
||||
if (pclastblock) {
|
||||
pclastblock->nextBlock = block;
|
||||
block->prevBlock = pclastblock;
|
||||
} else {
|
||||
pcbasicblocks = block;
|
||||
}
|
||||
pclastblock = block;
|
||||
return block;
|
||||
}
|
||||
|
||||
void pclabel(PCBlock *block, PCLabel *label) {
|
||||
PCLink *iter;
|
||||
PCLink *next;
|
||||
|
||||
iter = (PCLink *) label->block;
|
||||
while (iter) {
|
||||
next = (PCLink *) iter->block;
|
||||
iter->block = block;
|
||||
iter = next;
|
||||
}
|
||||
|
||||
label->block = block;
|
||||
label->resolved = 1;
|
||||
label->nextLabel = block->labels;
|
||||
block->labels = label;
|
||||
}
|
||||
|
||||
void pcbranch(PCBlock *block, PCLabel *label) {
|
||||
PCLink *link;
|
||||
|
||||
link = (PCLink *) lalloc(sizeof(PCLink));
|
||||
memclrw(link, sizeof(PCLink));
|
||||
|
||||
link->block = label->block;
|
||||
if (!label->resolved)
|
||||
label->block = (PCBlock *) link;
|
||||
link->nextLink = block->successors;
|
||||
block->successors = link;
|
||||
}
|
||||
|
||||
void pccomputepredecessors() {
|
||||
PCBlock *block;
|
||||
PCLink *succ;
|
||||
PCLink *pred;
|
||||
|
||||
for (block = pcbasicblocks; block; block = block->nextBlock) {
|
||||
for (succ = block->successors; succ; succ = succ->nextLink) {
|
||||
pred = (PCLink *) lalloc(sizeof(PCLink));
|
||||
memclrw(pred, sizeof(PCLink));
|
||||
|
||||
pred->block = block;
|
||||
pred->nextLink = succ->block->predecessors;
|
||||
succ->block->predecessors = pred;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void deleteblock(PCBlock *block) {
|
||||
block->prevBlock->nextBlock = block->nextBlock;
|
||||
if (block->nextBlock)
|
||||
block->nextBlock->prevBlock = block->prevBlock;
|
||||
block->flags |= fPCBlockFlag20;
|
||||
}
|
||||
|
||||
void deleteunreachableblocks() {
|
||||
PCBlock *block;
|
||||
|
||||
computedepthfirstordering();
|
||||
|
||||
for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) {
|
||||
if (!(block->flags & fPCBlockFlag4))
|
||||
deleteblock(block);
|
||||
}
|
||||
}
|
||||
|
||||
void appendpcode(PCBlock *block, PCode *pcode) {
|
||||
if (block->firstPCode) {
|
||||
pcode->nextPCode = 0;
|
||||
pcode->prevPCode = block->lastPCode;
|
||||
block->lastPCode->nextPCode = pcode;
|
||||
block->lastPCode = pcode;
|
||||
} else {
|
||||
block->lastPCode = pcode;
|
||||
block->firstPCode = pcode;
|
||||
pcode->prevPCode = 0;
|
||||
pcode->nextPCode = 0;
|
||||
}
|
||||
pcode->block = block;
|
||||
block->pcodeCount++;
|
||||
}
|
||||
|
||||
void deletepcode(PCode *pcode) {
|
||||
PCBlock *block;
|
||||
|
||||
block = pcode->block;
|
||||
if (pcode->prevPCode)
|
||||
pcode->prevPCode->nextPCode = pcode->nextPCode;
|
||||
else
|
||||
block->firstPCode = pcode->nextPCode;
|
||||
if (pcode->nextPCode)
|
||||
pcode->nextPCode->prevPCode = pcode->prevPCode;
|
||||
else
|
||||
block->lastPCode = pcode->prevPCode;
|
||||
|
||||
pcode->block = 0;
|
||||
block->pcodeCount--;
|
||||
block->flags &= ~fPCBlockFlag8;
|
||||
}
|
||||
|
||||
void insertpcodebefore(PCode *anchor, PCode *newpcode) {
|
||||
PCBlock *block;
|
||||
|
||||
block = anchor->block;
|
||||
if (anchor->prevPCode)
|
||||
anchor->prevPCode->nextPCode = newpcode;
|
||||
else
|
||||
block->firstPCode = newpcode;
|
||||
newpcode->nextPCode = anchor;
|
||||
newpcode->prevPCode = anchor->prevPCode;
|
||||
anchor->prevPCode = newpcode;
|
||||
newpcode->_1C = anchor->_1C;
|
||||
|
||||
newpcode->block = block;
|
||||
block->pcodeCount++;
|
||||
block->flags &= ~fPCBlockFlag8;
|
||||
}
|
||||
|
||||
void insertpcodeafter(PCode *anchor, PCode *newpcode) {
|
||||
PCBlock *block;
|
||||
|
||||
block = anchor->block;
|
||||
if (anchor->nextPCode)
|
||||
anchor->nextPCode->prevPCode = newpcode;
|
||||
else
|
||||
block->lastPCode = newpcode;
|
||||
newpcode->prevPCode = anchor;
|
||||
newpcode->nextPCode = anchor->nextPCode;
|
||||
anchor->nextPCode = newpcode;
|
||||
newpcode->_1C = anchor->_1C;
|
||||
|
||||
newpcode->block = block;
|
||||
block->pcodeCount++;
|
||||
block->flags &= ~fPCBlockFlag8;
|
||||
}
|
||||
|
||||
void setpcodeflags(int flags) {
|
||||
pclastblock->lastPCode->flags |= flags;
|
||||
if (flags & fSideEffects)
|
||||
pclastblock->lastPCode->flags &= ~(fIsCSE | fCommutative | fPCodeFlag10);
|
||||
}
|
||||
|
||||
void clearpcodeflags(int flags) {
|
||||
pclastblock->lastPCode->flags &= ~flags;
|
||||
}
|
||||
|
||||
int pccomputeoffsets() {
|
||||
int offset;
|
||||
PCBlock *block;
|
||||
|
||||
offset = 0;
|
||||
for (block = pcbasicblocks; block; block = block->nextBlock) {
|
||||
block->codeOffset = offset;
|
||||
offset += block->pcodeCount * 4;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
typedef struct _DFO {
|
||||
PCBlock *block;
|
||||
PCLink *link;
|
||||
} DFO;
|
||||
|
||||
static int depthfirstorder;
|
||||
|
||||
void computedepthfirstordering() {
|
||||
PCBlock *block;
|
||||
PCLink *link;
|
||||
DFO *dfo;
|
||||
int index;
|
||||
|
||||
depthfirstordering = (PCBlock **) lalloc(sizeof(PCBlock *) * pcblockcount);
|
||||
memclrw(depthfirstordering, sizeof(PCBlock *) * pcblockcount);
|
||||
depthfirstorder = pcblockcount;
|
||||
|
||||
for (block = pcbasicblocks; block; block = block->nextBlock) {
|
||||
block->flags &= ~fPCBlockFlag4;
|
||||
}
|
||||
|
||||
dfo = (DFO *) oalloc(sizeof(DFO) * pcblockcount);
|
||||
pcbasicblocks->flags |= fPCBlockFlag4;
|
||||
|
||||
dfo->block = pcbasicblocks;
|
||||
dfo->link = pcbasicblocks->successors;
|
||||
index = 1;
|
||||
while (index) {
|
||||
if ((link = dfo[index - 1].link)) {
|
||||
dfo[index - 1].link = link->nextLink;
|
||||
block = link->block;
|
||||
if (!(block->flags & fPCBlockFlag4)) {
|
||||
block->flags |= fPCBlockFlag4;
|
||||
dfo[index].block = block;
|
||||
dfo[index].link = block->successors;
|
||||
index++;
|
||||
}
|
||||
} else {
|
||||
depthfirstordering[--depthfirstorder] = dfo[--index].block;
|
||||
}
|
||||
}
|
||||
|
||||
while (depthfirstorder) {
|
||||
depthfirstordering[--depthfirstorder] = 0;
|
||||
}
|
||||
}
|
110
PCode.h
Normal file
110
PCode.h
Normal file
@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct _PCodeArg {
|
||||
unsigned int _0;
|
||||
unsigned int _4;
|
||||
unsigned int _8;
|
||||
} PCodeArg;
|
||||
|
||||
typedef struct _PCode {
|
||||
struct _PCode *nextPCode;
|
||||
struct _PCode *prevPCode;
|
||||
struct _PCBlock *block;
|
||||
unsigned int xx_C;
|
||||
unsigned int _10;
|
||||
int flags;
|
||||
unsigned int _18;
|
||||
unsigned int _1C;
|
||||
short op;
|
||||
short argCount;
|
||||
PCodeArg args[0];
|
||||
} PCode;
|
||||
|
||||
typedef struct _PCLabel {
|
||||
struct _PCLabel *nextLabel;
|
||||
struct _PCBlock *block;
|
||||
short resolved;
|
||||
short index;
|
||||
} PCLabel;
|
||||
|
||||
typedef struct _PCLink {
|
||||
struct _PCLink *nextLink;
|
||||
struct _PCBlock *block;
|
||||
} PCLink;
|
||||
|
||||
typedef struct _PCBlock {
|
||||
struct _PCBlock *nextBlock;
|
||||
struct _PCBlock *prevBlock;
|
||||
PCLabel *labels;
|
||||
PCLink *predecessors;
|
||||
PCLink *successors;
|
||||
PCode *firstPCode;
|
||||
PCode *lastPCode;
|
||||
int blockIndex;
|
||||
int codeOffset; // in bytes
|
||||
int loopWeight;
|
||||
short pcodeCount;
|
||||
unsigned short flags;
|
||||
} PCBlock;
|
||||
|
||||
/* PCode Flags */
|
||||
enum {
|
||||
fPCodeFlag1 = 1,
|
||||
fPCodeFlag2 = 2,
|
||||
fPCodeFlag4 = 4,
|
||||
fPCodeFlag8 = 8,
|
||||
fPCodeFlag10 = 0x10,
|
||||
fIsPtrOp = 0x20,
|
||||
fIsConst = 0x40,
|
||||
fIsVolatile = 0x80,
|
||||
fSideEffects = 0x100,
|
||||
fPCodeFlag200 = 0x200,
|
||||
fPCodeFlag400 = 0x400,
|
||||
fPCodeFlag800 = 0x800,
|
||||
fPCodeFlag1000 = 0x1000,
|
||||
fCommutative = 0x2000,
|
||||
fIsCSE = 0x4000,
|
||||
fOverflow = 0x800000,
|
||||
fLink = 0x1000000,
|
||||
fBranchNotTaken = 0x4000000,
|
||||
fBranchTaken = 0x8000000,
|
||||
fAbsolute = 0x10000000,
|
||||
fSetsCarry = 0x10000000,
|
||||
};
|
||||
|
||||
enum {
|
||||
fPCBlockFlag1 = 1,
|
||||
fPCBlockFlag2 = 2,
|
||||
fPCBlockFlag4 = 4,
|
||||
fPCBlockFlag8 = 8,
|
||||
fPCBlockFlag10 = 0x10,
|
||||
fPCBlockFlag20 = 0x20
|
||||
};
|
||||
|
||||
extern PCBlock *pcbasicblocks;
|
||||
extern PCBlock *pclastblock;
|
||||
extern void *prologue;
|
||||
extern void *epilogue;
|
||||
extern PCBlock **depthfirstordering;
|
||||
extern int pcblockcount;
|
||||
extern int pcloopweight;
|
||||
|
||||
extern void initpcode();
|
||||
extern PCode *makepcode(short op, ...);
|
||||
extern void emitpcode(short op, ...);
|
||||
extern PCode *copypcode(PCode *pcode);
|
||||
extern PCLabel *makepclabel();
|
||||
extern PCBlock *makepcblock();
|
||||
extern void pclabel(PCBlock *block, PCLabel *label);
|
||||
extern void pcbranch(PCBlock *block, PCLabel *label);
|
||||
extern void pccomputepredecessors();
|
||||
extern void deleteblock(PCBlock *block);
|
||||
extern void deleteunreachableblocks();
|
||||
extern void appendpcode(PCBlock *block, PCode *pcode);
|
||||
extern void deletepcode(PCode *pcode);
|
||||
extern void insertpcodebefore(PCode *anchor, PCode *newpcode);
|
||||
extern void insertpcodeafter(PCode *anchor, PCode *newpcode);
|
||||
extern void setpcodeflags(int flags);
|
||||
extern void clearpcodeflags(int flags);
|
||||
extern int pccomputeoffsets();
|
||||
extern void computedepthfirstordering();
|
55
PCodeInfo.c
Normal file
55
PCodeInfo.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include "PCodeInfo.h"
|
||||
|
||||
void pcode_get_hi_lo(int a1, char a2, int *pA, int *pB) {
|
||||
|
||||
}
|
||||
|
||||
int pcode_check_imm_bits(int a1, int a2, int a3) {
|
||||
|
||||
}
|
||||
|
||||
int pcode_const_from_format(char *buf, int *pResult) {
|
||||
|
||||
}
|
||||
|
||||
PCode *vformatpcode(short opcode, va_list argList) {
|
||||
|
||||
}
|
||||
|
||||
int expectandformatoperand(PCodeArg *operand, unsigned char expectedKind, char a3, int bitCount, char *buf) {
|
||||
}
|
||||
|
||||
int formatoperand(PCodeArg *operand, char *buf) {
|
||||
|
||||
}
|
||||
|
||||
void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
|
||||
|
||||
}
|
||||
|
||||
PCode *makecopyinstruction(PCodeArg *a, PCodeArg *b) {
|
||||
|
||||
}
|
||||
|
||||
int is_location_independent(PCode *pcode) {
|
||||
|
||||
}
|
||||
|
||||
int can_reuse_stored_value(PCode *a, PCode *b) {
|
||||
|
||||
}
|
||||
|
||||
int nbytes_loaded_or_stored_by(PCode *pcode) {
|
||||
|
||||
}
|
||||
|
||||
void change_num_operands(PCode *pcode, int newNum) {
|
||||
|
||||
}
|
||||
|
||||
void change_opcode(PCode *pcode, short opcode) {
|
||||
pcode->flags = (pcode->flags & ~(opcodeinfo[pcode->op].flags & ~fIsPtrOp)) | opcodeinfo[opcode].flags;
|
||||
if ((pcode->flags & fPCodeFlag10) && (pcode->flags & (fPCodeFlag1 | fPCodeFlag8)))
|
||||
pcode->flags &= ~fPCodeFlag10;
|
||||
pcode->op = opcode;
|
||||
}
|
462
PCodeInfo.h
Normal file
462
PCodeInfo.h
Normal file
@ -0,0 +1,462 @@
|
||||
#pragma once
|
||||
|
||||
#include "PCode.h"
|
||||
|
||||
typedef struct _OpcodeInfo {
|
||||
const char *name;
|
||||
const char *format;
|
||||
unsigned char x8;
|
||||
unsigned char x9;
|
||||
int xA;
|
||||
unsigned int insn;
|
||||
} OpcodeInfo;
|
||||
|
||||
enum {
|
||||
PC_B = 0x0,
|
||||
PC_BL = 0x1,
|
||||
PC_BC = 0x2,
|
||||
PC_BCLR = 0x3,
|
||||
PC_BCCTR = 0x4,
|
||||
PC_BT = 0x5,
|
||||
PC_BTLR = 0x6,
|
||||
PC_BTCTR = 0x7,
|
||||
PC_BF = 0x8,
|
||||
PC_BFLR = 0x9,
|
||||
PC_BFCTR = 0xA,
|
||||
PC_BDNZ = 0xB,
|
||||
PC_BDNZT = 0xC,
|
||||
PC_BDNZF = 0xD,
|
||||
PC_BDZ = 0xE,
|
||||
PC_BDZT = 0xF,
|
||||
PC_BDZF = 0x10,
|
||||
PC_BLR = 0x11,
|
||||
PC_BCTR = 0x12,
|
||||
PC_BCTRL = 0x13,
|
||||
PC_BLRL = 0x14,
|
||||
PC_LBZ = 0x15,
|
||||
PC_LBZU = 0x16,
|
||||
PC_LBZX = 0x17,
|
||||
PC_LBZUX = 0x18,
|
||||
PC_LHZ = 0x19,
|
||||
PC_LHZU = 0x1A,
|
||||
PC_LHZX = 0x1B,
|
||||
PC_LHZUX = 0x1C,
|
||||
PC_LHA = 0x1D,
|
||||
PC_LHAU = 0x1E,
|
||||
PC_LHAX = 0x1F,
|
||||
PC_LHAUX = 0x20,
|
||||
PC_LHBRX = 0x21,
|
||||
PC_LWZ = 0x22,
|
||||
PC_LWZU = 0x23,
|
||||
PC_LWZX = 0x24,
|
||||
PC_LWZUX = 0x25,
|
||||
PC_LWBRX = 0x26,
|
||||
PC_LMW = 0x27,
|
||||
PC_STB = 0x28,
|
||||
PC_STBU = 0x29,
|
||||
PC_STBX = 0x2A,
|
||||
PC_STBUX = 0x2B,
|
||||
PC_STH = 0x2C,
|
||||
PC_STHU = 0x2D,
|
||||
PC_STHX = 0x2E,
|
||||
PC_STHUX = 0x2F,
|
||||
PC_STHBRX = 0x30,
|
||||
PC_STW = 0x31,
|
||||
PC_STWU = 0x32,
|
||||
PC_STWX = 0x33,
|
||||
PC_STWUX = 0x34,
|
||||
PC_STWBRX = 0x35,
|
||||
PC_STMW = 0x36,
|
||||
PC_DCBF = 0x37,
|
||||
PC_DCBST = 0x38,
|
||||
PC_DCBT = 0x39,
|
||||
PC_DCBTST = 0x3A,
|
||||
PC_DCBZ = 0x3B,
|
||||
PC_ADD = 0x3C,
|
||||
PC_ADDC = 0x3D,
|
||||
PC_ADDE = 0x3E,
|
||||
PC_ADDI = 0x3F,
|
||||
PC_ADDIC = 0x40,
|
||||
PC_ADDICR = 0x41,
|
||||
PC_ADDIS = 0x42,
|
||||
PC_ADDME = 0x43,
|
||||
PC_ADDZE = 0x44,
|
||||
PC_DIVW = 0x45,
|
||||
PC_DIVWU = 0x46,
|
||||
PC_MULHW = 0x47,
|
||||
PC_MULHWU = 0x48,
|
||||
PC_MULLI = 0x49,
|
||||
PC_MULLW = 0x4A,
|
||||
PC_NEG = 0x4B,
|
||||
PC_SUBF = 0x4C,
|
||||
PC_SUBFC = 0x4D,
|
||||
PC_SUBFE = 0x4E,
|
||||
PC_SUBFIC = 0x4F,
|
||||
PC_SUBFME = 0x50,
|
||||
PC_SUBFZE = 0x51,
|
||||
PC_CMPI = 0x52,
|
||||
PC_CMP = 0x53,
|
||||
PC_CMPLI = 0x54,
|
||||
PC_CMPL = 0x55,
|
||||
PC_ANDI = 0x56,
|
||||
PC_ANDIS = 0x57,
|
||||
PC_ORI = 0x58,
|
||||
PC_ORIS = 0x59,
|
||||
PC_XORI = 0x5A,
|
||||
PC_XORIS = 0x5B,
|
||||
PC_AND = 0x5C,
|
||||
PC_OR = 0x5D,
|
||||
PC_XOR = 0x5E,
|
||||
PC_NAND = 0x5F,
|
||||
PC_NOR = 0x60,
|
||||
PC_EQV = 0x61,
|
||||
PC_ANDC = 0x62,
|
||||
PC_ORC = 0x63,
|
||||
PC_EXTSB = 0x64,
|
||||
PC_EXTSH = 0x65,
|
||||
PC_CNTLZW = 0x66,
|
||||
PC_RLWINM = 0x67,
|
||||
PC_RLWNM = 0x68,
|
||||
PC_RLWIMI = 0x69,
|
||||
PC_SLW = 0x6A,
|
||||
PC_SRW = 0x6B,
|
||||
PC_SRAWI = 0x6C,
|
||||
PC_SRAW = 0x6D,
|
||||
PC_CRAND = 0x6E,
|
||||
PC_CRANDC = 0x6F,
|
||||
PC_CREQV = 0x70,
|
||||
PC_CRNAND = 0x71,
|
||||
PC_CRNOR = 0x72,
|
||||
PC_CROR = 0x73,
|
||||
PC_CRORC = 0x74,
|
||||
PC_CRXOR = 0x75,
|
||||
PC_MCRF = 0x76,
|
||||
PC_MTXER = 0x77,
|
||||
PC_MTCTR = 0x78,
|
||||
PC_MTLR = 0x79,
|
||||
PC_MTCRF = 0x7A,
|
||||
PC_MTMSR = 0x7B,
|
||||
PC_MTSPR = 0x7C,
|
||||
PC_MFMSR = 0x7D,
|
||||
PC_MFSPR = 0x7E,
|
||||
PC_MFXER = 0x7F,
|
||||
PC_MFCTR = 0x80,
|
||||
PC_MFLR = 0x81,
|
||||
PC_MFCR = 0x82,
|
||||
PC_MFFS = 0x83,
|
||||
PC_MTFSF = 0x84,
|
||||
PC_EIEIO = 0x85,
|
||||
PC_ISYNC = 0x86,
|
||||
PC_SYNC = 0x87,
|
||||
PC_RFI = 0x88,
|
||||
PC_LI = 0x89,
|
||||
PC_LIS = 0x8A,
|
||||
PC_MR = 0x8B,
|
||||
PC_NOP = 0x8C,
|
||||
PC_NOT = 0x8D,
|
||||
PC_LFS = 0x8E,
|
||||
PC_LFSU = 0x8F,
|
||||
PC_LFSX = 0x90,
|
||||
PC_LFSUX = 0x91,
|
||||
PC_LFD = 0x92,
|
||||
PC_LFDU = 0x93,
|
||||
PC_LFDX = 0x94,
|
||||
PC_LFDUX = 0x95,
|
||||
PC_STFS = 0x96,
|
||||
PC_STFSU = 0x97,
|
||||
PC_STFSX = 0x98,
|
||||
PC_STFSUX = 0x99,
|
||||
PC_STFD = 0x9A,
|
||||
PC_STFDU = 0x9B,
|
||||
PC_STFDX = 0x9C,
|
||||
PC_STFDUX = 0x9D,
|
||||
PC_FMR = 0x9E,
|
||||
PC_FABS = 0x9F,
|
||||
PC_FNEG = 0xA0,
|
||||
PC_FNABS = 0xA1,
|
||||
PC_FADD = 0xA2,
|
||||
PC_FADDS = 0xA3,
|
||||
PC_FSUB = 0xA4,
|
||||
PC_FSUBS = 0xA5,
|
||||
PC_FMUL = 0xA6,
|
||||
PC_FMULS = 0xA7,
|
||||
PC_FDIV = 0xA8,
|
||||
PC_FDIVS = 0xA9,
|
||||
PC_FMADD = 0xAA,
|
||||
PC_FMADDS = 0xAB,
|
||||
PC_FMSUB = 0xAC,
|
||||
PC_FMSUBS = 0xAD,
|
||||
PC_FNMADD = 0xAE,
|
||||
PC_FNMADDS = 0xAF,
|
||||
PC_FNMSUB = 0xB0,
|
||||
PC_FNMSUBS = 0xB1,
|
||||
PC_FRES = 0xB2,
|
||||
PC_FRSQRTE = 0xB3,
|
||||
PC_FSEL = 0xB4,
|
||||
PC_FRSP = 0xB5,
|
||||
PC_FCTIW = 0xB6,
|
||||
PC_FCTIWZ = 0xB7,
|
||||
PC_FCMPU = 0xB8,
|
||||
PC_FCMPO = 0xB9,
|
||||
PC_LWARX = 0xBA,
|
||||
PC_LSWI = 0xBB,
|
||||
PC_LSWX = 0xBC,
|
||||
PC_STFIWX = 0xBD,
|
||||
PC_STSWI = 0xBE,
|
||||
PC_STSWX = 0xBF,
|
||||
PC_STWCX = 0xC0,
|
||||
PC_ECIWX = 0xC1,
|
||||
PC_ECOWX = 0xC2,
|
||||
PC_DCBI = 0xC3,
|
||||
PC_ICBI = 0xC4,
|
||||
PC_MCRFS = 0xC5,
|
||||
PC_MCRXR = 0xC6,
|
||||
PC_MFTB = 0xC7,
|
||||
PC_MFSR = 0xC8,
|
||||
PC_MTSR = 0xC9,
|
||||
PC_MFSRIN = 0xCA,
|
||||
PC_MTSRIN = 0xCB,
|
||||
PC_MTFSB0 = 0xCC,
|
||||
PC_MTFSB1 = 0xCD,
|
||||
PC_MTFSFI = 0xCE,
|
||||
PC_SC = 0xCF,
|
||||
PC_FSQRT = 0xD0,
|
||||
PC_FSQRTS = 0xD1,
|
||||
PC_TLBIA = 0xD2,
|
||||
PC_TLBIE = 0xD3,
|
||||
PC_TLBLD = 0xD4,
|
||||
PC_TLBLI = 0xD5,
|
||||
PC_TLBSYNC = 0xD6,
|
||||
PC_TW = 0xD7,
|
||||
PC_TRAP = 0xD8,
|
||||
PC_TWI = 0xD9,
|
||||
PC_OPWORD = 0xDA,
|
||||
PC_MFROM = 0xDB,
|
||||
PC_DSA = 0xDC,
|
||||
PC_ESA = 0xDD,
|
||||
PC_DCCCI = 0xDE,
|
||||
PC_DCREAD = 0xDF,
|
||||
PC_ICBT = 0xE0,
|
||||
PC_ICCCI = 0xE1,
|
||||
PC_ICREAD = 0xE2,
|
||||
PC_RFCI = 0xE3,
|
||||
PC_TLBRE = 0xE4,
|
||||
PC_TLBSX = 0xE5,
|
||||
PC_TLBWE = 0xE6,
|
||||
PC_WRTEE = 0xE7,
|
||||
PC_WRTEEI = 0xE8,
|
||||
PC_MFDCR = 0xE9,
|
||||
PC_MTDCR = 0xEA,
|
||||
PC_DCBA = 0xEB,
|
||||
PC_DSS = 0xEC,
|
||||
PC_DSSALL = 0xED,
|
||||
PC_DST = 0xEE,
|
||||
PC_DSTT = 0xEF,
|
||||
PC_DSTST = 0xF0,
|
||||
PC_DSTSTT = 0xF1,
|
||||
PC_LVEBX = 0xF2,
|
||||
PC_LVEHX = 0xF3,
|
||||
PC_LVEWX = 0xF4,
|
||||
PC_LVSL = 0xF5,
|
||||
PC_LVSR = 0xF6,
|
||||
PC_LVX = 0xF7,
|
||||
PC_LVXL = 0xF8,
|
||||
PC_STVEBX = 0xF9,
|
||||
PC_STVEHX = 0xFA,
|
||||
PC_STVEWX = 0xFB,
|
||||
PC_STVX = 0xFC,
|
||||
PC_STVXL = 0xFD,
|
||||
PC_MFVSCR = 0xFE,
|
||||
PC_MTVSCR = 0xFF,
|
||||
PC_VADDCUW = 0x100,
|
||||
PC_VADDFP = 0x101,
|
||||
PC_VADDSBS = 0x102,
|
||||
PC_VADDSHS = 0x103,
|
||||
PC_VADDSWS = 0x104,
|
||||
PC_VADDUBM = 0x105,
|
||||
PC_VADDUBS = 0x106,
|
||||
PC_VADDUHM = 0x107,
|
||||
PC_VADDUHS = 0x108,
|
||||
PC_VADDUWM = 0x109,
|
||||
PC_VADDUWS = 0x10A,
|
||||
PC_VAND = 0x10B,
|
||||
PC_VANDC = 0x10C,
|
||||
PC_VAVGSB = 0x10D,
|
||||
PC_VAVGSH = 0x10E,
|
||||
PC_VAVGSW = 0x10F,
|
||||
PC_VAVGUB = 0x110,
|
||||
PC_VAVGUH = 0x111,
|
||||
PC_VAVGUW = 0x112,
|
||||
PC_VCFSX = 0x113,
|
||||
PC_VCFUX = 0x114,
|
||||
PC_VCMPBFP = 0x115,
|
||||
PC_VCMPEQFP = 0x116,
|
||||
PC_VCMPEQUB = 0x117,
|
||||
PC_VCMPEQUH = 0x118,
|
||||
PC_VCMPEQUW = 0x119,
|
||||
PC_VCMPGEFP = 0x11A,
|
||||
PC_VCMPGTFP = 0x11B,
|
||||
PC_VCMPGTSB = 0x11C,
|
||||
PC_VCMPGTSH = 0x11D,
|
||||
PC_VCMPGTSW = 0x11E,
|
||||
PC_VCMPGTUB = 0x11F,
|
||||
PC_VCMPGTUH = 0x120,
|
||||
PC_VCMPGTUW = 0x121,
|
||||
PC_VCTSXS = 0x122,
|
||||
PC_VCTUXS = 0x123,
|
||||
PC_VEXPTEFP = 0x124,
|
||||
PC_VLOGEFP = 0x125,
|
||||
PC_VMAXFP = 0x126,
|
||||
PC_VMAXSB = 0x127,
|
||||
PC_VMAXSH = 0x128,
|
||||
PC_VMAXSW = 0x129,
|
||||
PC_VMAXUB = 0x12A,
|
||||
PC_VMAXUH = 0x12B,
|
||||
PC_VMAXUW = 0x12C,
|
||||
PC_VMINFP = 0x12D,
|
||||
PC_VMINSB = 0x12E,
|
||||
PC_VMINSH = 0x12F,
|
||||
PC_VMINSW = 0x130,
|
||||
PC_VMINUB = 0x131,
|
||||
PC_VMINUH = 0x132,
|
||||
PC_VMINUW = 0x133,
|
||||
PC_VMRGHB = 0x134,
|
||||
PC_VMRGHH = 0x135,
|
||||
PC_VMRGHW = 0x136,
|
||||
PC_VMRGLB = 0x137,
|
||||
PC_VMRGLH = 0x138,
|
||||
PC_VMRGLW = 0x139,
|
||||
PC_VMULESB = 0x13A,
|
||||
PC_VMULESH = 0x13B,
|
||||
PC_VMULEUB = 0x13C,
|
||||
PC_VMULEUH = 0x13D,
|
||||
PC_VMULOSB = 0x13E,
|
||||
PC_VMULOSH = 0x13F,
|
||||
PC_VMULOUB = 0x140,
|
||||
PC_VMULOUH = 0x141,
|
||||
PC_VNOR = 0x142,
|
||||
PC_VOR = 0x143,
|
||||
PC_VPKPX = 0x144,
|
||||
PC_VPKSHSS = 0x145,
|
||||
PC_VPKSHUS = 0x146,
|
||||
PC_VPKSWSS = 0x147,
|
||||
PC_VPKSWUS = 0x148,
|
||||
PC_VPKUHUM = 0x149,
|
||||
PC_VPKUHUS = 0x14A,
|
||||
PC_VPKUWUM = 0x14B,
|
||||
PC_VPKUWUS = 0x14C,
|
||||
PC_VREFP = 0x14D,
|
||||
PC_VRFIM = 0x14E,
|
||||
PC_VRFIN = 0x14F,
|
||||
PC_VRFIP = 0x150,
|
||||
PC_VRFIZ = 0x151,
|
||||
PC_VRLB = 0x152,
|
||||
PC_VRLH = 0x153,
|
||||
PC_VRLW = 0x154,
|
||||
PC_VRSQRTEFP = 0x155,
|
||||
PC_VSL = 0x156,
|
||||
PC_VSLB = 0x157,
|
||||
PC_VSLH = 0x158,
|
||||
PC_VSLO = 0x159,
|
||||
PC_VSLW = 0x15A,
|
||||
PC_VSPLTB = 0x15B,
|
||||
PC_VSPLTH = 0x15C,
|
||||
PC_VSPLTW = 0x15D,
|
||||
PC_VSPLTISB = 0x15E,
|
||||
PC_VSPLTISH = 0x15F,
|
||||
PC_VSPLTISW = 0x160,
|
||||
PC_VSR = 0x161,
|
||||
PC_VSRAB = 0x162,
|
||||
PC_VSRAH = 0x163,
|
||||
PC_VSRAW = 0x164,
|
||||
PC_VSRB = 0x165,
|
||||
PC_VSRH = 0x166,
|
||||
PC_VSRO = 0x167,
|
||||
PC_VSRW = 0x168,
|
||||
PC_VSUBCUW = 0x169,
|
||||
PC_VSUBFP = 0x16A,
|
||||
PC_VSUBSBS = 0x16B,
|
||||
PC_VSUBSHS = 0x16C,
|
||||
PC_VSUBSWS = 0x16D,
|
||||
PC_VSUBUBM = 0x16E,
|
||||
PC_VSUBUBS = 0x16F,
|
||||
PC_VSUBUHM = 0x170,
|
||||
PC_VSUBUHS = 0x171,
|
||||
PC_VSUBUWM = 0x172,
|
||||
PC_VSUBUWS = 0x173,
|
||||
PC_VSUMSWS = 0x174,
|
||||
PC_VSUM2SWS = 0x175,
|
||||
PC_VSUM4SBS = 0x176,
|
||||
PC_VSUM4SHS = 0x177,
|
||||
PC_VSUM4UBS = 0x178,
|
||||
PC_VUPKHPX = 0x179,
|
||||
PC_VUPKHSB = 0x17A,
|
||||
PC_VUPKHSH = 0x17B,
|
||||
PC_VUPKLPX = 0x17C,
|
||||
PC_VUPKLSB = 0x17D,
|
||||
PC_VUPKLSH = 0x17E,
|
||||
PC_VXOR = 0x17F,
|
||||
PC_VMADDFP = 0x180,
|
||||
PC_VMHADDSHS = 0x181,
|
||||
PC_VMHRADDSHS = 0x182,
|
||||
PC_VMLADDUHM = 0x183,
|
||||
PC_VMSUMMBM = 0x184,
|
||||
PC_VMSUMSHM = 0x185,
|
||||
PC_VMSUMSHS = 0x186,
|
||||
PC_VMSUMUBM = 0x187,
|
||||
PC_VMSUMUHM = 0x188,
|
||||
PC_VMSUMUHS = 0x189,
|
||||
PC_VNMSUBFP = 0x18A,
|
||||
PC_VPERM = 0x18B,
|
||||
PC_VSEL = 0x18C,
|
||||
PC_VSLDOI = 0x18D,
|
||||
PC_VMR = 0x18E,
|
||||
PC_VMRP = 0x18F,
|
||||
PC_SLE = 0x190,
|
||||
PC_SLEQ = 0x191,
|
||||
PC_SLIQ = 0x192,
|
||||
PC_SLLIQ = 0x193,
|
||||
PC_SLLQ = 0x194,
|
||||
PC_SLQ = 0x195,
|
||||
PC_SRAIQ = 0x196,
|
||||
PC_SRAQ = 0x197,
|
||||
PC_SRE = 0x198,
|
||||
PC_SREA = 0x199,
|
||||
PC_SREQ = 0x19A,
|
||||
PC_SRIQ = 0x19B,
|
||||
PC_SRLIQ = 0x19C,
|
||||
PC_SRLQ = 0x19D,
|
||||
PC_SRQ = 0x19E,
|
||||
PC_MASKG = 0x19F,
|
||||
PC_MASKIR = 0x1A0,
|
||||
PC_LSCBX = 0x1A1,
|
||||
PC_DIV = 0x1A2,
|
||||
PC_DIVS = 0x1A3,
|
||||
PC_DOZ = 0x1A4,
|
||||
PC_MUL = 0x1A5,
|
||||
PC_NABS = 0x1A6,
|
||||
PC_ABS = 0x1A7,
|
||||
PC_CLCS = 0x1A8,
|
||||
PC_DOZI = 0x1A9,
|
||||
PC_RLMI = 0x1AA,
|
||||
PC_RRIB = 0x1AB,
|
||||
PC_PENTRY = 0x1AC,
|
||||
PC_PEXIT = 0x1AD,
|
||||
OPCODE_MAX = 0x1AE
|
||||
};
|
||||
|
||||
extern OpcodeInfo opcodeInfo[OPCODE_MAX];
|
||||
|
||||
extern void pcode_get_hi_lo(int a1, char a2, int *pA, int *pB);
|
||||
extern int pcode_check_imm_bits(int a1, int a2, int a3);
|
||||
extern int pcode_const_from_format(char *buf, int *pResult);
|
||||
extern PCode *vformatpcode(short opcode, va_list argList);
|
||||
extern int expectandformatoperand(PCodeArg *operand, unsigned char expectedKind, char a3, int bitCount, char *buf);
|
||||
extern int formatoperand(PCodeArg *operand, char *buf);
|
||||
extern void formatoperands(PCode *pcode, char *buf, int showBasicBlocks);
|
||||
extern PCode *makecopyinstruction(PCodeArg *a, PCodeArg *b);
|
||||
extern int is_location_independent(PCode *pcode);
|
||||
extern int can_reuse_stored_value(PCode *a, PCode *b);
|
||||
extern int nbytes_loaded_or_stored_by(PCode *pcode);
|
||||
extern void change_num_operands(PCode *pcode, int newNum);
|
||||
extern void change_opcode(PCode *pcode, short opcode);
|
226
ParserFace.c
Normal file
226
ParserFace.c
Normal file
@ -0,0 +1,226 @@
|
||||
#include "UCWInterface.h"
|
||||
|
||||
struct ParseOptsType parseopts;
|
||||
|
||||
// TODO move me imports
|
||||
extern CWResult CWSecretGetNamedPreferences(CWPluginContext context, const char *name, Handle *pHandle);
|
||||
extern CWResult CWParserSetNamedPreferences(CWPluginContext context, const char *name, Handle pHandle);
|
||||
extern CWResult CWParserGetCommandLine(CWPluginContext context, CWCommandLineArgs **pArgs);
|
||||
extern CWResult CWParserGetToolInfo(CWPluginContext context, struct ToolVersionInfo **pToolVersion);
|
||||
extern CWResult CWParserGetTargetInfo(CWPluginContext context, unsigned long *pCpu, unsigned long *pOs);
|
||||
extern CWResult CWParserGetPanels(CWPluginContext context, int *pNumPanels, char ***pPanelNames);
|
||||
extern CWResult CWParserGetPlugins(CWPluginContext context, int *pNumPlugins, struct CLPluginInfo **pPlugins);
|
||||
extern void/*?*/ CWGetPluginRequest(CWPluginContext context, long *request);
|
||||
extern void/*?*/ CWDonePluginRequest(CWPluginContext context, CWResult result);
|
||||
extern void *pTool;
|
||||
extern void SetupParserToolOptions();
|
||||
extern void CLPReportError(short code, ...);
|
||||
extern unsigned char ParserToolMatchesPlugin(unsigned long plugintype, unsigned long language, unsigned long cpu, unsigned long os);
|
||||
extern unsigned char ParserToolHandlesPanels(int numPanels, char **panelNames);
|
||||
// TODO move me imports
|
||||
|
||||
char *failedCallback;
|
||||
|
||||
static CWResult SetupParamBlock(CWPluginContext context) {
|
||||
struct PCmdLineEnvir cle;
|
||||
Handle h;
|
||||
int x;
|
||||
CWResult result;
|
||||
|
||||
memset(&parseopts, 0, sizeof(parseopts));
|
||||
parseopts.context = context;
|
||||
|
||||
result = CWSecretGetNamedPreferences(context, "CmdLine Environment", &h);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
cle = **((struct PCmdLineEnvir **) h);
|
||||
parseopts.underIDE = cle.underIDE;
|
||||
parseopts.ioRows = cle.rows;
|
||||
parseopts.ioCols = cle.cols;
|
||||
|
||||
result = CWParserGetCommandLine(context, &parseopts.args);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = CWParserGetToolInfo(context, &parseopts.toolVersion);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = CWParserGetTargetInfo(context, &parseopts.cpu, &parseopts.os);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = CWParserGetPanels(context, &parseopts.numPanels, &parseopts.panelNames);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = CWParserGetPlugins(context, &parseopts.numPlugins, &parseopts.plugins);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
parseopts.passingArgs = 0;
|
||||
for (x = 0; x < parseopts.numPlugins; x++) {
|
||||
if (parseopts.plugins[x].storeCommandLine)
|
||||
parseopts.passingArgs = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CWResult SetupOptions(CWPluginContext context) {
|
||||
if (!pTool) {
|
||||
return 2;
|
||||
} else {
|
||||
SetupParserToolOptions();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static CWResult Parse(CWPluginContext context) {
|
||||
CWResult result;
|
||||
|
||||
// TODO
|
||||
return result;
|
||||
}
|
||||
|
||||
Handle Parser_FindPrefPanel(char *name) {
|
||||
Handle h;
|
||||
int idx;
|
||||
|
||||
// TODO pTool
|
||||
}
|
||||
|
||||
CWResult Parser_StorePanels(CWPluginContext context) {
|
||||
int idx;
|
||||
CWResult result;
|
||||
char *name;
|
||||
Handle h;
|
||||
|
||||
for (idx = 0; idx < parseopts.numPanels; idx++) {
|
||||
name = parseopts.panelNames[idx];
|
||||
h = Parser_FindPrefPanel(name);
|
||||
if (h) {
|
||||
result = CWParserSetNamedPreferences(parseopts.context, name, h);
|
||||
if (result) {
|
||||
CLPReportError(68, name);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CWResult StoreResults(CWPluginContext context) {
|
||||
// TODO Arg
|
||||
}
|
||||
|
||||
short CWParser_GetDropInFlags(const DropInFlags **flags, long *flagsSize) {
|
||||
static const DropInFlags sFlags = {
|
||||
kCurrentDropInFlagsVersion,
|
||||
CWFOURCHAR('P','a','r','s'),
|
||||
7,
|
||||
0,
|
||||
'Seep',
|
||||
12
|
||||
};
|
||||
*flags = &sFlags;
|
||||
*flagsSize = sizeof(sFlags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
short CWParser_GetDropInName(const char **dropinName) {
|
||||
static const char *sDropInName = "Command-Line Parser";
|
||||
*dropinName = sDropInName;
|
||||
return 0;
|
||||
}
|
||||
|
||||
short CWParser_GetDisplayName(const char **displayName) {
|
||||
static const char *sDisplayName = "Command-Line Parser";
|
||||
*displayName = sDisplayName;
|
||||
return 0;
|
||||
}
|
||||
|
||||
short CWParser_GetPanelList(const CWPanelList **panelList) {
|
||||
static const CWPanelList sPanelList = {
|
||||
kCurrentCWFamilyListVersion,
|
||||
0,
|
||||
0
|
||||
};
|
||||
*panelList = &sPanelList;
|
||||
return 0;
|
||||
}
|
||||
|
||||
short CWParser_GetTargetList(const CWTargetList **targetList) {
|
||||
static const unsigned long sCPU = '****';
|
||||
static const unsigned long sOS = '****';
|
||||
static const CWTargetList sTargetList = {
|
||||
kCurrentCWTargetListVersion,
|
||||
1,
|
||||
&sCPU,
|
||||
1,
|
||||
&sOS
|
||||
};
|
||||
*targetList = &sTargetList;
|
||||
return 0;
|
||||
}
|
||||
|
||||
short CWParser_GetVersionInfo(const VersionInfo **versioninfo) {
|
||||
static const VersionInfo vi = {
|
||||
1, 1, 0, 0
|
||||
};
|
||||
*versioninfo = &vi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
short Parser_SupportsPlugin(struct CLPluginInfo *pluginfo, CWDataType cpu, CWDataType os, Boolean *isSupported) {
|
||||
*isSupported = ParserToolMatchesPlugin(pluginfo->plugintype, pluginfo->language, cpu, os);
|
||||
return 0;
|
||||
}
|
||||
|
||||
short Parser_SupportsPanels(int numPanels, char **panelNames, Boolean *isSupported) {
|
||||
*isSupported = ParserToolHandlesPanels(numPanels, panelNames);
|
||||
return 0;
|
||||
}
|
||||
|
||||
jmp_buf exit_plugin;
|
||||
|
||||
short parser_main(CWPluginContext context) {
|
||||
long request;
|
||||
CWResult result;
|
||||
|
||||
CWGetPluginRequest(context, &request);
|
||||
result = setjmp(exit_plugin);
|
||||
if (result == 0) {
|
||||
switch (request) {
|
||||
case reqInitialize:
|
||||
result = 0;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
result = SetupParamBlock(context);
|
||||
if (!result)
|
||||
result = Parser_StorePanels(context);
|
||||
break;
|
||||
case 2:
|
||||
result = SetupParamBlock(context);
|
||||
if (!result) {
|
||||
result = SetupOptions(context);
|
||||
if (!result) {
|
||||
result = Parse(context);
|
||||
if (!result)
|
||||
result = StoreResults(context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (failedCallback && result != 1)
|
||||
fprintf(stderr, "Unexpected error in %s [%d]\n", failedCallback, result);
|
||||
}
|
||||
CWDonePluginRequest(context, result);
|
||||
|
||||
return result;
|
||||
}
|
384
UCLTMain.c
Normal file
384
UCLTMain.c
Normal file
@ -0,0 +1,384 @@
|
||||
#include "UCWInterface.h"
|
||||
|
||||
static short CLT_dummymain() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short CLT_GetDropInFlags(const DropInFlags **flags, long *flagsSize) {
|
||||
static const DropInFlags sFlags = {
|
||||
kCurrentDropInFlagsVersion,
|
||||
CWFOURCHAR('c','l','d','r'),
|
||||
7,
|
||||
0,
|
||||
0,
|
||||
12
|
||||
};
|
||||
*flags = &sFlags;
|
||||
*flagsSize = sizeof(sFlags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short CLT_GetDropInName(const char **dropInName) {
|
||||
static const char *sDropInName = "Command-Line Driver";
|
||||
*dropInName = sDropInName;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short CLT_GetDisplayName(const char **displayName) {
|
||||
static const char *sDisplayName = "Command-Line Driver";
|
||||
*displayName = sDisplayName;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short CLT_GetPanelList(const CWPanelList **panelList) {
|
||||
static const char *sPanelNames[4];
|
||||
static CWPanelList sPanelList = {
|
||||
kCurrentCWPanelListVersion,
|
||||
4,
|
||||
sPanelNames
|
||||
};
|
||||
|
||||
sPanelNames[0] = "CmdLine Panel";
|
||||
if (clState.plugintype == CWDROPINCOMPILERTYPE) {
|
||||
sPanelNames[1] = "CmdLine Compiler Panel";
|
||||
sPanelNames[2] = "CmdLine Linker Panel";
|
||||
sPanelList.count = 3;
|
||||
} else {
|
||||
sPanelNames[1] = "CmdLine Linker Panel";
|
||||
sPanelList.count = 2;
|
||||
}
|
||||
*panelList = &sPanelList;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short CLT_GetTargetList(const CWTargetList **targetList) {
|
||||
static CWDataType sCPU = CWFOURCHAR('*','*','*','*');
|
||||
static CWDataType sOS = CWFOURCHAR('*','*','*','*');
|
||||
static CWTargetList sTargetList = {
|
||||
kCurrentCWTargetListVersion,
|
||||
1,
|
||||
&sCPU,
|
||||
1,
|
||||
&sOS
|
||||
};
|
||||
*targetList = &sTargetList;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short CLT_GetVersionInfo(const VersionInfo **versioninfo) {
|
||||
static const VersionInfo vi = {
|
||||
3, 0, 0, 0
|
||||
};
|
||||
*versioninfo = &vi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short CLT_GetFileTypeMappings(const OSFileTypeMappingList **mappingList) {
|
||||
static const OSFileTypeMapping ftmes[2] = {
|
||||
{CWFOURCHAR('B','r','w','s'), "DubL", 4, 0, 0},
|
||||
{CWFOURCHAR('M','M','P','r'), "looc", 4, 0, 0}
|
||||
};
|
||||
static const OSFileTypeMappingList ftml = {
|
||||
2,
|
||||
ftmes
|
||||
};
|
||||
*mappingList = &ftml;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BasePluginCallbacks clcb = {
|
||||
CLT_dummymain,
|
||||
CLT_GetDropInFlags,
|
||||
CLT_GetDisplayName,
|
||||
CLT_GetDropInName,
|
||||
CLT_GetPanelList,
|
||||
0,
|
||||
0,
|
||||
CLT_GetVersionInfo,
|
||||
CLT_GetFileTypeMappings
|
||||
};
|
||||
|
||||
static int RegisterStaticCmdLinePlugin() {
|
||||
return RegisterStaticPlugin(&clcb);
|
||||
}
|
||||
|
||||
const char *STR12000[100]; // TODO do me later
|
||||
|
||||
static int RegisterCmdLineResources() {
|
||||
return RegisterResource("Command-line strings", 12000, &STR12000);
|
||||
}
|
||||
|
||||
static int special_debug(unsigned char flag, char *) {
|
||||
if (flag) {
|
||||
SetupDebuggingTraps();
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int special_plugin_debug(unsigned char flag, char *) {
|
||||
if (flag) {
|
||||
clState.pluginDebug = 1;
|
||||
return 1;
|
||||
} else {
|
||||
return clState.pluginDebug;
|
||||
}
|
||||
}
|
||||
|
||||
static int special_stdout_base(unsigned char flag, char *) {
|
||||
if (flag) {
|
||||
return 1;
|
||||
} else {
|
||||
return clState.stdoutBase != 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct SpecialOption {
|
||||
const char *name;
|
||||
char **location;
|
||||
int (*callback)(unsigned char a, char *b);
|
||||
};
|
||||
static struct SpecialOption special_options[3] = {
|
||||
{"", 0, special_debug},
|
||||
{"--plugin-debug", 0, special_plugin_debug},
|
||||
{"--stdout", /*TODO clState*/ 0, special_stdout_base}
|
||||
};
|
||||
|
||||
void Main_PreParse(int *pArgc, char ***pArgv) {
|
||||
int i;
|
||||
struct SpecialOption *opt;
|
||||
|
||||
if (*pArgc > 1) {
|
||||
restart:
|
||||
for (i = 0, opt = &special_options[0]; i < 3; i++, opt++) {
|
||||
if (!strcmp(opt->name, (*pArgv)[1])) {
|
||||
if (opt->location) {
|
||||
*opt->location = (*pArgv)[2];
|
||||
opt->callback(1, *opt->location);
|
||||
(*pArgv)[1] = (*pArgv)[0];
|
||||
(*pArgc)--;
|
||||
(*pArgv)++;
|
||||
|
||||
(*pArgv)[1] = (*pArgv)[0];
|
||||
(*pArgc)--;
|
||||
(*pArgv)++;
|
||||
} else {
|
||||
opt->callback(1, 0);
|
||||
(*pArgv)[1] = (*pArgv)[0];
|
||||
(*pArgc)--;
|
||||
(*pArgv)++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*pArgc) > 1 && i < 3)
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
void Main_PassSpecialArgs(void *unk1, void *unk2) {
|
||||
int i;
|
||||
struct SpecialOption *opt;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
opt = &special_options[i];
|
||||
if (opt->callback(0, 0)) {
|
||||
AppendArgumentList(unk1, unk2, opt->name);
|
||||
if (opt->location)
|
||||
AppendArgumentList(unk1, unk2, (*opt->location) ? *opt->location : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int MainInitialized;
|
||||
void *gProj;
|
||||
PCmdLine optsCmdLine;
|
||||
PCmdLineEnvir optsEnvir;
|
||||
PCmdLineCompiler optsCompiler;
|
||||
PCmdLineLinker optsLinker;
|
||||
|
||||
int Main_Initialize(int argc, const char **argv) {
|
||||
static char secret[8];
|
||||
char buf[256];
|
||||
|
||||
OS_InitProgram(&argc, &argv);
|
||||
memset(&clState, 0, sizeof(CLState));
|
||||
special_options[0].name = secret;
|
||||
secret[7] = 0;
|
||||
secret[4] = 'b';
|
||||
secret[1] = '-';
|
||||
secret[5] = 'u';
|
||||
secret[2] = 'd';
|
||||
secret[0] = '-';
|
||||
secret[3] = 'e';
|
||||
secret[6] = 'g';
|
||||
|
||||
Main_PreParse(&argc, &argv);
|
||||
clState.argc = argc;
|
||||
clState.argv = argv;
|
||||
// TODO more shite
|
||||
|
||||
MainInitialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Main_Terminate(int code) {
|
||||
if (MainInitialized) {
|
||||
Plugins_Term();
|
||||
License_Terminate();
|
||||
Proj_Terminate(gProj);
|
||||
IO_Terminate();
|
||||
MainInitialized = 0;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int Main_ParseCommandLine() {
|
||||
// TODO: clState, Plugins, gTarg, ...
|
||||
}
|
||||
|
||||
static int Main_SetupParamBlock() {
|
||||
// TODO: OS, PrefPanes, clState, ...
|
||||
PrefPanelsChangedCallback(0);
|
||||
}
|
||||
|
||||
static int Main_ResolveProject() {
|
||||
// TODO: Various project things
|
||||
}
|
||||
|
||||
static int UpdatePCmdLineFromVersion(const PCmdLine *oldVer, PCmdLine *newVer) {
|
||||
static unsigned char warned;
|
||||
short ver = oldVer->version;
|
||||
*newVer = *oldVer;
|
||||
|
||||
// TODO: clState
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int UpdatePCmdLineEnvirFromVersion(const PCmdLineEnvir *oldVer, PCmdLineEnvir *newVer) {
|
||||
static unsigned char warned;
|
||||
short ver = oldVer->version;
|
||||
*newVer = *oldVer;
|
||||
|
||||
// TODO: clState
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int UpdatePCmdLineCompilerFromVersion(const PCmdLineCompiler *oldVer, PCmdLineCompiler *newVer) {
|
||||
static unsigned char warned;
|
||||
short ver = oldVer->version;
|
||||
*newVer = *oldVer;
|
||||
|
||||
// TODO: clState
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int UpdatePCmdLineLinkerFromVersion(const PCmdLineLinker *oldVer, PCmdLineLinker *newVer) {
|
||||
static unsigned char warned;
|
||||
short ver = oldVer->version;
|
||||
*newVer = *oldVer;
|
||||
|
||||
// TODO: clState
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int UpdatePrefPanels(const char *name) {
|
||||
PrefPanel *panel;
|
||||
Handle handle;
|
||||
|
||||
if (!name || !ustrcmp(name, "CmdLine Panel")) {
|
||||
if ((panel = Prefs_FindPanel("CmdLine Panel")) && (handle = PrefPanel_GetHandle(panel))) {
|
||||
if (name) {
|
||||
if (!UpdatePCmdLineFromVersion((PCmdLine *) *handle, &optsCmdLine))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
CLReportError(91, "CmdLine Panel");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !ustrcmp(name, "CmdLine Environment")) {
|
||||
if ((panel = Prefs_FindPanel("CmdLine Environment")) && (handle = PrefPanel_GetHandle(panel))) {
|
||||
if (name) {
|
||||
if (!UpdatePCmdLineEnvirFromVersion((PCmdLineEnvir *) *handle, &optsEnvir))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
CLReportError(91, "CmdLine Environment");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !ustrcmp(name, "CmdLine Compiler Panel")) {
|
||||
if ((panel = Prefs_FindPanel("CmdLine Compiler Panel")) && (handle = PrefPanel_GetHandle(panel))) {
|
||||
if (name) {
|
||||
if (!UpdatePCmdLineCompilerFromVersion((PCmdLineCompiler *) *handle, &optsCompiler))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
CLReportError(91, "CmdLine Compiler Panel");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !ustrcmp(name, "CmdLine Linker Panel")) {
|
||||
if ((panel = Prefs_FindPanel("CmdLine Linker Panel")) && (handle = PrefPanel_GetHandle(panel))) {
|
||||
if (name) {
|
||||
if (!UpdatePCmdLineLinkerFromVersion((PCmdLineLinker *) *handle, &optsLinker))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
CLReportError(91, "CmdLine Linker Panel");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetupCmdLinePrefPanels() {
|
||||
int result;
|
||||
|
||||
PrefPanelsChangedCallback = UpdatePrefPanels;
|
||||
result = Prefs_AddPanel(
|
||||
PrefPanel_New("CmdLine Environment", &optsEnvir, sizeof(PCmdLineEnvir))
|
||||
);
|
||||
result |= (
|
||||
Prefs_AddPanel(PrefPanel_New("CmdLine Panel", 0, sizeof(PCmdLine)))
|
||||
&& Prefs_AddPanel(PrefPanel_New("CmdLine Compiler Panel", 0, sizeof(PCmdLineCompiler)))
|
||||
&& Prefs_AddPanel(PrefPanel_New("CmdLine Linker Panel", 0, sizeof(PCmdLineLinker)))
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int Main_SetupContext() {
|
||||
// TODO Target, Plugins, clState
|
||||
return 1;
|
||||
}
|
||||
|
||||
jmp_buf exit_program;
|
||||
|
||||
int Main_Driver() {
|
||||
volatile int result;
|
||||
|
||||
result = setjmp(exit_program);
|
||||
if (!result) {
|
||||
if (!SetupCmdLinePrefPanels())
|
||||
CLFatalError("Could not initialize preferences");
|
||||
|
||||
Main_SetupContext();
|
||||
if (!(result = Main_ParseCommandLine())) {
|
||||
if (!(result = Main_SetupParamBlock()))
|
||||
result = Main_ResolveProject();
|
||||
}
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
110
UMain.c
Normal file
110
UMain.c
Normal file
@ -0,0 +1,110 @@
|
||||
#include "UCWInterface.h"
|
||||
|
||||
// 1C40 to 2008
|
||||
|
||||
// TODO move me
|
||||
// TODO move me
|
||||
|
||||
// unsure where this is, may be here, maybe not?
|
||||
extern char cmdline_build_date[32];
|
||||
extern char cmdline_build_time[32];
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
unsigned long cpu;
|
||||
unsigned long os;
|
||||
unsigned long language;
|
||||
unsigned long plugintype;
|
||||
unsigned long style;
|
||||
int result;
|
||||
|
||||
if (CmdLine_Initialize(argc, argv, CMDLINE_BUILD_DATE, CMDLINE_BUILD_TIME))
|
||||
exit(1);
|
||||
|
||||
if (!RegisterStaticParserResources() || !RegisterStaticTargetResources()) {
|
||||
fprintf(stderr, "\nFATAL ERROR: Could not initialize resource strings\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!RegisterStaticParserPlugins() || !RegisterStaticTargetPlugins()) {
|
||||
fprintf(stderr, "\nFATAL ERROR: Could not initialize built-in plugins\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!RegisterStaticParserToolInfo()) {
|
||||
fprintf(stderr, "\nFATAL ERROR: Could not initialize options\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
GetStaticTarget(&cpu, &os);
|
||||
SetBuildTarget(cpu, os);
|
||||
GetStaticPluginType(&language, &plugintype);
|
||||
SetPluginType(language, plugintype);
|
||||
GetStaticParserPluginType(&style);
|
||||
SetParserType(style);
|
||||
|
||||
result = CmdLine_Driver();
|
||||
if (result) {
|
||||
if (result == 2)
|
||||
fprintf(stderr, "\nUser break, cancelled...\n");
|
||||
else
|
||||
fprintf(stderr, "\nErrors caused tool to abort.\n");
|
||||
}
|
||||
CmdLine_Terminate(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int RegisterResource(const char *name, short index, void *data) {
|
||||
Handle r;
|
||||
|
||||
if (data == 0) {
|
||||
r = GetResource('STR#', index);
|
||||
if (r == 0) {
|
||||
CLFatalError("Resource ('STR#',%d) '%s' not found in executable\n", index, name);
|
||||
return 0;
|
||||
}
|
||||
ReleaseResource(r);
|
||||
return 1;
|
||||
} else {
|
||||
return Res_AddResource(name, index, data);
|
||||
}
|
||||
}
|
||||
|
||||
int RegisterStaticPlugin(const BasePluginCallbacks *cb) {
|
||||
return Plugins_Add(Plugin_New(cb, 0, 0));
|
||||
}
|
||||
|
||||
int RegisterStaticCompilerLinkerPlugin(const BasePluginCallbacks *cb, void *b) {
|
||||
return Plugins_Add(Plugin_New(cb, b, 0));
|
||||
}
|
||||
|
||||
int RegisterStaticParserPlugin(const BasePluginCallbacks *cb, void *b) {
|
||||
return Plugins_Add(Plugin_New(cb, 0, b));
|
||||
}
|
||||
|
||||
void SetBuildTarget(CWDataType cpu, CWDataType os) {
|
||||
clState.cpu = cpu;
|
||||
clState.os = os;
|
||||
}
|
||||
|
||||
void SetParserType(CWDataType style) {
|
||||
clState.style = style;
|
||||
}
|
||||
|
||||
void SetPluginType(CWDataType language, CWDataType plugintype) {
|
||||
clState.language = language;
|
||||
clState.plugintype = plugintype;
|
||||
}
|
||||
|
||||
int CmdLine_Initialize(int argc, const char **argv, const char *buildDate, const char *buildTime) {
|
||||
strncpy(cmdline_build_date, buildDate, sizeof(cmdline_build_date));
|
||||
strncpy(cmdline_build_time, buildTime, sizeof(cmdline_build_time));
|
||||
return Main_Initialize(argc, argv);
|
||||
}
|
||||
|
||||
int CmdLine_Driver() {
|
||||
return Main_Driver();
|
||||
}
|
||||
|
||||
int CmdLine_Terminate(int code) {
|
||||
return Main_Terminate(code);
|
||||
}
|
1918
mwcc_decomp.h
Normal file
1918
mwcc_decomp.h
Normal file
File diff suppressed because it is too large
Load Diff
1
sdk_hdrs/CWDropInPanel.h
Executable file
1
sdk_hdrs/CWDropInPanel.h
Executable file
File diff suppressed because one or more lines are too long
1
sdk_hdrs/CWPluginErrors.h
Executable file
1
sdk_hdrs/CWPluginErrors.h
Executable file
@ -0,0 +1 @@
|
||||
/*
* CWPluginErrors.h - CW_Result constants for plugin errors
*
* Copyright © 1995-1997 Metrowerks, Inc. All rights reserved.
*
*/
#ifndef __CWPluginErrors_H__
#define __CWPluginErrors_H__
#ifdef __MWERKS__
# pragma once
#endif
enum
{
// common errors for all plugins
cwNoErr, /* successful return */
cwErrUserCanceled, /* operation canceled by user */
cwErrRequestFailed, /* generic failure when plugin fails */
cwErrInvalidParameter, /* one or more callback parameters invalid */
cwErrInvalidCallback, /* invalid given current request and plugin type*/
cwErrInvalidMPCallback, /* this request is not support from MP threads */
cwErrOSError, /* OS-specific, call CWGetCallbackOSError() */
cwErrOutOfMemory, /* not enough memory */
cwErrFileNotFound, /* file not found on disk */
cwErrUnknownFile, /* bad file number, doesn't exist */
cwErrSilent, /* request failed but plugin didn't report any */
/* errors and doesn't want IDE to report that */
/* an unknown error occurred */
cwErrCantSetAttribute, /* plugin requested inapplicable file flags in */
/* CWAddProjectEntry */
cwErrStringBufferOverflow, /* an output string buffer was too small */
cwErrDirectoryNotFound, /* unable to find a directory being sought */
cwErrLastCommonError = 512,
// compiler/linker errors
cwErrUnknownSegment, /* bad segment number, doesn't exist */
cwErrSBMNotFound, /* */
cwErrObjectFileNotStored, /* No external object file has been stored */
cwErrLicenseCheckFailed,/* license check failed, error reported by IDE */
cwErrFileSpecNotSpecified, /* a file spec was unspecified */
cwErrFileSpecInvalid, /* a file spec was invalid */
cwErrLastCompilerLinkerError = 1024
};
#endif // __CWPluginErrors_H__
|
1
sdk_hdrs/CWPlugins.h
Executable file
1
sdk_hdrs/CWPlugins.h
Executable file
File diff suppressed because one or more lines are too long
1
sdk_hdrs/CWRuntimeFeatures.h
Executable file
1
sdk_hdrs/CWRuntimeFeatures.h
Executable file
File diff suppressed because one or more lines are too long
1
sdk_hdrs/CWUnixPluginPrefix.h
Executable file
1
sdk_hdrs/CWUnixPluginPrefix.h
Executable file
@ -0,0 +1 @@
|
||||
/*
* CWUnixPluginPrefix.h
*
* Copyright © 1999 Metrowerks, Inc. All rights reserved.
*
*/
#ifndef MW_CWUnixPluginPrefix_H
#define MW_CWUnixPluginPrefix_H
#define CW_USE_PRAGMA_EXPORT 0
#include "CWRuntimeFeatures.h"
#ifdef __MWERKS__
#if !__option(bool)
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#endif
#endif
#endif /* MW_CWUnixPluginPrefix_H */
|
1
sdk_hdrs/CWWinPluginPrefix.h
Executable file
1
sdk_hdrs/CWWinPluginPrefix.h
Executable file
@ -0,0 +1 @@
|
||||
#include <Win32Headers.mch>
#ifndef WIN32
#define WIN32 1
#endif
#define CW_USE_PRAGMA_EXPORT 0
#ifdef __MWERKS__
#if !__option(bool)
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#endif
#endif
|
1
sdk_hdrs/CatTypes.h
Executable file
1
sdk_hdrs/CatTypes.h
Executable file
@ -0,0 +1 @@
|
||||
#ifndef __CATTYPES_H__
#define __CATTYPES_H__
typedef int CatNodeID;
#define NODE_NULL -1
#define NODE_ROOT 0
#define kCatalogClass "CodeWarrior.CatalogModelObject"
#define kFolderClass "CodeWarrior.FolderModelObject"
#define kTrashNodeClass "CodeWarrior.TrashNode"
// internal properties used in the catalog
#define kContentsFolder "ContentsFolder"
#define kClass "Class"
#define kComments "Comments"
#define kFile "File"
#define kNodeLocked "Locked"
#define kModDate "Modified"
#define kName "Name"
#define kID "ID"
#define kFolderSuffix "_Contents"
#define kDefCatalogExt "ctlg"
#define kDefCatalogFolderExt "ctlgf"
// Command group ID for commands in the catalog menu...
const long cmdGroup_CatalogMenu = 10000;
// catalog-specific menu commands to go with those defined by the IDE;
// such as cmd_Cut, cmd_Copy, etc.
const long cmd_CatalogRename = 10000; // plugin commands in the range 10000-10999
const long cmd_CatalogProperties = 10001;
const long cmd_ShowCatalogBrowser = 10002;
const long cmd_ShowCatalogPalette = 10003;
const long cmd_NewCatalog = 10004;
const long cmd_NewFolder = 10005;
const long cmd_OpenCatalog = 10006;
const long cmd_CloseCatalog = 10007;
const long cmd_ImportControls = 10008;
const long cmd_ShowPrevious = 10009;
const long cmd_ShowNext = 10010;
const long cmd_ExpandIndexView = 10011;
const long cmd_CollapseIndexView = 10012;
const long cmd_ToggleIndexView = 10013;
const long cmd_CloseCatalogPalette = 10014;
enum UPDATE_TYPE
{
UPDATE_NONE = 0,
UPDATE_CHILDREN,
UPDATE_DESCENDANTS
};
enum CatTransType
{
CATTRANS_TYPE_UNKNOWN,
CATTRANS_TYPE_ALIAS,
CATTRANS_TYPE_COPY,
CATTRANS_TYPE_DELETE,
CATTRANS_TYPE_DROP,
CATTRANS_TYPE_EDITPROPERTIES,
CATTRANS_TYPE_LOCK,
CATTRANS_TYPE_MOVE,
CATTRANS_TYPE_PASTE,
CATTRANS_TYPE_RENAME,
CATTRANS_TYPE_UNLOCK
};
struct CatWindowData
{
bool fUseDefSize;
bool fUseDefPos;
SIZE size;
POINT pos;
CatWindowData() : fUseDefSize(true), fUseDefPos(true)
{
pos.x = pos.y = 0;
size.cx = size.cy = 0;
}
};
#endif // __CATTYPES_H__
|
1
sdk_hdrs/CompilerMapping.h
Executable file
1
sdk_hdrs/CompilerMapping.h
Executable file
File diff suppressed because one or more lines are too long
1
sdk_hdrs/DropInCompilerLinker.h
Executable file
1
sdk_hdrs/DropInCompilerLinker.h
Executable file
File diff suppressed because one or more lines are too long
1
sdk_hdrs/DropInPanel.h
Executable file
1
sdk_hdrs/DropInPanel.h
Executable file
File diff suppressed because one or more lines are too long
1
sdk_hdrs/DropInPanelWin32.h
Executable file
1
sdk_hdrs/DropInPanelWin32.h
Executable file
@ -0,0 +1 @@
|
||||
/*
DropInPanelWin32.h
This is the old name for the file that is now called CWDropInPanel.h.
It is here for backward compatibility with older panels. New panels
should include CWDropInPanel.h instead.
*/
#ifndef __DROPINPANELWIN32_H__
#define __DROPINPANELWIN32_H__
#include "CWDropInPanel.h"
#endif
|
1
sdk_hdrs/DropInVCS.h
Executable file
1
sdk_hdrs/DropInVCS.h
Executable file
File diff suppressed because one or more lines are too long
1
sdk_hdrs/MWBrowse.h
Executable file
1
sdk_hdrs/MWBrowse.h
Executable file
@ -0,0 +1 @@
|
||||
/*
* MWBrowse.h
*
* Copyright © 1993-96 Metrowerks, Inc. All rights reserved.
*
* Types and constants needed for emitting CodeWarrior
* browse information.
*/
#ifndef __MWBROWSE_H__
#define __MWBROWSE_H__
#ifdef __MWERKS__
#pragma once
#endif
#include "MWLangDefs.h"
#ifdef __MWERKS__
#pragma options align=mac68k
#endif
#ifdef _MSC_VER
#pragma pack(push,2)
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define BROWSE_HEADER 0xBEABBAEB
#define BROWSE_VERSION 2
#define BROWSE_EARLIEST_COMPATIBLE_VERSION 2
typedef struct BrowseHeader {
long browse_header; // always set to BROWSE_HEADER
long browse_version; // always set to BROWSE_VERSION
short browse_language; // the language of this translation unit, enum ELanguage
short uses_name_table; // TRUE: uses name table from CW object code
long earliest_compatible_version;// always set to BROWSE_EARLIEST_COMPATIBLE_VERSION
long reserved[15]; // for future extensions
} BrowseHeader;
typedef unsigned char EBrowserItem;
enum {
browseFunction, // function, procedure, or method
browseGlobal, // global variable
browseClass, // class, struct, or union
browseMacro, // macro
browseEnum, // enum, enumerated type member
browseTypedef, // user-defined type other than class
browseConstant, // constant value
browseTemplate, // C++ template
browsePackage, // Java package
browseCompSymbolStart = 0x70,
browseEnd = 0xFF // used to denote end-of-list
};
// flag constants for functions, member functions, data members
enum
{
kAbstract = 1, // abstract/pure virtual
kStatic = 2, // static member
kFinal = 4, // final Java class, method, or data member
kMember = 8, // item is a class member
// reserve flags 0x10, 0x20, and 0x40 for other general flags
// flags specific to classes
kInterface = 0x80, // class is Java interface
kPublic = 0x100, // class is public Java class
// flags specific to functions and member functions
kInline = 0x80, // inline function
kPascal = 0x100, // pascal function
kAsm = 0x200, // asm function
kVirtual = 0x400, // virtual member function
kCtor = 0x800, // is constructor
kDtor = 0x1000, // is destructor
kNative = 0x2000, // native Java method
kSynch = 0x4000, // synchronized Java method
kIntrinsic = 0x8000, // intrinsic routine (for General Magic)
kConst = 0x10000, // const function
// flags specific to data members
kTransient = 0x80, // transient Java data member
kVolatile = 0x100 // volatile Java data member
};
typedef enum EAccess
{ // can be used as mask values
accessNone = 0,
accessPrivate = 1,
accessProtected = 2,
accessPublic = 4,
accessAll = accessPrivate+accessProtected+accessPublic
} EAccess;
typedef unsigned char EMember;
enum
{
memberFunction, // member function/method
memberData, // data member/field
memberEnd = 0xFF // denotes end-of-list
};
typedef enum ETemplateType
{ // templates are either class or function templates
templateClass,
templateFunction
} ETemplateType;
/********************************************************************************/
/* Old (pre-CW9) browse data support definitions */
/********************************************************************************/
#define BROWSE_OLD_VERSION 0
enum {
BROWSE_SCOPE_STATIC, // local to this file
BROWSE_SCOPE_EXTERN // global to all files
};
enum {
BROWSE_OBJECT_FUNCTION, // function object
BROWSE_OBJECT_DATA // data object
};
enum { // browse data types
BROWSE_END, // end of browse data
BROWSE_OBJECT // a function/data definition
};
typedef struct BrowseObjectDef {
short type; // always BROWSE_OBJECT
short size; // size of following data
char object_type; // one of: (BROWSE_OBJECT_FUNCTION,BROWSE_OBJECT_DATA)
char object_scope; // one of: (BROWSE_SCOPE_STATIC,BROWSE_SCOPE_EXTERN)
long source_offset; // offset of declartation in source code
// char name[...]; followed by padded object name (c-string)
// char classname[...]; followed by padded class name string (c-string)
} BrowseObjectDef;
typedef struct BrowseHeader_Old {
long browse_header; // always set to BROWSE_HEADER
long browse_version; // always set to BROWSE_VERSION
long reserved[14]; // for future extensions
} BrowseHeader_Old;
#ifdef __cplusplus
}
#endif
#ifdef _MSC_VER
#pragma pack(pop)
#endif
#ifdef __MWERKS__
#pragma options align=reset
#endif
#endif // __MWBROWSE_H__
|
1
sdk_hdrs/MWLangDefs.h
Executable file
1
sdk_hdrs/MWLangDefs.h
Executable file
@ -0,0 +1 @@
|
||||
/*
* MWLangDefs.h
*
* Copyright © 1994-1996 metrowerks inc. All rights reserved.
*
* Language constants.
*/
#ifndef MWLangDefs_H
#define MWLangDefs_H
enum ELanguage
{
langUnknown,
langC,
langCPlus,
langPascal,
langObjectPascal,
langJava,
langAssembler, // don't care which assembler
langFortran,
langRez
};
#endif // !MWLangDefs_H
|
3
setup.sh
Normal file
3
setup.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#export MWCIncludes=/Applications/Metrowerks\ CodeWarrior\ 7.0/Metrowerks\ CodeWarrior/MacOS\ Support/Universal/Interfaces/CIncludes:/Applications/Metrowerks\ CodeWarrior\ 7.0/Metrowerks\ CodeWarrior/MSL/MSL_C/MSL_Common/Include
|
||||
#export MWCIncludes=/usr/include
|
||||
export MWCIncludes=/Applications/Metrowerks\ CodeWarrior\ 7.0/Metrowerks\ CodeWarrior/MacOS\ X\ Support/MacHeaders\ Mach-O
|
Loading…
x
Reference in New Issue
Block a user