⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlconfig.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 GL_FALSE;    } else	assert (range == NULL);    info->nRanges = nRanges;    info->ranges = ranges;    return GL_TRUE;}/** \brief Check if a value is in one of info->ranges. */static GLboolean checkValue (const driOptionValue *v, const driOptionInfo *info) {    GLuint i;    assert (info->type != DRI_BOOL); /* should be caught by the parser */    if (info->nRanges == 0)	return GL_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 GL_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 GL_TRUE;	break;      default:	assert (0); /* should never happen */    }    return GL_FALSE;}/** \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,args...) do { \    __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \                      (int) XML_GetCurrentLineNumber(data->parser), \                      (int) XML_GetCurrentColumnNumber(data->parser), \                      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,args...) do { \    __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \                      (int) XML_GetCurrentLineNumber(data->parser), \                      (int) XML_GetCurrentColumnNumber(data->parser), \                      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,args...) 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),		\             args); \    abort();\} while (0)/** \brief Parser context for __driConfigOptions. */struct OptInfoData {    const char *name;    XML_Parser parser;    driOptionCache *cache;    GLboolean inDriInfo;    GLboolean inSection;    GLboolean inDesc;    GLboolean inOption;    GLboolean inEnum;    int curOption;};/** \brief Elements in __driConfigOptions. */enum OptInfoElem {    OI_DESCRIPTION = 0, OI_DRIINFO, OI_ENUM, OI_OPTION, OI_SECTION, OI_COUNT};static const XML_Char *OptInfoElems[] = {    "description", "driinfo", "enum", "option", "section"};/** \brief Parse attributes of an enum element. * * We're not actually interested in the data. Just make sure this is ok * for external configuration tools. */static void parseEnumAttr (struct OptInfoData *data, const XML_Char **attr) {    GLuint i;    const XML_Char *value = NULL, *text = NULL;    driOptionValue v;    GLuint 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. * * We're not actually interested in the data. Just make sure this is ok * for external configuration tools. */static void parseDescAttr (struct OptInfoData *data, const XML_Char **attr) {    GLuint 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;    GLuint opt, i;    for (i = 0; attr[i]; i += 2) {	GLuint 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	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! */	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: %s.", 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 <driinfo> elements.");	if (attr[0])	    XML_FATAL1 ("attributes specified on <driinfo> element.");	data->inDriInfo = GL_TRUE;	break;      case OI_SECTION:	if (!data->inDriInfo)	    XML_FATAL1 ("<section> must be inside <driinfo>.");	if (data->inSection)	    XML_FATAL1 ("nested <section> elements.");	if (attr[0])	    XML_FATAL1 ("attributes specified on <section> element.");	data->inSection = GL_TRUE;	break;      case OI_DESCRIPTION:	if (!data->inSection && !data->inOption)	    XML_FATAL1 ("<description> must be inside <description> or <option.");	if (data->inDesc)	    XML_FATAL1 ("nested <description> elements.");	data->inDesc = GL_TRUE;	parseDescAttr (data, attr);	break;      case OI_OPTION:	if (!data->inSection)	    XML_FATAL1 ("<option> must be inside <section>.");	if (data->inDesc)	    XML_FATAL1 ("<option> nested in <description> element.");	if (data->inOption)	    XML_FATAL1 ("nested <option> elements.");	data->inOption = GL_TRUE;	parseOptInfoAttr (data, attr);	break;      case OI_ENUM:	if (!(data->inOption && data->inDesc))	    XML_FATAL1 ("<enum> must be inside <option> and <description>.");	if (data->inEnum)	    XML_FATAL1 ("nested <enum> elements.");	data->inEnum = GL_TRUE;	parseEnumAttr (data, attr);	break;      default:	XML_FATAL ("unknown element: %s.", name);    }}/** \brief Handler for end element events. */static void optInfoEndElem (void *userData, const XML_Char *name) {    struct OptInfoData *data = (struct OptInfoData *)userData;    enum OptInfoElem elem = bsearchStr (name, OptInfoElems, OI_COUNT);    switch (elem) {      case OI_DRIINFO:	data->inDriInfo = GL_FALSE;	break;      case OI_SECTION:	data->inSection = GL_FALSE;	break;      case OI_DESCRIPTION:	data->inDesc = GL_FALSE;	break;      case OI_OPTION:	data->inOption = GL_FALSE;	break;      case OI_ENUM:	data->inEnum = GL_FALSE;	break;      default:	assert (0); /* should have been caught by StartElem */    }}void driParseOptionInfo (driOptionCache *info,			 const char *configOptions, GLuint nConfigOptions) {    XML_Parser p;    int status;    struct OptInfoData userData;    struct OptInfoData *data = &userData;    GLuint realNoptions;  /* determine hash table size and allocate memory:   * 3/2 of the number of options, rounded up, so there remains always   * at least one free entry. This is needed for detecting undefined   * options in configuration files without getting a hash table overflow.   * Round this up to a power of two. */    GLuint minSize = (nConfigOptions*3 + 1) / 2;    GLuint size, log2size;    for (size = 1, log2size = 0; size < minSize; size <<= 1, ++log2size);    info->tableSize = log2size;    info->info = CALLOC (size * sizeof (driOptionInfo));    info->values = CALLOC (size * sizeof (driOptionValue));    if (info->info == NULL || info->values == NULL) {	fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__);	abort();    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -