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

📄 xmlconfig.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * XML DRI client-side driver configuration * Copyright (C) 2003 Felix Kuehling * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *  *//** * \file xmlconfig.c * \brief Driver-independent client-side part of the XML configuration * \author Felix Kuehling */#include "glheader.h"#include <string.h>#include <assert.h>#include <expat.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include "imports.h"#include "dri_util.h"#include "xmlconfig.h"/* * OS dependent ways of getting the name of the running program */#if (defined(__unix__) || defined(unix)) && !defined(USG)#include <sys/param.h>#endif#undef GET_PROGRAM_NAME#if (defined(__GNU_LIBRARY__) || defined(__GLIBC__)) && !defined(__UCLIBC__)#    if !defined(__GLIBC__) || (__GLIBC__ < 2)/* These aren't declared in any libc5 header */extern char *program_invocation_name, *program_invocation_short_name;#    endif#    define GET_PROGRAM_NAME() program_invocation_short_name#elif defined(__FreeBSD__) && (__FreeBSD__ >= 2)#    include <osreldate.h>#    if (__FreeBSD_version >= 440000)#        include <stdlib.h>#        define GET_PROGRAM_NAME() getprogname()#    endif#elif defined(__NetBSD__) && defined(__NetBSD_Version) && (__NetBSD_Version >= 106000100)#    include <stdlib.h>#    define GET_PROGRAM_NAME() getprogname()#elif defined(__sun)/* Solaris has getexecname() which returns the full path - return just   the basename to match BSD getprogname() */#    include <stdlib.h>#    include <libgen.h>#    define GET_PROGRAM_NAME() basename(getexecname())#endif#if !defined(GET_PROGRAM_NAME)#    if defined(OpenBSD) || defined(NetBSD) || defined(__UCLIBC__)/* This is a hack. It's said to work on OpenBSD, NetBSD and GNU. * Rogelio M.Serrano Jr. reported it's also working with UCLIBC. It's * used as a last resort, if there is no documented facility available. */static const char *__getProgramName () {    extern const char *__progname;    char * arg = strrchr(__progname, '/');    if (arg)        return arg+1;    else        return __progname;}#        define GET_PROGRAM_NAME() __getProgramName()#    else#        define GET_PROGRAM_NAME() ""#        warning "Per application configuration won't work with your OS version."#    endif#endif/** \brief Find an option in an option cache with the name as key */static GLuint findOption (const driOptionCache *cache, const char *name) {    GLuint len = strlen (name);    GLuint size = 1 << cache->tableSize, mask = size - 1;    GLuint hash = 0;    GLuint i, shift;  /* compute a hash from the variable length name */    for (i = 0, shift = 0; i < len; ++i, shift = (shift+8) & 31)	hash += (GLuint)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;}/** \brief Count the real number of options in an option cache */static GLuint countOptions (const driOptionCache *cache) {    GLuint size = 1 << cache->tableSize;    GLuint i, count = 0;    for (i = 0; i < size; ++i)	if (cache->info[i].name)	    count++;    return count;}/** \brief Like strdup but using MALLOC and with error checking. */#define XSTRDUP(dest,source) do { \    GLuint len = strlen (source); \    if (!(dest = MALLOC (len+1))) { \	fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); \	abort(); \    } \    memcpy (dest, source, len+1); \} 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 GLuint bsearchStr (const XML_Char *name,			  const XML_Char *elems[], GLuint 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. * * 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 GLint strToI (const XML_Char *string, const XML_Char **tail, int base) {    GLint radix = base == 0 ? 10 : base;    GLint result = 0;    GLint sign = 1;    GLboolean numberFound = GL_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 = GL_TRUE; 	if (*(string+1) == 'x' || *(string+1) == 'X') {	    radix = 16;	    string += 2;	} else {	    radix = 8;	    string++;	}    }    do {	GLint 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 = GL_TRUE;	    result = radix*result + digit;	    string++;	} else	    break;    } while (GL_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 occor 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 GLfloat strToF (const XML_Char *string, const XML_Char **tail) {    GLint nDigits = 0, pointPos, exponent;    GLfloat 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 * (GLfloat)pow (10.0, (GLdouble)(pointPos-1 + exponent));    /* second pass: parse digits */    do {	if (*string != '.') {	    assert (*string >= '0' && *string <= '9');	    result += scale * (GLfloat)(*string - '0');	    scale *= 0.1f;	    nDigits--;	}	string++;    } while (nDigits > 0);    return result;}/** \brief Parse a value of a given type. */static GLboolean 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 = GL_FALSE;	    tail = string + 5;	} else if (!strcmp (string, "true")) {	    v->_bool = GL_TRUE;	    tail = string + 4;	}	else	    return GL_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;    }    if (tail == string)	return GL_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 GL_FALSE; /* something left over that is not part of value */    return GL_TRUE;}/** \brief Parse a list of ranges of type info->type. */static GLboolean parseRanges (driOptionInfo *info, const XML_Char *string) {    XML_Char *cp, *range;    GLuint 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__);

⌨️ 快捷键说明

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