diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 3190205d..c51f3bc5 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -1158,7 +1158,7 @@ static void Cmd_Apropos_f( void ) return; } - ispattern = partial && ( Q_strchr( partial, '*' ) || Q_strchr( partial, '?' )); + ispattern = partial && Q_strpbrk( partial, "*?" ); if( !ispattern ) partial = va( "*%s*", partial ); diff --git a/engine/common/common.c b/engine/common/common.c index a9fdae32..c5bb1563 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -1142,7 +1142,7 @@ qboolean COM_IsSafeFileToDownload( const char *filename ) Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename )); - if( Q_strstr( lwrfilename, "\\" ) || Q_strstr( lwrfilename, ":" ) || Q_strstr( lwrfilename, ".." ) || Q_strstr( lwrfilename, "~" )) + if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ) ) return false; if( lwrfilename[0] == '/' ) diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index 57b76750..529407b5 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -85,8 +85,9 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) if( Q_stricmp( ext, "bsp" )) continue; Q_strncpy( message, "^1error^7", sizeof( message )); - Q_strncpy( compiler, "", sizeof( compiler )); - Q_strncpy( generator, "", sizeof( generator )); + compiler[0] = '\0'; + generator[0] = '\0'; + f = FS_Open( t->filenames[i], "rb", con_gamemaps->value ); if( f ) @@ -446,7 +447,7 @@ qboolean Cmd_GetSoundList( const char *s, char *completedname, int length ) t = FS_Search( va( "%s%s*.*", DEFAULT_SOUNDPATH, s ), true, false ); if( !t ) return false; - Q_strncpy( matchbuf, t->filenames[0] + Q_strlen( DEFAULT_SOUNDPATH ), MAX_STRING ); + Q_strncpy( matchbuf, t->filenames[0] + sizeof( DEFAULT_SOUNDPATH ) - 1, MAX_STRING ); COM_StripExtension( matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); @@ -459,7 +460,7 @@ qboolean Cmd_GetSoundList( const char *s, char *completedname, int length ) if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" )) continue; - Q_strncpy( matchbuf, t->filenames[i] + Q_strlen( DEFAULT_SOUNDPATH ), MAX_STRING ); + Q_strncpy( matchbuf, t->filenames[i] + sizeof( DEFAULT_SOUNDPATH ) - 1, MAX_STRING ); COM_StripExtension( matchbuf ); Con_Printf( "%16s\n", matchbuf ); numsounds++; @@ -541,13 +542,16 @@ qboolean Cmd_GetKeysList( const char *s, char *completedname, int length ) size_t i, numkeys; string keys[256]; string matchbuf; + int len; // compare keys list with current keyword + len = Q_strlen( s ); + for( i = 0, numkeys = 0; i < 255; i++ ) { const char *keyname = Key_KeynumToString( i ); - if(( *s == '*' ) || !Q_strnicmp( keyname, s, Q_strlen( s ))) + if(( *s == '*' ) || !Q_strnicmp( keyname, s, len)) Q_strcpy( keys[numkeys++], keyname ); } @@ -628,7 +632,7 @@ qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length ) while( *list.completionString && (*list.completionString == '\\' || *list.completionString == '/') ) list.completionString++; - if( !Q_strlen( list.completionString ) ) + if( !COM_CheckStringEmpty( list.completionString ) ) return false; // find matching commands and variables @@ -730,15 +734,18 @@ qboolean Cmd_GetGamesList( const char *s, char *completedname, int length ) int i, numgamedirs; string gamedirs[MAX_MODS]; string matchbuf; + int len; // stand-alone games doesn't have cmd "game" if( !Cmd_Exists( "game" )) return false; // compare gamelist with current keyword + len = Q_strlen( s ); + for( i = 0, numgamedirs = 0; i < SI.numgames; i++ ) { - if(( *s == '*' ) || !Q_strnicmp( SI.games[i]->gamefolder, s, Q_strlen( s ))) + if(( *s == '*' ) || !Q_strnicmp( SI.games[i]->gamefolder, s, len)) Q_strcpy( gamedirs[numgamedirs++], SI.games[i]->gamefolder ); } @@ -780,6 +787,7 @@ qboolean Cmd_GetCDList( const char *s, char *completedname, int length ) int i, numcdcommands; string cdcommands[8]; string matchbuf; + int len; const char *cd_command[] = { @@ -794,9 +802,11 @@ qboolean Cmd_GetCDList( const char *s, char *completedname, int length ) }; // compare CD command list with current keyword + len = Q_strlen( s ); + for( i = 0, numcdcommands = 0; i < 8; i++ ) { - if(( *s == '*' ) || !Q_strnicmp( cd_command[i], s, Q_strlen( s ))) + if(( *s == '*' ) || !Q_strnicmp( cd_command[i], s, len)) Q_strcpy( cdcommands[numcdcommands++], cd_command[i] ); } @@ -841,7 +851,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) return true; // exist // setup mpfilter - Q_snprintf( mpfilter, sizeof( mpfilter ), "maps/%s", GI->mp_filter ); + size = Q_snprintf( mpfilter, sizeof( mpfilter ), "maps/%s", GI->mp_filter ); t = FS_Search( "maps/*.bsp", false, onlyingamedir ); if( !t ) @@ -855,7 +865,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) } buffer = Mem_Calloc( host.mempool, t->numfilenames * 2 * sizeof( result )); - use_filter = Q_strlen( GI->mp_filter ) ? true : false; + use_filter = COM_CheckStringEmpty( GI->mp_filter ) ? true : false; for( i = 0; i < t->numfilenames; i++ ) { @@ -866,7 +876,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "bsp" )) continue; - if( use_filter && !Q_strnicmp( t->filenames[i], mpfilter, Q_strlen( mpfilter ))) + if( use_filter && !Q_strnicmp( t->filenames[i], mpfilter, size)) continue; f = FS_Open( t->filenames[i], "rb", onlyingamedir ); @@ -958,7 +968,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) } // write generated maps.lst - if( FS_WriteFile( "maps.lst", buffer, Q_strlen( buffer ))) + if( FS_WriteFile( "maps.lst", buffer, size)) { if( buffer ) Mem_Free( buffer ); return true; @@ -1133,7 +1143,7 @@ void Con_CompleteCommand( field_t *field ) while( *con.completionString && (*con.completionString == '\\' || *con.completionString == '/') ) con.completionString++; - if( !Q_strlen( con.completionString ) ) + if( !COM_CheckStringEmpty( con.completionString ) ) return; // free the old autocomplete list @@ -1166,7 +1176,7 @@ void Con_CompleteCommand( field_t *field ) while( *con.completionBuffer && (*con.completionBuffer == '\\' || *con.completionBuffer == '/') ) con.completionBuffer++; - if( !Q_strlen( con.completionBuffer ) ) + if( !COM_CheckStringEmpty( con.completionBuffer ) ) return; if( Cmd_AutocompleteName( con.completionBuffer, Cmd_Argc() - 1, filename, sizeof( filename ) ) ) diff --git a/engine/common/cvar.c b/engine/common/cvar.c index 89c39ab6..f0a64e4b 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -184,7 +184,7 @@ const char *Cvar_ValidateString( convar_t *var, const char *value ) pszValue = szNew; // g-cont. is this even need? - if( !Q_strlen( szNew )) Q_strncpy( szNew, "empty", sizeof( szNew )); + if( !COM_CheckStringEmpty( szNew ) ) Q_strncpy( szNew, "empty", sizeof( szNew )); } if( FBitSet( var->flags, FCVAR_NOEXTRAWHITEPACE )) diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index 946e2fed..fb2cca15 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -269,7 +269,7 @@ static void stringlistappend( stringlist_t *list, char *text ) { size_t textlen; - if( !Q_stricmp( text, "." ) || !Q_stricmp( text, ".." )) + if( !Q_strcmp( text, "." ) || !Q_strcmp( text, ".." )) return; // ignore the virtual directories if( list->numstrings >= list->maxstrings ) @@ -1257,7 +1257,7 @@ void FS_AddGameHierarchy( const char *dir, uint flags ) } } - if( host.rodir[0] ) + if( COM_CheckStringEmpty( host.rodir ) ) { // append new flags to rodir, except FS_GAMEDIR_PATH and FS_CUSTOM_PATH uint newFlags = FS_NOWRITE_PATH | (flags & (~FS_GAMEDIR_PATH|FS_CUSTOM_PATH)); @@ -1342,7 +1342,7 @@ int FS_CheckNastyPath( const char *path, qboolean isgamedir ) // instead of /, but we rely on / working already, so there's no reason to // support a Mac-only path // Amiga and Windows: : tries to go to root of drive - if( Q_strstr( path, ":" )) return 1; // non-portable attempt to go to root of drive + if( Q_strchr( path, ':' )) return 1; // non-portable attempt to go to root of drive // Amiga: // is parent directory if( Q_strstr( path, "//" )) return 1; // non-portable attempt to go to parent directory @@ -1428,24 +1428,24 @@ static void FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo ) FS_Printf( f, "// generated by %s %s-%s (%s-%s)\n\n\n", XASH_ENGINE_NAME, XASH_VERSION, Q_buildcommit(), Q_buildos(), Q_buildarch() ); - if( Q_strlen( GameInfo->basedir )) + if( COM_CheckStringEmpty( GameInfo->basedir ) ) FS_Printf( f, "basedir\t\t\"%s\"\n", GameInfo->basedir ); // DEPRECATED: gamedir key isn't supported by FWGS fork // but write it anyway to keep compability with original Xash3D - if( Q_strlen( GameInfo->gamefolder )) + if( COM_CheckStringEmpty( GameInfo->gamefolder ) ) FS_Printf( f, "gamedir\t\t\"%s\"\n", GameInfo->gamefolder ); - if( Q_strlen( GameInfo->falldir )) + if( COM_CheckStringEmpty( GameInfo->falldir ) ) FS_Printf( f, "fallback_dir\t\"%s\"\n", GameInfo->falldir ); - if( Q_strlen( GameInfo->title )) + if( COM_CheckStringEmpty( GameInfo->title ) ) FS_Printf( f, "title\t\t\"%s\"\n", GameInfo->title ); - if( Q_strlen( GameInfo->startmap )) + if( COM_CheckStringEmpty( GameInfo->startmap ) ) FS_Printf( f, "startmap\t\t\"%s\"\n", GameInfo->startmap ); - if( Q_strlen( GameInfo->trainmap )) + if( COM_CheckStringEmpty( GameInfo->trainmap ) ) FS_Printf( f, "trainmap\t\t\"%s\"\n", GameInfo->trainmap ); if( GameInfo->version != 0.0f ) @@ -1454,32 +1454,32 @@ static void FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo ) if( GameInfo->size != 0 ) FS_Printf( f, "size\t\t%lu\n", GameInfo->size ); - if( Q_strlen( GameInfo->game_url )) + if( COM_CheckStringEmpty( GameInfo->game_url ) ) FS_Printf( f, "url_info\t\t\"%s\"\n", GameInfo->game_url ); - if( Q_strlen( GameInfo->update_url )) + if( COM_CheckStringEmpty( GameInfo->update_url ) ) FS_Printf( f, "url_update\t\t\"%s\"\n", GameInfo->update_url ); - if( Q_strlen( GameInfo->type )) + if( COM_CheckStringEmpty( GameInfo->type ) ) FS_Printf( f, "type\t\t\"%s\"\n", GameInfo->type ); - if( Q_strlen( GameInfo->date )) + if( COM_CheckStringEmpty( GameInfo->date ) ) FS_Printf( f, "date\t\t\"%s\"\n", GameInfo->date ); - if( Q_strlen( GameInfo->dll_path )) + if( COM_CheckStringEmpty( GameInfo->dll_path ) ) FS_Printf( f, "dllpath\t\t\"%s\"\n", GameInfo->dll_path ); - if( Q_strlen( GameInfo->game_dll )) + if( COM_CheckStringEmpty( GameInfo->game_dll ) ) FS_Printf( f, "gamedll\t\t\"%s\"\n", GameInfo->game_dll ); - if( Q_strlen( GameInfo->game_dll_linux )) + if( COM_CheckStringEmpty( GameInfo->game_dll_linux ) ) FS_Printf( f, "gamedll_linux\t\t\"%s\"\n", GameInfo->game_dll_linux ); - if( Q_strlen( GameInfo->game_dll_osx )) + if( COM_CheckStringEmpty( GameInfo->game_dll_osx ) ) FS_Printf( f, "gamedll_osx\t\t\"%s\"\n", GameInfo->game_dll_osx ); - if( Q_strlen( GameInfo->iconpath )) + if( COM_CheckStringEmpty( GameInfo->iconpath )) FS_Printf( f, "icon\t\t\"%s\"\n", GameInfo->iconpath ); switch( GameInfo->gamemode ) @@ -1488,11 +1488,11 @@ static void FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo ) case 2: FS_Print( f, "gamemode\t\t\"multiplayer_only\"\n" ); break; } - if( Q_strlen( GameInfo->sp_entity )) + if( COM_CheckStringEmpty( GameInfo->sp_entity )) FS_Printf( f, "sp_entity\t\t\"%s\"\n", GameInfo->sp_entity ); - if( Q_strlen( GameInfo->mp_entity )) + if( COM_CheckStringEmpty( GameInfo->mp_entity )) FS_Printf( f, "mp_entity\t\t\"%s\"\n", GameInfo->mp_entity ); - if( Q_strlen( GameInfo->mp_filter )) + if( COM_CheckStringEmpty( GameInfo->mp_filter )) FS_Printf( f, "mp_filter\t\t\"%s\"\n", GameInfo->mp_filter ); if( GameInfo->secure ) @@ -1900,7 +1900,7 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo ) Q_snprintf( liblist_path, sizeof( liblist_path ), "%s/liblist.gam", gamedir ); // here goes some RoDir magic... - if( host.rodir[0] ) + if( COM_CheckStringEmpty( host.rodir ) ) { string filepath_ro, liblist_ro; fs_offset_t roLibListTime, roGameInfoTime, rwGameInfoTime; @@ -2033,7 +2033,7 @@ void FS_Init( void ) if( !fs_caseinsensitive ) { - if( host.rodir[0] && !Q_strcmp( host.rodir, host.rootdir ) ) + if( COM_CheckStringEmpty( host.rodir ) && !Q_strcmp( host.rodir, host.rootdir ) ) { Sys_Error( "RoDir and default rootdir can't point to same directory!" ); } @@ -2041,7 +2041,7 @@ void FS_Init( void ) else #endif { - if( host.rodir[0] && !Q_stricmp( host.rodir, host.rootdir ) ) + if( COM_CheckStringEmpty( host.rodir ) && !Q_stricmp( host.rodir, host.rootdir ) ) { Sys_Error( "RoDir and default rootdir can't point to same directory!" ); } @@ -2068,7 +2068,7 @@ void FS_Init( void ) } // add readonly directories first - if( host.rodir[0] ) + if( COM_CheckStringEmpty( host.rodir ) ) { stringlistinit( &dirs ); listdirectory( &dirs, host.rodir, false ); @@ -2109,7 +2109,7 @@ void FS_Init( void ) for( i = 0; i < dirs.numstrings; i++ ) { - if( !FS_SysFolderExists( dirs.strings[i] ) || ( !Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path )) + if( !FS_SysFolderExists( dirs.strings[i] ) || ( !Q_strcmp( dirs.strings[i], ".." ) && !fs_ext_path )) continue; if( SI.games[SI.numgames] == NULL ) @@ -2468,7 +2468,7 @@ static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedir COM_ExtractFilePath( name, wadname ); wadfolder[0] = '\0'; - if( Q_strlen( wadname )) + if( COM_CheckStringEmpty( wadname ) ) { COM_FileBase( wadname, wadname ); Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); @@ -3249,6 +3249,7 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath ) dll_user_t *hInst; int i, index; int start = 0; + int len; // check for bad exports if( !COM_CheckString( dllname )) @@ -3261,7 +3262,9 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath ) start += 9; // replace all backward slashes - for( i = 0; i < Q_strlen( dllname ); i++ ) + len = Q_strlen( dllname ); + + for( i = 0; i < len; i++ ) { if( dllname[i+start] == '\\' ) dllpath[i] = '/'; else dllpath[i] = Q_tolower( dllname[i+start] ); @@ -3555,7 +3558,7 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) COM_FileBase( pattern, wadpattern ); wadfolder[0] = '\0'; - if( Q_strlen( wadname )) + if( COM_CheckStringEmpty( wadname )) { COM_FileBase( wadname, wadname ); Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); @@ -3914,7 +3917,7 @@ wfile_t *W_Open( const char *filename, int *error ) wad->handle = FS_Open( basename, "rb", false ); // HACKHACK: try to open WAD by full path for RoDir, when searchpaths are not ready - if( host.rodir[0] && fs_ext_path && wad->handle == NULL ) + if( COM_CheckStringEmpty( host.rodir ) && fs_ext_path && wad->handle == NULL ) wad->handle = FS_SysOpen( filename, "rb" ); if( wad->handle == NULL ) diff --git a/engine/common/host.c b/engine/common/host.c index aa6df9c6..fd6326b1 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -782,6 +782,7 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha int developer = DEFAULT_DEV; const char *baseDir; char ticrate[16]; + int len; // some commands may turn engine into infinite loop, // e.g. xash.exe +game xash -game xash @@ -924,12 +925,14 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha #endif } - if( host.rootdir[Q_strlen( host.rootdir ) - 1] == '/' ) - host.rootdir[Q_strlen( host.rootdir ) - 1] = 0; + len = Q_strlen( host.rootdir ); + + if( host.rootdir[len - 1] == '/' ) + host.rootdir[len - 1] = 0; // get readonly root. The order is: check for arg, then env. // if still not got it, rodir is disabled. - host.rodir[0] = 0; + host.rodir[0] = '\0'; if( !Sys_GetParmFromCmdLine( "-rodir", host.rodir )) { char *roDir = getenv( "XASH3D_RODIR" ); @@ -938,10 +941,12 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha Q_strncpy( host.rodir, roDir, sizeof( host.rodir )); } - if( host.rodir[0] && host.rodir[Q_strlen( host.rodir ) - 1] == '/' ) - host.rodir[Q_strlen( host.rodir ) - 1] = 0; + len = Q_strlen( host.rodir ); - if ( !host.rootdir[0] || SetCurrentDirectory( host.rootdir ) != 0) + if( len && host.rodir[len - 1] == '/' ) + host.rodir[len - 1] = 0; + + if( !COM_CheckStringEmpty( host.rootdir ) || SetCurrentDirectory( host.rootdir ) != 0 ) Con_Reportf( "%s is working directory now\n", host.rootdir ); else Sys_Error( "Changing working directory to %s failed.\n", host.rootdir ); diff --git a/engine/common/hpak.c b/engine/common/hpak.c index 000cf39a..2c486931 100644 --- a/engine/common/hpak.c +++ b/engine/common/hpak.c @@ -376,7 +376,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet ) if( quiet ) HPAK_FlushHostQueue(); // not an error - just flush queue - if( !filename || !*filename ) + if( !COM_CheckString( filename ) ) return true; Q_strncpy( pakname, filename, sizeof( pakname )); @@ -476,7 +476,7 @@ void HPAK_CheckIntegrity( const char *filename ) { string pakname; - if( !filename || !filename[0] ) + if( !COM_CheckString( filename ) ) return; Q_strncpy( pakname, filename, sizeof( pakname )); @@ -493,7 +493,7 @@ void HPAK_CheckSize( const char *filename ) maxsize = hpk_maxsize->value; if( maxsize <= 0 ) return; - if( !filename || !filename[0] ) + if( !COM_CheckString( filename ) ) return; Q_strncpy( pakname, filename, sizeof( pakname )); @@ -574,7 +574,7 @@ static qboolean HPAK_ResourceForIndex( const char *filename, int index, resource string pakname; file_t *f; - if( !filename || !filename[0] ) + if( !COM_CheckString( filename ) ) return false; Q_strncpy( pakname, filename, sizeof( pakname )); diff --git a/engine/common/infostring.c b/engine/common/infostring.c index f8d654e4..35167d95 100644 --- a/engine/common/infostring.c +++ b/engine/common/infostring.c @@ -122,7 +122,7 @@ qboolean Info_IsValid( const char *s ) } *o = 0; - if( !Q_strlen( value )) + if( !COM_CheckStringEmpty( value ) ) return false; if( *s ) s++; @@ -245,7 +245,7 @@ qboolean GAME_EXPORT Info_RemoveKey( char *s, const char *key ) if( cmpsize > ( MAX_KV_SIZE - 1 )) cmpsize = MAX_KV_SIZE - 1; - if( Q_strstr( key, "\\" )) + if( Q_strchr( key, '\\' )) return false; while( 1 ) @@ -417,7 +417,7 @@ qboolean Info_SetValueForStarKey( char *s, const char *key, const char *value, i char new[1024], *v; int c, team; - if( Q_strstr( key, "\\" ) || Q_strstr( value, "\\" )) + if( Q_strchr( key, '\\' ) || Q_strchr( value, '\\' )) { Con_Printf( S_ERROR "SetValueForKey: can't use keys or values with a \\\n" ); return false; @@ -426,7 +426,7 @@ qboolean Info_SetValueForStarKey( char *s, const char *key, const char *value, i if( Q_strstr( key, ".." ) || Q_strstr( value, ".." )) return false; - if( Q_strstr( key, "\"" ) || Q_strstr( value, "\"" )) + if( Q_strchr( key, '\"' ) || Q_strchr( value, '\"' )) { Con_Printf( S_ERROR "SetValueForKey: can't use keys or values with a \"\n" ); return false; @@ -437,7 +437,7 @@ qboolean Info_SetValueForStarKey( char *s, const char *key, const char *value, i Info_RemoveKey( s, key ); - if( !value || !Q_strlen( value )) + if( !COM_CheckString( value ) ) return true; // just clear variable Q_snprintf( new, sizeof( new ), "\\%s\\%s", key, value ); diff --git a/engine/common/model.c b/engine/common/model.c index fd3bcd93..9075676d 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -55,7 +55,7 @@ static void Mod_Modellist_f( void ) for( i = nummodels = 0, mod = mod_known; i < mod_numknown; i++, mod++ ) { - if( !mod->name[0] ) + if( !COM_CheckStringEmpty( mod->name ) ) continue; // free slot Con_Printf( "%s\n", mod->name ); nummodels++; @@ -74,7 +74,7 @@ Mod_FreeUserData static void Mod_FreeUserData( model_t *mod ) { // ignore submodels and freed models - if( !mod->name[0] || mod->name[0] == '*' ) + if( !COM_CheckStringEmpty( mod->name ) || mod->name[0] == '*' ) return; if( Host_IsDedicated() ) @@ -101,7 +101,7 @@ Mod_FreeModel void Mod_FreeModel( model_t *mod ) { // already freed? - if( !mod || !mod->name[0] ) + if( !mod || !COM_CheckStringEmpty( mod->name ) ) return; if( mod->type != mod_brush || mod->name[0] != '*' ) @@ -223,7 +223,7 @@ model_t *Mod_FindName( const char *filename, qboolean trackCRC ) // find a free model slot spot for( i = 0, mod = mod_known; i < mod_numknown; i++, mod++ ) - if( !mod->name[0] ) break; // this is a valid spot + if( !COM_CheckStringEmpty( mod->name ) ) break; // this is a valid spot if( i == mod_numknown ) { diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 271dfcce..93fd8acb 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -1371,7 +1371,7 @@ void Netchan_UpdateProgress( netchan_t *chan ) } *out = '\0'; - if( Q_strlen( sz ) > 0 && sz[0] != '!' ) + if( COM_CheckStringEmpty( sz ) && sz[0] != '!' ) Q_strncpy( host.downloadfile, sz, sizeof( host.downloadfile )); } } diff --git a/engine/common/net_encode.c b/engine/common/net_encode.c index c132b1bd..b5ad8ed4 100644 --- a/engine/common/net_encode.c +++ b/engine/common/net_encode.c @@ -344,7 +344,7 @@ delta_info_t *Delta_FindStructByEncoder( const char *encoderName ) { int i; - if( !encoderName || !encoderName[0] ) + if( !COM_CheckString( encoderName ) ) return NULL; for( i = 0; i < NUM_FIELDS( dt_info ); i++ ) diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c index b372c133..e7793061 100644 --- a/engine/common/net_ws.c +++ b/engine/common/net_ws.c @@ -1441,7 +1441,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast } } - if( !net_interface[0] || !Q_stricmp( net_interface, "localhost" )) + if( !COM_CheckStringEmpty( net_interface ) || !Q_stricmp( net_interface, "localhost" )) addr.sin_addr.s_addr = INADDR_ANY; else NET_StringToSockaddr( net_interface, (struct sockaddr *)&addr, false ); diff --git a/public/crtlib.c b/public/crtlib.c index 27d8d81d..6affcb93 100644 --- a/public/crtlib.c +++ b/public/crtlib.c @@ -603,6 +603,22 @@ int Q_sprintf( char *buffer, const char *format, ... ) return result; } +char *Q_strpbrk(const char *s, const char *accept) +{ + for( ; *s; s++ ) + { + const char *k; + + for( k = accept; *k; k++ ) + { + if( *s == *k ) + return (char*)s; + } + } + + return NULL; +} + uint Q_hashkey( const char *string, uint hashSize, qboolean caseinsensitive ) { uint i, hashKey = 0; diff --git a/public/crtlib.h b/public/crtlib.h index f64db6f2..22939aba 100644 --- a/public/crtlib.h +++ b/public/crtlib.h @@ -72,6 +72,7 @@ char *Q_strstr( const char *string, const char *string2 ); int Q_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list args ); int Q_snprintf( char *buffer, size_t buffersize, const char *format, ... ) _format( 3 ); int Q_sprintf( char *buffer, const char *format, ... ) _format( 2 ); +char *Q_strpbrk(const char *s, const char *accept); #define Q_memprint( val ) Q_pretifymem( val, 2 ) char *Q_pretifymem( float value, int digitsafterdecimal ); char *va( const char *format, ... ) _format( 1 ); @@ -87,6 +88,7 @@ void COM_PathSlashFix( char *path ); char COM_Hex2Char( uint8_t hex ); void COM_Hex2String( uint8_t hex, char *str ); #define COM_CheckString( string ) ( ( !string || !*string ) ? 0 : 1 ) +#define COM_CheckStringEmpty( string ) ( ( !*string ) ? 0 : 1 ) int matchpattern( const char *in, const char *pattern, qboolean caseinsensitive ); int matchpattern_with_separator( const char *in, const char *pattern, qboolean caseinsensitive, const char *separators, qboolean wildcard_least_one );