summaryrefslogtreecommitdiff
path: root/source/q_shared.c
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2010-09-15 22:41:27 +0400
committerAndrey Nazarov <skuller@skuller.net>2010-09-15 22:41:27 +0400
commitcd8d25aa0b96b48e1a6d0edf9893afe9cbf796c1 (patch)
tree322d2ed47d1ab4c7afdd5e70f34829f252877872 /source/q_shared.c
parentde41ad148d857184ead919fa488fd58cec5b1864 (diff)
Renamed source tree subdirectory into ‘src’, moved ‘asm’ subdirectory there and renamed it into ‘i386’.
Diffstat (limited to 'source/q_shared.c')
-rw-r--r--source/q_shared.c1229
1 files changed, 0 insertions, 1229 deletions
diff --git a/source/q_shared.c b/source/q_shared.c
deleted file mode 100644
index a032749..0000000
--- a/source/q_shared.c
+++ /dev/null
@@ -1,1229 +0,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-#include <config.h>
-#include "q_shared.h"
-
-vec3_t vec3_origin = { 0, 0, 0 };
-
-void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
-{
- float angle;
- float sr, sp, sy, cr, cp, cy;
-
- angle = angles[YAW] * (M_PI*2 / 360);
- sy = sin(angle);
- cy = cos(angle);
- angle = angles[PITCH] * (M_PI*2 / 360);
- sp = sin(angle);
- cp = cos(angle);
- angle = angles[ROLL] * (M_PI*2 / 360);
- sr = sin(angle);
- cr = cos(angle);
-
- if (forward)
- {
- forward[0] = cp*cy;
- forward[1] = cp*sy;
- forward[2] = -sp;
- }
- if (right)
- {
- right[0] = (-1*sr*sp*cy+-1*cr*-sy);
- right[1] = (-1*sr*sp*sy+-1*cr*cy);
- right[2] = -1*sr*cp;
- }
- if (up)
- {
- up[0] = (cr*sp*cy+-sr*-sy);
- up[1] = (cr*sp*sy+-sr*cy);
- up[2] = cr*cp;
- }
-}
-
-vec_t VectorNormalize (vec3_t v)
-{
- float length, ilength;
-
- length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
- length = sqrt (length); // FIXME
-
- if (length)
- {
- ilength = 1/length;
- v[0] *= ilength;
- v[1] *= ilength;
- v[2] *= ilength;
- }
-
- return length;
-
-}
-
-vec_t VectorNormalize2 (vec3_t v, vec3_t out)
-{
- float length, ilength;
-
- length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
- length = sqrt (length); // FIXME
-
- if (length)
- {
- ilength = 1/length;
- out[0] = v[0]*ilength;
- out[1] = v[1]*ilength;
- out[2] = v[2]*ilength;
- }
-
- return length;
-
-}
-
-void ClearBounds (vec3_t mins, vec3_t maxs) {
- mins[0] = mins[1] = mins[2] = 99999;
- maxs[0] = maxs[1] = maxs[2] = -99999;
-}
-
-void AddPointToBounds (const vec3_t v, vec3_t mins, vec3_t maxs) {
- int i;
- vec_t val;
-
- for (i=0 ; i<3 ; i++)
- {
- val = v[i];
- if (val < mins[i])
- mins[i] = val;
- if (val > maxs[i])
- maxs[i] = val;
- }
-}
-
-void UnionBounds( vec3_t a[2], vec3_t b[2], vec3_t c[2] ) {
- c[0][0] = b[0][0] < a[0][0] ? b[0][0] : a[0][0];
- c[0][1] = b[0][1] < a[0][1] ? b[0][1] : a[0][1];
- c[0][2] = b[0][2] < a[0][2] ? b[0][2] : a[0][2];
-
- c[1][0] = b[1][0] > a[1][0] ? b[1][0] : a[1][0];
- c[1][1] = b[1][1] > a[1][1] ? b[1][1] : a[1][1];
- c[1][2] = b[1][2] > a[1][2] ? b[1][2] : a[1][2];
-}
-
-/*
-=================
-RadiusFromBounds
-=================
-*/
-vec_t RadiusFromBounds (const vec3_t mins, const vec3_t maxs) {
- int i;
- vec3_t corner;
- vec_t a, b;
-
- for (i=0 ; i<3 ; i++)
- {
- a = Q_fabs(mins[i]);
- b = Q_fabs(maxs[i]);
- corner[i] = a > b ? a : b;
- }
-
- return VectorLength (corner);
-}
-
-//====================================================================================
-
-static const char hexchars[] = "0123456789ABCDEF";
-
-/*
-============
-COM_SkipPath
-============
-*/
-char *COM_SkipPath( const char *pathname ) {
- char *last;
-
- if( !pathname ) {
- Com_Error( ERR_FATAL, "%s: NULL", __func__ );
- }
-
- last = (char *)pathname;
- while( *pathname ) {
- if( *pathname == '/' )
- last = (char *)pathname + 1;
- pathname++;
- }
- return last;
-}
-
-/*
-============
-COM_StripExtension
-============
-*/
-void COM_StripExtension( const char *in, char *out, size_t size ) {
- char *s;
-
- Q_strlcpy( out, in, size );
-
- s = out + strlen( out );
-
- while( s != out ) {
- if( *s == '/' ) {
- break;
- }
- if( *s == '.' ) {
- *s = 0;
- break;
- }
- s--;
- }
-}
-
-/*
-============
-COM_FileExtension
-============
-*/
-char *COM_FileExtension( const char *in ) {
- const char *s;
- const char *last;
-
- if( !in ) {
- Com_Error( ERR_FATAL, "%s: NULL", __func__ );
- }
-
- s = in + strlen( in );
- last = s;
-
- while( s != in ) {
- if( *s == '/' ) {
- break;
- }
- if( *s == '.' ) {
- return (char *)s;
- }
- s--;
- }
-
- return (char *)last;
-}
-
-/*
-============
-COM_FileBase
-============
-*/
-void COM_FileBase (char *in, char *out)
-{
- char *s, *s2;
-
- s = in + strlen(in) - 1;
-
- while (s != in && *s != '.')
- s--;
-
- for (s2 = s ; s2 != in && *s2 != '/' ; s2--)
- ;
-
- if (s-s2 < 2)
- out[0] = 0;
- else
- {
- s--;
- strncpy (out,s2+1, s-s2);
- out[s-s2] = 0;
- }
-}
-
-/*
-============
-COM_FilePath
-
-Returns the path up to, but not including the last /
-============
-*/
-void COM_FilePath( const char *in, char *out, size_t size ) {
- char *s;
-
- Q_strlcpy( out, in, size );
- s = strrchr( out, '/' );
- if( s ) {
- *s = 0;
- } else {
- *out = 0;
- }
-}
-
-
-/*
-==================
-COM_DefaultExtension
-
-if path doesn't have .EXT, append extension
-(extension should include the .)
-==================
-*/
-size_t COM_DefaultExtension( char *path, const char *ext, size_t size ) {
- char *src;
- size_t len;
-
- if( *path ) {
- len = strlen( path );
- src = path + len - 1;
-
- while( *src != '/' && src != path ) {
- if( *src == '.' )
- return len; // it has an extension
- src--;
- }
- }
-
- len = Q_strlcat( path, ext, size );
- return len;
-}
-
-/*
-==================
-COM_IsFloat
-
-Returns true if the given string is valid representation
-of floating point number.
-==================
-*/
-qboolean COM_IsFloat( const char *s ) {
- int c, dot = '.';
-
- if( *s == '-' ) {
- s++;
- }
- if( !*s ) {
- return qfalse;
- }
-
- do {
- c = *s++;
- if( c == dot ) {
- dot = 0;
- } else if( !Q_isdigit( c ) ) {
- return qfalse;
- }
- } while( *s );
-
- return qtrue;
-}
-
-qboolean COM_IsUint( const char *s ) {
- int c;
-
- if( !*s ) {
- return qfalse;
- }
-
- do {
- c = *s++;
- if( !Q_isdigit( c ) ) {
- return qfalse;
- }
- } while( *s );
-
- return qtrue;
-}
-
-qboolean COM_HasSpaces( const char *s ) {
- while( *s ) {
- if( *s <= 32 ) {
- return qtrue;
- }
- s++;
- }
- return qfalse;
-}
-
-unsigned COM_ParseHex( const char *s ) {
- int c;
- unsigned result;
-
- for( result = 0; *s; s++ ) {
- if( ( c = Q_charhex( *s ) ) == -1 ) {
- break;
- }
- if( result & ~( UINT_MAX >> 4 ) ) {
- return UINT_MAX;
- }
- result = c | ( result << 4 );
- }
-
- return result;
-}
-
-int QDECL SortStrcmp( const void *p1, const void *p2 ) {
- return strcmp( *( const char ** )p1, *( const char ** )p2 );
-}
-
-int QDECL SortStricmp( const void *p1, const void *p2 ) {
- return Q_stricmp( *( const char ** )p1, *( const char ** )p2 );
-}
-
-/*
-================
-COM_strclr
-
-Operates inplace, normalizing high-bit and removing unprintable characters.
-Returns final number of characters, not including the NUL character.
-================
-*/
-size_t COM_strclr( char *s ) {
- char *p;
- int c;
- size_t len;
-
- p = s;
- len = 0;
- while( *s ) {
- c = *s++;
- c &= 127;
- if( Q_isprint( c ) ) {
- *p++ = c;
- len++;
- }
- }
-
- *p = 0;
-
- return len;
-}
-
-qboolean COM_iswhite( const char *s ) {
- int c;
-
- while( *s ) {
- c = *s++;
- c &= 127;
- if( Q_isgraph( c ) ) {
- return qfalse;
- }
- }
-
- return qtrue;
-}
-
-size_t COM_FormatFileSize( char *dest, size_t bytes, size_t size ) {
- if( bytes >= 1000000 ) {
- return Q_snprintf( dest, size, "%2.1fM", ( float )bytes / 1000000 );
- }
- if( bytes >= 1000 ) {
- return Q_snprintf( dest, size, "%3"PRIz"K", bytes / 1000 );
- }
- return Q_snprintf( dest, size, "%3"PRIz, bytes );
-}
-
-/*
-============
-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 *va( const char *format, ... ) {
- va_list argptr;
- static char buffers[2][0x2800];
- static int index;
-
- index ^= 1;
-
- va_start( argptr, format );
- Q_vsnprintf( buffers[index], sizeof( buffers[0] ), format, argptr );
- va_end( argptr );
-
- return buffers[index];
-}
-
-static char com_token[4][MAX_TOKEN_CHARS];
-static int com_tokidx;
-
-/*
-==============
-COM_Parse
-
-Parse a token out of a string.
-Handles C and C++ comments.
-==============
-*/
-char *COM_Parse( const char **data_p ) {
- int c;
- int len;
- const char *data;
- char *s = com_token[com_tokidx++ & 3];
-
- data = *data_p;
- len = 0;
- s[0] = 0;
-
- if( !data ) {
- *data_p = NULL;
- return s;
- }
-
-// skip whitespace
-skipwhite:
- while( ( c = *data ) <= ' ' ) {
- if( c == 0 ) {
- *data_p = NULL;
- return s;
- }
- data++;
- }
-
-// skip // comments
- if( c == '/' && data[1] == '/' ) {
- data += 2;
- while( *data && *data != '\n' )
- data++;
- goto skipwhite;
- }
-
-// skip /* */ comments
- if( c == '/' && data[1] == '*' ) {
- data += 2;
- while( *data ) {
- if( data[0] == '*' && data[1] == '/' ) {
- data += 2;
- break;
- }
- data++;
- }
- goto skipwhite;
- }
-
-// handle quoted strings specially
- if( c == '\"' ) {
- data++;
- while( 1 ) {
- c = *data++;
- if( c == '\"' || !c ) {
- goto finish;
- }
-
- if( len < MAX_TOKEN_CHARS - 1 ) {
- s[len++] = c;
- }
- }
- }
-
-// parse a regular word
- do {
- if( len < MAX_TOKEN_CHARS - 1 ) {
- s[len++] = c;
- }
- data++;
- c = *data;
- } while( c > 32 );
-
-finish:
- s[len] = 0;
-
- *data_p = data;
- return s;
-}
-
-/*
-==============
-COM_Compress
-
-Operates in place, removing excess whitespace and comments.
-Non-contiguous line feeds are preserved.
-
-Returns resulting data length.
-==============
-*/
-int COM_Compress( char *data ) {
- int c, n = 0;
- char *s = data, *d = data;
-
- while( *s ) {
- // skip whitespace
- if( *s <= ' ' ) {
- n = ' ';
- do {
- c = *s++;
- if( c == '\n' ) {
- n = '\n';
- }
- if( !c ) {
- goto finish;
- }
- } while( *s <= ' ' );
- }
-
- // skip // comments
- if( s[0] == '/' && s[1] == '/' ) {
- n = ' ';
- s += 2;
- while( *s && *s != '\n' ) {
- s++;
- }
- continue;
- }
-
- // skip /* */ comments
- if( s[0] == '/' && s[1] == '*' ) {
- n = ' ';
- s += 2;
- while( *s ) {
- if( s[0] == '*' && s[1] == '/' ) {
- s += 2;
- break;
- }
- s++;
- }
- continue;
- }
-
- // add whitespace character
- if( n ) {
- *d++ = n;
- n = 0;
- }
-
- // handle quoted strings specially
- if( *s == '\"' ) {
- s++;
- *d++ = '\"';
- do {
- c = *s++;
- if( !c ) {
- goto finish;
- }
- *d++ = c;
- } while( c != '\"' );
- continue;
- }
-
- // handle line feed escape
- if( *s == '\\' && s[1] == '\n' ) {
- s += 2;
- continue;
- }
-
- // parse a regular word
- do {
- *d++ = *s++;
- } while( *s > ' ' );
- }
-
-finish:
- *d = 0;
-
- return d - data;
-}
-
-/*
-============================================================================
-
- LIBRARY REPLACEMENT FUNCTIONS
-
-============================================================================
-*/
-
-int Q_strncasecmp( const char *s1, const char *s2, size_t n ) {
- int c1, c2;
-
- do {
- c1 = *s1++;
- c2 = *s2++;
-
- if( !n-- )
- return 0; /* strings are equal until end point */
-
- if( c1 != c2 ) {
- c1 = Q_tolower( c1 );
- c2 = Q_tolower( c2 );
- if( c1 < c2 )
- return -1;
- if( c1 > c2 )
- return 1; /* strings not equal */
- }
- } while( c1 );
-
- return 0; /* strings are equal */
-}
-
-int Q_strcasecmp( const char *s1, const char *s2 ) {
- int c1, c2;
-
- do {
- c1 = *s1++;
- c2 = *s2++;
-
- if( c1 != c2 ) {
- c1 = Q_tolower( c1 );
- c2 = Q_tolower( c2 );
- if( c1 < c2 )
- return -1;
- if( c1 > c2 )
- return 1; /* strings not equal */
- }
- } while( c1 );
-
- return 0; /* strings are equal */
-}
-
-char *Q_strcasestr( const char *s1, const char *s2 ) {
- size_t l1, l2;
-
- l2 = strlen( s2 );
- if( !l2 ) {
- return ( char * )s1;
- }
-
- l1 = strlen( s1 );
- while( l1 >= l2 ) {
- l1--;
- if( !Q_strncasecmp( s1, s2, l2 ) ) {
- return ( char * )s1;
- }
- s1++;
- }
-
- return NULL;
-}
-
-/*
-===============
-Q_strlcpy
-
-Returns length of the source string.
-===============
-*/
-size_t Q_strlcpy( char *dst, const char *src, size_t size ) {
- size_t ret = strlen( src );
-
- if( size ) {
- size_t len = ret >= size ? size - 1 : ret;
- memcpy( dst, src, len );
- dst[len] = 0;
- }
-
- return ret;
-}
-
-/*
-===============
-Q_strlcat
-
-Returns length of the source and destinations strings combined.
-===============
-*/
-size_t Q_strlcat( char *dst, const char *src, size_t size ) {
- size_t ret, len = strlen( dst );
-
- if( len >= size ) {
- Com_Error( ERR_FATAL, "%s: already overflowed", __func__ );
- }
-
- ret = Q_strlcpy( dst + len, src, size - len );
- ret += len;
-
- return ret;
-}
-
-/*
-===============
-Q_concat
-
-Returns number of characters that would be written into the buffer,
-excluding trailing '\0'. If the returned value is equal to or greater than
-buffer size, resulting string is truncated.
-===============
-*/
-size_t Q_concat( char *dest, size_t size, ... ) {
- va_list argptr;
- const char *s;
- size_t len, total = 0;
-
- va_start( argptr, size );
- while( ( s = va_arg( argptr, const char * ) ) != NULL ) {
- len = strlen( s );
- if( total + len < size ) {
- memcpy( dest, s, len );
- dest += len;
- }
- total += len;
- }
- va_end( argptr );
-
- if( size ) {
- *dest = 0;
- }
-
- return total;
-}
-
-/*
-===============
-Q_vsnprintf
-
-Returns number of characters that would be written into the buffer,
-excluding trailing '\0'. If the returned value is equal to or greater than
-buffer size, resulting string is truncated.
-===============
-*/
-size_t Q_vsnprintf( char *dest, size_t size, const char *fmt, va_list argptr ) {
- int ret;
-
- if( size > INT_MAX ) {
- Com_Error( ERR_FATAL, "%s: bad buffer size", __func__ );
- }
-
-#ifdef _WIN32
- // work around broken M$ C runtime semantics.
- if( !size ) {
- return 0;
- }
- ret = _vsnprintf( dest, size - 1, fmt, argptr );
- if( ret >= size - 1 ) {
- dest[size - 1] = 0;
- }
-#else
- ret = vsnprintf( dest, size, fmt, argptr );
-#endif
-
- // this shouldn't happen
- if( ret < 0 ) {
- if( size ) {
- *dest = 0;
- }
- ret = 0;
- }
-
- return ( size_t )ret;
-}
-
-/*
-===============
-Q_vscnprintf
-
-Returns number of characters actually written into the buffer,
-excluding trailing '\0'. If buffer size is 0, this function does nothing
-and returns 0.
-===============
-*/
-size_t Q_vscnprintf( char *dest, size_t size, const char *fmt, va_list argptr ) {
- size_t ret;
-
- if( !size ) {
- return 0;
- }
-
- ret = Q_vsnprintf( dest, size, fmt, argptr );
- return ret >= size ? size - 1 : ret;
-}
-
-
-/*
-===============
-Q_snprintf
-
-Returns number of characters that would be written into the buffer,
-excluding trailing '\0'. If the returned value is equal to or greater than
-buffer size, resulting string is truncated.
-===============
-*/
-size_t Q_snprintf( char *dest, size_t size, const char *fmt, ... ) {
- va_list argptr;
- size_t ret;
-
- va_start( argptr, fmt );
- ret = Q_vsnprintf( dest, size, fmt, argptr );
- va_end( argptr );
-
- return ret;
-}
-
-/*
-===============
-Q_scnprintf
-
-Returns number of characters actually written into the buffer,
-excluding trailing '\0'. If buffer size is 0, this function does nothing
-and returns 0.
-===============
-*/
-size_t Q_scnprintf( char *dest, size_t size, const char *fmt, ... ) {
- va_list argptr;
- size_t ret;
-
- va_start( argptr, fmt );
- ret = Q_vscnprintf( dest, size, fmt, argptr );
- va_end( argptr );
-
- return ret;
-}
-
-char *Q_strchrnul( const char *s, int c ) {
- while( *s && *s != c ) {
- s++;
- }
- return ( char * )s;
-}
-
-void Q_setenv( const char *name, const char *value ) {
-#ifdef _WIN32
-#ifndef __COREDLL__
- if( !value ) {
- value = "";
- }
-#if( _MSC_VER >= 1400 )
- _putenv_s( name, value );
-#else
- _putenv( va( "%s=%s", name, value ) );
-#endif
-#endif
-#else // _WIN32
- if( value ) {
- setenv( name, value, 1 );
- } else {
- unsetenv( name );
- }
-#endif // !_WIN32
-}
-
-/*
-=====================================================================
-
- INFO STRINGS
-
-=====================================================================
-*/
-
-/*
-===============
-Info_ValueForKey
-
-Searches the string for the given
-key and returns the associated value, or an empty string.
-===============
-*/
-char *Info_ValueForKey( const char *s, const char *key ) {
- static char value[4][MAX_INFO_STRING]; // use 4 buffers so compares
- // work without stomping on each other
- static int valueindex;
- char pkey[MAX_INFO_STRING];
- char *o;
-
- valueindex++;
- if( *s == '\\' )
- s++;
- while( 1 ) {
- o = pkey;
- while( *s != '\\' ) {
- if( !*s )
- return "";
- *o++ = *s++;
- }
- *o = 0;
- s++;
-
- o = value[valueindex & 3];
- while( *s != '\\' && *s ) {
- *o++ = *s++;
- }
- *o = 0;
-
- if( !strcmp( key, pkey ) )
- return value[valueindex & 3];
-
- if( !*s )
- return "";
- s++;
- }
-
- return "";
-}
-
-/*
-==================
-Info_RemoveKey
-==================
-*/
-void Info_RemoveKey( char *s, const char *key ) {
- char *start;
- char pkey[MAX_INFO_STRING];
- char *o;
-
- while( 1 ) {
- start = s;
- if( *s == '\\' )
- s++;
- o = pkey;
- while( *s != '\\' ) {
- if( !*s )
- return;
- *o++ = *s++;
- }
- *o = 0;
- s++;
-
- while( *s != '\\' && *s ) {
- s++;
- }
-
- if( !strcmp( key, pkey ) ) {
- o = start; // remove this part
- while( *s ) {
- *o++ = *s++;
- }
- *o = 0;
- s = start;
- continue; // search for duplicates
- }
-
- if( !*s )
- return;
- }
-
-}
-
-
-/*
-==================
-Info_Validate
-
-Some characters are illegal in info strings because they
-can mess up the server's parsing.
-Also checks the length of keys/values and the whole string.
-==================
-*/
-qboolean Info_Validate( const char *s ) {
- size_t len, total;
- int c;
-
- total = 0;
- while( 1 ) {
- //
- // validate key
- //
- if( *s == '\\' ) {
- s++;
- if( ++total == MAX_INFO_STRING ) {
- return qfalse; // oversize infostring
- }
- }
- if( !*s ) {
- return qfalse; // missing key
- }
- len = 0;
- while( *s != '\\' ) {
- c = *s++;
- if( !Q_isprint( c ) || c == '\"' || c == ';' ) {
- return qfalse; // illegal characters
- }
- if( ++len == MAX_INFO_KEY ) {
- return qfalse; // oversize key
- }
- if( ++total == MAX_INFO_STRING ) {
- return qfalse; // oversize infostring
- }
- if( !*s ) {
- return qfalse; // missing value
- }
- }
-
- //
- // validate value
- //
- s++;
- if( ++total == MAX_INFO_STRING ) {
- return qfalse; // oversize infostring
- }
- if( !*s ) {
- return qfalse; // missing value
- }
- len = 0;
- while( *s != '\\' ) {
- c = *s++;
- if( !Q_isprint( c ) || c == '\"' || c == ';' ) {
- return qfalse; // illegal characters
- }
- if( ++len == MAX_INFO_VALUE ) {
- return qfalse; // oversize value
- }
- if( ++total == MAX_INFO_STRING ) {
- return qfalse; // oversize infostring
- }
- if( !*s ) {
- return qtrue; // end of string
- }
- }
- }
-
- return qfalse; // quiet compiler warning
-}
-
-/*
-============
-Info_SubValidate
-============
-*/
-size_t Info_SubValidate( const char *s ) {
- size_t len;
- int c;
-
- len = 0;
- while( *s ) {
- c = *s++;
- c &= 127; // strip high bits
- if( c == '\\' || c == '\"' || c == ';' ) {
- return SIZE_MAX; // illegal characters
- }
- if( ++len == MAX_QPATH ) {
- return MAX_QPATH; // oversize value
- }
- }
-
- return len;
-}
-
-/*
-==================
-Info_SetValueForKey
-==================
-*/
-qboolean Info_SetValueForKey( char *s, const char *key, const char *value ) {
- char newi[MAX_INFO_STRING], *v;
- size_t l, kl, vl;
- int c;
-
- // validate key
- kl = Info_SubValidate( key );
- if( kl >= MAX_QPATH ) {
- return qfalse;
- }
-
- // validate value
- vl = Info_SubValidate( value );
- if( vl >= MAX_QPATH ) {
- return qfalse;
- }
-
- Info_RemoveKey( s, key );
- if( !vl ) {
- return qtrue;
- }
-
- l = strlen( s );
- if( l + kl + vl + 2 >= MAX_INFO_STRING ) {
- return qfalse;
- }
-
- newi[0] = '\\';
- memcpy( newi + 1, key, kl );
- newi[kl + 1] = '\\';
- memcpy( newi + kl + 2, value, vl + 1 );
-
- // only copy ascii values
- s += l;
- v = newi;
- while( *v ) {
- c = *v++;
- c &= 127; // strip high bits
- if( Q_isprint( c ) )
- *s++ = c;
- }
- *s = 0;
-
- return qtrue;
-}
-
-/*
-==================
-Info_NextPair
-==================
-*/
-void Info_NextPair( const char **string, char *key, char *value ) {
- char *o;
- const char *s;
-
- *value = *key = 0;
-
- s = *string;
- if( !s ) {
- return;
- }
-
- if( *s == '\\' )
- s++;
-
- if( !*s ) {
- *string = NULL;
- return;
- }
-
- o = key;
- while( *s && *s != '\\' ) {
- *o++ = *s++;
- }
-
- *o = 0;
-
- if( !*s ) {
- *string = NULL;
- return;
- }
-
- o = value;
- s++;
- while( *s && *s != '\\' ) {
- *o++ = *s++;
- }
- *o = 0;
-
- if( *s ) {
- s++;
- }
-
- *string = s;
-
-}
-
-/*
-==================
-Info_Print
-==================
-*/
-void Info_Print( const char *infostring ) {
- char key[MAX_INFO_STRING];
- char value[MAX_INFO_STRING];
-
- while( infostring ) {
- Info_NextPair( &infostring, key, value );
-
- if( !key[0] ) {
- break;
- }
-
- if( value[0] ) {
- Com_Printf( "%-20s %s\n", key, value );
- } else {
- Com_Printf( "%-20s <MISSING VALUE>\n", key );
- }
- }
-}
-