diff --git a/src/util/meson.build b/src/util/meson.build index 3174c85c970..e1a820c6fe3 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -196,11 +196,16 @@ idep_mesautil = declare_dependency( dependencies : [dep_zlib, dep_clock, dep_thread, dep_atomic, dep_m], ) +xmlconfig_deps = [] +if not with_platform_android + xmlconfig_deps += dep_expat +endif + _libxmlconfig = static_library( 'xmlconfig', files_xmlconfig, include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux], - dependencies : [idep_mesautil, dep_expat, dep_m], + dependencies : [idep_mesautil, dep_m, xmlconfig_deps], c_args : [ c_msvc_compat_args, '-DSYSCONFDIR="@0@"'.format( @@ -215,7 +220,7 @@ _libxmlconfig = static_library( ) idep_xmlconfig = declare_dependency( - dependencies : dep_expat, + dependencies : xmlconfig_deps, link_with : _libxmlconfig, ) diff --git a/src/util/xmlconfig.c b/src/util/xmlconfig.c index 9cbbf2cc2a7..b54fd10001f 100644 --- a/src/util/xmlconfig.c +++ b/src/util/xmlconfig.c @@ -27,6 +27,12 @@ * \author Felix Kuehling */ +#ifdef ANDROID +#define WITH_XMLCONFIG 0 +#else +#define WITH_XMLCONFIG 1 +#endif + #include #include #include @@ -35,7 +41,9 @@ #include #include #include +#if WITH_XMLCONFIG #include +#endif #include #include #include @@ -53,16 +61,6 @@ #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) @@ -100,6 +98,314 @@ findOption(const driOptionCache *cache, const char *name) } \ } while (0) +/** \brief Check if a value is in info->range. */ +UNUSED static bool +checkValue(const driOptionValue *v, const driOptionInfo *info) +{ + switch (info->type) { + case DRI_ENUM: /* enum is just a special integer */ + case DRI_INT: + return (info->range.start._int == info->range.end._int || + (v->_int >= info->range.start._int && + v->_int <= info->range.end._int)); + + case DRI_FLOAT: + return (info->range.start._float == info->range.end._float || + (v->_float >= info->range.start._float && + v->_float <= info->range.end._float)); + + default: + return true; + } +} + +void +driParseOptionInfo(driOptionCache *info, + const driOptionDescription *configOptions, + unsigned numOptions) +{ + /* Make the hash table big enough to fit more than the maximum number of + * config options we've ever seen in a driver. + */ + info->tableSize = 6; + info->info = calloc(1 << info->tableSize, sizeof(driOptionInfo)); + info->values = calloc(1 << info->tableSize, sizeof(driOptionValue)); + if (info->info == NULL || info->values == NULL) { + fprintf(stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); + abort(); + } + + UNUSED bool in_section = false; + for (int o = 0; o < numOptions; o++) { + const driOptionDescription *opt = &configOptions[o]; + + if (opt->info.type == DRI_SECTION) { + in_section = true; + continue; + } + + /* for driconf xml generation, options must always be preceded by a + * DRI_CONF_SECTION + */ + assert(in_section); + + const char *name = opt->info.name; + int i = findOption(info, name); + driOptionInfo *optinfo = &info->info[i]; + driOptionValue *optval = &info->values[i]; + + assert(!optinfo->name); /* No duplicate options in your list. */ + + optinfo->type = opt->info.type; + XSTRDUP(optinfo->name, name); + + switch (opt->info.type) { + case DRI_BOOL: + optval->_bool = opt->value._bool; + break; + + case DRI_INT: + case DRI_ENUM: + optval->_int = opt->value._int; + break; + + case DRI_FLOAT: + optval->_float = opt->value._float; + break; + + case DRI_STRING: + XSTRDUP(optval->_string, opt->value._string); + break; + + case DRI_SECTION: + unreachable("handled above"); + } + + assert(checkValue(optval, optinfo)); + } +} + +char * +driGetOptionsXml(const driOptionDescription *configOptions, unsigned numOptions) +{ + char *str = ralloc_strdup(NULL, + "\n" \ + "\n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + "]>" \ + "\n"); + + bool in_section = false; + for (int o = 0; o < numOptions; o++) { + const driOptionDescription *opt = &configOptions[o]; + + const char *name = opt->info.name; + const char *types[] = { + [DRI_BOOL] = "bool", + [DRI_INT] = "int", + [DRI_FLOAT] = "float", + [DRI_ENUM] = "enum", + [DRI_STRING] = "string", + }; + + if (opt->info.type == DRI_SECTION) { + if (in_section) + ralloc_asprintf_append(&str, " \n"); + + ralloc_asprintf_append(&str, + "
\n" + " \n", + opt->desc); + + in_section = true; + continue; + } + + ralloc_asprintf_append(&str, + " \n"); + } + + assert(in_section); + ralloc_asprintf_append(&str, "
\n"); + + ralloc_asprintf_append(&str, "
\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); } @@ -324,302 +630,6 @@ parseRange(driOptionInfo *info, const char *string) return true; } -/** \brief Check if a value is in info->range. */ -UNUSED static bool -checkValue(const driOptionValue *v, const driOptionInfo *info) -{ - switch (info->type) { - case DRI_ENUM: /* enum is just a special integer */ - case DRI_INT: - return (info->range.start._int == info->range.end._int || - (v->_int >= info->range.start._int && - v->_int <= info->range.end._int)); - - case DRI_FLOAT: - return (info->range.start._float == info->range.end._float || - (v->_float >= info->range.start._float && - 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"); - } -} - -/** \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, - unsigned numOptions) -{ - /* Make the hash table big enough to fit more than the maximum number of - * config options we've ever seen in a driver. - */ - info->tableSize = 6; - info->info = calloc(1 << info->tableSize, sizeof(driOptionInfo)); - info->values = calloc(1 << info->tableSize, sizeof(driOptionValue)); - if (info->info == NULL || info->values == NULL) { - fprintf(stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); - abort(); - } - - UNUSED bool in_section = false; - for (int o = 0; o < numOptions; o++) { - const driOptionDescription *opt = &configOptions[o]; - - if (opt->info.type == DRI_SECTION) { - in_section = true; - continue; - } - - /* for driconf xml generation, options must always be preceded by a - * DRI_CONF_SECTION - */ - assert(in_section); - - const char *name = opt->info.name; - int i = findOption(info, name); - driOptionInfo *optinfo = &info->info[i]; - driOptionValue *optval = &info->values[i]; - - assert(!optinfo->name); /* No duplicate options in your list. */ - - optinfo->type = opt->info.type; - XSTRDUP(optinfo->name, name); - - switch (opt->info.type) { - case DRI_BOOL: - optval->_bool = opt->value._bool; - break; - - case DRI_INT: - case DRI_ENUM: - optval->_int = opt->value._int; - break; - - case DRI_FLOAT: - optval->_float = opt->value._float; - break; - - case DRI_STRING: - XSTRDUP(optval->_string, opt->value._string); - break; - - case DRI_SECTION: - unreachable("handled above"); - } - - assert(checkValue(optval, optinfo)); - } -} - -char * -driGetOptionsXml(const driOptionDescription *configOptions, unsigned numOptions) -{ - char *str = ralloc_strdup(NULL, - "\n" \ - "\n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - "]>" \ - "\n"); - - bool in_section = false; - for (int o = 0; o < numOptions; o++) { - const driOptionDescription *opt = &configOptions[o]; - - const char *name = opt->info.name; - const char *types[] = { - [DRI_BOOL] = "bool", - [DRI_INT] = "int", - [DRI_FLOAT] = "float", - [DRI_ENUM] = "enum", - [DRI_STRING] = "string", - }; - - if (opt->info.type == DRI_SECTION) { - if (in_section) - ralloc_asprintf_append(&str, " \n"); - - ralloc_asprintf_append(&str, - "
\n" - " \n", - opt->desc); - - in_section = true; - continue; - } - - ralloc_asprintf_append(&str, - " \n"); - } - - assert(in_section); - ralloc_asprintf_append(&str, "
\n"); - - ralloc_asprintf_append(&str, "
\n"); - - char *output = strdup(str); - ralloc_free(str); - - return output; -} - -/** \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) @@ -861,26 +871,6 @@ optConfEndElem(void *userData, const char *name) } } -/** \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<tableSize) * sizeof(driOptionValue)); - if (cache->values == NULL) { - fprintf(stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); - abort(); - } - memcpy(cache->values, info->values, - (1<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) { @@ -986,6 +976,27 @@ parseConfigDir(struct OptConfData *data, const char *dirname) 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<tableSize) * sizeof(driOptionValue)); + if (cache->values == NULL) { + fprintf(stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); + abort(); + } + memcpy(cache->values, info->values, + (1<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" @@ -1002,11 +1013,12 @@ driParseConfigFiles(driOptionCache *cache, const driOptionCache *info, 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; @@ -1026,6 +1038,7 @@ driParseConfigFiles(driOptionCache *cache, const driOptionCache *info, snprintf(filename, PATH_MAX, "%s/.drirc", home); parseOneConfigFile(&userData, filename); } +#endif /* WITH_XMLCONFIG */ } void