VBoolean VGetAttrValue (VAttrListPosn *posn, VDictEntry *dict, VRepnKind repn, VPointer value) { /* Convert it to the requested representation: */ switch (repn) { case VBitRepn: case VUByteRepn: case VSByteRepn: case VShortRepn: case VLongRepn: case VFloatRepn: case VDoubleRepn: case VBooleanRepn: case VStringRepn: return (VGetAttrRepn (posn) == VStringRepn && VDecodeAttrValue (posn->ptr->value, dict, repn, value)); default: if (VGetAttrRepn (posn) != repn) return FALSE; * (VPointer *) value = posn->ptr->value; return TRUE; } }
static int ParseArgValues (int *arg, int argc, char **argv, VOptionDescRec *opt) { VArgVector *vec = (VArgVector *) opt->value; VPointer values; int nvalues = 0; VDictEntry *dict = opt->dict; char *cp; /* Locate the place we're to store the argument values: */ if (opt->number == 0) { /* If a variable number of arguments is expected, allocate storage to hold them: */ vec->vector = values = VMalloc ((argc - *arg) * VRepnSize (opt->repn)); } else values = opt->value; /* If no dictionary is specified for a boolean-valued option, use the default one of true, false, yes, no... */ if (opt->repn == VBooleanRepn && ! dict) dict = VBooleanDict; /* Parse argument values until we've reached the required number, we've run out of entered arguments, or we encounter one that is ill-formed: */ while ((opt->number == 0 || nvalues < opt->number) && (*arg < argc)) { cp = argv[*arg]; /* Special treatment for string-valued options: */ if (opt->repn == VStringRepn) { /* An argument of the form -string is not interpreted as a string value: */ if (cp[0] == '-' && cp[1] != 0 && cp[1] != '-') break; /* An argument of the form --string is interpreted as string: */ if (cp[0] == '-' && cp[1] == '-' && cp[2] != 0) cp += 2; } /* Convert the argument to the specified internal form: */ if (! VDecodeAttrValue (cp, dict, opt->repn, values)) break; nvalues++; values = (VPointer) ((char *) values + VRepnSize (opt->repn)); argv[(*arg)++] = NULL; } /* Special treatment of boolean-valued options: if the option has just one value associated with it then treat -option <other options> like -option true <other options>: */ if (opt->repn == VBooleanRepn && opt->number == 1 && nvalues == 0) { * (VBoolean *) opt->value = TRUE; nvalues = 1; } return nvalues; }
VDictEntry *VLookupDictValue (VDictEntry *dict, VRepnKind repn, ...) { va_list args; VLong i_value = 0; VDouble f_value = 0.0; VString s_value = NULL; VBoolean i_valid; /* Unravel the arguments passed: */ if (! dict) return NULL; va_start (args, repn); switch (repn) { case VBitRepn: i_value = va_arg (args, VBitPromoted); break; case VUByteRepn: i_value = va_arg (args, VUBytePromoted); break; case VSByteRepn: i_value = va_arg (args, VSBytePromoted); break; case VShortRepn: i_value = va_arg (args, VShortPromoted); break; case VLongRepn: i_value = va_arg (args, VLongPromoted); break; case VFloatRepn: f_value = va_arg (args, VFloatPromoted); break; case VDoubleRepn: f_value = va_arg (args, VDoublePromoted); break; case VBooleanRepn: i_value = va_arg (args, VBooleanPromoted); break; case VStringRepn: s_value = va_arg (args, VString); break; default: VError ("VLookupDictValue: Can't lookup %s value", VRepnName (repn)); } va_end (args); /* Search the dictionary by value: */ switch (repn) { case VBitRepn: case VUByteRepn: case VSByteRepn: case VShortRepn: case VLongRepn: case VBooleanRepn: for ( ; dict->keyword; dict++) { /* Is the entry's value only stored as a string? */ if (dict->svalue && ! dict->icached) { /* Yes -- try to convert the string to an integer, and cache that value: */ if (! VDecodeAttrValue (dict->svalue, NULL, VLongRepn, & dict->ivalue)) break; dict->icached = TRUE; } /* Test against the integer value stored in the entry: */ if (i_value == dict->ivalue) return dict; } break; case VFloatRepn: case VDoubleRepn: for ( ; dict->keyword; dict++) { /* Does the entry include a cached floating point value? */ if (! dict->fcached) { /* No -- obtain it from an integer or string value: */ if (dict->svalue) { if (! VDecodeAttrValue (dict->svalue, NULL, VDoubleRepn, & dict->fvalue)) break; } else dict->fvalue = dict->ivalue; dict->fcached = TRUE; } /* Test against the cached float value now stored in the entry: */ if (f_value == dict->fvalue) return dict; } break; case VStringRepn: /* In case we're searching a dictionary with only integer values stored, try to convert the supplied string value to an integer: */ i_valid = VDecodeAttrValue (s_value, NULL, VLongRepn, & i_value); for ( ; dict->keyword; dict++) { /* If the entry includes a string value, compare with it: */ if (dict->svalue) { if (strcmp (s_value, dict->svalue) == 0) return dict; } /* Otherwise, compare with its integer value: */ else if (i_valid && i_value == dict->ivalue) return dict; } break; default: break; } return NULL; }