diff --git a/public/crtlib.c b/public/crtlib.c index 796f2ca2..8be2e472 100644 --- a/public/crtlib.c +++ b/public/crtlib.c @@ -590,21 +590,13 @@ COM_StripExtension */ void COM_StripExtension( char *path ) { - size_t length; + const char *ext = COM_FileExtension( path ); - length = Q_strlen( path ); + if( COM_StringEmptyOrNULL( ext )) + return; // no extension - if( length > 0 ) - length--; - - while( length > 0 && path[length] != '.' ) - { - length--; - if( path[length] == '/' || path[length] == '\\' || path[length] == ':' ) - return; // no extension - } - - if( length ) path[length] = 0; + // ext points one past the dot + path[ext - path - 1] = 0; } /* @@ -614,21 +606,14 @@ COM_DefaultExtension */ void COM_DefaultExtension( char *path, const char *extension, size_t size ) { - const char *src; - size_t len; + size_t len; // if path doesn't have a .EXT, append extension // (extension should include the .) + if( !COM_StringEmptyOrNULL( COM_FileExtension( path ))) + return; + len = Q_strlen( path ); - src = path + len - 1; - - while( *src != '/' && src != path ) - { - // it has an extension - if( *src == '.' ) return; - src--; - } - Q_strncpy( &path[len], extension, size - len ); } diff --git a/public/tests/test_fileext.c b/public/tests/test_fileext.c index cac0021b..47bccb28 100644 --- a/public/tests/test_fileext.c +++ b/public/tests/test_fileext.c @@ -1,25 +1,113 @@ +#include "xash3d_mathlib.h" #include "crtlib.h" -int main( int argc, char **argv ) +static int Test_FileExtension( void ) { - int i; - const char *strings[] = + static const char *strings[][2] = { - "test.txt", "txt", - "path/to/file.wad", "wad", - "noext", "", - "dir/", "", - "dir.pk3dir/", "", - "https.proto://is_this_an_url?", "", - "inside.wad/AAATRIGGER", "", - "c:/games/gamedir/liblist.cum", "cum", + { "test.txt", "txt" }, + { "path/to/file.wad", "wad" }, + { "noext", "" }, + { "dir/", "" }, + { "dir.pk3dir/", "" }, + { "https.proto://is_this_an_url?", "" }, + { "inside.wad/AAATRIGGER", "" }, + { "c:/games/gamedir/liblist.cum", "cum" }, + { "", "" }, + { "trailingdot.", "" }, + { ".hidden", "hidden" }, + { "multi.dot.ext", "ext" }, + { "../relative/path", "" }, + { "../relative/file.bsp", "bsp" }, }; - for( i = 0; i < sizeof( strings ) / sizeof( strings[0] ); i += 2 ) + for( int i = 0; i < ARRAYSIZE( strings ); i++ ) { - if( Q_strcmp( COM_FileExtension( strings[i] ), strings[i + 1] )) - return i; + const char *got = COM_FileExtension( strings[i][0] ); + + if( Q_strcmp( got, strings[i][1] )) + return i + 1; } return 0; } + +static int Test_StripExtension( void ) +{ + static const char *strings[][2] = + { + { "test.txt", "test" }, + { "path/to/file.wad", "path/to/file" }, + { "noext", "noext" }, + { "dir/", "dir/" }, + { "dir.pk3dir/", "dir.pk3dir/" }, + { "inside.wad/AAATRIGGER", "inside.wad/AAATRIGGER" }, + { "https.proto://is_this_an_url?", "https.proto://is_this_an_url?" }, + { "c:/games/gamedir/liblist.cum", "c:/games/gamedir/liblist" }, + { "multi.dot.ext", "multi.dot" }, + { "trailingdot.", "trailingdot." }, + { ".hidden", "" }, + { "", "" }, + { "..", ".." }, + }; + + for( int i = 0; i < ARRAYSIZE( strings ); i++ ) + { + string s; + + Q_strncpy( s, strings[i][0], sizeof( s )); + COM_StripExtension( s ); + + if( Q_strcmp( s, strings[i][1] )) + return i + 1; + } + + return 0; +} + +static int Test_DefaultExtension( void ) +{ + static const char *strings[][3] = + { + { "file", ".bsp", "file.bsp" }, + { "path/to/file", ".wad", "path/to/file.wad" }, + { "file.txt", ".bsp", "file.txt" }, + { "path/to/file.bsp", ".wad", "path/to/file.bsp" }, + { "c:/games/gamedir/liblist.cum", ".bsp", "c:/games/gamedir/liblist.cum" }, + { "dir/", ".bsp", "dir/.bsp" }, + { "dir.pk3dir/", ".bsp", "dir.pk3dir/.bsp" }, + { "inside.wad/AAATRIGGER", ".bsp", "inside.wad/AAATRIGGER.bsp" }, + { "trailingdot.", ".bsp", "trailingdot..bsp" }, + { "", ".bsp", ".bsp" }, + }; + + for( int i = 0; i < ARRAYSIZE( strings ); i++ ) + { + string s; + + Q_strncpy( s, strings[i][0], sizeof( s )); + COM_DefaultExtension( s, strings[i][1], sizeof( s )); + + if( Q_strcmp( s, strings[i][2] )) + return i + 1; + } + + return 0; +} + +int main( int argc, char **argv ) +{ + int ret = Test_FileExtension(); + if( ret ) + return ret; + + ret = Test_StripExtension(); + if( ret ) + return ret + 32; + + ret = Test_DefaultExtension(); + if( ret ) + return ret + 64; + + return 0; +}