diff options
Diffstat (limited to 'unsorted/Option.c')
-rw-r--r-- | unsorted/Option.c | 1134 |
1 files changed, 1134 insertions, 0 deletions
diff --git a/unsorted/Option.c b/unsorted/Option.c new file mode 100644 index 0000000..410c807 --- /dev/null +++ b/unsorted/Option.c @@ -0,0 +1,1134 @@ +#include "parser.h" + +#define MAXSTACK 8 + +static OptionList *optionlists[32]; +int numoptionlists; +static OptionList internalset; +static OptionList legalset; +int numinternalset; +int numlegalset; +int maxlegalset; +char curopt[1024]; +Opt48 oStack[8]; +int oStackPtr; + +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 & OTF_STICKY)) { + if (Utils_CompareOptionString(opt->names, optname, opt->avail & OTF_CASED, OTF_STICKY)) { + 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 & (OTF_STICKY | OTF_CASED)) + legalset.list[numlegalset++] = internalset.list[r]; + } + for (r = 0; r < numinternalset; r++) { + if (!(internalset.list[r]->avail & (OTF_STICKY | 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 &= ~(OTF_INTERNAL_ALREADY_SEEN | OTF_INTERNAL_SEEN_CONFLICTED); + } + } +} + +static void Option_SpellList(char *buffer, OptionList *conflicts, int flags) { + Option **scan; + Boolean first; + int total; + char tmp[256]; + Option **next; + int slflags; + + 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]) { + 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 & OTF_HAS_SUB_OPTIONS) + 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) { + ArgToken *tmp; + int ret; // not in stabs but i think this exists + + if (level == 1) { + return (tok->val == ATK_ARG_END) || (tok->val == ATK_OPTION) || (tok->val == ATK_ARG); + } else if (level == 2) { + tmp = Arg_UsedToken(); + ret = (tok->val == ATK_COMMA && tmp->val != ATK_OPTION) || (tok->val == ATK_ARG && tmp->val != ATK_ARG_END); + Arg_UndoToken(); + return ret; + } else if (level == 3) { + return (tok->val == ATK_EQUALS) || (tok->val == ATK_ARG); + } else { + return 0; + } +} + +static short endingStack[5][3]; +static Boolean Option_IsEndingThisLevel(int level, ArgToken *tok) { + ArgToken *tmp; + + if (!tok) + return 1; + if (tok->val == endingStack[level][0]) + return 1; + + if (endingStack[level][1] && tok->val == endingStack[level][1]) { + tmp = Arg_UsedToken(); + if (tmp && tmp->val == endingStack[level][2]) { + Arg_UndoToken(); + return 1; + } + Arg_UndoToken(); + } + + return 0; +} + +static Boolean Option_IsEndingLevel(int level, ArgToken *tok) { + if (!tok) + return 1; + + while (level > 0) { + if (Option_IsEndingThisLevel(level - 1, tok)) + return 1; + level--; + } + + return 0; +} + +int Option_Parse(Option *opt, int oflags) { + int ret; + int pushed; + int samelevel; + int subparse; + int flags; + char errstr[1024]; + Option **cscan; + Option **scan; + int goingtosubparse; + ArgToken *tok; + + ret = 1; + pushed = 0; + samelevel = (opt->avail & OTF_GLOBAL) == (oflags & OFLAGS_1); + subparse = (oflags & OFLAGS_2) != 0; + flags = 0; + if (subparse) flags |= PFLAGS_4; + if (oflags & OFLAGS_8) flags |= PFLAGS_8; + if (oflags & OFLAGS_40) flags |= PFLAGS_1; + + if (curopt[0]) { + pushed = 1; + Option_PushOpt(opt, curopt); + } + + if (samelevel) { + if (!(flags & PFLAGS_1)) { + if ((opt->avail & OTF_INTERNAL_ALREADY_SEEN) && (opt->avail & OTF_ONLY_ONCE)) { + Option_Warning(CLPStr30_OptionShouldNotBeSpecifiedMultipleTimes); + } else if (opt->avail & OTF_HAS_CONFLICTS) { + cscan = opt->conflicts->list; + while (*cscan && (*cscan == opt || !((*cscan)->avail & OTF_INTERNAL_ALREADY_SEEN))) { + ++cscan; + } + + if (*cscan && *cscan != opt) { + (*cscan)->avail &= ~OTF_INTERNAL_ALREADY_SEEN; + Option_SpellList(errstr, opt->conflicts, oflags); + if (opt->conflicts->help) + Option_Warning(CLPStr32_OptionOverridesEffectWithHelp, (*cscan)->names, errstr, opt->conflicts->help); + else + Option_Warning(CLPStr31_OptionOverridesEffect, (*cscan)->names, errstr); + } + } + } + + if (Option_ThisTool() == OTF_TOOL_COMPILER && Option_ForTool(opt, OTF_TOOL_LINKER | OTF_TOOL_DISASSEMBLER)) { + flags |= PFLAGS_2; + if (!Option_ForThisTool(opt)) + flags |= PFLAGS_1; + if (!subparse) + Arg_AddToToolArgs(&linkargs, ATK_ARG_END, 0); + Args_AddToToolArgs(&linkargs); + } + + if (!(flags & PFLAGS_1)) { + if (opt->avail & OTF_OBSOLETE) { + if (opt->help) + Option_Error(CLPStr22_OptionObsoleteWithHelp, opt->help); + else + Option_Error(CLPStr21_OptionObsolete); + flags |= PFLAGS_1; + } + + if (opt->avail & OTF_IGNORED) { + if (!(opt->avail & (OTF_WARNING | OTF_MEANINGLESS))) { + if (opt->help) + Option_Warning(CLPStr27_OptionIgnoredWithText, opt->help); + else + Option_Warning(CLPStr26_OptionIgnored); + } + flags |= PFLAGS_1; + } else if (opt->avail & OTF_SUBSTITUTED) { + Option_Warning(CLPStr23_OptionXSubstitutedWithX, curopt, opt->help); + } else if (opt->avail & OTF_DEPRECATED) { + if (opt->help) + Option_Warning(CLPStr25_OptionDeprecatedWithHelp, opt->help); + else + Option_Warning(CLPStr24_OptionDeprecated); + } + + if (opt->avail & OTF_WARNING) + Option_Warning(CLPStr28_WarningText, opt->help); + if (opt->avail & OTF_MEANINGLESS) + Option_Warning(CLPStr29_OptionHasNoEffect); + } + + opt->avail |= OTF_INTERNAL_ALREADY_SEEN; + if (opt->avail & OTF_HAS_CONFLICTS) { + scan = opt->conflicts->list; + opt->avail |= OTF_INTERNAL_SEEN_CONFLICTED; + while (*scan) { + (*scan)->avail |= OTF_INTERNAL_SEEN_CONFLICTED; + scan++; + } + } + } else { + flags |= PFLAGS_1; + } + + goingtosubparse = opt->avail & OTF_HAS_SUB_OPTIONS; + if (opt->param) { + ret = Params_Parse(opt->param, flags | (goingtosubparse ? PFLAGS_20 : 0)); + } else { + tok = Arg_PeekToken(); + if (tok && tok->val == ATK_EQUALS) + Arg_UsedToken(); + } + + if (ret && goingtosubparse) { + ret = ret && Options_Parse( + opt->sub, + (oflags & ~OFLAGS_4) + | OFLAGS_2 + | ((flags & PFLAGS_1) ? OFLAGS_40 : 0) + | (subparse ? OFLAGS_10 : 0) + | ((opt->avail & OTF_SUB_OPTIONS_OPTIONAL) ? OFLAGS_4 : 0) + ); + } + + if (pushed) + Option_PopOpt(curopt); + + if (Option_ThisTool() == OTF_TOOL_COMPILER && !subparse) + Arg_AddToToolArgs(&linkargs, ATK_ARG_END, 0); + + return ret; +} + +static int Option_MatchString(char *list, char *str, int flags, int *result) { + int str_len; + char cpy[64]; + + if (result) + *result = 0; + + if (!list[0] && !str[0]) + return 1; + + while (*list) { + if (Utils_CompareOptionString(list, str, flags & OTF_CASED, 0)) + return 1; + + switch (flags & OTF_SLFLAGS_MASK) { + case OTF_SLFLAGS_8: + if (my_tolower(str[0]) == 'n' && my_tolower(str[1]) == 'o' && Utils_CompareOptionString(list, str + 2, flags & OTF_CASED, 0)) { + if (result) + *result |= 0x100000; + return 1; + } + break; + case OTF_SLFLAGS_20: + if (my_tolower(str[0]) == 'n' && my_tolower(str[1]) == 'o' && str[2] == '-' && Utils_CompareOptionString(list, str + 3, flags & OTF_CASED, 0)) { + if (result) + *result |= 0x400000; + return 1; + } + break; + case OTF_SLFLAGS_10: + str_len = strlen(str); + if (str[str_len - 1] == '-') { + strcpy(cpy, str); + cpy[str_len - 1] = 0; + if (Utils_CompareOptionString(list, cpy, flags & OTF_CASED, 0)) { + if (result) + *result |= 0x200000; + return 1; + } + } + break; + } + + while (*list && *list != '|') + ++list; + + if (*list) + ++list; + if (*list == '|') + ++list; + } + + return 0; +} + +static Option *Option_Lookup(OptionList *search, int unk, int *flags) { + Option **os; + Option *stickyopt; + int stickyflags; + Boolean matched; + char *names; + + os = search->list; + stickyopt = 0; + stickyflags = *flags; + + if (os) { + while (*os) { + names = (*os)->names; + if (((*os)->avail & OTF_STICKY) == OTF_STICKY) { + while (*names && *names != '|') + ++names; + if (*names) + ++names; + if (*names == '|') + ++names; + } + + matched = Option_MatchString(names, curopt, (*os)->avail & (OTF_SLFLAGS_MASK | OTF_CASED), flags) && (*names || names == (*os)->names); + if (matched) { + if (!stickyopt || (*os)->names[0] == curopt[0] || strlen(curopt) > 1) + return *os; + } + + if ((*os)->avail & OTF_STICKY) { + matched = Utils_CompareOptionString((*os)->names, curopt, (*os)->avail & OTF_CASED, 2); + if (matched) + stickyflags |= OTF_STICKY; + } else { + matched = 0; + } + + if (matched) + stickyopt = *os; + + ++os; + } + } + + *flags = stickyflags; + return stickyopt; +} + +static int Options_DoParse(OptionList *search, int flags) { + // search: r26 *n + // flags: r28 *n + int haderrors; // r30 *n + int parsedany; // r23 *n + int failed; // r24 *n + int matchflags; // stack 0x38 + int subparse; // r20 *n + ArgToken *starttok; // r0 (actually r19 i think?) + int mystery_r31; // figure out what var this actually is + ArgToken *tok; // r25 *n + ArgToken *opttok; // r27 *n + ArgToken *token_r18; // r18 MAYBE???? + Option *opt; // r16 *n + Boolean isOpt; // r0 + char *lptr; // r17 *n + char *optname; // r16 *n + + // 915 + haderrors = 0; + // 917 + failed = 0; + // 918 + matchflags = 0; + // 920 + subparse = (flags & OFLAGS_2) != 0; + // 921 + mystery_r31 = subparse && (flags & OFLAGS_10); + // 925 + opttok = 0; + // 929 + mystery_r31 = (subparse == 0) ? 1 : (mystery_r31 == 0) ? 2 : 3; + + starttok = Arg_PeekToken(); // i think this is starttok + while ((token_r18 = Arg_PeekToken())) { + parsedany = 0; + isOpt = ((mystery_r31 == 1) && (token_r18->val == ATK_OPTION)) || ((mystery_r31 == 2) && (token_r18->val == ATK_ARG) && (token_r18->text[0] || search->flags & LISTFLAGS_4)) || ((mystery_r31 == 3) && (token_r18->val == ATK_EQUALS)); + // 950 17CFD4 + if ((mystery_r31 == 3) && isOpt) { + token_r18 = Arg_UsedToken(); + isOpt = token_r18 && (token_r18->val == ATK_ARG); + flags &= ~OFLAGS_4; + } + // 957 17D00C + if (isOpt) { + // 959 + opt = 0; + // 960 + Arg_GetTokenText(token_r18, curopt, sizeof(curopt), 0); + // 963 + if (curopt[0]) { + opt = Option_Lookup(search, 0x700000, &matchflags); + if (opt) { + opttok = token_r18; + if (!(matchflags & 2)) { + // 972 + if (token_r18->val == ATK_OPTION) + Arg_UsedToken(); + token_r18 = Arg_UsedToken(); + } else { + lptr = opt->names; + optname = token_r18->text; + while (*lptr && *lptr != '|') + ++lptr; + token_r18 = Arg_UsedToken(); + + if (!subparse) + strcpy(token_r18->text, optname + (lptr - opt->names)); + + curopt[(lptr - opt->names)] = 0; + + if (!token_r18->text || !token_r18->text[0]) { + Option_PushOpt(0, curopt); + Option_ParamError(CLPStr34_ArgumentsExpected, curopt); + Option_PopOpt(0); + return 0; + } + } + } + } + + // 1006 + if (!opt) { + // 1009 + if (search->flags & LISTFLAGS_4) { + char saveopt[1024]; // stack 0xBC + strcpy(saveopt, curopt); + curopt[0] = 0; + opt = Option_Lookup(search, 0, &matchflags); + strcpy(curopt, token_r18->text); + + // 1019 + if (opt) { + if (opt->names[0]) + token_r18 = Arg_UsedToken(); + if (token_r18->val == ATK_EQUALS) + Arg_UsedToken(); + haderrors = Option_Parse(opt, flags) == 0; + parsedany = 1; + if (haderrors) + failed = 1; + opt = 0; + } else { + CLPFatalError("Missing default for variable list"); + return 0; + } + // 1041 + strcpy(curopt, saveopt); + } else if (!opt) { + // 1059 + curopt[0] = 0; + // 1061 + if (mystery_r31 > 1) { + if ((flags & OFLAGS_4) && token_r18 == starttok) + return haderrors == 0; + // 1072 + if (search->flags & LISTFLAGS_ALLOW_UNKNOWNS) { + if (!(flags & OFLAGS_1)) { + Option_SpellList(curparam, search, flags); + Option_Warning(CLPStr20_UnknownOptionX_ExpectedOneOfX, token_r18->text, curparam); + } + Arg_UsedToken(); + parsedany = 1; + } else { + // 1090 + Option_SpellList(curparam, search, flags); + Option_Error(CLPStr20_UnknownOptionX_ExpectedOneOfX, token_r18->text, curparam); + failed = 1; + haderrors++; + } + } else { + // 1099 + if ((search->flags & LISTFLAGS_ALLOW_UNKNOWNS) || parseopts.ignoreUnknown) { + // 1101 + if (!(flags & OFLAGS_1)) + Option_Warning(CLPStr19_UnknownOptionX, token_r18->text); + Arg_UsedToken(); + Arg_GetToken(); + parsedany = 1; + } else { + // 1115 + Option_Error(CLPStr19_UnknownOptionX, token_r18->text); + failed = 1; + haderrors++; + } + } + } + } + + // 1126 - after_if_1006 + if (!haderrors && !failed && opt) { + flags &= ~OFLAGS_8; + if (matchflags & 0x700000) + flags |= OFLAGS_8; + haderrors = Option_Parse(opt, flags) == 0; + if (haderrors) + failed = 1; + parsedany++; + } // else: goto 1229 + } else if ((mystery_r31 == 1) && (token_r18->val == ATK_ARG)) { + // 1142 + opttok = 0; + curopt[0] = 0; + opt = Option_Lookup(search, 0, &matchflags); + strcpy(curopt, token_r18->text); + if (!opt) { + Option_Warning(CLPStr33_NoDefaultHandlerSetUpForX_Ignoring, curopt); + failed = 1; + } else { + if (!(flags & OFLAGS_1)) { + haderrors = Option_Parse(opt, flags) == 0; + } else { + parseopts.possibleFiles++; + haderrors = 0; + } + parsedany = 1; + if (haderrors) + failed = 1; + else + Arg_UsedToken(); + } + } else if ((mystery_r31 > 1) && Option_IsEndingLevel(mystery_r31, token_r18)) { + // 1193 + Option *opt; + char saveopt[64]; // stack 0x7C + strcpy(saveopt, curopt); + if (!(search->flags & LISTFLAGS_4)) { + curopt[0] = 0; + opt = Option_Lookup(search, 0, &matchflags); // probably wrong result reg + } else { + opt = 0; // probably wrong reg + } + // 1203 + if (!opt) { + // 1205 + if (!(flags & OFLAGS_4)) { + Option_Error(CLPStr34_ArgumentsExpected, saveopt); + failed = 1; + haderrors++; + } else { + strcpy(curopt, saveopt); + break; + } + } else { + // 1219 + haderrors = Option_Parse(opt, flags) == 0; + parsedany = 1; + if (haderrors) + failed = 1; + } + // 1224 + strcpy(curopt, saveopt); + } + + // 1229 after_if_1126 + // This is where tok comes into play. + tok = Arg_PeekToken(); + // 1231 + if (!failed) { + if (tok && (tok->val == ATK_ARG) && (matchflags & 2)) { + // 1235 + ArgToken *prev; // r16 + char sticky[64]; // stack 0x3C + prev = Arg_UndoToken(); + tok = Arg_UsedToken(); + if (tok->text[0] && prev == opttok) { + if (opttok) { + strcpy(sticky, opttok->text); + sticky[strlen(tok->text)] = 0; + Option_PushOpt(0, sticky); + Param_Error(CLPStr36_UnexpectedAdditionalArgumentX, Arg_GetTokenName(tok)); + Option_PopOpt(0); + } else { + CLPReportError(CLPStr36_UnexpectedAdditionalArgumentX, Arg_GetTokenName(tok)); + } + // 1251 + haderrors++; + // goes to 1323 + } else { + // 1256 + if (!tok->text[0]) + tok = Arg_UsedToken(); + // 1257 + if (flags & OFLAGS_1) + parseopts.possibleFiles++; + // goes to 1323 + } + } else { + // 1267 + if (Option_IsEndingThisLevel(mystery_r31 - 1, tok)) + break; + if (Option_IsEndingThisLevel(mystery_r31 + 1, tok)) { + // 1276 + ArgToken *prev = tok; // r16 + tok = Arg_UsedToken(); + // 1278 + if ((mystery_r31 != 1) || (tok->val != ATK_OPTION)) { + // 1280 + if (opttok) { + Option_PushOpt(0, opttok->text); + if (tok->val == ATK_ARG) + Param_Error(CLPStr36_UnexpectedAdditionalArgumentX, Arg_GetTokenName(tok)); + else + Param_Error(CLPStr35_TokenXNotExpected, Arg_GetTokenName(prev)); + Option_PopOpt(opttok->text); + } else if (tok->val == ATK_ARG) { + // 1292 + CLPReportError(CLPStr36_UnexpectedAdditionalArgumentX, Arg_GetTokenName(tok)); + } else { + // 1294 + CLPReportError(CLPStr35_TokenXNotExpected, Arg_GetTokenName(prev)); + } + haderrors++; + failed++; + } + // goto 1323 + } else if ((mystery_r31 < 2) && Option_IsEndingThisLevel(mystery_r31 + 2, tok)) { + // 1303 + if (opttok) { + Option_PushOpt(0, opttok->text); + if (tok->val == ATK_ARG) + Param_Error(CLPStr36_UnexpectedAdditionalArgumentX, Arg_GetTokenName(tok)); + else + Param_Error(CLPStr35_TokenXNotExpected, Arg_GetTokenName(tok)); + Option_PopOpt(opttok->text); + } else if (tok->val == ATK_ARG) { + CLPReportError(CLPStr36_UnexpectedAdditionalArgumentX, Arg_GetTokenName(tok)); + } else { + CLPReportError(CLPStr35_TokenXNotExpected, Arg_GetTokenName(tok)); + } + haderrors++; + failed++; + } + } + } // else: 1323 + + if (haderrors || failed) { + while (!Option_IsEndingLevel(mystery_r31, tok)) + tok = Arg_GetToken(); + if (!tok) + tok = Arg_UndoToken(); +#line 1335 + OPTION_ASSERT(tok); + } + + if (!parsedany || haderrors) + break; + + if (Option_IsEndingThisLevel(mystery_r31, tok)) + Arg_UsedToken(); + else if (!Option_ContinuesThisLevel(mystery_r31, tok)) + break; + } + + return haderrors == 0; +} + +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(CLPStr38_NoHelpAvailableForOptionX, opt); + Help_Term(); + ret = 1; + } else { + Option_Error(CLPStr19_UnknownOptionX, opt); + ret = 0; + } + + Option_PopOpt(curopt); + Option_PopList(); + return ret; +} + +int Options_DisplayHelp() { + if (parseopts.helpFlags & HELPFLAGS_1) + return Option_Help(parseopts.helpKey); + else + return Options_Help(parseopts.helpKey); +} |