#include "mwcc_decomp.h" #define OPTION_ASSERT(cond) do { if (!(cond)) { printf("%s:%u: failed assertion\n", __FILE__, __LINE__); abort(); } } while(0) char curparam[4096]; char *descparam = &curparam[0]; char *helpparam = &curparam[1024]; char *defaultparam = &curparam[2048]; #define copy_8(dst, src) \ do { \ ((unsigned char *) (dst))[0] = ((unsigned char *) (src))[0]; \ } while (0) #define copy_16(dst, src) \ do { \ ((unsigned char *) (dst))[0] = ((unsigned char *) (src))[0]; \ ((unsigned char *) (dst))[1] = ((unsigned char *) (src))[1]; \ } while (0) #define copy_32(dst, src) \ do { \ ((unsigned char *) (dst))[0] = ((unsigned char *) (src))[0]; \ ((unsigned char *) (dst))[1] = ((unsigned char *) (src))[1]; \ ((unsigned char *) (dst))[2] = ((unsigned char *) (src))[2]; \ ((unsigned char *) (dst))[3] = ((unsigned char *) (src))[3]; \ } while (0) #define inline_write_32(dst, val) do { \ union {unsigned char bytes[4]; unsigned long lg;} _val, _arg; \ copy_32(_arg.bytes, val); \ _val.lg = _arg.lg; \ copy_32(dst, _val.bytes); \ } while (0) #define inline_write_16(dst, val) do { \ union {unsigned char bytes[2]; unsigned short sh;} _val, _arg; \ copy_16(_arg.bytes, val); \ _val.sh = _arg.sh; \ copy_16(dst, _val.bytes); \ } while (0) #define inline_write_8(ptr, val) copy_8(ptr, val) #define inline_andor_32(dst, and, or) do { \ union {unsigned char bytes[4]; unsigned long lg;} _val, _arg, _arg2; \ copy_32(_val.bytes, dst); \ copy_32(_arg.bytes, and); \ copy_32(_arg2.bytes, or); \ _val.lg = (_val.lg & ~_arg.lg) | _arg2.lg; \ copy_32(dst, _val.bytes); \ } while(0) #define inline_andor_16(dst, and, or) do { \ union {unsigned char bytes[2]; unsigned short sh;} _val, _arg, _arg2; \ copy_16(_val.bytes, dst); \ copy_16(_arg.bytes, and); \ copy_16(_arg2.bytes, or); \ _val.sh = (_val.sh & ~_arg.sh) | _arg2.sh; \ copy_16(dst, _val.bytes); \ } while(0) #define inline_andor_8(dst, and, or) do { \ ((unsigned char *) (dst))[0] = (((unsigned char *) (dst))[0] & ~((unsigned char *) (and))[0]) | ((unsigned char *) (or))[0]; \ } while(0) #define inline_xor_32(dst, arg) do { \ union {unsigned char bytes[4]; unsigned long lg;} _val, _arg; \ copy_32(_val.bytes, dst); \ copy_32(_arg.bytes, arg); \ _val.lg = _val.lg ^ _arg.lg; \ copy_32(dst, _val.bytes); \ } while(0) #define inline_xor_16(dst, arg) do { \ union {unsigned char bytes[2]; unsigned short sh;} _val, _arg; \ copy_16(_val.bytes, dst); \ copy_16(_arg.bytes, arg); \ _val.sh = _val.sh ^ _arg.sh; \ copy_16(dst, _val.bytes); \ } while(0) #define inline_xor_8(dst, arg) do { \ ((unsigned char *) (dst))[0] = (((unsigned char *) (dst))[0] ^ ((unsigned char *) (arg))[0]); \ } while(0) // forward declaration static int Param_GetArgument(PARAM_T *param, const char **cparam, int exec); static int Param_Parse(PARAM_T *param, const char *cparam, int flags); static int Param_None(PARAM_T *p, const char *pstr, int flags) { return 1; } static void DescHelpParam_None(PARAM_T *p, const char **desc, const char **help, const char **defaul) { *desc = 0; *help = 0; *defaul = 0; } static int CompareParam_None(PARAM_T *p) { return 0; } static void DescHelpParam_Number(NUM_T *p, const char **desc, const char **help, const char **defaul) { unsigned long value; unsigned char value8; unsigned short value16; value = 0; *desc = 0; if (p->myname) *desc = p->myname; if (p->size == 1) { if (!*desc) *desc = "byte"; if (p->num) copy_8(&value8, p->num); value = value8; } else if (p->size == 2) { if (!*desc) *desc = "short"; if (p->num) copy_16(&value16, p->num); value = value16; } else if (p->size == 4) { if (!*desc) *desc = "long"; if (p->num) copy_32(&value, p->num); } if (p->size == 4) { if (p->lo != p->hi) sprintf(helpparam, "range 0x%x - 0x%x", p->lo, p->hi); *help = helpparam; if (value <= 0x10000) sprintf(defaultparam, "%u", value); else sprintf(defaultparam, "0x%x", value); *defaul = defaultparam; } else { if (p->lo != p->hi) sprintf(helpparam, "range %u - %u", p->lo, p->hi); *help = helpparam; sprintf(defaultparam, "%u", value); *defaul = defaultparam; } if (!p->num) *defaul = 0; if (p->lo == p->hi) *help = 0; } static int CompareParam_Number(NUM_T *p) { return 0; } static int Param_Number(NUM_T *p, const char *pstr, int flags) { unsigned long val; unsigned long lo; unsigned long hi; const char *opstr; val = 0; opstr = pstr; if (!pstr[0]) { Param_Error(5, "", pstr); return 0; } if (((*pstr == '0') && my_tolower(pstr[1]) == 'x') || (*pstr == '$')) { // 218 if (pstr[0] == '$') pstr += 1; else pstr += 2; while (*pstr) { if (!my_isxdigit(*pstr)) { Param_Error(5, "hexadecimal ", opstr); return 0; } if (val > 0xFFFFFFF) { Param_Error(4, opstr); return 0; } val = (val << 4) | (my_isdigit(*pstr) ? (*pstr - '0') : (my_tolower(*pstr) - 'a' + 10)); ++pstr; } } else if (pstr[0] == '0') { pstr += 1; while (*pstr) { if (*pstr < '0' || *pstr >= '8') { Param_Error(5, "octal ", opstr); return 0; } if (val > 0x1FFFFFFF) { Param_Error(4, opstr); return 0; } val = (val << 3) | (*pstr - '0'); ++pstr; } } else { while (*pstr) { if (!my_isdigit(*pstr)) { Param_Error(5, "decimal ", opstr); return 0; } if (val > 0x19999999) { Param_Error(4, opstr); return 0; } val = (val * 10) + (*pstr - '0'); ++pstr; } } if (p->lo == p->hi) { if (p->size == 1) { lo = 0; hi = 0xFF; } else if (p->size == 2) { lo = 0; hi = 0xFFFF; } else { lo = 0; hi = 0xFFFFFFFF; } } else { lo = p->lo; hi = p->hi; } if (!p->fit && (val < lo || val > hi)) { Param_Error(6, val, lo, hi); return 0; } if (val < lo) { Param_Warning(7, val, lo, hi, lo); val = lo; } else if (val > hi) { Param_Warning(7, val, lo, hi, hi); val = hi; } if (p->size == 1) { unsigned char val8 = val; inline_write_8(p->num, &val8); } if (p->size == 2) { unsigned short val16 = val; inline_write_16(p->num, &val16); } else if (p->size == 4) { unsigned long val32 = val; inline_write_32(p->num, &val32); } return 1; } static void DescHelpParam_FTypeCreator(FTYPE_T *p, const char **desc, const char **help, const char **defaul) { if (p->myname) *desc = p->myname; else if (p->iscreator) *desc = "creator"; else *desc = "type"; if (!p->fc) { *defaul = 0; } else { unsigned long tmp; unsigned char *ptr; ptr = (unsigned char *) defaultparam; tmp = *p->fc; ptr[0] = '\''; ptr[1] = tmp & 0xFF; ptr[2] = (tmp >> 8) & 0xFF; ptr[3] = (tmp >> 16) & 0xFF; ptr[4] = (tmp >> 24) & 0xFF; ptr[5] = '\''; ptr[6] = 0; *defaul = defaultparam; } } static int CompareParam_FTypeCreator(FTYPE_T *p) { return 0; } static int Param_FTypeCreator(FTYPE_T *p, const char *pstr, int flags) { char x[4] = " "; int cnt; const char *opstr; cnt = 0; opstr = pstr; while (*pstr && cnt < 4) { x[cnt++] = *(pstr++); } if (*pstr) { Param_Error(8, opstr); return 0; } inline_write_32(p->fc, &x); return 1; } static void DescHelpParam_String(STRING_T *p, const char **desc, const char **help, const char **defaul) { if (p->myname) *desc = p->myname; else *desc = "string"; if (!p->str) { *help = 0; *defaul = 0; } else { sprintf(helpparam, "maximum length %d chars", p->maxlen - 1); *help = helpparam; if (*p->str) { sprintf(defaultparam, "'%s'", p->str); *defaul = defaultparam; } else { *defaul = "none"; } } } static int CompareParam_String(STRING_T *p) { return 0; } static int Param_String(STRING_T *p, const char *pstr, int flags) { int len; len = strlen(pstr); strncpy(p->str, pstr, p->maxlen - 1); if (p->pstring) c2pstr(p->str); if (len > p->maxlen) { Param_Error(9, pstr, pstr + len - 5, p->maxlen - 1); return 0; } return 1; } static void DescHelpParam_ID_or_SYM(STRING_T *p, const char **desc, const char **help, const char **defaul) { if (p->myname) *desc = p->myname; else if (p->which == PARAMWHICH_Id) *desc = "identifier"; else *desc = "symbol"; if (!p->str) { *help = *defaul = 0; } else { sprintf(helpparam, "maximum length %d chars", p->maxlen - 1); *help = helpparam; if (*p->str) { sprintf(defaultparam, "'%s'", p->str); *defaul = defaultparam; } else { *defaul = "none"; } } } static int CompareParam_ID_or_SYM(STRING_T *p) { return 0; } static int Param_ID_or_SYM(STRING_T *p, const char *pstr, int flags) { const char *ptr; const char *x; if (Param_String(p, pstr, flags)) { if (p->which == PARAMWHICH_Id) { x = "$_"; } else if (p->which == PARAMWHICH_Sym) { x = "_.$@?#"; } for (ptr = pstr; *ptr; ++ptr) { if (ptr == pstr && my_isdigit(*ptr)) Param_Warning(10, pstr); if (!my_isalnum(*ptr) && !strchr(x, *ptr)) Param_Warning(11, pstr, *ptr); } return 1; } else { return 0; } } static void DescHelpParam_OnOff(ONOFF_T *p, const char **desc, const char **help, const char **defaul) { unsigned char def; if (p->myname) *desc = p->myname; else *desc = "on|off"; *help = 0; if (!p->var) { *defaul = 0; } else { if (p->var) *((unsigned char *) &def) = *((unsigned char *) p->var); if (def) *defaul = "on"; else *defaul = "off"; } } static int CompareParam_OnOff(ONOFF_T *p) { return 0; } static int Param_OnOff(ONOFF_T *p, const char *pstr, int flags) { Boolean mytrue = (flags & PARAMPARSEFLAGS_8) == 0; if (!ustrcmp(pstr, "on")) { *(p->var) = mytrue; } else if (!ustrcmp(pstr, "off")) { *(p->var) = mytrue == 0; } else { Param_Error(12, pstr); return 0; } return 1; } static void DescHelpParam_OffOn(ONOFF_T *p, const char **desc, const char **help, const char **defaul) { unsigned char def; if (p->myname) *desc = p->myname; else *desc = "off|on"; *help = 0; if (!p->var) { *defaul = 0; } else { if (p->var) *((unsigned char *) &def) = *((unsigned char *) p->var); if (!def) *defaul = "on"; else *defaul = "off"; } } static int CompareParam_OffOn(OFFON_T *p) { return 0; } static int Param_OffOn(OFFON_T *p, const char *pstr, int flags) { Boolean mytrue = (flags & PARAMPARSEFLAGS_8) == 0; if (!ustrcmp(pstr, "off")) { *(p->var) = mytrue; } else if (!ustrcmp(pstr, "on")) { *(p->var) = mytrue == 0; } else { Param_Error(12, pstr); return 0; } return 1; } static void DescHelpParam_FilePath(FILEPATH_T *p, const char **desc, const char **help, const char **defaul) { if (p->myname) *desc = p->myname; else *desc = "filepath"; *help = 0; *defaul = p->defaultstr; } static int CompareParam_FilePath(FILEPATH_T *p) { return 0; } static int Param_FilePath(FILEPATH_T *p, const char *pstr, int flags) { int err; OSSpec spec; char canon[256]; int clen; if (!pstr[0]) { ((unsigned char *) p->filename)[0] = 0; return 1; } err = OS_MakeFileSpec(pstr, &spec); if (err) { Param_Error(18, pstr, OS_GetErrText(err)); return 0; } OS_SpecToString(&spec, canon, sizeof(canon)); if (p->fflags & 1) { c2pstrcpy(p->filename, canon); } else { clen = strlen(canon); if (clen > p->maxlen) { Param_Error(13, canon + clen - 32, canon); return 0; } strcpy(p->filename, canon); } return 1; } static void DescHelpParam_Mask(MASK_T *p, const char **desc, const char **help, const char **defaul) { *help = 0; *desc = 0; *defaul = 0; } static int CompareParam_Mask(MASK_T *p) { if (p->size == 1) { unsigned char or8 = p->ormask, and8 = p->andmask, val8; if (p->num) copy_8(&val8, p->num); return ((val8 & ~and8) | or8) == val8; } else if (p->size == 2) { unsigned short or16 = p->ormask, and16 = p->andmask, val16; if (p->num) copy_16(&val16, p->num); return ((val16 & ~and16) | or16) == val16; } else { unsigned long or32 = p->ormask, and32 = p->andmask, val32; if (p->num) copy_32(&val32, p->num); return ((val32 & ~and32) | or32) == val32; } } static int Param_Mask(MASK_T *p, const char *pstr, int flags) { if (p->size == 1) { unsigned char or8 = p->ormask, and8 = p->andmask, tmp8; if (flags & PARAMPARSEFLAGS_8) { tmp8 = and8; and8 = and8 | or8; or8 = tmp8; } inline_andor_8(p->num, &and8, &or8); } else if (p->size == 2) { unsigned short or16 = p->ormask, and16 = p->andmask, tmp16; if (flags & PARAMPARSEFLAGS_8) { tmp16 = and16; and16 = and16 | or16; or16 = tmp16; } inline_andor_16(p->num, &and16, &or16); } else { unsigned long or32 = p->ormask, and32 = p->andmask, tmp32; if (flags & PARAMPARSEFLAGS_8) { tmp32 = and32; and32 = and32 | or32; or32 = tmp32; } inline_andor_32(p->num, &and32, &or32); } return 1; } static void DescHelpParam_Toggle(TOGGLE_T *p, const char **desc, const char **help, const char **defaul) { *help = 0; *desc = 0; *defaul = 0; } static int CompareParam_Toggle(TOGGLE_T *p) { if (p->size == 1) { unsigned char mask8, val8; mask8 = (unsigned char) p->mask; if (p->num) copy_8(&val8, p->num); return (val8 ^ mask8) == val8; } else if (p->size == 2) { unsigned short mask16, val16; mask16 = (unsigned short) p->mask; if (p->num) copy_16(&val16, p->num); return (val16 ^ mask16) == val16; } else { unsigned long mask32, val32; mask32 = p->mask; if (p->num) copy_16(&val32, p->num); // BUG ALERT return (val32 ^ mask32) == val32; } } static int Param_Toggle(TOGGLE_T *p, const char *pstr, int flags) { if (p->size == 1) { unsigned char val8; val8 = (unsigned char) p->mask; inline_xor_8(p->num, &val8); } else if (p->size == 2) { unsigned short val16; val16 = (unsigned short) p->mask; inline_xor_16(p->num, &val16); } else { inline_xor_32(p->num, &p->mask); } return 1; } static void DescHelpParam_Set(SET_T *p, const char **desc, const char **help, const char **defaul) { *help = 0; *desc = 0; *defaul = 0; } static int CompareParam_Set(SET_T *p) { if (p->size == 1) { unsigned char set8, val8; set8 = (unsigned char) p->value; if (p->num) copy_8(&val8, p->num); return set8 == val8; } else if (p->size == 2) { unsigned short set16, val16; set16 = (unsigned short) p->value; if (p->num) copy_16(&val16, p->num); return set16 == val16; } else { unsigned long set32, val32; set32 = p->value; if (p->num) copy_32(&val32, p->num); return set32 == val32; } } static int Param_Set(SET_T *p, const char *pstr, int flags) { if (p->size == 1) { unsigned char val8; val8 = (unsigned char) p->value; if ((flags & PARAMPARSEFLAGS_8) && val8 <= 1) val8 = (val8 == 0); inline_write_8(p->num, &val8); } else if (p->size == 2) { unsigned short val16; val16 = (unsigned short) p->value; if ((flags & PARAMPARSEFLAGS_8) && val16 <= 1) val16 = (val16 == 0); inline_write_16(p->num, &val16); } else { unsigned long val32; val32 = p->value; if ((flags & PARAMPARSEFLAGS_8) && val32 <= 1) val32 = (val32 == 0); inline_write_32(p->num, &val32); } return 1; } static void DescHelpParam_SetString(SETSTRING_T *p, const char **desc, const char **help, const char **defaul) { *help = 0; *desc = 0; *defaul = 0; } static int CompareParam_SetString(SETSTRING_T *p, int flags) { if (p->pstring) return pstrcmp((const unsigned char *) p->var, (const unsigned char *) p->value) == 0; else return strcmp(p->var, p->value) == 0; } static int Param_SetString(SETSTRING_T *p, const char *pstr, int flags) { if (p->pstring) memcpy(p->var, p->value, p->value[0]); else strcpy(p->var, p->value); return 1; } static void DescHelpParam_Generic(GENERIC_T *p, const char **desc, const char **help, const char **defaul) { if (p->myname) *desc = p->myname; else if ((p->flags & PARAMFLAGS_3) != 1) *desc = "xxx"; else *desc = 0; *help = p->help; *defaul = 0; } static int CompareParam_Generic(GENERIC_T *p) { return 0; } static int Param_Generic(GENERIC_T *p, const char *pstr, int flags) { return p->parse(curopt, p->var, pstr, flags); } static void DescHelpParam_Setting(SETTING_T *p, const char **desc, const char **help, const char **defaul) { char *dptr = descparam; dptr += sprintf(dptr, "%s", p->myname ? p->myname : "var"); if ((p->flags & PARAMFLAGS_3) != 1) { sprintf(dptr, "%s=%s%s", (p->flags & PARAMFLAGS_2) ? "[" : "", p->valuename ? p->valuename : "...", (p->flags & PARAMFLAGS_2) ? "]" : "" ); } *desc = descparam; *help = 0; *defaul = 0; } static int CompareParam_Setting(SETTING_T *p) { return 0; } static int Param_Setting(SETTING_T *p, const char *pstr, int flags) { char savevar[256]; const char *vstr; ArgToken *tok; Boolean equals = 0; if (!pstr) { Param_Error(40); return 0; } strncpy(savevar, pstr, sizeof(savevar)); tok = Arg_PeekToken(); if (tok && tok->val == ATK_4) { Arg_UsedToken(); equals = 1; if (!Param_GetArgument((PARAM_T *) p, &vstr, flags)) return 0; } else { vstr = 0; } if (!vstr && equals) vstr = ""; return p->parse(savevar, vstr); } static void DescHelpParam_IfArg(IFARG_T *p, const char **desc, const char **help, const char **defaul) { const char *d1 = 0; const char *d2 = 0; const char *h1 = 0; const char *h2 = 0; const char *df1 = 0; const char *df2 = 0; char desclocal[1024]; char *dptr = desclocal; char helplocal[1024]; char *hptr = helplocal; const char *ind; desclocal[0] = 0; helplocal[0] = 0; if (p->parg) Param_DescHelp(p->parg, &d1, &h1, &df1); if (p->pnone) Param_DescHelp(p->pnone, &d2, &h2, &df2); if (p->helpa && p->helpn) { if (df1) hptr += sprintf(hptr, "%s (default is %s), else %s", p->helpa, df1, p->helpn); else hptr += sprintf(hptr, "%s, else %s", p->helpa, p->helpn); } else if (p->helpa) { hptr += sprintf(hptr, "%s", p->helpa); if (df1) hptr += sprintf(hptr, "; default is %s", df1); } else if (p->helpn) { hptr += sprintf(hptr, "nothing, else %s", p->helpn); } if (d1) { if (p->myname) { dptr += sprintf(dptr, "[%s]", p->myname ? p->myname: "param"); } else if (h1) { ind = strchr(d1, '\n'); if (!ind) ind = d1 + strlen(d1); dptr += sprintf(dptr, "[%.*s]", ind - d1, d1); } else { dptr += sprintf(dptr, "[%s]", d1); d1 = 0; } } if (h1 || h2) { dptr += sprintf(dptr, "\n\t"); hptr += sprintf(hptr, "\n\t"); if (h1) { if (d1) dptr += sprintf(dptr, "%s", d1); if (h1) hptr += sprintf(hptr, "%s", h1); if (h2) { dptr += sprintf(dptr, "\b\t"); hptr += sprintf(hptr, "\b\t"); } } if (h2) { if (d2) dptr += sprintf(dptr, "%s", d2); else dptr += sprintf(dptr, "(if blank)"); if (h2) hptr += sprintf(hptr, "%s", h2); dptr += sprintf(dptr, "\n"); hptr += sprintf(hptr, "\n"); } dptr += sprintf(dptr, "\b"); hptr += sprintf(hptr, "\b"); } if (dptr != desclocal) { strcpy(descparam, desclocal); *desc = descparam; } else { *desc = 0; } if (hptr != helplocal) { strcpy(helpparam, helplocal); *help = helpparam; } else { *help = 0; } *defaul = 0; } static int CompareParam_IfArg(IFARG_T *p) { return 0; } static int Param_IfArg(IFARG_T *p, const char *pstr, int flags) { if (pstr) return Param_Parse(p->parg, pstr, flags); else if (p->pnone) return Param_Parse(p->pnone, pstr, flags); else return 1; } typedef int (*PARSE_FUNC)(PARAM_T *, const char *, int); PARSE_FUNC ParamParsers[16] = { (PARSE_FUNC) &Param_None, (PARSE_FUNC) &Param_FTypeCreator, (PARSE_FUNC) &Param_FilePath, (PARSE_FUNC) &Param_Number, (PARSE_FUNC) &Param_String, (PARSE_FUNC) &Param_ID_or_SYM, (PARSE_FUNC) &Param_ID_or_SYM, (PARSE_FUNC) &Param_OnOff, (PARSE_FUNC) &Param_OffOn, (PARSE_FUNC) &Param_Mask, (PARSE_FUNC) &Param_Toggle, (PARSE_FUNC) &Param_Set, (PARSE_FUNC) &Param_SetString, (PARSE_FUNC) &Param_Generic, (PARSE_FUNC) &Param_IfArg, (PARSE_FUNC) &Param_Setting }; static int Param_Parse(PARAM_T *param, const char *cparam, int flags) { if (!param) CLPFatalError("PARAM_T is NULL"); if (param->which >= PARAMWHICH_None && param->which < PARAMWHICH_MAX) { return ParamParsers[param->which](param, cparam, flags); } else { CLPFatalError("Unhandled PARAM_T (%d)", param->which); return 0; } } typedef void (*DESC_HELP_FUNC)(PARAM_T *, const char **, const char **, const char **); DESC_HELP_FUNC DescHelpParams[16] = { (DESC_HELP_FUNC) &DescHelpParam_None, (DESC_HELP_FUNC) &DescHelpParam_FTypeCreator, (DESC_HELP_FUNC) &DescHelpParam_FilePath, (DESC_HELP_FUNC) &DescHelpParam_Number, (DESC_HELP_FUNC) &DescHelpParam_String, (DESC_HELP_FUNC) &DescHelpParam_ID_or_SYM, (DESC_HELP_FUNC) &DescHelpParam_ID_or_SYM, (DESC_HELP_FUNC) &DescHelpParam_OnOff, (DESC_HELP_FUNC) &DescHelpParam_OffOn, (DESC_HELP_FUNC) &DescHelpParam_Mask, (DESC_HELP_FUNC) &DescHelpParam_Toggle, (DESC_HELP_FUNC) &DescHelpParam_Set, (DESC_HELP_FUNC) &DescHelpParam_SetString, (DESC_HELP_FUNC) &DescHelpParam_Generic, (DESC_HELP_FUNC) &DescHelpParam_IfArg, (DESC_HELP_FUNC) &DescHelpParam_Setting }; void Param_DescHelp(PARAM_T *param, const char **desc, const char **help, const char **defaul) { *desc = 0; *help = 0; *defaul = 0; if (!param) { CLPFatalError("PARAM_T is NULL"); return; } if (param->which >= PARAMWHICH_None && param->which < PARAMWHICH_MAX) { DescHelpParams[param->which](param, desc, help, defaul); } else { CLPFatalError("Unhandled PARAM_T (%d)", param->which); } } typedef int (*COMPARE_FUNC)(PARAM_T *); COMPARE_FUNC CompareParams[16] = { (COMPARE_FUNC) &CompareParam_None, (COMPARE_FUNC) &CompareParam_FTypeCreator, (COMPARE_FUNC) &CompareParam_FilePath, (COMPARE_FUNC) &CompareParam_Number, (COMPARE_FUNC) &CompareParam_String, (COMPARE_FUNC) &CompareParam_ID_or_SYM, (COMPARE_FUNC) &CompareParam_ID_or_SYM, (COMPARE_FUNC) &CompareParam_OnOff, (COMPARE_FUNC) &CompareParam_OffOn, (COMPARE_FUNC) &CompareParam_Mask, (COMPARE_FUNC) &CompareParam_Toggle, (COMPARE_FUNC) &CompareParam_Set, (COMPARE_FUNC) &CompareParam_SetString, (COMPARE_FUNC) &CompareParam_Generic, (COMPARE_FUNC) &CompareParam_IfArg, (COMPARE_FUNC) &CompareParam_Setting }; int Param_Compare(PARAM_T *param) { if (!param) CLPFatalError("PARAM_T is NULL"); if (param->which >= PARAMWHICH_None && param->which < PARAMWHICH_MAX) { return CompareParams[param->which](param); } else { CLPFatalError("Unhandled PARAM_T (%d)", param->which); return 0; } } static void Param_PushParam(const char *param) { Args_Push(4, (void *) param, 0); } static void Param_PopParam() { Args_Pop(4); } static Boolean Param_IsNonTextFile(const char *fname, Boolean warn) { OSSpec tmp; CWDataType mactype; Boolean isfile; if (!OS_MakeSpec(fname, &tmp, &isfile)) { if (isfile) { if (!OS_Status(&tmp)) { if (!OS_GetMacFileType(&tmp, &mactype)) { if (mactype != 'TEXT') { if (warn) Param_Warning(77, fname); return 1; } } } } } return 0; } static int Param_GetArgument(PARAM_T *param, const char **cparam, int exec) { int subparse; short nextOpt; short nextParam; short lastOpt; ArgToken *tok; subparse = (exec & PARAMPARSEFLAGS_4) != 0; nextOpt = !subparse ? ATK_1 : ATK_5; nextParam = !subparse ? ATK_5 : ATK_4; lastOpt = !subparse ? ATK_0 : ATK_1; tok = Arg_PeekToken(); #line 1467 OPTION_ASSERT(tok); if ((param->flags & PARAMFLAGS_3) == 0) { if (tok->val == nextParam || tok->val == ATK_4) tok = Arg_UsedToken(); if (tok->val == nextOpt || tok->val == nextParam || tok->val == lastOpt) { Param_Error(34); return 0; } if (tok->val != ATK_2) { Param_Error(57, "parameter", Arg_GetTokenName(tok)); return 0; } Arg_GetTokenText(tok, curparam, sizeof(curparam), 1); Arg_UsedToken(); *cparam = curparam; if (param->flags & PARAMFLAGS_8) { tok = Arg_PeekToken(); if (tok->val == ATK_4) Arg_UsedToken(); } } else if (param->flags & PARAMFLAGS_1) { *cparam = 0; if (tok->val == ATK_4 && !subparse) { if (!(exec & PARAMPARSEFLAGS_40)) { Param_Error(37); return 0; } Arg_UsedToken(); } } else if (param->flags & PARAMFLAGS_2) { if (tok->val == nextOpt || tok->val == lastOpt) { *cparam = 0; } else if (tok->val == nextParam) { tok = Arg_UsedToken(); if (tok->val == ATK_2) { Arg_GetTokenText(tok, curparam, sizeof(curparam), 1); if ((param->flags & PARAMFLAGS_12) && Param_IsNonTextFile(curparam, !(exec & PARAMPARSEFLAGS_1))) { *cparam = 0; } else { Arg_UsedToken(); *cparam = curparam; } } else { *cparam = 0; } } else if (tok->val == ATK_2 && !tok->text[0]) { tok = Arg_UsedToken(); if (tok->val == nextParam) Arg_UsedToken(); *cparam = 0; } else if ((exec & PARAMPARSEFLAGS_4) && tok->val != ATK_4) { *cparam = 0; } else { if (tok->val == ATK_4) tok = Arg_UsedToken(); if (tok->val == ATK_2) { Arg_GetTokenText(tok, curparam, sizeof(curparam), 1); if ((param->flags & PARAMFLAGS_12) && Param_IsNonTextFile(curparam, !(exec & PARAMPARSEFLAGS_1))) { *cparam = 0; } else { Arg_UsedToken(); *cparam = curparam; } } else { *cparam = 0; } } } else { CLPFatalError("Unknown parameter type"); } if (pTool->TYPE == CWDROPINCOMPILERTYPE && (exec & PARAMPARSEFLAGS_2) && *cparam) { if (!(exec & PARAMPARSEFLAGS_10)) { if (subparse) Arg_AddToToolArgs(&linkargs, ATK_4, 0); else Arg_AddToToolArgs(&linkargs, ATK_5, 0); } Param_PushParam(*cparam); Args_AddToToolArgs(&linkargs); Param_PopParam(); } return 1; } int Params_Parse(PARAM_T *param, int flags) { const char *cparam; flags |= PARAMPARSEFLAGS_10; if (param) { while (param) { if (flags & PARAMPARSEFLAGS_20) flags |= PARAMPARSEFLAGS_40; if (!Param_GetArgument(param, &cparam, flags)) return 0; if (!(flags & PARAMPARSEFLAGS_1)) { if (!Param_Parse(param, cparam, flags | (short) ((param->flags & PARAMFLAGS_4) ? PARAMPARSEFLAGS_20 : 0))) return 0; } else if (param->flags & PARAMFLAGS_4) { if (!Param_GetArgument(param, &cparam, flags | PARAMPARSEFLAGS_4)) return 0; } if (cparam) flags &= ~PARAMPARSEFLAGS_10; flags &= ~PARAMPARSEFLAGS_40; param = param->next; } } return 1; } void Param_Error(short id, ...) { va_list va; va_start(va, id); Option_ParamError(id, va); va_end(va); } void Param_Warning(short id, ...) { va_list va; va_start(va, id); Option_ParamWarning(id, va); va_end(va); }