diff --git a/engine/common/cvar.c b/engine/common/cvar.c index ef43c421..869b0fed 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -960,6 +960,16 @@ static void Cvar_SetGL( const char *name, const char *value ) Cvar_FullSet( name, value, FCVAR_GLCONFIG ); } +static int ShouldSetCvar_splitstr_handler( char *prev, char *next, void *userdata ) +{ + size_t len = next - prev; + + if( !Q_strnicmp( prev, userdata, len )) + return 1; + + return 0; +} + static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged ) { const char *prefixes[] = { "cl_", "gl_", "m_", "r_", "hud_", "joy_", "con_", "scr_" }; @@ -978,31 +988,8 @@ static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged ) // TODO: for cmd exceptions, make generic function if( cvar_active_filter_quirks ) { - const char *cur, *next; - - cur = cvar_active_filter_quirks->cvars; - next = Q_strchr( cur, ';' ); - - // TODO: implement Q_strchrnul - while( cur && *cur ) - { - size_t len = next ? next - cur : Q_strlen( cur ); - - // found, quit - if( !Q_strnicmp( cur, v->name, len )) - return true; - - if( next ) - { - cur = next + 1; - next = Q_strchr( cur, ';' ); - } - else - { - // stop - cur = NULL; - } - } + if( Q_splitstr((char *)cvar_active_filter_quirks->cvars, ';', v->name, ShouldSetCvar_splitstr_handler )) + return true; } if( FBitSet( v->flags, FCVAR_FILTERABLE )) diff --git a/engine/common/host.c b/engine/common/host.c index d6fe74f7..1c878327 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -889,41 +889,47 @@ static void Host_RunTests( int stage ) } #endif +static int Host_CheckBugcomp_splitstr_handler( char *prev, char *next, void *userdata ) +{ + size_t i; + uint32_t *flags = userdata; + + *next = '\0'; + + if( !COM_CheckStringEmpty( prev )) + return 0; + + for( i = 0; i < ARRAYSIZE( bugcomp_features ); i++ ) + { + if( !Q_stricmp( bugcomp_features[i].arg, prev )) + { + SetBits( *flags, bugcomp_features[i].mask ); + break; + } + } + + if( i == ARRAYSIZE( bugcomp_features )) + { + Con_Printf( S_ERROR "Unknown bugcomp flag %s\n", prev ); + Con_Printf( "Valid flags are:\n" ); + for( i = 0; i < ARRAYSIZE( bugcomp_features ); i++ ) + Con_Printf( "\t%s: %s\n", bugcomp_features[i].arg, bugcomp_features[i].msg ); + } + + return 0; +} + static uint32_t Host_CheckBugcomp( void ) { - const char *prev, *next; uint32_t flags = 0; - string args, arg; - size_t i; + string args; if( !Sys_CheckParm( "-bugcomp" )) return 0; if( Sys_GetParmFromCmdLine( "-bugcomp", args ) && isalpha( args[0] )) { - for( prev = args, next = Q_strchrnul( prev, '+' ); ; prev = next + 1, next = Q_strchrnul( prev, '+' )) - { - Q_strncpy( arg, prev, next - prev + 1 ); - for( i = 0; i < ARRAYSIZE( bugcomp_features ); i++ ) - { - if( !Q_stricmp( bugcomp_features[i].arg, arg )) - { - SetBits( flags, bugcomp_features[i].mask ); - break; - } - } - - if( i == ARRAYSIZE( bugcomp_features )) - { - Con_Printf( S_ERROR "Unknown bugcomp flag %s\n", arg ); - Con_Printf( "Valid flags are:\n" ); - for( i = 0; i < ARRAYSIZE( bugcomp_features ); i++ ) - Con_Printf( "\t%s: %s\n", bugcomp_features[i].arg, bugcomp_features[i].msg ); - } - - if( !*next ) - break; - } + Q_splitstr( args, '+', &flags, Host_CheckBugcomp_splitstr_handler ); } else { diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index cc120550..fccc60be 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -1910,6 +1910,32 @@ static void Mod_LoadSubmodels( model_t *mod, dbspmodel_t *bmod ) } } +static int Mod_LoadEntities_splitstr_handler( char *prev, char *next, void *userdata ) +{ + string token; + + *next = '\0'; + + if( !COM_CheckStringEmpty( prev )) + return 0; + + COM_FixSlashes( prev ); + COM_FileBase( prev, token, sizeof( token )); + + // make sure that wad is really exist + if( FS_FileExists( va( "%s.wad", token ), false )) + { + int num = world.wadlist.count++; + Q_strncpy( world.wadlist.wadnames[num], token, sizeof( world.wadlist.wadnames[0] )); + world.wadlist.wadusage[num] = 0; + } + + if( world.wadlist.count >= MAX_MAP_WADS ) + return 1; + + return 0; +} + /* ================= Mod_LoadEntities @@ -1917,23 +1943,22 @@ Mod_LoadEntities */ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod ) { - byte *entpatch = NULL; - char token[MAX_TOKEN]; - char wadstring[MAX_TOKEN]; - string keyname; - char *pfile; + byte *entpatch = NULL; + char token[MAX_TOKEN]; + string keyname; + char *pfile; if( bmod->isworld ) { - char entfilename[MAX_QPATH]; + char entfilename[MAX_QPATH]; fs_offset_t entpatchsize; - size_t ft1, ft2; + int ft1, ft2; - // world is check for entfile too + // if world check for entfile too Q_strncpy( entfilename, mod->name, sizeof( entfilename )); COM_ReplaceExtension( entfilename, ".ent", sizeof( entfilename )); - // make sure what entity patch is never than bsp + // make sure that entity patch is never than bsp ft1 = FS_FileTime( mod->name, false ); ft2 = FS_FileTime( entfilename, true ); @@ -1952,11 +1977,19 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod ) } } - // make sure what we really has terminator - mod->entities = Mem_Calloc( mod->mempool, bmod->entdatasize + 1 ); + // make sure that we really have null terminator + mod->entities = Mem_Malloc( mod->mempool, bmod->entdatasize + 1 ); memcpy( mod->entities, bmod->entdata, bmod->entdatasize ); // moving to private model pool - if( entpatch ) Mem_Free( entpatch ); // release entpatch if present - if( !bmod->isworld ) return; + mod->entities[bmod->entdatasize] = 0; + + if( entpatch ) + { + Mem_Free( entpatch ); // release entpatch if present + entpatch = NULL; + } + + if( !bmod->isworld ) + return; pfile = (char *)mod->entities; world.generator[0] = '\0'; @@ -1975,7 +2008,9 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod ) // parse key if(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) == NULL ) Host_Error( "%s: EOF without closing brace\n", __func__ ); - if( token[0] == '}' ) break; // end of desc + + if( token[0] == '}' ) + break; // end of desc Q_strncpy( keyname, token, sizeof( keyname )); @@ -1987,33 +2022,7 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod ) Host_Error( "%s: closing brace without data\n", __func__ ); if( !Q_stricmp( keyname, "wad" )) - { - char *pszWadFile; - - Q_strncpy( wadstring, token, sizeof( wadstring ) - 2 ); - wadstring[sizeof( wadstring ) - 2] = 0; - - if( !Q_strchr( wadstring, ';' )) - Q_strncat( wadstring, ";", sizeof( wadstring )); - - // parse wad pathes - for( pszWadFile = strtok( wadstring, ";" ); pszWadFile != NULL; pszWadFile = strtok( NULL, ";" )) - { - COM_FixSlashes( pszWadFile ); - COM_FileBase( pszWadFile, token, sizeof( token )); - - // make sure that wad is really exist - if( FS_FileExists( va( "%s.wad", token ), false )) - { - int num = world.wadlist.count++; - Q_strncpy( world.wadlist.wadnames[num], token, sizeof( world.wadlist.wadnames[0] )); - world.wadlist.wadusage[num] = 0; - } - - if( world.wadlist.count >= MAX_MAP_WADS ) - break; // too many wads... - } - } + Q_splitstr( token, ';', NULL, Mod_LoadEntities_splitstr_handler ); else if( !Q_stricmp( keyname, "message" )) Q_strncpy( world.message, token, sizeof( world.message )); else if( !Q_stricmp( keyname, "compiler" ) || !Q_stricmp( keyname, "_compiler" ))