reorganise things a bit to align further with the actual names/structure

This commit is contained in:
Ash Wolf
2023-01-15 12:14:05 +00:00
parent 8078e7f897
commit 35d488e972
84 changed files with 920 additions and 917 deletions

View File

@@ -0,0 +1,590 @@
#include "parser.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;
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_ARG && 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_ARG_END && (pprev->val == ATK_COMMA || pprev->val == ATK_EQUALS) && (ppprev->val != ATK_ARG || pppprev->val != ATK_OPTION)) {
if (parserDebug)
printf("Coalescing args with '%s'\n", Arg_GetTokenName(pprev));
val = pprev->val;
numargtoks -= 2;
} else if (pprev->val == ATK_ARG_END && ((int) val == ATK_COMMA || (int) val == ATK_EQUALS)) {
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(void) {
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(CLPStr74, (short) err, "response ", name);
return 0;
} else {
respfilestart = respfile;
Arg_SkipRespFileWS();
in_response_file = 1;
return 1;
}
}
static void Arg_CloseRespFile(void) {
in_response_file = 0;
OS_FreeFileHandle(&respfilehandle);
}
static char *Arg_GetRespFileToken(void) {
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(void) {
if (!in_response_file)
return margind < margc;
else if (respfile[0])
return 1;
else
return margind < margc;
}
static void Arg_Parse(void) {
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_ARG_END, 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(CLPStr2, argstart, argstart + strlen(argstart) - 15, sizeof(buffer));
}
*bufptr = 0;
} else {
if (isOpt) {
Arg_AddToken(ATK_OPTION, buffer);
Arg_AddToken(ATK_ARG, buffer);
} else {
Arg_AddToken(ATK_ARG, buffer);
}
Arg_AddToken(
(unsigned char) ((ch == ',') ? ATK_COMMA : (((ch == '=') || (ch == SEP3)) ? ATK_EQUALS : ATK_END)),
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_OPTION, buffer + (isList && strchr(MAINOPTCHAR, buffer[0])));
Arg_AddToken(ATK_ARG, buffer + (isList && strchr(MAINOPTCHAR, buffer[0])) + 1);
} else {
Arg_AddToken(ATK_ARG, buffer);
Arg_AddToken(ATK_ARG_END, 0);
}
}
if (isOpt || isList)
Arg_AddToken(ATK_ARG_END, 0);
Arg_AddToken(ATK_END, 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(void) {
ArgToken *cur;
while (numargtoks > 0) {
cur = &argtoks[--numargtoks];
if (cur->text)
free(cur->text);
}
if (maxargtoks)
free(argtoks);
maxargtoks = 0;
}
void Arg_Reset(void) {
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_END;
cur->text = 0;
}
argtoks[numargtoks++].val = ATK_ARG_END;
argtoks[numargtoks++].val = ATK_END;
scantok = numargtoks - 2;
}
ArgToken *Arg_PeekToken(void) {
if (scantok >= numargtoks)
return 0;
else
return &argtoks[scantok];
}
ArgToken *Arg_UsedToken(void) {
if (scantok < numargtoks)
scantok++;
return Arg_PeekToken();
}
int Arg_IsEmpty(void) {
ArgToken *tok;
tok = Arg_PeekToken();
return (tok == 0 || tok->val == ATK_END);
}
ArgToken *Arg_GetToken(void) {
ArgToken *ret;
ret = Arg_PeekToken();
if (ret)
scantok++;
return ret;
}
ArgToken *Arg_UndoToken(void) {
if (scantok > 0) {
scantok--;
return Arg_PeekToken();
} else {
return 0;
}
}
const char *Arg_GetTokenName(ArgToken *tok) {
if ((int) tok->val == ATK_ARG)
return tok->text;
return
((int) tok->val == ATK_OPTION) ? "option" :
((int) tok->val == ATK_COMMA) ? "comma" :
(((int) compat == COMPAT_1 && (int) tok->val == ATK_EQUALS)) ? "colon or equals" :
(((int) compat != COMPAT_1 && (int) tok->val == ATK_EQUALS)) ? "equals" :
((int) tok->val == ATK_ARG_END) ? "end of argument" :
((int) tok->val == ATK_END) ? "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_ARG || tok->val == ATK_OPTION)
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(CLPStr56, 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_END:
Arg_FinishToolArgs(ta);
break;
case ATK_ARG_END:
if (ta->argv && ta->argv[ta->argc])
Arg_GrowArgs(ta);
break;
case ATK_ARG:
Arg_GrowArg(ta, toktxt);
break;
case ATK_OPTION:
Arg_GrowArg(ta, "-");
break;
case ATK_EQUALS:
Arg_GrowArg(ta, "=");
break;
case ATK_COMMA:
Arg_GrowArg(ta, ",");
break;
default:
CLPFatalError(__FILE__, 787, "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);
}
}

View File

@@ -0,0 +1,561 @@
#include "parser.h"
typedef struct _Side {
short offset;
short width;
char buffer[1024];
short bptr;
short blen;
short indent;
short vrow;
short vcol;
Boolean atEOL;
Boolean impInd;
} Side;
short helpExtras;
Boolean 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(void);
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(void) {
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(void) {
Help_Output(&left, &right);
}
static void Help_NewLine(void) {
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 & OTF_HAS_SUB_OPTIONS)) {
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 & OTF_STICKY)
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 & OTF_STICKY) && !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 & OTF_HIDE_DEFAULT)) {
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 & OTF_HIDE_DEFAULT)) {
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 & OTF_HAS_SUB_OPTIONS) && opt->sub) {
if (!allNoArgs) {
Side_Print(
&left,
"%s",
(opt->avail & OTF_SUB_OPTIONS_OPTIONAL) ? ((lastparam->flags & PARAMFLAGS_8) ? "[=" : "[,") : ((lastparam->flags & PARAMFLAGS_8) ? "=" : ",")
);
} else if (!(opt->avail & OTF_STICKY)) {
if (opt->avail & OTF_SUB_OPTIONS_OPTIONAL) {
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 & OTF_SUB_OPTIONS_OPTIONAL) {
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 & OTF_SUB_OPTIONS_OPTIONAL) ? "]" : ""
);
Side_Print(&left, "\t");
Side_Print(&right, "\t");
Help_Options(opt->sub, 1, "");
Side_Print(&right, "\b");
Side_Print(&left, "\b");
} else {
Side_Print(&left, "\n");
Side_Print(&right, "\n");
}
}
Help_Flush();
return 1;
}
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() == 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(void) {
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(void) {
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(void) {
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(void) {
ShowTextHandle(0, helptext);
DisposeHandle(helptext);
}

View File

@@ -0,0 +1,83 @@
#include "parser.h"
void ShowTextHandle(const char *description, Handle text) {
CWMemHandle mh;
if (!text)
return;
if (description)
CLPStatus(71, description);
CWSecretAttachHandle(parseopts.context, text, &mh);
CWParserDisplayTextHandle(parseopts.context, description, mh);
}
void ShowVersion(Boolean decorate) {
char *vplugin;
char *valtplugin;
const char *bdate;
const char *btime;
Handle txt;
int x;
vplugin = 0;
valtplugin = 0;
if (parseopts.printedVersion)
return;
txt = NewHandle(0);
if (!txt) {
fprintf(stderr, "\n*** Out of memory\n");
exit(-23);
}
for (x = 0; x < parseopts.numPlugins; x++) {
if (parseopts.plugins[x].plugintype == CWDROPINDRIVERTYPE) continue;
if (parseopts.plugins[x].plugintype == CWDROPINPARSERTYPE) continue;
if (pTool->TYPE == parseopts.plugins[x].plugintype) {
if (!vplugin && pTool->LANG == parseopts.plugins[x].language)
vplugin = parseopts.plugins[x].version;
else
valtplugin = parseopts.plugins[x].version;
}
}
CWParserGetBuildDate(parseopts.context, &bdate, &btime);
HPrintF(txt, "\n");
if (parseopts.toolVersion) {
HPrintF(
txt,
"%s.\n%s, %s\nAll rights reserved.\n%s\n",
pTool->toolInfo,
parseopts.toolVersion->copyright,
parseopts.toolVersion->company,
parseopts.toolVersion->version
);
} else {
HPrintF(
txt,
"%s.\nCopyright (c)%s Metrowerks, Inc.\nAll rights reserved.\n%s\n",
pTool->toolInfo,
pTool->copyright,
vplugin ? vplugin : valtplugin ? valtplugin : ""
);
}
HPrintF(txt, "Runtime Built: %s %s\n", bdate, btime);
HPrintF(txt, "\n");
if (decorate) {
HPrintF(
txt,
"Please enter '%s %chelp' for information about options.\n\n",
OS_GetFileNamePtr(parseopts.args->argv[0]),
MAINOPTCHAR[0]
);
}
ShowTextHandle(0, txt);
DisposeHandle(txt);
parseopts.printedVersion = 1;
}

View File

@@ -0,0 +1,166 @@
#include "parser.h"
Boolean setOldOptimizerOptions;
typedef struct {
Boolean commonsubs;
Boolean loopinvariants;
Boolean propagation;
Boolean deadstore;
Boolean strengthreduction;
Boolean deadcode;
Boolean lifetimes;
} PIROptimizer; // assumed name
static PIROptimizer pIrOptimizer = {0};
Pragma irPragmas[] = {
&pIrOptimizer.commonsubs, "opt_common_subs", 0,
&pIrOptimizer.loopinvariants, "opt_loop_invariants", 0,
&pIrOptimizer.propagation, "opt_propagation", 0,
&pIrOptimizer.deadstore, "opt_dead_assignments", 0,
&pIrOptimizer.deadcode, "opt_dead_code", 0,
&pIrOptimizer.strengthreduction, "opt_strength_reduction", 0,
&pIrOptimizer.lifetimes, "opt_lifetimes", 0,
0, 0, 0
};
int SetPragmaOptimizationsToUnspecified(const char *opt, void *, const char *, int) {
if (setOldOptimizerOptions)
Option_Warning(CLPStr62);
memset(&pIrOptimizer, 0, sizeof(pIrOptimizer));
TargetSetPragmaOptimizationsToUnspecified();
return 1;
}
int SetOptFlags(const char *opt, void *str, const char *, int flags) {
// this is very similar to ToolHelper
// might also fail to match
unsigned char *ptr;
Boolean set;
Boolean no;
UInt16 flag;
ptr = (unsigned char *) str;
no = (Boolean) ((flags & PARAMPARSEFLAGS_8) >> 3);
set = (Boolean) (no ^ 1);
while (*ptr) {
if (*ptr == '+') {
set = !no;
} else if (*ptr == '-') {
set = no;
} else if (*ptr == '|') {
set = (Boolean) (no ^ 1);
} else {
flag = (ptr[0] << 8) | ptr[1];
if ((flag >= 'G0' && flag <= 'G4') || (flag == 'Gs') || (flag == 'Gp'))
SetPragmaOptimizationsToUnspecified(opt, NULL, NULL, 0);
switch (flag) {
case 'Cs':
pIrOptimizer.commonsubs = set ? 1 : 2;
setOldOptimizerOptions = 1;
break;
case 'Li':
pIrOptimizer.loopinvariants = set ? 1 : 2;
setOldOptimizerOptions = 1;
break;
case 'Pr':
pIrOptimizer.propagation = set ? 1 : 2;
setOldOptimizerOptions = 1;
break;
case 'Ds':
pIrOptimizer.deadstore = set ? 1 : 2;
setOldOptimizerOptions = 1;
break;
case 'Sr':
pIrOptimizer.strengthreduction = set ? 1 : 2;
setOldOptimizerOptions = 1;
break;
case 'Dc':
pIrOptimizer.deadcode = set ? 1 : 2;
setOldOptimizerOptions = 1;
break;
case 'Lt':
pIrOptimizer.lifetimes = set ? 1 : 2;
setOldOptimizerOptions = 1;
break;
case 'G0':
pGlobalOptimizer.optimizationlevel = set ? 0 : 0;
break;
case 'G1':
pGlobalOptimizer.optimizationlevel = set ? 1 : 0;
break;
case 'G2':
pGlobalOptimizer.optimizationlevel = set ? 2 : 0;
break;
case 'G3':
pGlobalOptimizer.optimizationlevel = set ? 3 : 0;
break;
case 'G4':
pGlobalOptimizer.optimizationlevel = set ? 4 : 0;
break;
case 'Gs':
pGlobalOptimizer.optfor = set ? 1 : 0;
break;
case 'Gp':
pGlobalOptimizer.optfor = set ? 0 : 1;
break;
default:
if (!TargetSetOptFlags(flag, set))
CLPFatalError("Bad optimizer settings in %s (%c%c)\n", str, ptr[0], ptr[1]);
}
++ptr;
}
++ptr;
}
return 1;
}
int DisplayOptimizationOptions(const char *, void *, const char *, int) {
SInt32 oldsize;
Handle h;
h = NewHandle(0);
if (!h)
exit(-23);
HPrintF(h, "\t- global optimizer level %d\n", pGlobalOptimizer.optimizationlevel);
HPrintF(h, "\t- global optimize for %s\n", (pGlobalOptimizer.optfor == 0) ? "speed" : "size");
oldsize = GetHandleSize(h);
if (pIrOptimizer.commonsubs)
HPrintF(h, "\t- common subexpression elimination %s\n", (pIrOptimizer.commonsubs == 1) ? "on" : "off");
if (pIrOptimizer.loopinvariants)
HPrintF(h, "\t- loop invariants %s\n", (pIrOptimizer.loopinvariants == 1) ? "on" : "off");
if (pIrOptimizer.commonsubs)
HPrintF(h, "\t- constant propagation %s\n", (pIrOptimizer.propagation == 1) ? "on" : "off");
if (pIrOptimizer.deadstore)
HPrintF(h, "\t- dead store elimination %s\n", (pIrOptimizer.deadstore == 1) ? "on" : "off");
if (pIrOptimizer.deadcode)
HPrintF(h, "\t- dead code elimination %s\n", (pIrOptimizer.deadcode == 1) ? "on" : "off");
if (pIrOptimizer.strengthreduction)
HPrintF(h, "\t- strength reduction %s\n", (pIrOptimizer.strengthreduction == 1) ? "on" : "off");
if (pIrOptimizer.lifetimes)
HPrintF(h, "\t- variable lifetimes %s\n", (pIrOptimizer.lifetimes == 1) ? "on" : "off");
if (oldsize == GetHandleSize(h))
HPrintF(h, "\t- no extra global optimizations\n");
HPrintF(h, "Backend-specific optimizer options:\n");
oldsize = GetHandleSize(h);
TargetDisplayOptimizationOptions(h);
if (oldsize == GetHandleSize(h))
HPrintF(h, "\t- no extra backend-specific optimizations\n");
ShowTextHandle(NULL, h);
DisposeHandle(h);
return 1;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
#include "parser.h"
static char errorbuf[1024];
void CLPReportError_V(const char *format, va_list ap) {
vsprintf(errorbuf, format, ap);
CWReportMessage(parseopts.context, NULL, errorbuf, NULL, messagetypeError, 0);
parseopts.hadErrors = 1;
}
void CLPReportWarning_V(const char *format, va_list ap) {
vsprintf(errorbuf, format, ap);
CWReportMessage(parseopts.context, NULL, errorbuf, NULL, messagetypeWarning, 0);
}
void CLPReport_V(const char *format, va_list ap) {
vsprintf(errorbuf, format, ap);
CWReportMessage(parseopts.context, NULL, errorbuf, NULL, messagetypeInfo, 0);
}
void CLPStatus_V(const char *format, va_list ap) {
vsprintf(errorbuf, format, ap);
CWShowStatus(parseopts.context, errorbuf, NULL);
}
void CLPAlert_V(const char *format, va_list ap) {
vsprintf(errorbuf, format, ap);
CWAlert(parseopts.context, errorbuf, NULL, NULL, NULL);
parseopts.hadErrors = 1;
}
void CLPOSAlert_V(const char *format, SInt32 err, va_list ap) {
vsprintf(errorbuf, format, ap);
CWAlert(parseopts.context, errorbuf, "Operating system error:", OS_GetErrText(err), NULL);
}
char *CLPGetErrorString(SInt16 errid, char *buffer) {
getindstring(buffer, 12010, errid);
return buffer;
}
void CLPReportError(SInt16 errid, ...) {
char format[256];
va_list va;
CLPGetErrorString(errid, format);
va_start(va, errid);
CLPReportError_V(format, va);
va_end(va);
}
void CLPReportWarning(SInt16 errid, ...) {
char format[256];
va_list va;
CLPGetErrorString(errid, format);
va_start(va, errid);
CLPReportWarning_V(format, va);
va_end(va);
}
void CLPReport(SInt16 errid, ...) {
char format[256];
va_list va;
CLPGetErrorString(errid, format);
va_start(va, errid);
CLPReport_V(format, va);
va_end(va);
}
void CLPAlert(SInt16 errid, ...) {
char format[256];
va_list va;
CLPGetErrorString(errid, format);
va_start(va, errid);
CLPAlert_V(format, va);
va_end(va);
}
void CLPOSAlert(SInt16 errid, SInt16 err, ...) {
char format[256];
va_list va;
CLPGetErrorString(errid, format);
va_start(va, err);
CLPOSAlert_V(format, err, va);
va_end(va);
}
void CLPProgress(SInt16 errid, ...) {
char format[256];
va_list va;
CLPGetErrorString(errid, format);
va_start(va, errid);
CLPStatus_V(format, va);
va_end(va);
}
void CLPStatus(SInt16 errid, ...) {
char format[256];
va_list va;
CLPGetErrorString(errid, format);
va_start(va, errid);
CLPStatus_V(format, va);
va_end(va);
}
void CLPFatalError(const char *format, ...) {
va_list va;
va_start(va, format);
CLPAlert_V(format, va);
va_end(va);
longjmp(exit_plugin, -123);
}

View File

@@ -0,0 +1,298 @@
#include "parser.h"
const char *failedCallback;
jmp_buf exit_plugin;
ParseOptsType parseopts;
static CWResult SetupParamBlock(CWPluginContext context) {
CWResult result;
int x;
Handle h;
PCmdLineEnvir cle;
memset(&parseopts, 0, sizeof(parseopts));
parseopts.context = context;
result = CWSecretGetNamedPreferences(context, "CmdLine Environment", &h);
if (result)
return result;
cle = **((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;
parseopts.success = 1;
parseopts.currentSegment = 1;
parseopts.currentOverlayGroup = 0;
parseopts.currentOverlay = 0;
Arg_InitToolArgs(&linkargs);
Arg_InitToolArgs(&prelinkargs);
Arg_InitToolArgs(&postlinkargs);
if (pTool->PreParse)
parseopts.success &= pTool->PreParse();
Arg_Init(parseopts.args->argc, parseopts.args->argv);
parseopts.noOptions = Arg_IsEmpty();
parseopts.success &= Options_Parse(Options_GetOptions(), OFLAGS_1) && !parseopts.hadErrors;
Arg_Reset();
result = Parser_StorePanels(context);
if (result)
return result;
if (pTool->MidParse && parseopts.success)
parseopts.success &= pTool->MidParse();
result = Parser_StorePanels(context);
if (result)
return result;
if (parseopts.showHelp && parseopts.success)
parseopts.success &= Options_DisplayHelp();
Arg_Reset();
if (parseopts.success)
parseopts.success &= Options_Parse(Options_GetOptions(), 0) && !parseopts.hadErrors;
if (pTool->PostParse && parseopts.success)
parseopts.success &= pTool->PostParse();
Arg_Terminate();
return (parseopts.success && !parseopts.hadErrors) ? cwNoErr : cwErrRequestFailed;
}
Handle Parser_FindPrefPanel(const char *name) {
int idx;
Handle h;
for (idx = 0; idx < pTool->numPrefDataPanels; idx++) {
if (!ustrcmp(name, pTool->prefDataPanels[idx].name)) {
h = NewHandle(pTool->prefDataPanels[idx].size);
if (!h)
return NULL;
HLock(h);
memcpy(*h, pTool->prefDataPanels[idx].ptr, pTool->prefDataPanels[idx].size);
HUnlock(h);
return h;
}
}
return NULL;
}
CWResult Parser_StorePanels(CWPluginContext context) {
int idx;
CWResult result;
const 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(CLPStr68, name);
return result;
}
}
}
return cwNoErr;
}
static CWResult StoreResults(CWPluginContext context) {
int idx; // r25
CWResult result;
CWCommandLineArgs args;
UInt32 id; // r8
UInt32 lg; // r10
result = Parser_StorePanels(context);
if (result)
return result;
for (idx = 0; idx < parseopts.numPlugins; idx++) {
if (parseopts.plugins[idx].plugintype == CWDROPINLINKERTYPE && parseopts.plugins[idx].storeCommandLine) {
if (parseopts.plugins[idx].dropinflags & isPreLinker) {
Arg_ToolArgsForPlugin(&prelinkargs, &args);
} else if (parseopts.plugins[idx].dropinflags & isPostLinker) {
Arg_ToolArgsForPlugin(&postlinkargs, &args);
} else {
Arg_ToolArgsForPlugin(&linkargs, &args);
}
result = CWParserStoreCommandLineForPlugin(parseopts.context, idx, &args);
if (result)
return result;
} else if (parseopts.plugins[idx].storeCommandLine) {
id = parseopts.plugins[idx].plugintype;
lg = parseopts.plugins[idx].language;
fprintf(stderr,
"*** No support for %c%c%c%c/%c%c%c%c tool\n",
(id & 0xFF000000) >> 24,
(id & 0x00FF0000) >> 16,
(id & 0x0000FF00) >> 8,
(id & 0x000000FF),
(lg & 0xFF000000) >> 24,
(lg & 0x00FF0000) >> 16,
(lg & 0x0000FF00) >> 8,
(lg & 0x000000FF)
);
}
}
return cwNoErr;
}
CWPLUGIN_ENTRY (CWParser_GetDropInFlags)(const DropInFlags **flags, SInt32 *flagsSize) {
static const DropInFlags sFlags = {
kCurrentDropInFlagsVersion,
CWDROPINPARSERTYPE,
7,
0,
'Seep',
12
};
*flags = &sFlags;
*flagsSize = sizeof(sFlags);
return 0;
}
CWPLUGIN_ENTRY (CWParser_GetDropInName)(const char **dropinName) {
static const char *sDropInName = "Command-Line Parser";
*dropinName = sDropInName;
return 0;
}
CWPLUGIN_ENTRY (CWParser_GetDisplayName)(const char **displayName) {
static const char *sDisplayName = "Command-Line Parser";
*displayName = sDisplayName;
return 0;
}
CWPLUGIN_ENTRY (CWParser_GetPanelList)(const CWPanelList **panelList) {
static CWPanelList sPanelList = {
kCurrentCWFamilyListVersion,
0,
0
};
*panelList = &sPanelList;
return 0;
}
CWPLUGIN_ENTRY (CWParser_GetTargetList)(const CWTargetList **targetList) {
static CWDataType sCPU = '****';
static CWDataType sOS = '****';
static CWTargetList sTargetList = {
kCurrentCWTargetListVersion,
1,
&sCPU,
1,
&sOS
};
*targetList = &sTargetList;
return 0;
}
CWPLUGIN_ENTRY (CWParser_GetVersionInfo)(const VersionInfo **versioninfo) {
static const VersionInfo vi = {
1, 1, 0, 0
};
*versioninfo = &vi;
return 0;
}
CWPLUGIN_ENTRY (Parser_SupportsPlugin)(const struct CLPluginInfo *pluginfo, CWDataType cpu, CWDataType os, Boolean *isSupported) {
*isSupported = ParserToolMatchesPlugin(pluginfo->plugintype, pluginfo->language, cpu, os);
return 0;
}
CWPLUGIN_ENTRY (Parser_SupportsPanels)(int numPanels, const char **panelNames, Boolean *isSupported) {
*isSupported = ParserToolHandlesPanels(numPanels, panelNames);
return 0;
}
CWPLUGIN_ENTRY (parser_main)(CWPluginContext context) {
CWResult result;
SInt32 request;
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;
}

View File

@@ -0,0 +1,156 @@
#include "parser.h"
Handle definesHandle;
int Opt_AddStringToDefines(const char *opt, void *str, const char *param, int flags) {
AddStringToHandle(&definesHandle, (const char *) str);
if (param)
AddStringToHandle(&definesHandle, param);
return 1;
}
int Opt_DefineSymbol(const char *var, const char *value) {
char tmp[1024];
if (pTool->LANG == Lang_C_CPP || pTool->LANG == CWFOURCHAR('A','s','m',' ') || pTool->LANG == Lang_Rez) {
sprintf(tmp, "#define %s %s\n", var, value ? value : "1");
} else if (pTool->LANG == Lang_Pascal) {
sprintf(tmp, "{$definec %s %s}\n", var, value ? value : "1");
} else {
sprintf(tmp, "Option '-D|d' is not supported with this plugin");
CLPReportError(CLPStr28_WarningText, tmp);
return 0;
}
AddStringToHandle(&definesHandle, tmp);
return 1;
}
int Opt_UndefineSymbol(const char *opt, void *, const char *arg, int flags) {
char tmp[300];
if (pTool->LANG == Lang_C_CPP || pTool->LANG == CWFOURCHAR('A','s','m',' ')) {
sprintf(tmp, "#undef %s\n", arg);
} else if (pTool->LANG == Lang_Pascal) {
sprintf(tmp, "{$undefc %s}\n", arg);
} else {
sprintf(tmp, "Option -%s is not supported with this plugin", opt);
CLPReportError(CLPStr28_WarningText, tmp);
return 0;
}
AddStringToHandle(&definesHandle, tmp);
return 1;
}
int Opt_AddPrefixFile(const char *opt, void *handle, const char *filename, int flags) {
char tmp[300];
handle = !handle ? &definesHandle : handle;
if (!filename[0])
return 1;
if (pTool->LANG == Lang_C_CPP || pTool->LANG == CWFOURCHAR('A','s','m',' ')) {
if (filename[0] == '<' && filename[strlen(filename) - 1] == '>') {
snprintf(tmp, sizeof(tmp), "#include %s\n", filename);
} else {
snprintf(tmp, sizeof(tmp), "#include \"%s\"\n", filename);
}
} else if (pTool->LANG == Lang_Pascal) {
snprintf(tmp, sizeof(tmp), "{$I+}\n{$I %s}\n{$I-}\n", filename);
} else {
sprintf(tmp, "Option -%s is not supported with this plugin", opt);
CLPReportError(CLPStr28_WarningText, tmp);
return 0;
}
AddStringToHandle((Handle *) handle, tmp);
return 1;
}
int Opt_PragmaTrueFalse(const char *, void *flag, const char *, int flags) {
if (flags & PARAMPARSEFLAGS_8)
*((unsigned char *) flag) = PR_OFF;
else
*((unsigned char *) flag) = PR_ON;
return 1;
}
int Opt_PragmaFalseTrue(const char *, void *flag, const char *, int flags) {
if (flags & PARAMPARSEFLAGS_8)
*((unsigned char *) flag) = PR_ON;
else
*((unsigned char *) flag) = PR_OFF;
return 1;
}
int Opt_PragmaOnOff(const char *, void *flag, const char *arg) {
if (!arg) {
CLPReportError(CLPStr34_ArgumentsExpected);
return 0;
}
if (!ustrcmp(arg, "on")) {
*((unsigned char *) flag) = PR_ON;
} else if (!ustrcmp(arg, "off")) {
*((unsigned char *) flag) = PR_OFF;
} else {
CLPReportError(CLPStr12, arg);
return 0;
}
return 1;
}
int Opt_PragmaOffOn(const char *, void *flag, const char *arg) {
if (!arg) {
CLPReportError(CLPStr34_ArgumentsExpected);
return 0;
}
if (!ustrcmp(arg, "on")) {
*((unsigned char *) flag) = PR_OFF;
} else if (!ustrcmp(arg, "off")) {
*((unsigned char *) flag) = PR_ON;
} else {
CLPReportError(CLPStr12, arg);
return 0;
}
return 1;
}
int SetupPragmas(const Pragma *pragmas) {
const char *set;
char on;
char off;
char tmp[300];
while (pragmas->pragma) {
if (pragmas->flags == PRAGMA_FLAGS_0 || pragmas->flags == PRAGMA_FLAGS_1) {
set = 0;
on = !(pragmas->flags == PRAGMA_FLAGS_1) ? PR_ON : PR_OFF;
off = !(pragmas->flags == PRAGMA_FLAGS_1) ? PR_OFF : PR_ON;
if (*((char *)pragmas->value) == on)
set = "on";
else if (*((char *)pragmas->value) == off)
set = "off";
else if (*((char *)pragmas->value) == PR_AUTO)
set = "auto";
else if (*((char *)pragmas->value) == PR_RESET)
set = "reset";
else
OS_ASSERT(186, *((char *)pragmas->value) == PR_UNSET);
if (set) {
snprintf(tmp, sizeof(tmp), "#pragma %s %s\n", pragmas->pragma, set);
AddStringToHandle(&definesHandle, tmp);
}
} else {
OS_ASSERT(195, !"Can't handle pragma");
}
pragmas++;
}
return 1;
}

View File

@@ -0,0 +1,535 @@
#include "parser.h"
#include "cmdline.h"
#include <errno.h>
SInt16 lastStage;
Boolean dashIMinusMovesPaths;
Boolean usedDashIMinus;
Boolean namingSysPaths;
static char STSbuf[256];
int FindFileInPath(const char *filename, OSSpec *fss) {
CWFileInfo fi;
CWResult result;
fi.fullsearch = 1;
fi.dependencyType = 0;
fi.suppressload = 1;
fi.isdependentoffile = kCurrentCompiledFile;
result = CWFindAndLoadFile(parseopts.context, filename, &fi);
if (!result) {
OS_FSSpec_To_OSSpec(&fi.filespec, fss);
return 1;
} else {
return 0;
}
}
char *GetEnvVar(const char *name, Boolean warn, const char **match) {
const char *nptr;
const char *last;
char *ret;
nptr = name;
last = name;
while (*nptr) {
ret = getenv(nptr);
if (ret) {
if (match)
*match = nptr;
return ret;
}
last = nptr;
nptr = &nptr[1 + strlen(nptr)];
}
if (warn)
CLPReportWarning(CLPStr52, last);
*match = 0;
return 0;
}
static Boolean MatchesExtension(const char *list, const char *filename) {
char *fn;
const char *eptr;
const char *ptr;
fn = OS_GetFileNamePtr((char *) filename);
eptr = strrchr(fn, '.');
if (!eptr)
return 0;
if (!list)
return 1;
ptr = eptr;
while (*list) {
if (*list == '|' && !*ptr)
return 1;
if (my_tolower(*list) == my_tolower(*ptr)) {
list++;
ptr++;
continue;
}
while (*list && *list != '|')
list++;
if (*list)
list++;
ptr = eptr;
}
return !*list && !*ptr;
}
int Opt_AddAccessPath(const char *opt, void *var, const char *arg, int flags) {
OSPathSpec spec;
int err;
arg = arg ? arg : opt;
if (!arg)
return 0;
if (!arg[0])
return 1;
if (strlen(arg) >= 256) {
CLPReportError(CLPStr13, arg + strlen(arg) - 32, 256);
return 0;
}
err = OS_MakePathSpec(0, arg, &spec);
if (err == ENOENT || err == ENOENT) {
CLPReportWarning(CLPStr45, arg);
return 1;
} else if (err != 0) {
CLPOSAlert(CLPStr45, err, arg);
return 1;
}
// this 'if' gets optimised unnecessarily
if (!AddAccessPath(&spec, namingSysPaths, 0, var != NULL))
return 0;
else
return 1;
}
int Opt_AddFrameworkPath(const char *opt, void *var, const char *arg, int flags) {
OSPathSpec spec;
int err;
arg = arg ? arg : opt;
if (!arg)
return 0;
if (!arg[0])
return 1;
if (strlen(arg) >= 256) {
CLPReportError(CLPStr13, arg + strlen(arg) - 32, 256);
return 0;
}
err = OS_MakePathSpec(0, arg, &spec);
if (err == ENOENT || err == ENOENT) {
CLPReportWarning(CLPStr45, arg);
return 1;
} else if (err != 0) {
CLPOSAlert(CLPStr45, err, arg);
return 1;
} else {
Frameworks_AddPath(&spec);
return 1;
}
}
int Opt_AddFramework(const char *opt, void *var, const char *arg, int flags) {
if (!Frameworks_AddFramework(arg ? arg : opt, 0, 0))
return 0;
else
return 1;
}
void ListParseMessage(void (*errprint)(const char *, va_list), const char *envvar, SInt16 id, ...) {
char buf[1024];
va_list ap;
if (envvar && envvar[0])
sprintf(buf, "In environment variable '%s':\n", envvar);
else
buf[0] = 0;
CLPGetErrorString(id, buf + strlen(buf));
va_start(ap, id);
errprint(buf, ap);
va_end(ap);
}
int AddAccessPathList(const char *list, char sep1, char sep2, int source, char *text, Boolean system, SInt32 position, Boolean recursive) {
char tmp[256];
Boolean recurse;
OSPathSpec spec;
int err;
short type;
char *ptr;
type = (Boolean) ((system == 1) ? 1 : 0) | (!source ? 0 : 2);
recurse = (list[0] == '+');
if (recurse)
++list;
if (!strchr(list, sep1))
sep1 = sep2;
while (*list) {
ptr = tmp;
while (*list && *list != sep1 && (ptr + 1) < &tmp[256]) {
*(ptr++) = *(list++);
}
*ptr = 0;
if ((ptr + 1) >= &tmp[256]) {
ListParseMessage(
CLPReportError_V,
(source == 1) ? text : NULL,
CLPStr9,
tmp,
tmp + strlen(tmp) - 16,
256);
return 0;
}
err = OS_MakePathSpec(0, tmp, &spec);
if (err) {
ListParseMessage(
CLPReportWarning_V,
(source == 1) ? text : NULL,
CLPStr45,
tmp);
} else {
AddAccessPath(&spec, type, position, recurse ^ recursive);
}
if (*list)
++list;
recurse = *list == '+';
if (recurse)
++list;
}
return 1;
}
int Opt_FindAndAddFile(const char *opt, void *var, const char *arg, int flags) {
OSSpec spec;
int err;
Boolean isfile;
arg = arg ? arg : opt;
if (!arg)
return 0;
if (!*arg)
return 1;
parseopts.userSpecifiedFiles++;
err = OS_MakeSpec(arg, &spec, &isfile);
if (!err)
err = OS_Status(&spec);
if (!err && !isfile) {
CLPReportError(CLPStr47, arg);
parseopts.unusedFiles++;
return 0;
} else if (err && err != ENOENT) {
CLPOSAlert(CLPStr44, err, arg);
parseopts.unusedFiles++;
return 0;
} else if (err && parseopts.alwaysUsePaths) {
err = FindFileInPath(arg, &spec) ? 0 : ENOENT;
}
if (err) {
CLPReportError(CLPStr44, arg);
parseopts.unusedFiles++;
return 0;
}
if (var && !MatchesExtension((const char *) var, arg))
CLPReportWarning(CLPStr76, arg, var);
if (!AddFileToProject(&spec, lastStage, parseopts.lastoutputname, 1, -1)) {
parseopts.unusedFiles++;
return 0;
} else {
parseopts.lastoutputname[0] = 0;
return 1;
}
}
int Opt_FindAndAddFileRef(const char *opt, void *var, const char *arg) {
OSSpec spec;
int err;
Boolean isfile;
arg = arg ? arg : opt;
if (!arg)
return 0;
if (!*arg)
return 1;
parseopts.userSpecifiedFiles++;
if (var && !MatchesExtension((const char *) var, arg))
CLPReportWarning(CLPStr76, arg, var);
err = OS_MakeSpec(arg, &spec, &isfile);
if (!err)
err = OS_Status(&spec);
if (!err && !isfile) {
CLPReportError(CLPStr47, arg);
parseopts.unusedFiles++;
return 0;
} else if (err && parseopts.alwaysUsePaths) {
err = FindFileInPath(arg, &spec) ? 0 : ENOENT;
}
if (!AddFileToProject(&spec, 0, 0, err == 0, -1)) {
parseopts.unusedFiles++;
return 0;
} else {
return AddAccessPath(&spec.path, 1, -1, 0) != 0;
}
}
int Opt_AddUnixLibraryFile(const char *opt, void *var, const char *name) {
OSSpec spec;
Boolean failed;
const char *eptr;
const char *eend;
char tmpname[64];
if (strlen(name) >= 56) {
CLPReportError(CLPStr13, name + strlen(name) - 32, 64);
return 0;
}
failed = 1;
if (!var)
var = ".lib|.a";
eptr = (const char *) var;
while (eptr && *eptr) {
eend = eptr;
while (*eend && *eend != '|')
++eend;
sprintf(tmpname, "lib%s%*.*s", name, eend - eptr, eend - eptr, eptr);
if (FindFileInPath(tmpname, &spec)) {
failed = 0;
break;
}
if (*eend)
eptr = eend + 1;
else
eptr = eend;
}
if (failed) {
failed = !FindFileInPath(name, &spec);
if (failed)
CLPReportError(CLPStr49, name, var, name);
}
if (!failed) {
if (!AddFileToProject(&spec, 0, 0, 1, -1)) {
parseopts.unusedFiles++;
failed = 1;
}
}
return !failed;
}
int AddFileList(const char *list, char sep1, char sep2, int source, char *text, SInt32 position) {
char tmp[256];
OSSpec spec;
char *ptr;
if (!strchr(list, sep1))
sep1 = sep2;
while (*list) {
ptr = tmp;
while (*list && *list != sep1 && (ptr + 1) < &tmp[256]) {
*(ptr++) = *(list++);
}
*ptr = 0;
if ((ptr + 1) >= &tmp[256]) {
ListParseMessage(
CLPReportError_V,
(source == 1) ? text : 0,
CLPStr9,
tmp,
tmp + strlen(tmp) - 16,
256
);
return 0;
}
if (!FindFileInPath(tmp, &spec)) {
if (OS_IsDir(&spec)) {
ListParseMessage(
CLPReportError_V,
(source == 1) ? text : 0,
CLPStr16,
tmp
);
} else {
ListParseMessage(
CLPReportWarning_V,
(source == 1) ? text : 0,
CLPStr44,
tmp
);
}
} else {
AddFileToProject(&spec, 0, 0, 1, position);
}
if (*list)
++list;
}
return 1;
}
int IsFileInOutputDirectory(const OSSpec *file) {
OSPathSpec outdir;
GetOutputFileDirectory(&outdir);
return OS_EqualPathSpec(&outdir, &file->path);
}
void GetCFileNameInOutputDirectory(const char *input, char *name, int maxlen) {
char filename[64];
OSSpec spec;
int err;
err = OS_MakeFileSpec(input, &spec);
if (err) {
CLPOSAlert(CLPStr64, err, input);
name[0] = 0;
return;
}
if (!IsFileInOutputDirectory(&spec)) {
CLPReportWarning(CLPStr61, OS_SpecToStringRelative(&spec, 0, STSbuf, sizeof(STSbuf)));
}
OS_NameSpecToString(&spec.name, filename, 256);
if (strlen(filename) >= maxlen) {
CLPReportWarning(CLPStr65, filename, maxlen - 1);
filename[maxlen - 1] = 0;
}
strcpy(name, filename);
}
void GetPFileNameInOutputDirectory(const char *input, unsigned char *name, int len) {
GetCFileNameInOutputDirectory(input, (char *) name, len);
c2pstr((char *) name);
}
void AddStringLenToHandle(Handle *h, const char *str, int len) {
SInt32 old;
if (!*h) {
if ((*h = NewHandle(len + 1))) {
HLock(*h);
memcpy(**h, str, len);
(**h)[len] = 0;
HUnlock(*h);
} else {
exit(-23);
}
} else {
old = GetHandleSize(*h) - 1;
SetHandleSize(*h, old + len + 1);
if (MemError() == noErr) {
HLock(*h);
memcpy(**h + old, str, len);
(**h)[old + len] = 0;
HUnlock(*h);
} else {
exit(-23);
}
}
}
void AddStringToHandle(Handle *h, const char *str) {
AddStringLenToHandle(h, str, strlen(str));
}
int Opt_PrintVersion(const char *opt, void *var, const char *arg, int flags) {
ShowVersion(0);
return 1;
}
void GetFirstSourceFilenameBase(char *buffer, char *defaul) {
int cnt;
OSSpec spec;
char compiler[32];
int x;
char *ext;
cnt = GetFileCount();
for (x = 0; x < cnt; x++) {
if (GetFileInfo(x, &spec, compiler)) {
if (compiler[0]) {
if (!strstr(compiler, "Lib")) {
OS_NameSpecToString(&spec.name, buffer, 256);
ext = strrchr(buffer, '.');
if (ext)
*ext = 0;
memmove(buffer, buffer, strlen(buffer) + 1);
return;
}
}
}
}
strcpy(buffer, defaul);
}
int Opt_SavePrefs(const char *opt, void *var, const char *arg, int flags) {
Parser_StorePanels(parseopts.context);
return 1;
}
int ParseNumber(const char *arg, Boolean emit_error, SInt32 *ret, const char **endptr) {
char *end;
if (arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X')) {
*ret = strtol(arg + 2, &end, 16);
} else if (arg[0] == '0') {
*ret = strtol(arg + 1, &end, 8);
} else {
*ret = strtol(arg, &end, 10);
}
if (endptr)
*endptr = end;
if (*end && emit_error) {
CLPReportError(CLPStr5, "", arg);
return 0;
}
return 1;
}
int Opt_MaybeMoveAccessPaths(const char *opt, void *var, const char *arg, int flags) {
if (dashIMinusMovesPaths && !usedDashIMinus)
MoveSystemPathsIntoUserList();
return 1;
}

View File

@@ -0,0 +1,241 @@
#include "parser.h"
extern char STSbuf[256];
int GetFileCount(void) {
SInt32 num;
CWGetProjectFileCount(parseopts.context, &num);
return num;
}
void SetFileOutputName(SInt32 position, SInt16 which, char *outfilename) {
CWResult result;
if (outfilename && outfilename[0]) {
result = CWParserSetFileOutputName(parseopts.context, position, which ? which : 1, outfilename);
if (result) {
failedCallback = "CWParserSetFileOutputName";
longjmp(exit_plugin, result);
}
}
}
int AddFileToProject(OSSpec *oss, SInt16 which, char *outfilename, Boolean exists, SInt32 position) {
CWFileSpec cws;
CWNewProjectEntryInfo pei;
CWResult result;
int err;
err = OS_OSSpec_To_FSSpec(oss, &cws);
if (err) {
CLPOSAlert(44, err, OS_SpecToStringRelative(oss, 0, STSbuf, sizeof(STSbuf)));
return 0;
}
if (position == -2) {
pei.position = 0;
} else if (position == -1) {
CWGetProjectFileCount(parseopts.context, &pei.position);
} else if (position == 0) {
pei.position = -1;
} else {
pei.position = position;
}
pei.segment = parseopts.currentSegment;
pei.overlayGroup = parseopts.currentOverlayGroup;
pei.overlay = parseopts.currentOverlay;
pei.groupPath = NULL;
pei.mergeintooutput = parseopts.mergeIntoOutput;
pei.weakimport = parseopts.weakImport;
pei.initbefore = parseopts.initBefore;
result = CWAddProjectEntry(parseopts.context, &cws, exists == 0, &pei, &position);
if (result) {
failedCallback = "CWAddProjectEntry";
longjmp(exit_plugin, result);
}
parseopts.initBefore = 0;
parseopts.weakImport = 0;
parseopts.mergeIntoOutput = 0;
SetFileOutputName(position, which, outfilename);
return 1;
}
Boolean GetFileInfo(SInt32 position, OSSpec *spec, char *plugin) {
CWProjectFileInfo pfi;
if (CWGetFileInfo(parseopts.context, position, 1, &pfi))
return 0;
OS_FSSpec_To_OSSpec(&pfi.filespec, spec);
strncpy(plugin, pfi.dropinname, 32);
plugin[31] = 0;
return 1;
}
int AddAccessPath(OSPathSpec *oss, SInt16 type, SInt32 position, Boolean recursive) {
CWNewAccessPathInfo api;
CWResult result;
OSSpec spec;
int err;
CWAccessPathListInfo apli;
if ((err = OS_MakeSpecWithPath(oss, NULL, 0, &spec)) || (err = OS_OSSpec_To_FSSpec(&spec, &api.pathSpec))) {
CLPOSAlert(45, err, OS_PathSpecToString(&spec.path, STSbuf, sizeof(STSbuf)));
return 0;
}
if (position == -2) {
api.position = 0;
} else if (position == -1 || position == 0) {
api.position = -1;
} else if (position == -1) {
result = CWGetAccessPathListInfo(parseopts.context, &apli);
if (result) {
failedCallback = "CWGetAccessPathListInfo";
longjmp(exit_plugin, result);
}
if ((type & 1) == 1) {
api.position = apli.systemPathCount;
} else {
api.position = apli.userPathCount;
}
} else {
api.position = position;
}
api.type = (type & 1) ? cwSystemPath : cwUserPath;
api.type = api.type | (CWAccessPathType) ((type & 2) ? cwAccessPathTypeFlag2 : 0);
api.recursive = recursive;
result = CWParserAddAccessPath(parseopts.context, &api);
if (result) {
failedCallback = "CWParserAddAccessPath";
longjmp(exit_plugin, result);
}
return 1;
}
int MoveSystemPathsIntoUserList(void) {
CWResult result = CWParserSwapAccessPaths(parseopts.context);
return result == cwNoErr;
}
void AddVirtualFile(const char *filename, Handle *text) {
CWResult result;
CWMemHandle mh;
if (*text) {
CWSecretAttachHandle(parseopts.context, *text, &mh);
result = CWParserCreateVirtualFile(parseopts.context, filename, mh);
if (result) {
failedCallback = "CWParserCreateVirtualFile";
longjmp(exit_plugin, result);
}
DisposeHandle(*text);
*text = NULL;
}
}
void GetOutputFileDirectory(OSPathSpec *dir) {
CWResult result;
CWFileSpec idefss;
OSSpec spec;
result = CWGetOutputFileDirectory(parseopts.context, &idefss);
if (result) {
failedCallback = "CWGetOutputFileDirectory";
longjmp(exit_plugin, result);
}
OS_FSSpec_To_OSSpec(&idefss, &spec);
*dir = spec.path;
}
void SetOutputFileDirectory(OSPathSpec *dir) {
CWResult result;
CWFileSpec idefss;
OSSpec spec;
OS_MakeSpecWithPath(dir, NULL, 0, &spec);
OS_OSSpec_To_FSSpec(&spec, &idefss);
result = CWParserSetOutputFileDirectory(parseopts.context, &idefss);
if (result) {
failedCallback = "CWParserSetOutputFileDirectory";
longjmp(exit_plugin, result);
}
}
void AddOverlayGroup(const char *name, CWAddr64 *addr, SInt32 *groupnum, SInt32 *overlaynum) {
CWResult result;
*overlaynum = -1;
result = CWParserAddOverlay1Group(parseopts.context, name, addr, groupnum);
if (result) {
if (result == cwErrInvalidCallback) {
CLPReportError(72);
} else {
failedCallback = "CWParserAddOverlay1Group";
longjmp(exit_plugin, result);
}
}
}
void AddOverlay(SInt32 groupnum, const char *name, SInt32 *overlaynum) {
CWResult result;
result = CWParserAddOverlay1(parseopts.context, name, groupnum, overlaynum);
if (result) {
if (result == cwErrInvalidCallback) {
CLPReportError(72);
} else {
failedCallback = "CWParserAddOverlay1";
longjmp(exit_plugin, result);
}
}
}
void AddSegment(const char *name, SInt16 attrs, SInt32 *segmentnum) {
CWResult result;
result = CWParserAddSegment(parseopts.context, name, attrs, segmentnum);
if (result) {
if (result == cwErrInvalidCallback) {
CLPReportError(73);
} else {
failedCallback = "CWParserAddSegment";
longjmp(exit_plugin, result);
}
}
}
void ChangeSegment(SInt32 segmentnum, const char *name, SInt16 attrs) {
CWResult result;
result = CWParserSetSegment(parseopts.context, segmentnum, name, attrs);
if (result) {
if (result == cwErrInvalidCallback) {
CLPReportError(73);
} else {
failedCallback = "CWParserSetSegment";
longjmp(exit_plugin, result);
}
}
}
int GetSegment(SInt32 segmentnum, char *name, SInt16 *attrs) {
CWResult result;
CWProjectSegmentInfo psi;
result = CWGetSegmentInfo(parseopts.context, segmentnum, &psi);
if (result) {
if (result == cwErrInvalidCallback) {
CLPReportError(73);
}
return 0;
}
strcpy(name, psi.name);
*attrs = psi.attributes;
return 1;
}

View File

@@ -0,0 +1,29 @@
#include "parser.h"
#include "cmdline.h"
static BasePluginCallbacks cb = {
parser_main,
CWParser_GetDropInFlags,
CWParser_GetDisplayName,
CWParser_GetDropInName,
CWParser_GetPanelList,
NULL,
NULL,
CWParser_GetVersionInfo,
NULL
};
static ParserPluginCallbacks pr_cb = {
Parser_SupportsPlugin,
Parser_SupportsPanels
};
int RegisterStaticParserPlugins(void) {
return RegisterStaticParserPlugin(&cb, &pr_cb);
}
#include "ParserErrors.r"
int RegisterStaticParserResources(void) {
return RegisterResource("Parser Strings", 12010, STR12010);
}

View File

@@ -0,0 +1,81 @@
#include "parser.h"
PExtraWarningC pExtraWarningC = {0};
Pragma warningPragmas[] = {
&pExtraWarningC.warn_largeargs, "warn_largeargs", 0,
&pExtraWarningC.warn_padding, "warn_padding", 0,
&pExtraWarningC.warn_resultnotused, "warn_resultnotused", 0,
&pExtraWarningC.warn_ptr_int_conv, "warn_ptr_int_conv", 0,
&pExtraWarningC.warn_no_side_effect, "warn_no_side_effect", 0,
0, 0, 0
};
int TargetSetWarningFlags(short val, Boolean set) {
switch (val) {
case 'Ip': pWarningC.warn_illpragma = set; break;
case 'Ed': pWarningC.warn_emptydecl = set; break;
case 'Pu': pWarningC.warn_possunwant = set; break;
case 'Uv': pWarningC.warn_unusedvar = set; break;
case 'Ua': pWarningC.warn_unusedarg = set; break;
case 'Ec': pWarningC.warn_extracomma = set; break;
case 'Pd': pWarningC.pedantic = set; break;
case 'Hv': pWarningC.warn_hidevirtual = set; break;
case 'Ic': pWarningC.warn_implicitconv = set; break;
case 'Ni': pWarningC.warn_notinlined = set; break;
case 'Sc': pWarningC.warn_structclass = set; break;
case 'Pa': pExtraWarningC.warn_padding = set ? PR_ON : PR_OFF; break;
case 'Nu': pExtraWarningC.warn_resultnotused = set ? PR_ON : PR_OFF; break;
case 'Se': pExtraWarningC.warn_no_side_effect = set ? PR_ON : PR_OFF; break;
case 'PI': pExtraWarningC.warn_ptr_int_conv = set ? PR_ON : PR_OFF; break;
case 'La': pExtraWarningC.warn_largeargs = set ? PR_ON : PR_OFF; break;
case 'We': pWarningC.warningerrors = set; break;
case 'Cp': pFrontEndC.checkprotos = set; break;
default: return 0;
}
return 1;
}
void TargetDisplayWarningOptions(Handle txt) {
HPrintF(txt, "C language warning options:\n");
if (pWarningC.warn_illpragma)
HPrintF(txt, "\t- illegal pragmas\n");
if (pWarningC.warn_emptydecl)
HPrintF(txt, "\t- empty declarations\n");
if (pWarningC.warn_possunwant)
HPrintF(txt, "\t- possible unwanted effects\n");
if (pWarningC.warn_unusedvar)
HPrintF(txt, "\t- unused variables\n");
if (pWarningC.warn_unusedarg)
HPrintF(txt, "\t- unused arguments\n");
if (pWarningC.warn_extracomma)
HPrintF(txt, "\t- extra commas\n");
if (pWarningC.pedantic)
HPrintF(txt, "\t- pedantic\n");
if (pWarningC.warn_hidevirtual)
HPrintF(txt, "\t- hidden virtual functions\n");
if (pWarningC.warn_implicitconv)
HPrintF(txt, "\t- implicit conversions\n");
if (pWarningC.warn_notinlined)
HPrintF(txt, "\t- 'inline' not performed\n");
if (pWarningC.warn_structclass)
HPrintF(txt, "\t- struct/class conflict\n");
if (pExtraWarningC.warn_largeargs == 1)
HPrintF(txt, "\t- large args passed to unprototyped functions\n");
if (pExtraWarningC.warn_padding == 1)
HPrintF(txt, "\t- padding added between struct members\n");
if (pExtraWarningC.warn_resultnotused == 1)
HPrintF(txt, "\t- result of non-void function call not used\n");
if (pExtraWarningC.warn_no_side_effect == 1)
HPrintF(txt, "\t- use of expressions as statements without side effects\n");
if (pExtraWarningC.warn_ptr_int_conv == 1)
HPrintF(txt, "\t- implicit integer/pointer conversions\n");
if (pFrontEndC.checkprotos)
HPrintF(txt, "\t- checking prototypes\n");
if (pWarningC.warningerrors)
HPrintF(txt, "\t- warnings are errors\n");
else
HPrintF(txt, "\t- warnings are not errors\n");
}

View File

@@ -0,0 +1,65 @@
#include "parser.h"
ParserTool *pTool;
int SetParserToolInfo(ParserTool *tool) {
pTool = tool;
OS_ASSERT(16, pTool->toolInfo && (parseopts.toolVersion || pTool->copyright));
return 1;
}
Boolean ParserToolMatchesPlugin(OSType type, OSType lang, OSType cpu, OSType os) {
if (!pTool) {
CLPFatalError("No options loaded for command line\n");
return 0;
}
if (
(type == CWDROPINANYTYPE || pTool->TYPE == CWDROPINANYTYPE || pTool->TYPE == type) &&
(lang == Lang_Any || pTool->LANG == Lang_Any || pTool->LANG == lang) &&
(cpu == targetCPUAny || pTool->CPU == targetCPUAny || pTool->CPU == cpu) &&
(os == targetOSAny || pTool->OS == targetOSAny || pTool->OS == os)
)
{
return 1;
} else {
return 0;
}
}
Boolean ParserToolHandlesPanels(int numPanels, const char **panelNames) {
int idx;
int scan;
if (!pTool)
CLPFatalError("No options loaded for command line\n");
for (idx = 0; idx < numPanels; idx++) {
for (scan = 0; scan < pTool->numPrefPanels; scan++) {
if (!ustrcmp(pTool->prefPanels[scan], panelNames[idx]))
break;
}
if (scan >= pTool->numPrefPanels)
break;
}
if (idx >= numPanels)
return 1;
else
return 0;
}
Boolean SetupParserToolOptions(void) {
int idx;
Options_Init();
for (idx = 0; idx < pTool->numOptionLists; idx++) {
Options_AddList(pTool->optionLists[idx]);
}
Options_SortOptions();
return 1;
}

View File

@@ -0,0 +1,36 @@
#include "parser.h"
#include "cmdline.h"
int Opt_DummyLinkerRoutine(const char *opt, void *, const char *, int) {
CLPFatalError("Calling linker option '%s'\n", opt);
return 0;
}
int Opt_DummyLinkerSettingRoutine(const char *var, const char *val) {
CLPFatalError("Calling linker settings option '%s'='%s'\n", var, val ? val : "");
return 0;
}
void FinishCompilerTool(void) {
SInt32 numfiles;
if (parseopts.lastoutputname[0]) {
numfiles = GetFileCount();
if (pCmdLine.stages == CmdLineStageMask_Dp) {
strcpy(pCmdLineCompiler.outMakefile, parseopts.lastoutputname);
} else if (outputOrdering == OutputOrdering2) {
if (parseopts.possibleFiles > 0 || parseopts.userSpecifiedFiles > 0)
CLPReportError(41, parseopts.lastoutputname);
else
CLPReportError(42, parseopts.lastoutputname);
} else {
SetFileOutputName(numfiles - 1, lastStage, parseopts.lastoutputname);
}
parseopts.lastoutputname[0] = 0;
}
if (setOutputDirectory)
pCmdLineCompiler.relPathInOutputDir = 0;
}

View File

@@ -0,0 +1,289 @@
#include "parser.h"
#include "cmdline.h"
#include <errno.h>
extern char STSbuf[256];
static Boolean setStage;
char linkerOutputFilename[256];
Boolean setLinkerOutputFilename;
Boolean setOutputDirectory;
SInt16 outputOrdering;
int Opt_HandleOutputName(const char *opt, void *, const char *filename, int flags) {
OSSpec spec;
int err;
SInt32 result;
Boolean isfile;
if (!filename)
filename = opt;
if ((pCmdLine.state == OptsCmdLineState_3 || (pCmdLine.state == OptsCmdLineState_0 && pTool->TYPE == CWDROPINLINKERTYPE)) && pCmdLine.toDisk != 4) {
if (setLinkerOutputFilename) {
CLPReportError(CLPStr41, filename);
return 0;
}
setLinkerOutputFilename = 1;
if (pTool->TYPE == CWDROPINCOMPILERTYPE) {
strncpy(linkerOutputFilename, filename, 256);
} else {
OSSpec spec;
int err;
Boolean isfile;
err = OS_MakeSpec(filename, &spec, &isfile);
if (err) {
CLPOSAlert(CLPStr64, err, filename);
return 0;
}
if (isfile)
OS_NameSpecToString(&spec.name, linkerOutputFilename, 256);
SetOutputFileDirectory(&spec.path);
}
return 1;
} else {
err = OS_MakeSpec(filename, &spec, &isfile);
if (err) {
CLPOSAlert(CLPStr64, err, filename);
return 0;
}
if (!err && !isfile) {
FSSpec ofd;
if (setOutputDirectory) {
CLPReportError(CLPStr59, filename);
return 0;
}
setOutputDirectory = 1;
OS_OSSpec_To_FSSpec(&spec, &ofd);
result = CWParserSetOutputFileDirectory(parseopts.context, &ofd);
if (result) {
failedCallback = "CWParserSetOutputFileDirectory";
longjmp(exit_plugin, result);
}
return 1;
} else {
SInt32 index;
CWProjectFileInfo pfi;
if (parseopts.lastoutputname[0]) {
CLPReportError(CLPStr41, filename);
return 0;
}
strncpy(parseopts.lastoutputname, filename, 256);
if (pCmdLine.stages == CmdLineStageMask_Dp)
return 1;
if (outputOrdering == OutputOrdering0 || outputOrdering == OutputOrdering1) {
CWGetProjectFileCount(parseopts.context, &index);
while (index-- > 0) {
if (!CWGetFileInfo(parseopts.context, index, 0, &pfi) && pfi.filetype == CWFOURCHAR('T','E','X','T')) {
outputOrdering = OutputOrdering1;
break;
}
}
if (index <= 0) {
CWGetProjectFileCount(parseopts.context, &index);
if (index > 0)
outputOrdering = OutputOrdering1;
--index;
}
if (outputOrdering == OutputOrdering0) {
outputOrdering = OutputOrdering2;
return 1;
}
SetFileOutputName(index, lastStage, parseopts.lastoutputname);
parseopts.lastoutputname[0] = 0;
}
return 1;
}
}
}
int ValidateToolState(Boolean mustHaveFiles) {
if (parseopts.noOptions) {
pCmdLine.state = OptsCmdLineState_1;
ShowVersion(1);
return 1;
}
if (parseopts.success) {
if (!parseopts.userSpecifiedFiles) {
if (!parseopts.hadAnyOutput) {
if (mustHaveFiles) {
CLPReportError(CLPStr70);
return 0;
}
} else {
if (mustHaveFiles)
pCmdLine.state = OptsCmdLineState_1;
return 1;
}
} else if (parseopts.unusedFiles > 0) {
CLPReportError(CLPStr69);
return 0;
}
}
if (pCmdLine.state == OptsCmdLineState_0 || (parseopts.userSpecifiedFiles > 0 && pCmdLine.state == OptsCmdLineState_1))
pCmdLine.state = OptsCmdLineState_3;
if (!setStage) {
pCmdLine.stages = CmdLineStageMask_Cg;
if (pCmdLine.state == OptsCmdLineState_2)
pCmdLine.toDisk |= 2;
}
if (pCmdLine.state == OptsCmdLineState_3 && !(pCmdLine.stages & CmdLineStageMask_Cg))
pCmdLine.state = OptsCmdLineState_2;
return 1;
}
void ToolReportMessage(SInt16 errid, SInt16 type, va_list va) {
char str[256];
char buf[1024];
GetIndString((StringPtr) str, 13000, errid);
p2cstr((StringPtr) str);
vsprintf(buf, str, va);
CWReportMessage(parseopts.context, 0, buf, 0, type, 0);
}
void ToolReportWarning(SInt16 id, ...) {
va_list va;
va_start(va, id);
ToolReportMessage(id, messagetypeWarning, va);
va_end(va);
}
void ToolReportError(SInt16 id, ...) {
va_list va;
va_start(va, id);
ToolReportMessage(id, messagetypeError, va);
va_end(va);
parseopts.hadErrors = 1;
}
void ToolReportOSError(SInt16 id, int err, ...) {
char str[256];
char buf[1024];
va_list va;
GetIndString((StringPtr) str, 13000, id);
p2cstr((StringPtr) str);
va_start(va, err);
vsprintf(buf, str, va);
va_end(va);
CWAlert(parseopts.context, buf, OS_GetErrText(err), 0, 0);
}
void ToolReportInfo(SInt16 id, ...) {
va_list va;
va_start(va, id);
ToolReportMessage(id, messagetypeInfo, va);
va_end(va);
}
int Opt_DoNotLink(const char *opt, void *var, const char *arg) {
if (pCmdLine.state == OptsCmdLineState_3 || pCmdLine.state == OptsCmdLineState_0 || pCmdLine.state == OptsCmdLineState_1)
pCmdLine.state = OptsCmdLineState_2;
return 1;
}
int Opt_IncreaseVerbosity(const char *opt, void *var, const char *arg, int flags) {
if (pCmdLine.verbose)
pCmdLine.verbose++;
else
pCmdLine.verbose = 2;
Parser_StorePanels(parseopts.context);
return 1;
}
int Opt_SetStage(const char *opt, void *str, const char *arg, int flags) {
unsigned char *ptr;
Boolean set;
Boolean no;
UInt16 flag;
ptr = (unsigned char *) str;
// doesn't match - type issue with 'no'
no = (Boolean) ((flags & PARAMPARSEFLAGS_8) >> 3);
set = (Boolean) (no ^ 1);
while (*ptr) {
if (*ptr == '+') {
set = !no;
} else if (*ptr == '-') {
set = no;
} else if (*ptr == '|') {
set = (Boolean) (no ^ 1);
} else {
flag = (ptr[0] << 8) | ptr[1];
setStage = 1;
switch (flag) {
case 'Cg':
if (set)
pCmdLine.stages |= CmdLineStageMask_Cg;
else
pCmdLine.stages &= ~CmdLineStageMask_Cg;
lastStage = CmdLineStage_Cg;
break;
case 'Ds':
if (set)
pCmdLine.stages |= CmdLineStageMask_Ds;
else
pCmdLine.stages &= ~CmdLineStageMask_Ds;
lastStage = CmdLineStage_Ds;
break;
case 'Pp':
if (set)
pCmdLine.stages |= CmdLineStageMask_Pp;
else
pCmdLine.stages &= ~CmdLineStageMask_Pp;
lastStage = CmdLineStage_Pp;
break;
case 'Dp':
if (set)
pCmdLine.stages |= CmdLineStageMask_Dp;
else
pCmdLine.stages &= ~CmdLineStageMask_Dp;
break;
default:
CLPFatalError("Bad stage settings in %s (%c%c)\n", str, ptr[0], ptr[1]);
}
++ptr;
}
++ptr;
}
return 1;
}
int Opt_RedirectStream(const char *opt, void *file, const char *filename) {
OSSpec spec;
int err;
FILE *nw;
err = OS_MakeFileSpec(filename, &spec);
if (err) {
CLPReportError(CLPStr78, filename, OS_GetErrText(err));
return 0;
}
nw = freopen(OS_SpecToString(&spec, STSbuf, 256), "wt", (FILE *) file);
if (!nw) {
CLPReportError(CLPStr78, filename, strerror(errno));
return 0;
}
return 1;
}

View File

@@ -0,0 +1,174 @@
#include "parser.h"
int my_tolower(char c) {
if (c >= 'A' && c <= 'Z')
return c | 0x20;
else
return c;
}
int my_isdigit(char c) {
return (c >= '0' && c <= '9');
}
int my_isalpha(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
int my_isalnum(char c) {
return my_isdigit(c) || my_isalpha(c);
}
int my_isxdigit(char c) {
return my_isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
char *Utils_SpellList(char *list, char *buffer, char opts) {
char *sptr;
char *eptr;
char *nptr;
char *bptr;
int pflen;
int npflen;
int undo;
char *neptr;
int cnt;
undo = 0;
bptr = buffer;
sptr = list;
pflen = 0;
while (sptr) {
if ((opts & 1) && !pflen)
*(bptr++) = *MAINOPTCHAR;
eptr = strchr(sptr, '|');
if (!eptr) {
eptr = sptr + strlen(sptr);
nptr = 0;
} else if (eptr[1] == '|') {
nptr = 0;
} else {
nptr = eptr + 1;
}
if (undo == 0 && !pflen) {
if (opts & 8) {
*(bptr++) = '[';
*(bptr++) = 'n';
*(bptr++) = 'o';
*(bptr++) = ']';
}
if (opts & 0x20) {
*(bptr++) = '[';
*(bptr++) = 'n';
*(bptr++) = 'o';
*(bptr++) = '-';
*(bptr++) = ']';
}
}
npflen = 0;
if (nptr) {
while (sptr < nptr && *nptr && *nptr != '|' && sptr[npflen] == nptr[npflen])
npflen++;
if (npflen) {
neptr = strchr(nptr, '|');
if (!neptr)
neptr = nptr + strlen(nptr);
if ((neptr - nptr) < (eptr - sptr) || ((sptr[1] && sptr[1] != '|') ? (sptr[1] != nptr[1]) : 0))
npflen = 0;
if (opts & 0x40)
npflen = 0;
}
}
if (pflen) {
sptr += pflen;
while (sptr < eptr) {
*(bptr++) = *(sptr++);
}
if (npflen > pflen) {
*(bptr++) = '[';
undo++;
}
if (npflen < pflen) {
*(bptr++) = ']';
undo--;
}
} else if (npflen) {
for (cnt = npflen; cnt > 0; cnt--) {
*(bptr++) = *(sptr++);
}
*(bptr++) = '[';
undo++;
}
while (sptr < eptr) {
*(bptr++) = *(sptr++);
}
if (opts & 0x10) {
*(bptr++) = '[';
*(bptr++) = '-';
*(bptr++) = ']';
}
if (opts & 0x40) {
*(bptr++) = '+';
}
sptr = nptr;
if (nptr && bptr[-1] != '[') {
if ((opts & 1) || (bptr[-1] == ']') || ((opts & 8) && !undo)) {
*(bptr++) = ' ';
*(bptr++) = '|';
*(bptr++) = ' ';
} else {
*(bptr++) = '|';
}
}
opts &= ~0x40;
pflen = npflen;
}
for (cnt = undo; cnt; cnt--) {
*(bptr++) = ']';
}
if (opts & 4)
bptr += sprintf(bptr, "=...");
*bptr = 0;
return bptr;
}
int Utils_CompareOptionString(const char *a, const char *b, int cased, int sticky) {
const char *ae;
const char *be;
for (ae = a; *ae && *ae != '|'; ae++) {}
for (be = b; *be && *be != '|'; be++) {}
if (sticky && (be - b) < (ae - a))
return 0;
if (cased) {
while (a < ae && b < be) {
if (*a != *b)
break;
a++;
b++;
}
} else {
while (a < ae && b < be) {
if (my_tolower(*a) != my_tolower(*b))
break;
a++;
b++;
}
}
return (a == ae) && (sticky || b == be);
}