12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214 |
- // q_shared.c -- stateless support routines that are included in each code dll
- // leave this at the top for PCH reasons...
- #include "common_headers.h"
- //#include "q_shared.h"
- float Com_Clamp( float min, float max, float value ) {
- if ( value < min ) {
- return min;
- }
- if ( value > max ) {
- return max;
- }
- return value;
- }
- /*
- ============
- COM_SkipPath
- ============
- */
- char *COM_SkipPath (char *pathname)
- {
- char *last;
-
- last = pathname;
- while (*pathname)
- {
- if (*pathname=='/')
- last = pathname+1;
- pathname++;
- }
- return last;
- }
- /*
- ============
- COM_StripExtension
- ============
- */
- void COM_StripExtension( const char *in, char *out ) {
- while ( *in && *in != '.' ) {
- *out++ = *in++;
- }
- *out = 0;
- }
- /*
- ==================
- COM_DefaultExtension
- ==================
- */
- void COM_DefaultExtension (char *path, int maxSize, const char *extension ) {
- char *src;
- if (path[0]) // or the strlen()-1 stuff gets a bad ptr for blank string
- {
- //
- // if path doesn't have a .EXT, append extension
- // (extension should include the .)
- //
- src = path + strlen(path) - 1;
- while (*src != '/' && src != path) {
- if ( *src == '.' ) {
- return; // it has an extension
- }
- src--;
- }
- }
- if (strlen(path)+strlen(extension) >= maxSize)
- {
- Com_Printf ("COM_DefaultExtension: overflow adding %s to %s\n", extension, path);
- }
- else
- {
- strcat(path, extension);
- }
- }
- /*
- ============================================================================
- BYTE ORDER FUNCTIONS
- ============================================================================
- */
- // can't just use function pointers, or dll linkage can
- // mess up when qcommon is included in multiple places
- static short (*_BigShort) (short l);
- static short (*_LittleShort) (short l);
- static int (*_BigLong) (int l);
- static int (*_LittleLong) (int l);
- static float (*_BigFloat) (float l);
- static float (*_LittleFloat) (float l);
- #ifdef _M_IX86
- //
- // optimised stuff for Intel, since most of our data is in that format anyway...
- //
- short BigShort(short l){return _BigShort(l);}
- int BigLong (int l) {return _BigLong(l);}
- float BigFloat (float l) {return _BigFloat(l);}
- //short LittleShort(short l) {return _LittleShort(l);} // these are now macros in q_shared.h
- //int LittleLong (int l) {return _LittleLong(l);} //
- //float LittleFloat (float l) {return _LittleFloat(l);} //
- //
- #else
- //
- // standard smart-swap code...
- //
- short BigShort(short l){return _BigShort(l);}
- short LittleShort(short l) {return _LittleShort(l);}
- int BigLong (int l) {return _BigLong(l);}
- int LittleLong (int l) {return _LittleLong(l);}
- float BigFloat (float l) {return _BigFloat(l);}
- float LittleFloat (float l) {return _LittleFloat(l);}
- //
- #endif
- short ShortSwap (short l)
- {
- byte b1,b2;
- b1 = l&255;
- b2 = (l>>8)&255;
- return (b1<<8) + b2;
- }
- short ShortNoSwap (short l)
- {
- return l;
- }
- int LongSwap (int l)
- {
- byte b1,b2,b3,b4;
- b1 = l&255;
- b2 = (l>>8)&255;
- b3 = (l>>16)&255;
- b4 = (l>>24)&255;
- return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
- }
- int LongNoSwap (int l)
- {
- return l;
- }
- float FloatSwap (float f)
- {
- union
- {
- float f;
- byte b[4];
- } dat1, dat2;
-
-
- dat1.f = f;
- dat2.b[0] = dat1.b[3];
- dat2.b[1] = dat1.b[2];
- dat2.b[2] = dat1.b[1];
- dat2.b[3] = dat1.b[0];
- return dat2.f;
- }
- float FloatNoSwap (float f)
- {
- return f;
- }
- /*
- ================
- Swap_Init
- ================
- */
- void Swap_Init (void)
- {
- byte swaptest[2] = {1,0};
- // set the byte swapping variables in a portable manner
- if ( *(short *)swaptest == 1)
- {
- _BigShort = ShortSwap;
- _LittleShort = ShortNoSwap;
- _BigLong = LongSwap;
- _LittleLong = LongNoSwap;
- _BigFloat = FloatSwap;
- _LittleFloat = FloatNoSwap;
- }
- else
- {
- _BigShort = ShortNoSwap;
- _LittleShort = ShortSwap;
- _BigLong = LongNoSwap;
- _LittleLong = LongSwap;
- _BigFloat = FloatNoSwap;
- _LittleFloat = FloatSwap;
- }
- }
- /*
- ============================================================================
- PARSING
- ============================================================================
- */
- static char com_token[MAX_TOKEN_CHARS];
- //JLFCALLOUT MPNOTUSED
- //#include functionality for files
- int parseDataCount = -1;
- parseData_t parseData[2];
- void COM_ParseInit( void )
- {
- memset(&(parseData[0]),0,sizeof(parseData_t));
- memset(&(parseData[1]),0,sizeof(parseData_t));
- COM_BeginParseSession();
- }
- #ifdef _XBOX
- void COM_BeginParseSession( bool nested )
- {
- if (nested)
- parseDataCount =1;
- else
- parseDataCount = 0;
- parseData[parseDataCount].com_lines = 1;
-
- }
- #else
- void COM_BeginParseSession( void )
- {
- parseDataCount =0;
- parseData[parseDataCount].com_lines = 1;
-
- }
- #endif
- int COM_GetCurrentParseLine( int index )
- {
- return parseData[parseDataCount].com_lines;
- }
- char *COM_Parse( const char **data_p )
- {
- return COM_ParseExt( data_p, qtrue );
- }
- /*
- ==============
- COM_Parse
- Parse a token out of a string
- Will never return NULL, just empty strings
- If "allowLineBreaks" is qtrue then an empty
- string will be returned if the next token is
- a newline.
- ==============
- */
- const char *SkipWhitespace( const char *data, qboolean *hasNewLines )
- {
- int c;
- while( (c = *data) <= ' ')
- {
- if( !c )
- {
- return NULL;
- }
- if( c == '\n' )
- {
- parseData[parseDataCount].com_lines++;
- *hasNewLines = qtrue;
- }
- data++;
- }
- return data;
- }
- char *COM_ParseExt( const char **data_p, qboolean allowLineBreaks )
- {
- int c = 0, len;
- qboolean hasNewLines = qfalse;
- const char *data;
- data = *data_p;
- len = 0;
- com_token[0] = 0;
- // make sure incoming data is valid
- if ( !data )
- {
- *data_p = NULL;
- return com_token;
- }
- while ( 1 )
- {
- // skip whitespace
- data = SkipWhitespace( data, &hasNewLines );
- if ( !data )
- {
- *data_p = NULL;
- return com_token;
- }
- if ( hasNewLines && !allowLineBreaks )
- {
- *data_p = data;
- return com_token;
- }
- c = *data;
- // skip double slash comments
- if ( c == '/' && data[1] == '/' )
- {
- while (*data && *data != '\n') // Advance to the end of the line
- {
- data++;
- }
- }
- // skip /* */ comments
- else if ( c=='/' && data[1] == '*' )
- {
- while ( *data && ( *data != '*' || data[1] != '/' ) ) // Advance to the */ characters
- {
- data++;
- }
- if ( *data )
- {
- data += 2;
- }
- }
- else
- {
- break;
- }
- }
- // handle quoted strings
- if (c == '\"')
- {
- data++;
- while (1)
- {
- c = *data++;
- if (c=='\"' || !c)
- {
- com_token[len] = 0;
- *data_p = ( char * ) data;
- return com_token;
- }
- if (len < MAX_TOKEN_CHARS)
- {
- com_token[len] = c;
- len++;
- }
- }
- }
- // parse a regular word
- do
- {
- if (len < MAX_TOKEN_CHARS)
- {
- com_token[len] = c;
- len++;
- }
- data++;
- c = *data;
- if ( c == '\n' )
- {
- parseData[parseDataCount].com_lines++;
- }
- } while (c>32);
- if (len == MAX_TOKEN_CHARS)
- {
- Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS);
- len = 0;
- }
- com_token[len] = 0;
- *data_p = ( char * ) data;
- return com_token;
- }
- /*
- ==============
- COM_Compress
- remove blank space and comments from source
- ==============
- */
- int COM_Compress( char *data_p ) {
- char *in, *out;
- int c;
- qboolean newline = qfalse, whitespace = qfalse;
-
- in = out = data_p;
- if (in) {
- while ((c = *in) != 0) {
- // skip double slash comments
- if ( c == '/' && in[1] == '/' ) {
- while (*in && *in != '\n') {
- in++;
- }
- // skip /* */ comments
- } else if ( c == '/' && in[1] == '*' ) {
- while ( *in && ( *in != '*' || in[1] != '/' ) )
- in++;
- if ( *in )
- in += 2;
- // record when we hit a newline
- } else if ( c == '\n' || c == '\r' ) {
- newline = qtrue;
- in++;
- // record when we hit whitespace
- } else if ( c == ' ' || c == '\t') {
- whitespace = qtrue;
- in++;
- // an actual token
- } else {
- // if we have a pending newline, emit it (and it counts as whitespace)
- if (newline) {
- *out++ = '\n';
- newline = qfalse;
- whitespace = qfalse;
- } if (whitespace) {
- *out++ = ' ';
- whitespace = qfalse;
- }
-
- // copy quoted strings unmolested
- if (c == '"') {
- *out++ = c;
- in++;
- while (1) {
- c = *in;
- if (c && c != '"') {
- *out++ = c;
- in++;
- } else {
- break;
- }
- }
- if (c == '"') {
- *out++ = c;
- in++;
- }
- } else {
- *out = c;
- out++;
- in++;
- }
- }
- }
- }
- *out = 0;
- return out - data_p;
- }
- /*
- ==================
- COM_MatchToken
- ==================
- */
- void COM_MatchToken( const char **buf_p, const char *match ) {
- const char *token;
- token = COM_Parse( buf_p );
- if ( strcmp( token, match ) )
- {
- Com_Error( ERR_DROP, "MatchToken: %s != %s", token, match );
- }
- }
- /*
- =================
- SkipBracedSection
- The next token should be an open brace.
- Skips until a matching close brace is found.
- Internal brace depths are properly skipped.
- =================
- */
- void SkipBracedSection ( const char **program) {
- const char *token;
- int depth=0;
- if (com_token[0]=='{') { //for tr_shader which just ate the brace
- depth = 1;
- }
- do {
- token = COM_ParseExt( program, qtrue );
- if( token[1] == 0 ) {
- if( token[0] == '{' ) {
- depth++;
- }
- else if( token[0] == '}' ) {
- depth--;
- }
- }
- } while (depth && *program);
- }
- /*
- =================
- SkipRestOfLine
- =================
- */
- void SkipRestOfLine ( const char **data ) {
- const char *p;
- int c;
- p = *data;
- while ( (c = *p++) != 0 ) {
- if ( c == '\n' ) {
- parseData[parseDataCount].com_lines++;
- break;
- }
- }
- *data = p;
- }
- void Parse1DMatrix ( const char **buf_p, int x, float *m) {
- const char *token;
- int i;
- COM_MatchToken( buf_p, "(" );
- for (i = 0 ; i < x ; i++) {
- token = COM_Parse(buf_p);
- m[i] = atof(token);
- }
- COM_MatchToken( buf_p, ")" );
- }
- void Parse2DMatrix ( const char **buf_p, int y, int x, float *m) {
- int i;
- COM_MatchToken( buf_p, "(" );
- for (i = 0 ; i < y ; i++) {
- Parse1DMatrix (buf_p, x, m + i * x);
- }
- COM_MatchToken( buf_p, ")" );
- }
- void Parse3DMatrix ( const char **buf_p, int z, int y, int x, float *m) {
- int i;
- COM_MatchToken( buf_p, "(" );
- for (i = 0 ; i < z ; i++) {
- Parse2DMatrix (buf_p, y, x, m + i * x*y);
- }
- COM_MatchToken( buf_p, ")" );
- }
- /*
- ============================================================================
- LIBRARY REPLACEMENT FUNCTIONS
- ============================================================================
- */
- int Q_isprint( int c )
- {
- if ( c >= 0x20 && c <= 0x7E )
- return ( 1 );
- return ( 0 );
- }
- int Q_islower( int c )
- {
- if (c >= 'a' && c <= 'z')
- return ( 1 );
- return ( 0 );
- }
- int Q_isupper( int c )
- {
- if (c >= 'A' && c <= 'Z')
- return ( 1 );
- return ( 0 );
- }
- int Q_isalpha( int c )
- {
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
- return ( 1 );
- return ( 0 );
- }
- /*
- char* Q_strrchr( const char* string, int c )
- {
- char cc = c;
- char *s;
- char *sp=(char *)0;
- s = (char*)string;
- while (*s)
- {
- if (*s == cc)
- sp = s;
- s++;
- }
- if (cc == 0)
- sp = s;
- return sp;
- }
- */
- /*
- =============
- Q_strncpyz
-
- Safe strncpy that ensures a trailing zero
- =============
- */
- void Q_strncpyz( char *dest, const char *src, int destsize, qboolean bBarfIfTooLong/* = qfalse */ )
- {
- if ( !src ) {
- Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" );
- }
- if ( destsize < 1 ) {
- Com_Error(ERR_FATAL,"Q_strncpyz: destsize < 1" );
- }
- if (bBarfIfTooLong)
- {
- if ( strlen(src)+1 > destsize)
- {
- Com_Error(ERR_FATAL,"String dest buffer too small to hold string \"%s\" %d > %d\n(source addr = %x, dest addr = %x",src, strlen(src)+1, destsize, src, dest);
- }
- }
- strncpy( dest, src, destsize-1 );
- dest[destsize-1] = 0;
- }
- /*
- int Q_stricmpn (const char *s1, const char *s2, int n) {
- int c1, c2;
-
- do {
- c1 = *s1++;
- c2 = *s2++;
- if (!n--) {
- return 0; // strings are equal until end point
- }
-
- if (c1 != c2) {
- if (c1 >= 'a' && c1 <= 'z') {
- c1 -= ('a' - 'A');
- }
- if (c2 >= 'a' && c2 <= 'z') {
- c2 -= ('a' - 'A');
- }
- if (c1 != c2) {
- return c1 < c2 ? -1 : 1;
- }
- }
- } while (c1);
-
- return 0; // strings are equal
- }
- int Q_strncmp (const char *s1, const char *s2, int n) {
- int c1, c2;
-
- do {
- c1 = *s1++;
- c2 = *s2++;
- if (!n--) {
- return 0; // strings are equal until end point
- }
-
- if (c1 != c2) {
- return c1 < c2 ? -1 : 1;
- }
- } while (c1);
-
- return 0; // strings are equal
- }
- char *Q_strlwr( char *s1 ) {
- char *s;
- s = s1;
- while ( *s ) {
- *s = tolower(*s);
- s++;
- }
- return s1;
- }
- char *Q_strupr( char *s1 ) {
- char *s;
- s = s1;
- while ( *s ) {
- *s = toupper(*s);
- s++;
- }
- return s1;
- }
- */
- // never goes past bounds or leaves without a terminating 0
- void Q_strcat( char *dest, int size, const char *src ) {
- int l1;
- l1 = strlen( dest );
- if ( l1 >= size ) {
- Com_Error( ERR_FATAL, "Q_strcat: already overflowed" );
- }
- if ( strlen(src)+1 > size - l1)
- { //do the error here instead of in Q_strncpyz to get a meaningful msg
- Com_Error(ERR_FATAL,"Q_strcat: cannot append \"%s\" to \"%s\"", src, dest);
- }
- Q_strncpyz( dest + l1, src, size - l1 );
- }
- int Q_PrintStrlen( const char *string ) {
- int len;
- const char *p;
- if( !string ) {
- return 0;
- }
- len = 0;
- p = string;
- while( *p ) {
- if( Q_IsColorString( p ) ) {
- p += 2;
- continue;
- }
- p++;
- len++;
- }
- return len;
- }
- char *Q_CleanStr( char *string ) {
- char* d;
- char* s;
- int c;
- s = string;
- d = string;
- while ((c = *s) != 0 ) {
- if ( Q_IsColorString( s ) ) {
- s++;
- }
- else if ( c >= 0x20 && c <= 0x7E ) {
- *d++ = c;
- }
- s++;
- }
- *d = '\0';
- return string;
- }
- void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) {
- int len;
- va_list argptr;
- char bigbuffer[1024];
- va_start (argptr,fmt);
- len = vsprintf (bigbuffer,fmt,argptr);
- va_end (argptr);
- if ( len >= sizeof( bigbuffer ) ) {
- Com_Error( ERR_FATAL, "Com_sprintf: overflowed bigbuffer" );
- }
- if (len >= size) {
- Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size);
- }
- Q_strncpyz (dest, bigbuffer, size );
- }
- /*
- ============
- va
- does a varargs printf into a temp buffer, so I don't need to have
- varargs versions of all text functions.
- FIXME: make this buffer size safe someday
- ============
- */
- char * QDECL va( const char *format, ... ) {
- int len;
- va_list argptr;
- static char buffers[4][1024]; // in case va is called by nested functions
- static int index = 0;
- char *const buf = buffers[index % 4];
- index++;
- va_start (argptr, format);
- len = vsprintf (buf, format,argptr);
- va_end (argptr);
- assert(len<sizeof(buffers[0]));
- return buf;
- }
- /*
- =====================================================================
- INFO STRINGS
- =====================================================================
- */
- /*
- ===============
- Info_ValueForKey
- Searches the string for the given
- key and returns the associated value, or an empty string.
- FIXME: overflow check?
- ===============
- */
- char *Info_ValueForKey( const char *s, const char *key ) {
- char pkey[MAX_INFO_KEY];
- static char value[2][MAX_INFO_VALUE]; // use two buffers so compares
- // work without stomping on each other
- static int valueindex = 0;
- char *o;
-
- if ( !s || !key ) {
- return "";
- }
- if ( strlen( s ) >= MAX_INFO_STRING ) {
- Com_Error( ERR_DROP, "Info_ValueForKey: oversize infostring" );
- }
- valueindex ^= 1;
- if (*s == '\\')
- s++;
- while (1)
- {
- o = pkey;
- while (*s != '\\')
- {
- if (!*s)
- return "";
- *o++ = *s++;
- }
- *o = 0;
- s++;
- o = value[valueindex];
- while (*s != '\\' && *s)
- {
- *o++ = *s++;
- }
- *o = 0;
- if (!Q_stricmp (key, pkey) )
- return value[valueindex];
- if (!*s)
- break;
- s++;
- }
- return "";
- }
- /*
- ===================
- Info_NextPair
- Used to itterate through all the key/value pairs in an info string
- ===================
- */
- void Info_NextPair( const char **head, char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] ) {
- char *o;
- const char *s;
- s = *head;
- if ( *s == '\\' ) {
- s++;
- }
- key[0] = 0;
- value[0] = 0;
- o = key;
- while ( *s != '\\' ) {
- if ( !*s ) {
- *o = 0;
- *head = s;
- return;
- }
- *o++ = *s++;
- }
- *o = 0;
- s++;
- o = value;
- while ( *s != '\\' && *s ) {
- *o++ = *s++;
- }
- *o = 0;
- *head = s;
- }
- /*
- ===================
- Info_RemoveKey
- ===================
- */
- void Info_RemoveKey( char *s, const char *key ) {
- char *start;
- char pkey[MAX_INFO_KEY];
- char value[MAX_INFO_VALUE];
- char *o;
- if ( strlen( s ) >= MAX_INFO_STRING ) {
- Com_Error( ERR_DROP, "Info_RemoveKey: oversize infostring" );
- }
- if (strchr (key, '\\')) {
- return;
- }
- while (1)
- {
- start = s;
- if (*s == '\\')
- s++;
- o = pkey;
- while (*s != '\\')
- {
- if (!*s)
- return;
- *o++ = *s++;
- }
- *o = 0;
- s++;
- o = value;
- while (*s != '\\' && *s)
- {
- if (!*s)
- return;
- *o++ = *s++;
- }
- *o = 0;
- if (!strcmp (key, pkey) )
- {
- strcpy (start, s); // remove this part
- return;
- }
- if (!*s)
- return;
- }
- }
- /*
- ==================
- Info_Validate
- Some characters are illegal in info strings because they
- can mess up the server's parsing
- ==================
- */
- qboolean Info_Validate( const char *s ) {
- if ( strchr( s, '\"' ) ) {
- return qfalse;
- }
- if ( strchr( s, ';' ) ) {
- return qfalse;
- }
- return qtrue;
- }
- /*
- ==================
- Info_SetValueForKey
- Changes or adds a key/value pair
- ==================
- */
- void Info_SetValueForKey( char *s, const char *key, const char *value ) {
- char newi[MAX_INFO_STRING];
- if ( strlen( s ) >= MAX_INFO_STRING ) {
- Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring" );
- }
- if (strchr (key, '\\') || strchr (value, '\\'))
- {
- Com_Printf ("Can't use keys or values with a \\(%s, %s)\n",key,value);
- return;
- }
- if (strchr (key, ';') || strchr (value, ';'))
- {
- Com_Printf ("Can't use keys or values with a semicolon(%s, %s)\n",key,value);
- return;
- }
- if (strchr (key, '\"') || strchr (value, '\"'))
- {
- Com_Printf ("Can't use keys or values with a \"(%s, %s)\n",key,value);
- return;
- }
- Info_RemoveKey (s, key);
- if (!value || !strlen(value))
- return;
- Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value);
- if (strlen(newi) + strlen(s) > MAX_INFO_STRING)
- {
- Com_Printf ("Info string length exceeded\n");
- return;
- }
- strcat (s, newi);
- }
- /*
- ========================================================================
- String ID Tables
- ========================================================================
- */
- /*
- -------------------------
- GetIDForString
- -------------------------
- */
- #define VALIDSTRING( a ) ( ( a != NULL ) && ( a[0] != NULL ) )
- int GetIDForString ( const stringID_table_t *table, const char *string )
- {
- int index = 0;
- while ( VALIDSTRING( table[index].name ) )
- {
- if ( !Q_stricmp( table[index].name, string ) )
- return table[index].id;
- index++;
- }
- return -1;
- }
- /*
- -------------------------
- GetStringForID
- -------------------------
- */
- const char *GetStringForID( const stringID_table_t *table, int id )
- {
- int index = 0;
- while ( VALIDSTRING( table[index].name ) )
- {
- if ( table[index].id == id )
- return table[index].name;
- index++;
- }
- return NULL;
- }
- /*
- ===============
- COM_ParseString
- ===============
- */
- qboolean COM_ParseString( const char **data, const char **s )
- {
- // *s = COM_ParseExt( data, qtrue );
- *s = COM_ParseExt( data, qfalse );
- if ( s[0] == 0 )
- {
- Com_Printf("unexpected EOF in COM_ParseString\n");
- return qtrue;
- }
- return qfalse;
- }
- /*
- ===============
- COM_ParseInt
- ===============
- */
- qboolean COM_ParseInt( const char **data, int *i )
- {
- const char *token;
- token = COM_ParseExt( data, qfalse );
- if ( token[0] == 0 )
- {
- Com_Printf( "unexpected EOF in COM_ParseInt\n" );
- return qtrue;
- }
- *i = atoi( token );
- return qfalse;
- }
- /*
- ===============
- COM_ParseFloat
- ===============
- */
- qboolean COM_ParseFloat( const char **data, float *f )
- {
- const char *token;
- token = COM_ParseExt( data, qfalse );
- if ( token[0] == 0 )
- {
- Com_Printf( "unexpected EOF in COM_ParseFloat\n" );
- return qtrue;
- }
- *f = atof( token );
- return qfalse;
- }
- /*
- ===============
- COM_ParseVec4
- ===============
- */
- qboolean COM_ParseVec4( const char **buffer, vec4_t *c)
- {
- int i;
- float f;
- for (i = 0; i < 4; i++)
- {
- if (COM_ParseFloat(buffer, &f))
- {
- return qtrue;
- }
- (*c)[i] = f;
- }
- return qfalse;
- }
- // end
|