From 4f37161a8f221cc31493c1ec3fb017f486754626 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 10 Sep 2020 16:54:38 -0700 Subject: [PATCH] util/xmlconfig: Indent to Mesa style. I'm heavily editing this code, and having Mesa's style not apply sucks. Reviewed-by: Eric Engestrom Part-of: --- src/util/xmlconfig.c | 1780 +++++++++++++++++++++++++------------------------- src/util/xmlconfig.h | 84 +-- 2 files changed, 933 insertions(+), 931 deletions(-) diff --git a/src/util/xmlconfig.c b/src/util/xmlconfig.c index 84d20ae..6426f59 100644 --- a/src/util/xmlconfig.c +++ b/src/util/xmlconfig.c @@ -67,52 +67,52 @@ be_verbose(void) static uint32_t findOption(const driOptionCache *cache, const char *name) { - uint32_t len = strlen (name); - uint32_t size = 1 << cache->tableSize, mask = size - 1; - uint32_t hash = 0; - uint32_t i, shift; - - /* compute a hash from the variable length name */ - for (i = 0, shift = 0; i < len; ++i, shift = (shift+8) & 31) - hash += (uint32_t)name[i] << shift; - hash *= hash; - hash = (hash >> (16-cache->tableSize/2)) & mask; - - /* this is just the starting point of the linear search for the option */ - for (i = 0; i < size; ++i, hash = (hash+1) & mask) { + uint32_t len = strlen(name); + uint32_t size = 1 << cache->tableSize, mask = size - 1; + uint32_t hash = 0; + uint32_t i, shift; + + /* compute a hash from the variable length name */ + for (i = 0, shift = 0; i < len; ++i, shift = (shift+8) & 31) + hash += (uint32_t)name[i] << shift; + hash *= hash; + hash = (hash >> (16-cache->tableSize/2)) & mask; + + /* this is just the starting point of the linear search for the option */ + for (i = 0; i < size; ++i, hash = (hash+1) & mask) { /* if we hit an empty entry then the option is not defined (yet) */ - if (cache->info[hash].name == 0) - break; - else if (!strcmp (name, cache->info[hash].name)) - break; - } - /* this assertion fails if the hash table is full */ - assert (i < size); - - return hash; + if (cache->info[hash].name == 0) + break; + else if (!strcmp(name, cache->info[hash].name)) + break; + } + /* this assertion fails if the hash table is full */ + assert (i < size); + + return hash; } /** \brief Like strdup with error checking. */ -#define XSTRDUP(dest,source) do { \ - if (!(dest = strdup(source))) { \ - fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); \ - abort(); \ - } \ -} while (0) - -static int compare (const void *a, const void *b) { - return strcmp (*(char *const*)a, *(char *const*)b); +#define XSTRDUP(dest,source) do { \ + if (!(dest = strdup(source))) { \ + fprintf(stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); \ + abort(); \ + } \ + } while (0) + +static int compare(const void *a, const void *b) { + return strcmp(*(char *const*)a, *(char *const*)b); } /** \brief Binary search in a string array. */ static uint32_t -bsearchStr (const XML_Char *name, const XML_Char *elems[], uint32_t count) +bsearchStr(const XML_Char *name, const XML_Char *elems[], uint32_t count) { - const XML_Char **found; - found = bsearch (&name, elems, count, sizeof (XML_Char *), compare); - if (found) - return found - elems; - else - return count; + const XML_Char **found; + found = bsearch(&name, elems, count, sizeof(XML_Char *), compare); + if (found) + return found - elems; + else + return count; } /** \brief Locale-independent integer parser. @@ -127,51 +127,51 @@ bsearchStr (const XML_Char *name, const XML_Char *elems[], uint32_t count) static int strToI(const XML_Char *string, const XML_Char **tail, int base) { - int radix = base == 0 ? 10 : base; - int result = 0; - int sign = 1; - bool numberFound = false; - const XML_Char *start = string; - - assert (radix >= 2 && radix <= 36); - - if (*string == '-') { - sign = -1; - string++; - } else if (*string == '+') - string++; - if (base == 0 && *string == '0') { - numberFound = true; - if (*(string+1) == 'x' || *(string+1) == 'X') { - radix = 16; - string += 2; - } else { - radix = 8; - string++; - } - } - do { - int digit = -1; - if (radix <= 10) { - if (*string >= '0' && *string < '0' + radix) - digit = *string - '0'; - } else { - if (*string >= '0' && *string <= '9') - digit = *string - '0'; - else if (*string >= 'a' && *string < 'a' + radix - 10) - digit = *string - 'a' + 10; - else if (*string >= 'A' && *string < 'A' + radix - 10) - digit = *string - 'A' + 10; - } - if (digit != -1) { - numberFound = true; - result = radix*result + digit; - string++; - } else - break; - } while (true); - *tail = numberFound ? string : start; - return sign * result; + int radix = base == 0 ? 10 : base; + int result = 0; + int sign = 1; + bool numberFound = false; + const XML_Char *start = string; + + assert(radix >= 2 && radix <= 36); + + if (*string == '-') { + sign = -1; + string++; + } else if (*string == '+') + string++; + if (base == 0 && *string == '0') { + numberFound = true; + if (*(string+1) == 'x' || *(string+1) == 'X') { + radix = 16; + string += 2; + } else { + radix = 8; + string++; + } + } + do { + int digit = -1; + if (radix <= 10) { + if (*string >= '0' && *string < '0' + radix) + digit = *string - '0'; + } else { + if (*string >= '0' && *string <= '9') + digit = *string - '0'; + else if (*string >= 'a' && *string < 'a' + radix - 10) + digit = *string - 'a' + 10; + else if (*string >= 'A' && *string < 'A' + radix - 10) + digit = *string - 'A' + 10; + } + if (digit != -1) { + numberFound = true; + result = radix*result + digit; + string++; + } else + break; + } while (true); + *tail = numberFound ? string : start; + return sign * result; } /** \brief Locale-independent floating-point parser. @@ -189,285 +189,285 @@ strToI(const XML_Char *string, const XML_Char **tail, int base) static float strToF(const XML_Char *string, const XML_Char **tail) { - int nDigits = 0, pointPos, exponent; - float sign = 1.0f, result = 0.0f, scale; - const XML_Char *start = string, *numStart; - - /* sign */ - if (*string == '-') { - sign = -1.0f; - string++; - } else if (*string == '+') - string++; - - /* first pass: determine position of decimal point, number of - * digits, exponent and the end of the number. */ - numStart = string; - while (*string >= '0' && *string <= '9') { - string++; - nDigits++; - } - pointPos = nDigits; - if (*string == '.') { - string++; - while (*string >= '0' && *string <= '9') { - string++; - nDigits++; - } - } - if (nDigits == 0) { - /* no digits, no number */ - *tail = start; - return 0.0f; - } - *tail = string; - if (*string == 'e' || *string == 'E') { - const XML_Char *expTail; - exponent = strToI (string+1, &expTail, 10); - if (expTail == string+1) - exponent = 0; - else - *tail = expTail; - } else - exponent = 0; - string = numStart; - - /* scale of the first digit */ - scale = sign * (float)pow (10.0, (double)(pointPos-1 + exponent)); - - /* second pass: parse digits */ - do { - if (*string != '.') { - assert (*string >= '0' && *string <= '9'); - result += scale * (float)(*string - '0'); - scale *= 0.1f; - nDigits--; - } - string++; - } while (nDigits > 0); - - return result; + int nDigits = 0, pointPos, exponent; + float sign = 1.0f, result = 0.0f, scale; + const XML_Char *start = string, *numStart; + + /* sign */ + if (*string == '-') { + sign = -1.0f; + string++; + } else if (*string == '+') + string++; + + /* first pass: determine position of decimal point, number of + * digits, exponent and the end of the number. */ + numStart = string; + while (*string >= '0' && *string <= '9') { + string++; + nDigits++; + } + pointPos = nDigits; + if (*string == '.') { + string++; + while (*string >= '0' && *string <= '9') { + string++; + nDigits++; + } + } + if (nDigits == 0) { + /* no digits, no number */ + *tail = start; + return 0.0f; + } + *tail = string; + if (*string == 'e' || *string == 'E') { + const XML_Char *expTail; + exponent = strToI(string+1, &expTail, 10); + if (expTail == string+1) + exponent = 0; + else + *tail = expTail; + } else + exponent = 0; + string = numStart; + + /* scale of the first digit */ + scale = sign * (float)pow(10.0, (double)(pointPos-1 + exponent)); + + /* second pass: parse digits */ + do { + if (*string != '.') { + assert(*string >= '0' && *string <= '9'); + result += scale * (float)(*string - '0'); + scale *= 0.1f; + nDigits--; + } + string++; + } while (nDigits > 0); + + return result; } /** \brief Parse a value of a given type. */ static unsigned char parseValue(driOptionValue *v, driOptionType type, const XML_Char *string) { - const XML_Char *tail = NULL; - /* skip leading white-space */ - string += strspn (string, " \f\n\r\t\v"); - switch (type) { - case DRI_BOOL: - if (!strcmp (string, "false")) { - v->_bool = false; - tail = string + 5; - } else if (!strcmp (string, "true")) { - v->_bool = true; - tail = string + 4; - } - else - return false; - break; - case DRI_ENUM: /* enum is just a special integer */ - case DRI_INT: - v->_int = strToI (string, &tail, 0); - break; - case DRI_FLOAT: - v->_float = strToF (string, &tail); - break; - case DRI_STRING: - free (v->_string); - v->_string = strndup(string, STRING_CONF_MAXLEN); - return true; - } - - if (tail == string) - return false; /* empty string (or containing only white-space) */ - /* skip trailing white space */ - if (*tail) - tail += strspn (tail, " \f\n\r\t\v"); - if (*tail) - return false; /* something left over that is not part of value */ - - return true; + const XML_Char *tail = NULL; + /* skip leading white-space */ + string += strspn(string, " \f\n\r\t\v"); + switch (type) { + case DRI_BOOL: + if (!strcmp(string, "false")) { + v->_bool = false; + tail = string + 5; + } else if (!strcmp(string, "true")) { + v->_bool = true; + tail = string + 4; + } + else + return false; + break; + case DRI_ENUM: /* enum is just a special integer */ + case DRI_INT: + v->_int = strToI(string, &tail, 0); + break; + case DRI_FLOAT: + v->_float = strToF(string, &tail); + break; + case DRI_STRING: + free(v->_string); + v->_string = strndup(string, STRING_CONF_MAXLEN); + return true; + } + + if (tail == string) + return false; /* empty string (or containing only white-space) */ + /* skip trailing white space */ + if (*tail) + tail += strspn(tail, " \f\n\r\t\v"); + if (*tail) + return false; /* something left over that is not part of value */ + + return true; } /** \brief Parse a list of ranges of type info->type. */ static unsigned char parseRanges(driOptionInfo *info, const XML_Char *string) { - XML_Char *cp, *range; - uint32_t nRanges, i; - driOptionRange *ranges; - - XSTRDUP (cp, string); - /* pass 1: determine the number of ranges (number of commas + 1) */ - range = cp; - for (nRanges = 1; *range; ++range) - if (*range == ',') - ++nRanges; - - if ((ranges = malloc(nRanges*sizeof(driOptionRange))) == NULL) { - fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); - abort(); - } - - /* pass 2: parse all ranges into preallocated array */ - range = cp; - for (i = 0; i < nRanges; ++i) { - XML_Char *end, *sep; - assert (range); - end = strchr (range, ','); - if (end) - *end = '\0'; - sep = strchr (range, ':'); - if (sep) { /* non-empty interval */ - *sep = '\0'; - if (!parseValue (&ranges[i].start, info->type, range) || - !parseValue (&ranges[i].end, info->type, sep+1)) - break; - if (info->type == DRI_INT && - ranges[i].start._int > ranges[i].end._int) - break; - if (info->type == DRI_FLOAT && - ranges[i].start._float > ranges[i].end._float) - break; - } else { /* empty interval */ - if (!parseValue (&ranges[i].start, info->type, range)) - break; - ranges[i].end = ranges[i].start; - } - if (end) - range = end+1; - else - range = NULL; - } - free(cp); - if (i < nRanges) { - free(ranges); - return false; - } else - assert (range == NULL); - - info->nRanges = nRanges; - info->ranges = ranges; - return true; + XML_Char *cp, *range; + uint32_t nRanges, i; + driOptionRange *ranges; + + XSTRDUP(cp, string); + /* pass 1: determine the number of ranges (number of commas + 1) */ + range = cp; + for (nRanges = 1; *range; ++range) + if (*range == ',') + ++nRanges; + + if ((ranges = malloc(nRanges*sizeof(driOptionRange))) == NULL) { + fprintf(stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); + abort(); + } + + /* pass 2: parse all ranges into preallocated array */ + range = cp; + for (i = 0; i < nRanges; ++i) { + XML_Char *end, *sep; + assert(range); + end = strchr(range, ','); + if (end) + *end = '\0'; + sep = strchr(range, ':'); + if (sep) { /* non-empty interval */ + *sep = '\0'; + if (!parseValue(&ranges[i].start, info->type, range) || + !parseValue(&ranges[i].end, info->type, sep+1)) + break; + if (info->type == DRI_INT && + ranges[i].start._int > ranges[i].end._int) + break; + if (info->type == DRI_FLOAT && + ranges[i].start._float > ranges[i].end._float) + break; + } else { /* empty interval */ + if (!parseValue(&ranges[i].start, info->type, range)) + break; + ranges[i].end = ranges[i].start; + } + if (end) + range = end+1; + else + range = NULL; + } + free(cp); + if (i < nRanges) { + free(ranges); + return false; + } else + assert(range == NULL); + + info->nRanges = nRanges; + info->ranges = ranges; + return true; } /** \brief Check if a value is in one of info->ranges. */ static bool checkValue(const driOptionValue *v, const driOptionInfo *info) { - uint32_t i; - assert (info->type != DRI_BOOL); /* should be caught by the parser */ - if (info->nRanges == 0) - return true; - switch (info->type) { - case DRI_ENUM: /* enum is just a special integer */ - case DRI_INT: - for (i = 0; i < info->nRanges; ++i) - if (v->_int >= info->ranges[i].start._int && - v->_int <= info->ranges[i].end._int) - return true; - break; - case DRI_FLOAT: - for (i = 0; i < info->nRanges; ++i) - if (v->_float >= info->ranges[i].start._float && - v->_float <= info->ranges[i].end._float) - return true; - break; - case DRI_STRING: - break; - default: - assert (0); /* should never happen */ - } - return false; + uint32_t i; + assert(info->type != DRI_BOOL); /* should be caught by the parser */ + if (info->nRanges == 0) + return true; + switch (info->type) { + case DRI_ENUM: /* enum is just a special integer */ + case DRI_INT: + for (i = 0; i < info->nRanges; ++i) + if (v->_int >= info->ranges[i].start._int && + v->_int <= info->ranges[i].end._int) + return true; + break; + case DRI_FLOAT: + for (i = 0; i < info->nRanges; ++i) + if (v->_float >= info->ranges[i].start._float && + v->_float <= info->ranges[i].end._float) + return true; + break; + case DRI_STRING: + break; + default: + assert(0); /* should never happen */ + } + return false; } /** * Print message to \c stderr if the \c LIBGL_DEBUG environment variable - * is set. - * + * is set. + * * Is called from the drivers. - * + * * \param f \c printf like format string. */ static void __driUtilMessage(const char *f, ...) { - va_list args; - const char *libgl_debug; - - libgl_debug=getenv("LIBGL_DEBUG"); - if (libgl_debug && !strstr(libgl_debug, "quiet")) { - fprintf(stderr, "libGL: "); - va_start(args, f); - vfprintf(stderr, f, args); - va_end(args); - fprintf(stderr, "\n"); - } + va_list args; + const char *libgl_debug; + + libgl_debug=getenv("LIBGL_DEBUG"); + if (libgl_debug && !strstr(libgl_debug, "quiet")) { + fprintf(stderr, "libGL: "); + va_start(args, f); + vfprintf(stderr, f, args); + va_end(args); + fprintf(stderr, "\n"); + } } /** \brief Output a warning message. */ -#define XML_WARNING1(msg) do {\ - __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser)); \ -} while (0) -#define XML_WARNING(msg, ...) do { \ - __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser), \ - ##__VA_ARGS__); \ -} while (0) +#define XML_WARNING1(msg) do { \ + __driUtilMessage("Warning in %s line %d, column %d: "msg, data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ + } while (0) +#define XML_WARNING(msg, ...) do { \ + __driUtilMessage("Warning in %s line %d, column %d: "msg, data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ + ##__VA_ARGS__); \ + } while (0) /** \brief Output an error message. */ -#define XML_ERROR1(msg) do { \ - __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser)); \ -} while (0) -#define XML_ERROR(msg, ...) do { \ - __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser), \ - ##__VA_ARGS__); \ -} while (0) +#define XML_ERROR1(msg) do { \ + __driUtilMessage("Error in %s line %d, column %d: "msg, data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ + } while (0) +#define XML_ERROR(msg, ...) do { \ + __driUtilMessage("Error in %s line %d, column %d: "msg, data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ + ##__VA_ARGS__); \ + } while (0) /** \brief Output a fatal error message and abort. */ -#define XML_FATAL1(msg) do { \ - fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ - data->name, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser)); \ - abort();\ -} while (0) -#define XML_FATAL(msg, ...) do { \ - fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ - data->name, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser), \ - ##__VA_ARGS__); \ - abort();\ -} while (0) +#define XML_FATAL1(msg) do { \ + fprintf(stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ + data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ + abort(); \ + } while (0) +#define XML_FATAL(msg, ...) do { \ + fprintf(stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ + data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ + ##__VA_ARGS__); \ + abort(); \ + } while (0) /** \brief Parser context for __driConfigOptions. */ struct OptInfoData { - const char *name; - XML_Parser parser; - driOptionCache *cache; - bool inDriInfo; - bool inSection; - bool inDesc; - bool inOption; - bool inEnum; - int curOption; + const char *name; + XML_Parser parser; + driOptionCache *cache; + bool inDriInfo; + bool inSection; + bool inDesc; + bool inOption; + bool inEnum; + int curOption; }; /** \brief Elements in __driConfigOptions. */ enum OptInfoElem { - OI_DESCRIPTION = 0, OI_DRIINFO, OI_ENUM, OI_OPTION, OI_SECTION, OI_COUNT + OI_DESCRIPTION = 0, OI_DRIINFO, OI_ENUM, OI_OPTION, OI_SECTION, OI_COUNT }; static const XML_Char *OptInfoElems[] = { - "description", "driinfo", "enum", "option", "section" + "description", "driinfo", "enum", "option", "section" }; /** \brief Parse attributes of an enum element. @@ -478,21 +478,21 @@ static const XML_Char *OptInfoElems[] = { static void parseEnumAttr(struct OptInfoData *data, const XML_Char **attr) { - uint32_t i; - const XML_Char *value = NULL, *text = NULL; - driOptionValue v; - uint32_t opt = data->curOption; - for (i = 0; attr[i]; i += 2) { - if (!strcmp (attr[i], "value")) value = attr[i+1]; - else if (!strcmp (attr[i], "text")) text = attr[i+1]; - else XML_FATAL("illegal enum attribute: %s.", attr[i]); - } - if (!value) XML_FATAL1 ("value attribute missing in enum."); - if (!text) XML_FATAL1 ("text attribute missing in enum."); - if (!parseValue (&v, data->cache->info[opt].type, value)) - XML_FATAL ("illegal enum value: %s.", value); - if (!checkValue (&v, &data->cache->info[opt])) - XML_FATAL ("enum value out of valid range: %s.", value); + uint32_t i; + const XML_Char *value = NULL, *text = NULL; + driOptionValue v; + uint32_t opt = data->curOption; + for (i = 0; attr[i]; i += 2) { + if (!strcmp(attr[i], "value")) value = attr[i+1]; + else if (!strcmp(attr[i], "text")) text = attr[i+1]; + else XML_FATAL("illegal enum attribute: %s.", attr[i]); + } + if (!value) XML_FATAL1("value attribute missing in enum."); + if (!text) XML_FATAL1("text attribute missing in enum."); + if (!parseValue(&v, data->cache->info[opt].type, value)) + XML_FATAL("illegal enum value: %s.", value); + if (!checkValue(&v, &data->cache->info[opt])) + XML_FATAL("enum value out of valid range: %s.", value); } /** \brief Parse attributes of a description element. @@ -503,408 +503,409 @@ parseEnumAttr(struct OptInfoData *data, const XML_Char **attr) static void parseDescAttr(struct OptInfoData *data, const XML_Char **attr) { - uint32_t i; - const XML_Char *lang = NULL, *text = NULL; - for (i = 0; attr[i]; i += 2) { - if (!strcmp (attr[i], "lang")) lang = attr[i+1]; - else if (!strcmp (attr[i], "text")) text = attr[i+1]; - else XML_FATAL("illegal description attribute: %s.", attr[i]); - } - if (!lang) XML_FATAL1 ("lang attribute missing in description."); - if (!text) XML_FATAL1 ("text attribute missing in description."); + uint32_t i; + const XML_Char *lang = NULL, *text = NULL; + for (i = 0; attr[i]; i += 2) { + if (!strcmp(attr[i], "lang")) lang = attr[i+1]; + else if (!strcmp(attr[i], "text")) text = attr[i+1]; + else XML_FATAL("illegal description attribute: %s.", attr[i]); + } + if (!lang) XML_FATAL1("lang attribute missing in description."); + if (!text) XML_FATAL1("text attribute missing in description."); } /** \brief Parse attributes of an option element. */ static void parseOptInfoAttr(struct OptInfoData *data, const XML_Char **attr) { - enum OptAttr {OA_DEFAULT = 0, OA_NAME, OA_TYPE, OA_VALID, OA_COUNT}; - static const XML_Char *optAttr[] = {"default", "name", "type", "valid"}; - const XML_Char *attrVal[OA_COUNT] = {NULL, NULL, NULL, NULL}; - const char *defaultVal; - driOptionCache *cache = data->cache; - uint32_t opt, i; - for (i = 0; attr[i]; i += 2) { - uint32_t attrName = bsearchStr (attr[i], optAttr, OA_COUNT); - if (attrName >= OA_COUNT) - XML_FATAL ("illegal option attribute: %s", attr[i]); - attrVal[attrName] = attr[i+1]; - } - if (!attrVal[OA_NAME]) XML_FATAL1 ("name attribute missing in option."); - if (!attrVal[OA_TYPE]) XML_FATAL1 ("type attribute missing in option."); - if (!attrVal[OA_DEFAULT]) XML_FATAL1 ("default attribute missing in option."); - - opt = findOption (cache, attrVal[OA_NAME]); - if (cache->info[opt].name) - XML_FATAL ("option %s redefined.", attrVal[OA_NAME]); - data->curOption = opt; - - XSTRDUP (cache->info[opt].name, attrVal[OA_NAME]); - - if (!strcmp (attrVal[OA_TYPE], "bool")) - cache->info[opt].type = DRI_BOOL; - else if (!strcmp (attrVal[OA_TYPE], "enum")) - cache->info[opt].type = DRI_ENUM; - else if (!strcmp (attrVal[OA_TYPE], "int")) - cache->info[opt].type = DRI_INT; - else if (!strcmp (attrVal[OA_TYPE], "float")) - cache->info[opt].type = DRI_FLOAT; - else if (!strcmp (attrVal[OA_TYPE], "string")) - cache->info[opt].type = DRI_STRING; - else - XML_FATAL ("illegal type in option: %s.", attrVal[OA_TYPE]); - - defaultVal = getenv (cache->info[opt].name); - if (defaultVal != NULL) { + enum OptAttr {OA_DEFAULT = 0, OA_NAME, OA_TYPE, OA_VALID, OA_COUNT}; + static const XML_Char *optAttr[] = {"default", "name", "type", "valid"}; + const XML_Char *attrVal[OA_COUNT] = {NULL, NULL, NULL, NULL}; + const char *defaultVal; + driOptionCache *cache = data->cache; + uint32_t opt, i; + for (i = 0; attr[i]; i += 2) { + uint32_t attrName = bsearchStr(attr[i], optAttr, OA_COUNT); + if (attrName >= OA_COUNT) + XML_FATAL("illegal option attribute: %s", attr[i]); + attrVal[attrName] = attr[i+1]; + } + if (!attrVal[OA_NAME]) XML_FATAL1("name attribute missing in option."); + if (!attrVal[OA_TYPE]) XML_FATAL1("type attribute missing in option."); + if (!attrVal[OA_DEFAULT]) XML_FATAL1("default attribute missing in option."); + + opt = findOption(cache, attrVal[OA_NAME]); + if (cache->info[opt].name) + XML_FATAL("option %s redefined.", attrVal[OA_NAME]); + data->curOption = opt; + + XSTRDUP(cache->info[opt].name, attrVal[OA_NAME]); + + if (!strcmp(attrVal[OA_TYPE], "bool")) + cache->info[opt].type = DRI_BOOL; + else if (!strcmp(attrVal[OA_TYPE], "enum")) + cache->info[opt].type = DRI_ENUM; + else if (!strcmp(attrVal[OA_TYPE], "int")) + cache->info[opt].type = DRI_INT; + else if (!strcmp(attrVal[OA_TYPE], "float")) + cache->info[opt].type = DRI_FLOAT; + else if (!strcmp(attrVal[OA_TYPE], "string")) + cache->info[opt].type = DRI_STRING; + else + XML_FATAL("illegal type in option: %s.", attrVal[OA_TYPE]); + + defaultVal = getenv(cache->info[opt].name); + if (defaultVal != NULL) { /* don't use XML_WARNING, we want the user to see this! */ - if (be_verbose()) { - fprintf(stderr, - "ATTENTION: default value of option %s overridden by environment.\n", - cache->info[opt].name); - } - } else - defaultVal = attrVal[OA_DEFAULT]; - if (!parseValue (&cache->values[opt], cache->info[opt].type, defaultVal)) - XML_FATAL ("illegal default value for %s: %s.", cache->info[opt].name, defaultVal); - - if (attrVal[OA_VALID]) { - if (cache->info[opt].type == DRI_BOOL) - XML_FATAL1 ("boolean option with valid attribute."); - if (!parseRanges (&cache->info[opt], attrVal[OA_VALID])) - XML_FATAL ("illegal valid attribute: %s.", attrVal[OA_VALID]); - if (!checkValue (&cache->values[opt], &cache->info[opt])) - XML_FATAL ("default value out of valid range '%s': %s.", - attrVal[OA_VALID], defaultVal); - } else if (cache->info[opt].type == DRI_ENUM) { - XML_FATAL1 ("valid attribute missing in option (mandatory for enums)."); - } else { - cache->info[opt].nRanges = 0; - cache->info[opt].ranges = NULL; - } + if (be_verbose()) { + fprintf(stderr, + "ATTENTION: default value of option %s overridden by environment.\n", + cache->info[opt].name); + } + } else + defaultVal = attrVal[OA_DEFAULT]; + if (!parseValue(&cache->values[opt], cache->info[opt].type, defaultVal)) + XML_FATAL("illegal default value for %s: %s.", cache->info[opt].name, defaultVal); + + if (attrVal[OA_VALID]) { + if (cache->info[opt].type == DRI_BOOL) + XML_FATAL1("boolean option with valid attribute."); + if (!parseRanges(&cache->info[opt], attrVal[OA_VALID])) + XML_FATAL("illegal valid attribute: %s.", attrVal[OA_VALID]); + if (!checkValue(&cache->values[opt], &cache->info[opt])) + XML_FATAL("default value out of valid range '%s': %s.", + attrVal[OA_VALID], defaultVal); + } else if (cache->info[opt].type == DRI_ENUM) { + XML_FATAL1("valid attribute missing in option (mandatory for enums)."); + } else { + cache->info[opt].nRanges = 0; + cache->info[opt].ranges = NULL; + } } /** \brief Handler for start element events. */ static void optInfoStartElem(void *userData, const XML_Char *name, const XML_Char **attr) { - struct OptInfoData *data = (struct OptInfoData *)userData; - enum OptInfoElem elem = bsearchStr (name, OptInfoElems, OI_COUNT); - switch (elem) { - case OI_DRIINFO: - if (data->inDriInfo) - XML_FATAL1 ("nested elements."); - if (attr[0]) - XML_FATAL1 ("attributes specified on element."); - data->inDriInfo = true; - break; - case OI_SECTION: - if (!data->inDriInfo) - XML_FATAL1 ("
must be inside ."); - if (data->inSection) - XML_FATAL1 ("nested
elements."); - if (attr[0]) - XML_FATAL1 ("attributes specified on
element."); - data->inSection = true; - break; - case OI_DESCRIPTION: - if (!data->inSection && !data->inOption) - XML_FATAL1 (" must be inside or inDesc) - XML_FATAL1 ("nested elements."); - data->inDesc = true; - parseDescAttr (data, attr); - break; - case OI_OPTION: - if (!data->inSection) - XML_FATAL1 ("