summaryrefslogtreecommitdiff
path: root/Parameter.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Parameter.c1148
1 files changed, 1148 insertions, 0 deletions
diff --git a/Parameter.c b/Parameter.c
new file mode 100644
index 0000000..6566f12
--- /dev/null
+++ b/Parameter.c
@@ -0,0 +1,1148 @@
+#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);
+}