00001
00002
00003
00004 #include "q_shared.h"
00005
00006
00007
00008
00009
00010
00011
00012
00013 int GetIDForString ( stringID_table_t *table, const char *string )
00014 {
00015 int index = 0;
00016
00017 while ( ( table[index].name != NULL ) &&
00018 ( table[index].name[0] != 0 ) )
00019 {
00020 if ( !Q_stricmp( table[index].name, string ) )
00021 return table[index].id;
00022
00023 index++;
00024 }
00025
00026 return -1;
00027 }
00028
00029
00030
00031
00032
00033
00034
00035 const char *GetStringForID( stringID_table_t *table, int id )
00036 {
00037 int index = 0;
00038
00039 while ( ( table[index].name != NULL ) &&
00040 ( table[index].name[0] != 0 ) )
00041 {
00042 if ( table[index].id == id )
00043 return table[index].name;
00044
00045 index++;
00046 }
00047
00048 return NULL;
00049 }
00050
00051 int Com_Clampi( int min, int max, int value )
00052 {
00053 if ( value < min )
00054 {
00055 return min;
00056 }
00057 if ( value > max )
00058 {
00059 return max;
00060 }
00061 return value;
00062 }
00063
00064 float Com_Clamp( float min, float max, float value ) {
00065 if ( value < min ) {
00066 return min;
00067 }
00068 if ( value > max ) {
00069 return max;
00070 }
00071 return value;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 char *COM_SkipPath (char *pathname)
00081 {
00082 char *last;
00083
00084 last = pathname;
00085 while (*pathname)
00086 {
00087 if (*pathname=='/')
00088 last = pathname+1;
00089 pathname++;
00090 }
00091 return last;
00092 }
00093
00094
00095
00096
00097
00098
00099 void COM_StripExtension( const char *in, char *out ) {
00100 while ( *in && *in != '.' ) {
00101 *out++ = *in++;
00102 }
00103 *out = 0;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 void COM_DefaultExtension (char *path, int maxSize, const char *extension ) {
00113 char oldPath[MAX_QPATH];
00114 char *src;
00115
00116
00117
00118
00119
00120 src = path + strlen(path) - 1;
00121
00122 while (*src != '/' && src != path) {
00123 if ( *src == '.' ) {
00124 return;
00125 }
00126 src--;
00127 }
00128
00129 Q_strncpyz( oldPath, path, sizeof( oldPath ) );
00130 Com_sprintf( path, maxSize, "%s%s", oldPath, extension );
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 short ShortSwap (short l)
00163 {
00164 byte b1,b2;
00165
00166 b1 = l&255;
00167 b2 = (l>>8)&255;
00168
00169 return (b1<<8) + b2;
00170 }
00171
00172 short ShortNoSwap (short l)
00173 {
00174 return l;
00175 }
00176
00177 int LongSwap (int l)
00178 {
00179 byte b1,b2,b3,b4;
00180
00181 b1 = l&255;
00182 b2 = (l>>8)&255;
00183 b3 = (l>>16)&255;
00184 b4 = (l>>24)&255;
00185
00186 return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
00187 }
00188
00189 int LongNoSwap (int l)
00190 {
00191 return l;
00192 }
00193
00194 qint64 Long64Swap (qint64 ll)
00195 {
00196 qint64 result;
00197
00198 result.b0 = ll.b7;
00199 result.b1 = ll.b6;
00200 result.b2 = ll.b5;
00201 result.b3 = ll.b4;
00202 result.b4 = ll.b3;
00203 result.b5 = ll.b2;
00204 result.b6 = ll.b1;
00205 result.b7 = ll.b0;
00206
00207 return result;
00208 }
00209
00210 qint64 Long64NoSwap (qint64 ll)
00211 {
00212 return ll;
00213 }
00214
00215 typedef union {
00216 float f;
00217 unsigned int i;
00218 } _FloatByteUnion;
00219
00220 float FloatSwap (const float *f) {
00221 const _FloatByteUnion *in;
00222 _FloatByteUnion out;
00223
00224 in = (_FloatByteUnion *)f;
00225 out.i = LongSwap(in->i);
00226
00227 return out.f;
00228 }
00229
00230 float FloatNoSwap (const float *f)
00231 {
00232 return *f;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 static char com_token[MAX_TOKEN_CHARS];
00281 static char com_parsename[MAX_TOKEN_CHARS];
00282 static int com_lines;
00283
00284 void COM_BeginParseSession( const char *name )
00285 {
00286 com_lines = 0;
00287 Com_sprintf(com_parsename, sizeof(com_parsename), "%s", name);
00288 }
00289
00290 int COM_GetCurrentParseLine( void )
00291 {
00292 return com_lines;
00293 }
00294
00295 char *COM_Parse( const char **data_p )
00296 {
00297 return COM_ParseExt( data_p, qtrue );
00298 }
00299
00300 void COM_ParseError( char *format, ... )
00301 {
00302 va_list argptr;
00303 static char string[4096];
00304
00305 va_start (argptr, format);
00306 vsprintf (string, format, argptr);
00307 va_end (argptr);
00308
00309 Com_Printf("ERROR: %s, line %d: %s\n", com_parsename, com_lines, string);
00310 }
00311
00312 void COM_ParseWarning( char *format, ... )
00313 {
00314 va_list argptr;
00315 static char string[4096];
00316
00317 va_start (argptr, format);
00318 vsprintf (string, format, argptr);
00319 va_end (argptr);
00320
00321 Com_Printf("WARNING: %s, line %d: %s\n", com_parsename, com_lines, string);
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 const char *SkipWhitespace( const char *data, qboolean *hasNewLines ) {
00337 int c;
00338
00339 while( (c = *data) <= ' ') {
00340 if( !c ) {
00341 return NULL;
00342 }
00343 if( c == '\n' ) {
00344 com_lines++;
00345 *hasNewLines = qtrue;
00346 }
00347 data++;
00348 }
00349
00350 return data;
00351 }
00352
00353 int COM_Compress( char *data_p ) {
00354 char *in, *out;
00355 int c;
00356 qboolean newline = qfalse, whitespace = qfalse;
00357
00358 in = out = data_p;
00359 if (in) {
00360 while ((c = *in) != 0) {
00361
00362 if ( c == '/' && in[1] == '/' ) {
00363 while (*in && *in != '\n') {
00364 in++;
00365 }
00366
00367 } else if ( c == '/' && in[1] == '*' ) {
00368 while ( *in && ( *in != '*' || in[1] != '/' ) )
00369 in++;
00370 if ( *in )
00371 in += 2;
00372
00373 } else if ( c == '\n' || c == '\r' ) {
00374 newline = qtrue;
00375 in++;
00376
00377 } else if ( c == ' ' || c == '\t') {
00378 whitespace = qtrue;
00379 in++;
00380
00381 } else {
00382
00383 if (newline) {
00384 *out++ = '\n';
00385 newline = qfalse;
00386 whitespace = qfalse;
00387 } if (whitespace) {
00388 *out++ = ' ';
00389 whitespace = qfalse;
00390 }
00391
00392
00393 if (c == '"') {
00394 *out++ = c;
00395 in++;
00396 while (1) {
00397 c = *in;
00398 if (c && c != '"') {
00399 *out++ = c;
00400 in++;
00401 } else {
00402 break;
00403 }
00404 }
00405 if (c == '"') {
00406 *out++ = c;
00407 in++;
00408 }
00409 } else {
00410 *out = c;
00411 out++;
00412 in++;
00413 }
00414 }
00415 }
00416 }
00417 *out = 0;
00418 return out - data_p;
00419 }
00420
00421 char *COM_ParseExt( const char **data_p, qboolean allowLineBreaks )
00422 {
00423 int c = 0, len;
00424 qboolean hasNewLines = qfalse;
00425 const char *data;
00426
00427 data = *data_p;
00428 len = 0;
00429 com_token[0] = 0;
00430
00431
00432 if ( !data )
00433 {
00434 *data_p = NULL;
00435 return com_token;
00436 }
00437
00438 while ( 1 )
00439 {
00440
00441 data = SkipWhitespace( data, &hasNewLines );
00442 if ( !data )
00443 {
00444 *data_p = NULL;
00445 return com_token;
00446 }
00447 if ( hasNewLines && !allowLineBreaks )
00448 {
00449 *data_p = data;
00450 return com_token;
00451 }
00452
00453 c = *data;
00454
00455
00456 if ( c == '/' && data[1] == '/' )
00457 {
00458 data += 2;
00459 while (*data && *data != '\n') {
00460 data++;
00461 }
00462 }
00463
00464 else if ( c=='/' && data[1] == '*' )
00465 {
00466 data += 2;
00467 while ( *data && ( *data != '*' || data[1] != '/' ) )
00468 {
00469 data++;
00470 }
00471 if ( *data )
00472 {
00473 data += 2;
00474 }
00475 }
00476 else
00477 {
00478 break;
00479 }
00480 }
00481
00482
00483 if (c == '\"')
00484 {
00485 data++;
00486 while (1)
00487 {
00488 c = *data++;
00489 if (c=='\"' || !c)
00490 {
00491 com_token[len] = 0;
00492 *data_p = ( char * ) data;
00493 return com_token;
00494 }
00495 if (len < MAX_TOKEN_CHARS)
00496 {
00497 com_token[len] = c;
00498 len++;
00499 }
00500 }
00501 }
00502
00503
00504 do
00505 {
00506 if (len < MAX_TOKEN_CHARS)
00507 {
00508 com_token[len] = c;
00509 len++;
00510 }
00511 data++;
00512 c = *data;
00513 if ( c == '\n' )
00514 com_lines++;
00515 } while (c>32);
00516
00517 if (len == MAX_TOKEN_CHARS)
00518 {
00519
00520 len = 0;
00521 }
00522 com_token[len] = 0;
00523
00524 *data_p = ( char * ) data;
00525 return com_token;
00526 }
00527
00528
00529 #if 0
00530
00531
00532
00533
00534
00535
00536 int COM_ParseInfos( char *buf, int max, char infos[][MAX_INFO_STRING] ) {
00537 char *token;
00538 int count;
00539 char key[MAX_TOKEN_CHARS];
00540
00541 count = 0;
00542
00543 while ( 1 ) {
00544 token = COM_Parse( &buf );
00545 if ( !token[0] ) {
00546 break;
00547 }
00548 if ( strcmp( token, "{" ) ) {
00549 Com_Printf( "Missing { in info file\n" );
00550 break;
00551 }
00552
00553 if ( count == max ) {
00554 Com_Printf( "Max infos exceeded\n" );
00555 break;
00556 }
00557
00558 infos[count][0] = 0;
00559 while ( 1 ) {
00560 token = COM_ParseExt( &buf, qtrue );
00561 if ( !token[0] ) {
00562 Com_Printf( "Unexpected end of info file\n" );
00563 break;
00564 }
00565 if ( !strcmp( token, "}" ) ) {
00566 break;
00567 }
00568 Q_strncpyz( key, token, sizeof( key ) );
00569
00570 token = COM_ParseExt( &buf, qfalse );
00571 if ( !token[0] ) {
00572 strcpy( token, "<NULL>" );
00573 }
00574 Info_SetValueForKey( infos[count], key, token );
00575 }
00576 count++;
00577 }
00578
00579 return count;
00580 }
00581 #endif
00582
00583
00584
00585
00586
00587
00588 qboolean COM_ParseString( const char **data, const char **s )
00589 {
00590
00591 *s = COM_ParseExt( data, qfalse );
00592 if ( s[0] == 0 )
00593 {
00594 Com_Printf("unexpected EOF\n");
00595 return qtrue;
00596 }
00597 return qfalse;
00598 }
00599
00600
00601
00602
00603
00604
00605 qboolean COM_ParseInt( const char **data, int *i )
00606 {
00607 const char *token;
00608
00609 token = COM_ParseExt( data, qfalse );
00610 if ( token[0] == 0 )
00611 {
00612 Com_Printf( "unexpected EOF\n" );
00613 return qtrue;
00614 }
00615
00616 *i = atoi( token );
00617 return qfalse;
00618 }
00619
00620
00621
00622
00623
00624
00625 qboolean COM_ParseFloat( const char **data, float *f )
00626 {
00627 const char *token;
00628
00629 token = COM_ParseExt( data, qfalse );
00630 if ( token[0] == 0 )
00631 {
00632 Com_Printf( "unexpected EOF\n" );
00633 return qtrue;
00634 }
00635
00636 *f = atof( token );
00637 return qfalse;
00638 }
00639
00640
00641
00642
00643
00644
00645 qboolean COM_ParseVec4( const char **buffer, vec4_t *c)
00646 {
00647 int i;
00648 float f;
00649
00650 for (i = 0; i < 4; i++)
00651 {
00652 if (COM_ParseFloat(buffer, &f))
00653 {
00654 return qtrue;
00655 }
00656 (*c)[i] = f;
00657 }
00658 return qfalse;
00659 }
00660
00661
00662
00663
00664
00665
00666 void COM_MatchToken( const char **buf_p, char *match ) {
00667 char *token;
00668
00669 token = COM_Parse( buf_p );
00670 if ( strcmp( token, match ) ) {
00671 Com_Error( ERR_DROP, "MatchToken: %s != %s", token, match );
00672 }
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 void SkipBracedSection (const char **program) {
00686 char *token;
00687 int depth;
00688
00689 depth = 0;
00690 do {
00691 token = COM_ParseExt( program, qtrue );
00692 if( token[1] == 0 ) {
00693 if( token[0] == '{' ) {
00694 depth++;
00695 }
00696 else if( token[0] == '}' ) {
00697 depth--;
00698 }
00699 }
00700 } while( depth && *program );
00701 }
00702
00703
00704
00705
00706
00707
00708 void SkipRestOfLine ( const char **data ) {
00709 const char *p;
00710 int c;
00711
00712 p = *data;
00713 while ( (c = *p++) != 0 ) {
00714 if ( c == '\n' ) {
00715 com_lines++;
00716 break;
00717 }
00718 }
00719
00720 *data = p;
00721 }
00722
00723
00724 void Parse1DMatrix (const char **buf_p, int x, float *m) {
00725 char *token;
00726 int i;
00727
00728 COM_MatchToken( buf_p, "(" );
00729
00730 for (i = 0 ; i < x ; i++) {
00731 token = COM_Parse(buf_p);
00732 m[i] = atof(token);
00733 }
00734
00735 COM_MatchToken( buf_p, ")" );
00736 }
00737
00738 void Parse2DMatrix (const char **buf_p, int y, int x, float *m) {
00739 int i;
00740
00741 COM_MatchToken( buf_p, "(" );
00742
00743 for (i = 0 ; i < y ; i++) {
00744 Parse1DMatrix (buf_p, x, m + i * x);
00745 }
00746
00747 COM_MatchToken( buf_p, ")" );
00748 }
00749
00750 void Parse3DMatrix (const char **buf_p, int z, int y, int x, float *m) {
00751 int i;
00752
00753 COM_MatchToken( buf_p, "(" );
00754
00755 for (i = 0 ; i < z ; i++) {
00756 Parse2DMatrix (buf_p, y, x, m + i * x*y);
00757 }
00758
00759 COM_MatchToken( buf_p, ")" );
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 int Q_isprint( int c )
00772 {
00773 if ( c >= 0x20 && c <= 0x7E )
00774 return ( 1 );
00775 return ( 0 );
00776 }
00777
00778 int Q_islower( int c )
00779 {
00780 if (c >= 'a' && c <= 'z')
00781 return ( 1 );
00782 return ( 0 );
00783 }
00784
00785 int Q_isupper( int c )
00786 {
00787 if (c >= 'A' && c <= 'Z')
00788 return ( 1 );
00789 return ( 0 );
00790 }
00791
00792 int Q_isalpha( int c )
00793 {
00794 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
00795 return ( 1 );
00796 return ( 0 );
00797 }
00798
00799 char* Q_strrchr( const char* string, int c )
00800 {
00801 char cc = c;
00802 char *s;
00803 char *sp=(char *)0;
00804
00805 s = (char*)string;
00806
00807 while (*s)
00808 {
00809 if (*s == cc)
00810 sp = s;
00811 s++;
00812 }
00813 if (cc == 0)
00814 sp = s;
00815
00816 return sp;
00817 }
00818
00819
00820
00821
00822
00823
00824
00825
00826 void Q_strncpyz( char *dest, const char *src, int destsize ) {
00827
00828 if ( !dest ) {
00829 Com_Error( ERR_FATAL, "Q_strncpyz: NULL dest" );
00830 }
00831 if ( !src ) {
00832 Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" );
00833 }
00834 if ( destsize < 1 ) {
00835 Com_Error(ERR_FATAL,"Q_strncpyz: destsize < 1" );
00836 }
00837
00838 strncpy( dest, src, destsize-1 );
00839 dest[destsize-1] = 0;
00840 }
00841
00842 int Q_stricmpn (const char *s1, const char *s2, int n) {
00843 int c1, c2;
00844
00845
00846 if ( s1 == NULL ) {
00847 if ( s2 == NULL )
00848 return 0;
00849 else
00850 return -1;
00851 }
00852 else if ( s2==NULL )
00853 return 1;
00854
00855
00856
00857 do {
00858 c1 = *s1++;
00859 c2 = *s2++;
00860
00861 if (!n--) {
00862 return 0;
00863 }
00864
00865 if (c1 != c2) {
00866 if (c1 >= 'a' && c1 <= 'z') {
00867 c1 -= ('a' - 'A');
00868 }
00869 if (c2 >= 'a' && c2 <= 'z') {
00870 c2 -= ('a' - 'A');
00871 }
00872 if (c1 != c2) {
00873 return c1 < c2 ? -1 : 1;
00874 }
00875 }
00876 } while (c1);
00877
00878 return 0;
00879 }
00880
00881 int Q_strncmp (const char *s1, const char *s2, int n) {
00882 int c1, c2;
00883
00884 do {
00885 c1 = *s1++;
00886 c2 = *s2++;
00887
00888 if (!n--) {
00889 return 0;
00890 }
00891
00892 if (c1 != c2) {
00893 return c1 < c2 ? -1 : 1;
00894 }
00895 } while (c1);
00896
00897 return 0;
00898 }
00899
00900 int Q_stricmp (const char *s1, const char *s2) {
00901 return (s1 && s2) ? Q_stricmpn (s1, s2, 99999) : -1;
00902 }
00903
00904
00905 char *Q_strlwr( char *s1 ) {
00906 char *s;
00907
00908 s = s1;
00909 while ( *s ) {
00910 *s = tolower(*s);
00911 s++;
00912 }
00913 return s1;
00914 }
00915
00916 char *Q_strupr( char *s1 ) {
00917 char *s;
00918
00919 s = s1;
00920 while ( *s ) {
00921 *s = toupper(*s);
00922 s++;
00923 }
00924 return s1;
00925 }
00926
00927
00928
00929 void Q_strcat( char *dest, int size, const char *src ) {
00930 int l1;
00931
00932 l1 = strlen( dest );
00933 if ( l1 >= size ) {
00934 Com_Error( ERR_FATAL, "Q_strcat: already overflowed" );
00935 }
00936 Q_strncpyz( dest + l1, src, size - l1 );
00937 }
00938
00939
00940 int Q_PrintStrlen( const char *string ) {
00941 int len;
00942 const char *p;
00943
00944 if( !string ) {
00945 return 0;
00946 }
00947
00948 len = 0;
00949 p = string;
00950 while( *p ) {
00951 if( Q_IsColorString( p ) ) {
00952 p += 2;
00953 continue;
00954 }
00955 p++;
00956 len++;
00957 }
00958
00959 return len;
00960 }
00961
00962
00963 char *Q_CleanStr( char *string ) {
00964 char* d;
00965 char* s;
00966 int c;
00967
00968 s = string;
00969 d = string;
00970 while ((c = *s) != 0 ) {
00971 if ( Q_IsColorString( s ) ) {
00972 s++;
00973 }
00974 else if ( c >= 0x20 && c <= 0x7E ) {
00975 *d++ = c;
00976 }
00977 s++;
00978 }
00979 *d = '\0';
00980
00981 return string;
00982 }
00983
00984
00985 void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) {
00986 int len;
00987 va_list argptr;
00988 char bigbuffer[32000];
00989
00990 va_start (argptr,fmt);
00991 len = vsprintf (bigbuffer,fmt,argptr);
00992 va_end (argptr);
00993 if ( len >= sizeof( bigbuffer ) ) {
00994 Com_Error( ERR_FATAL, "Com_sprintf: overflowed bigbuffer" );
00995 }
00996 if (len >= size) {
00997 Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size);
00998 #ifdef _DEBUG
00999 __asm {
01000 int 3;
01001 }
01002 #endif
01003 }
01004 Q_strncpyz (dest, bigbuffer, size );
01005 }
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 char * QDECL va( const char *format, ... ) {
01018 va_list argptr;
01019 static char string[2][32000];
01020 static int index = 0;
01021 char *buf;
01022
01023 buf = string[index & 1];
01024 index++;
01025
01026 va_start (argptr, format);
01027 vsprintf (buf, format,argptr);
01028 va_end (argptr);
01029
01030 return buf;
01031 }
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 char *Info_ValueForKey( const char *s, const char *key ) {
01052 char pkey[BIG_INFO_KEY];
01053 static char value[2][BIG_INFO_VALUE];
01054
01055 static int valueindex = 0;
01056 char *o;
01057
01058 if ( !s || !key ) {
01059 return "";
01060 }
01061
01062 if ( strlen( s ) >= BIG_INFO_STRING ) {
01063 Com_Error( ERR_DROP, "Info_ValueForKey: oversize infostring" );
01064 }
01065
01066 valueindex ^= 1;
01067 if (*s == '\\')
01068 s++;
01069 while (1)
01070 {
01071 o = pkey;
01072 while (*s != '\\')
01073 {
01074 if (!*s)
01075 return "";
01076 *o++ = *s++;
01077 }
01078 *o = 0;
01079 s++;
01080
01081 o = value[valueindex];
01082
01083 while (*s != '\\' && *s)
01084 {
01085 *o++ = *s++;
01086 }
01087 *o = 0;
01088
01089 if (!Q_stricmp (key, pkey) )
01090 return value[valueindex];
01091
01092 if (!*s)
01093 break;
01094 s++;
01095 }
01096
01097 return "";
01098 }
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108 void Info_NextPair( const char **head, char *key, char *value ) {
01109 char *o;
01110 const char *s;
01111
01112 s = *head;
01113
01114 if ( *s == '\\' ) {
01115 s++;
01116 }
01117 key[0] = 0;
01118 value[0] = 0;
01119
01120 o = key;
01121 while ( *s != '\\' ) {
01122 if ( !*s ) {
01123 *o = 0;
01124 *head = s;
01125 return;
01126 }
01127 *o++ = *s++;
01128 }
01129 *o = 0;
01130 s++;
01131
01132 o = value;
01133 while ( *s != '\\' && *s ) {
01134 *o++ = *s++;
01135 }
01136 *o = 0;
01137
01138 *head = s;
01139 }
01140
01141
01142
01143
01144
01145
01146
01147 void Info_RemoveKey( char *s, const char *key ) {
01148 char *start;
01149 char pkey[MAX_INFO_KEY];
01150 char value[MAX_INFO_VALUE];
01151 char *o;
01152
01153 if ( strlen( s ) >= MAX_INFO_STRING ) {
01154 Com_Error( ERR_DROP, "Info_RemoveKey: oversize infostring" );
01155 }
01156
01157 if (strchr (key, '\\')) {
01158 return;
01159 }
01160
01161 while (1)
01162 {
01163 start = s;
01164 if (*s == '\\')
01165 s++;
01166 o = pkey;
01167 while (*s != '\\')
01168 {
01169 if (!*s)
01170 return;
01171 *o++ = *s++;
01172 }
01173 *o = 0;
01174 s++;
01175
01176 o = value;
01177 while (*s != '\\' && *s)
01178 {
01179 if (!*s)
01180 return;
01181 *o++ = *s++;
01182 }
01183 *o = 0;
01184
01185 if (!strcmp (key, pkey) )
01186 {
01187 strcpy (start, s);
01188 return;
01189 }
01190
01191 if (!*s)
01192 return;
01193 }
01194
01195 }
01196
01197
01198
01199
01200
01201
01202 void Info_RemoveKey_Big( char *s, const char *key ) {
01203 char *start;
01204 char pkey[BIG_INFO_KEY];
01205 char value[BIG_INFO_VALUE];
01206 char *o;
01207
01208 if ( strlen( s ) >= BIG_INFO_STRING ) {
01209 Com_Error( ERR_DROP, "Info_RemoveKey_Big: oversize infostring" );
01210 }
01211
01212 if (strchr (key, '\\')) {
01213 return;
01214 }
01215
01216 while (1)
01217 {
01218 start = s;
01219 if (*s == '\\')
01220 s++;
01221 o = pkey;
01222 while (*s != '\\')
01223 {
01224 if (!*s)
01225 return;
01226 *o++ = *s++;
01227 }
01228 *o = 0;
01229 s++;
01230
01231 o = value;
01232 while (*s != '\\' && *s)
01233 {
01234 if (!*s)
01235 return;
01236 *o++ = *s++;
01237 }
01238 *o = 0;
01239
01240 if (!strcmp (key, pkey) )
01241 {
01242 strcpy (start, s);
01243 return;
01244 }
01245
01246 if (!*s)
01247 return;
01248 }
01249
01250 }
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263 qboolean Info_Validate( const char *s ) {
01264 if ( strchr( s, '\"' ) ) {
01265 return qfalse;
01266 }
01267 if ( strchr( s, ';' ) ) {
01268 return qfalse;
01269 }
01270 return qtrue;
01271 }
01272
01273
01274
01275
01276
01277
01278
01279
01280 void Info_SetValueForKey( char *s, const char *key, const char *value ) {
01281 char newi[MAX_INFO_STRING];
01282
01283 if ( strlen( s ) >= MAX_INFO_STRING ) {
01284 Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring" );
01285 }
01286
01287 if (strchr (key, '\\') || strchr (value, '\\'))
01288 {
01289 Com_Printf ("Can't use keys or values with a \\\n");
01290 return;
01291 }
01292
01293 if (strchr (key, ';') || strchr (value, ';'))
01294 {
01295 Com_Printf ("Can't use keys or values with a semicolon\n");
01296 return;
01297 }
01298
01299 if (strchr (key, '\"') || strchr (value, '\"'))
01300 {
01301 Com_Printf ("Can't use keys or values with a \"\n");
01302 return;
01303 }
01304
01305 Info_RemoveKey (s, key);
01306 if (!value || !strlen(value))
01307 return;
01308
01309 Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value);
01310
01311 if (strlen(newi) + strlen(s) > MAX_INFO_STRING)
01312 {
01313 Com_Printf ("Info string length exceeded\n");
01314 return;
01315 }
01316
01317 strcat (newi, s);
01318 strcpy (s, newi);
01319 }
01320
01321
01322
01323
01324
01325
01326
01327
01328 void Info_SetValueForKey_Big( char *s, const char *key, const char *value ) {
01329 char newi[BIG_INFO_STRING];
01330
01331 if ( strlen( s ) >= BIG_INFO_STRING ) {
01332 Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring" );
01333 }
01334
01335 if (strchr (key, '\\') || strchr (value, '\\'))
01336 {
01337 Com_Printf ("Can't use keys or values with a \\\n");
01338 return;
01339 }
01340
01341 if (strchr (key, ';') || strchr (value, ';'))
01342 {
01343 Com_Printf ("Can't use keys or values with a semicolon\n");
01344 return;
01345 }
01346
01347 if (strchr (key, '\"') || strchr (value, '\"'))
01348 {
01349 Com_Printf ("Can't use keys or values with a \"\n");
01350 return;
01351 }
01352
01353 Info_RemoveKey_Big (s, key);
01354 if (!value || !strlen(value))
01355 return;
01356
01357 Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value);
01358
01359 if (strlen(newi) + strlen(s) > BIG_INFO_STRING)
01360 {
01361 Com_Printf ("BIG Info string length exceeded\n");
01362 return;
01363 }
01364
01365 strcat (s, newi);
01366 }
01367
01368
01369
01370