* \author Felix Kuehling
*/
+#ifdef ANDROID
+#define WITH_XMLCONFIG 0
+#else
+#define WITH_XMLCONFIG 1
+#endif
+
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#if WITH_XMLCONFIG
#include <expat.h>
+#endif
#include <fcntl.h>
#include <math.h>
#include <unistd.h>
#define PATH_MAX 4096
#endif
-static bool
-be_verbose(void)
-{
- const char *s = getenv("MESA_DEBUG");
- if (!s)
- return true;
-
- return strstr(s, "silent") == NULL;
-}
-
/** \brief Find an option in an option cache with the name as key */
static uint32_t
findOption(const driOptionCache *cache, const char *name)
} \
} 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 char *name, const char *elems[], uint32_t count)
-{
- const char **found;
- found = bsearch(&name, elems, count, sizeof(char *), compare);
- if (found)
- return found - elems;
- else
- return count;
-}
-
-/** \brief Locale-independent integer parser.
- *
- * Works similar to strtol. Leading space is NOT skipped. The input
- * number may have an optional sign. Radix is specified by base. If
- * base is 0 then decimal is assumed unless the input number is
- * prefixed by 0x or 0X for hexadecimal or 0 for octal. After
- * returning tail points to the first character that is not part of
- * the integer number. If no number was found then tail points to the
- * start of the input string. */
-static int
-strToI(const char *string, const char **tail, int base)
-{
- int radix = base == 0 ? 10 : base;
- int result = 0;
- int sign = 1;
- bool numberFound = false;
- const 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.
- *
- * Works similar to strtod. Leading space is NOT skipped. The input
- * number may have an optional sign. '.' is interpreted as decimal
- * point and may occur at most once. Optionally the number may end in
- * [eE]<exponent>, where <exponent> is an integer as recognized by
- * strToI. In that case the result is number * 10^exponent. After
- * returning tail points to the first character that is not part of
- * the floating point number. If no number was found then tail points
- * to the start of the input string.
- *
- * Uses two passes for maximum accuracy. */
-static float
-strToF(const char *string, const char **tail)
-{
- int nDigits = 0, pointPos, exponent;
- float sign = 1.0f, result = 0.0f, scale;
- const 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 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 char *string)
-{
- const 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;
- case DRI_SECTION:
- unreachable("shouldn't be parsing values in section declarations");
- }
-
- 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
-parseRange(driOptionInfo *info, const char *string)
-{
- char *cp;
-
- XSTRDUP(cp, string);
-
- char *sep;
- sep = strchr(cp, ':');
- if (!sep) {
- free(cp);
- return false;
- }
-
- *sep = '\0';
- if (!parseValue(&info->range.start, info->type, cp) ||
- !parseValue(&info->range.end, info->type, sep+1))
- return false;
- if (info->type == DRI_INT &&
- info->range.start._int >= info->range.end._int)
- return false;
- if (info->type == DRI_FLOAT &&
- info->range.start._float >= info->range.end._float)
- return false;
-
- free(cp);
- return true;
-}
-
/** \brief Check if a value is in info->range. */
UNUSED static bool
checkValue(const driOptionValue *v, const driOptionInfo *info)
v->_float <= info->range.end._float));
default:
- return true;
- }
-}
-
-/**
- * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
- * 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");
+ return true;
}
}
-/** \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)
-/** \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)
-
void
driParseOptionInfo(driOptionCache *info,
const driOptionDescription *configOptions,
ralloc_asprintf_append(&str, "%d", opt->value._int);
break;
- case DRI_FLOAT:
- ralloc_asprintf_append(&str, "%f", opt->value._float);
- break;
+ case DRI_FLOAT:
+ ralloc_asprintf_append(&str, "%f", opt->value._float);
+ break;
+
+ case DRI_STRING:
+ ralloc_asprintf_append(&str, "%s", opt->value._string);
+ break;
+
+ case DRI_SECTION:
+ unreachable("handled above");
+ break;
+ }
+ ralloc_asprintf_append(&str, "\"");
+
+
+ switch (opt->info.type) {
+ case DRI_INT:
+ case DRI_ENUM:
+ if (opt->info.range.start._int < opt->info.range.end._int) {
+ ralloc_asprintf_append(&str, " valid=\"%d:%d\"",
+ opt->info.range.start._int,
+ opt->info.range.end._int);
+ }
+ break;
+
+ case DRI_FLOAT:
+ if (opt->info.range.start._float < opt->info.range.end._float) {
+ ralloc_asprintf_append(&str, " valid=\"%f:%f\"",
+ opt->info.range.start._float,
+ opt->info.range.end._float);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ralloc_asprintf_append(&str, ">\n"); /* end of <option> */
+
+
+ ralloc_asprintf_append(&str, " <description lang=\"en\" text=\"%s\"%s>\n",
+ opt->desc, opt->info.type != DRI_ENUM ? "/" : "");
+
+ if (opt->info.type == DRI_ENUM) {
+ for (int i = 0; i < ARRAY_SIZE(opt->enums) && opt->enums[i].desc; i++) {
+ ralloc_asprintf_append(&str, " <enum value=\"%d\" text=\"%s\"/>\n",
+ opt->enums[i].value, opt->enums[i].desc);
+ }
+ ralloc_asprintf_append(&str, " </description>\n");
+ }
+
+ ralloc_asprintf_append(&str, " </option>\n");
+ }
+
+ assert(in_section);
+ ralloc_asprintf_append(&str, " </section>\n");
+
+ ralloc_asprintf_append(&str, "</driinfo>\n");
+
+ char *output = strdup(str);
+ ralloc_free(str);
+
+ return output;
+}
+
+#if WITH_XMLCONFIG
+
+static bool
+be_verbose(void)
+{
+ const char *s = getenv("MESA_DEBUG");
+ if (!s)
+ return true;
+
+ return strstr(s, "silent") == NULL;
+}
+
+/**
+ * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
+ * 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");
+ }
+}
+
+/** \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)
+/** \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)
+
+/** \brief Parser context for configuration files. */
+struct OptConfData {
+ const char *name;
+ XML_Parser parser;
+ driOptionCache *cache;
+ int screenNum;
+ const char *driverName, *execName;
+ const char *kernelDriverName;
+ const char *engineName;
+ const char *applicationName;
+ uint32_t engineVersion;
+ uint32_t applicationVersion;
+ uint32_t ignoringDevice;
+ uint32_t ignoringApp;
+ uint32_t inDriConf;
+ uint32_t inDevice;
+ uint32_t inApp;
+ uint32_t inOption;
+};
+
+/** \brief Elements in configuration files. */
+enum OptConfElem {
+ OC_APPLICATION = 0, OC_DEVICE, OC_DRICONF, OC_ENGINE, OC_OPTION, OC_COUNT
+};
+static const char *OptConfElems[] = {
+ [OC_APPLICATION] = "application",
+ [OC_DEVICE] = "device",
+ [OC_DRICONF] = "driconf",
+ [OC_ENGINE] = "engine",
+ [OC_OPTION] = "option",
+};
+
+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 char *name, const char *elems[], uint32_t count)
+{
+ const char **found;
+ found = bsearch(&name, elems, count, sizeof(char *), compare);
+ if (found)
+ return found - elems;
+ else
+ return count;
+}
+
+/** \brief Locale-independent integer parser.
+ *
+ * Works similar to strtol. Leading space is NOT skipped. The input
+ * number may have an optional sign. Radix is specified by base. If
+ * base is 0 then decimal is assumed unless the input number is
+ * prefixed by 0x or 0X for hexadecimal or 0 for octal. After
+ * returning tail points to the first character that is not part of
+ * the integer number. If no number was found then tail points to the
+ * start of the input string. */
+static int
+strToI(const char *string, const char **tail, int base)
+{
+ int radix = base == 0 ? 10 : base;
+ int result = 0;
+ int sign = 1;
+ bool numberFound = false;
+ const 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.
+ *
+ * Works similar to strtod. Leading space is NOT skipped. The input
+ * number may have an optional sign. '.' is interpreted as decimal
+ * point and may occur at most once. Optionally the number may end in
+ * [eE]<exponent>, where <exponent> is an integer as recognized by
+ * strToI. In that case the result is number * 10^exponent. After
+ * returning tail points to the first character that is not part of
+ * the floating point number. If no number was found then tail points
+ * to the start of the input string.
+ *
+ * Uses two passes for maximum accuracy. */
+static float
+strToF(const char *string, const char **tail)
+{
+ int nDigits = 0, pointPos, exponent;
+ float sign = 1.0f, result = 0.0f, scale;
+ const char *start = string, *numStart;
- case DRI_STRING:
- ralloc_asprintf_append(&str, "%s", opt->value._string);
- break;
+ /* sign */
+ if (*string == '-') {
+ sign = -1.0f;
+ string++;
+ } else if (*string == '+')
+ string++;
- case DRI_SECTION:
- unreachable("handled above");
- break;
+ /* 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++;
}
- ralloc_asprintf_append(&str, "\"");
+ }
+ if (nDigits == 0) {
+ /* no digits, no number */
+ *tail = start;
+ return 0.0f;
+ }
+ *tail = string;
+ if (*string == 'e' || *string == 'E') {
+ const 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));
- switch (opt->info.type) {
- case DRI_INT:
- case DRI_ENUM:
- if (opt->info.range.start._int < opt->info.range.end._int) {
- ralloc_asprintf_append(&str, " valid=\"%d:%d\"",
- opt->info.range.start._int,
- opt->info.range.end._int);
- }
- break;
+ /* 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);
- case DRI_FLOAT:
- if (opt->info.range.start._float < opt->info.range.end._float) {
- ralloc_asprintf_append(&str, " valid=\"%f:%f\"",
- opt->info.range.start._float,
- opt->info.range.end._float);
- }
- break;
+ return result;
+}
- default:
- break;
+/** \brief Parse a value of a given type. */
+static unsigned char
+parseValue(driOptionValue *v, driOptionType type, const char *string)
+{
+ const 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;
+ case DRI_SECTION:
+ unreachable("shouldn't be parsing values in section declarations");
+ }
- ralloc_asprintf_append(&str, ">\n"); /* end of <option> */
+ 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;
+}
- ralloc_asprintf_append(&str, " <description lang=\"en\" text=\"%s\"%s>\n",
- opt->desc, opt->info.type != DRI_ENUM ? "/" : "");
+/** \brief Parse a list of ranges of type info->type. */
+static unsigned char
+parseRange(driOptionInfo *info, const char *string)
+{
+ char *cp;
- if (opt->info.type == DRI_ENUM) {
- for (int i = 0; i < ARRAY_SIZE(opt->enums) && opt->enums[i].desc; i++) {
- ralloc_asprintf_append(&str, " <enum value=\"%d\" text=\"%s\"/>\n",
- opt->enums[i].value, opt->enums[i].desc);
- }
- ralloc_asprintf_append(&str, " </description>\n");
- }
+ XSTRDUP(cp, string);
- ralloc_asprintf_append(&str, " </option>\n");
+ char *sep;
+ sep = strchr(cp, ':');
+ if (!sep) {
+ free(cp);
+ return false;
}
- assert(in_section);
- ralloc_asprintf_append(&str, " </section>\n");
-
- ralloc_asprintf_append(&str, "</driinfo>\n");
-
- char *output = strdup(str);
- ralloc_free(str);
+ *sep = '\0';
+ if (!parseValue(&info->range.start, info->type, cp) ||
+ !parseValue(&info->range.end, info->type, sep+1))
+ return false;
+ if (info->type == DRI_INT &&
+ info->range.start._int >= info->range.end._int)
+ return false;
+ if (info->type == DRI_FLOAT &&
+ info->range.start._float >= info->range.end._float)
+ return false;
- return output;
+ free(cp);
+ return true;
}
-/** \brief Parser context for configuration files. */
-struct OptConfData {
- const char *name;
- XML_Parser parser;
- driOptionCache *cache;
- int screenNum;
- const char *driverName, *execName;
- const char *kernelDriverName;
- const char *engineName;
- const char *applicationName;
- uint32_t engineVersion;
- uint32_t applicationVersion;
- uint32_t ignoringDevice;
- uint32_t ignoringApp;
- uint32_t inDriConf;
- uint32_t inDevice;
- uint32_t inApp;
- uint32_t inOption;
-};
-
-/** \brief Elements in configuration files. */
-enum OptConfElem {
- OC_APPLICATION = 0, OC_DEVICE, OC_DRICONF, OC_ENGINE, OC_OPTION, OC_COUNT
-};
-static const char *OptConfElems[] = {
- [OC_APPLICATION] = "application",
- [OC_DEVICE] = "device",
- [OC_DRICONF] = "driconf",
- [OC_ENGINE] = "engine",
- [OC_OPTION] = "option",
-};
-
/** \brief Parse attributes of a device element. */
static void
parseDeviceAttr(struct OptConfData *data, const char **attr)
}
}
-/** \brief Initialize an option cache based on info */
-static void
-initOptionCache(driOptionCache *cache, const driOptionCache *info)
-{
- unsigned i, size = 1 << info->tableSize;
- cache->info = info->info;
- cache->tableSize = info->tableSize;
- cache->values = malloc((1<<info->tableSize) * sizeof(driOptionValue));
- if (cache->values == NULL) {
- fprintf(stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__);
- abort();
- }
- memcpy(cache->values, info->values,
- (1<<info->tableSize) * sizeof(driOptionValue));
- for (i = 0; i < size; ++i) {
- if (cache->info[i].type == DRI_STRING)
- XSTRDUP(cache->values[i]._string, info->values[i]._string);
- }
-}
-
static void
_parseOneConfigFile(XML_Parser p)
{
free(entries);
}
+#endif /* WITH_XMLCONFIG */
+
+/** \brief Initialize an option cache based on info */
+static void
+initOptionCache(driOptionCache *cache, const driOptionCache *info)
+{
+ unsigned i, size = 1 << info->tableSize;
+ cache->info = info->info;
+ cache->tableSize = info->tableSize;
+ cache->values = malloc((1<<info->tableSize) * sizeof(driOptionValue));
+ if (cache->values == NULL) {
+ fprintf(stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__);
+ abort();
+ }
+ memcpy(cache->values, info->values,
+ (1<<info->tableSize) * sizeof(driOptionValue));
+ for (i = 0; i < size; ++i) {
+ if (cache->info[i].type == DRI_STRING)
+ XSTRDUP(cache->values[i]._string, info->values[i]._string);
+ }
+}
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
const char *applicationName, uint32_t applicationVersion,
const char *engineName, uint32_t engineVersion)
{
+ initOptionCache(cache, info);
+
+#if WITH_XMLCONFIG
char *home;
struct OptConfData userData;
- initOptionCache(cache, info);
-
userData.cache = cache;
userData.screenNum = screenNum;
userData.driverName = driverName;
snprintf(filename, PATH_MAX, "%s/.drirc", home);
parseOneConfigFile(&userData, filename);
}
+#endif /* WITH_XMLCONFIG */
}
void