diff --git a/libs/os/path.h b/libs/os/path.h index 2f4e2f56..60399705 100644 --- a/libs/os/path.h +++ b/libs/os/path.h @@ -113,32 +113,38 @@ inline const char* path_remove_directory( const char* path ){ return ""; } +inline bool path_separator( const char c ){ + return c == '/' || c == '\\'; +} + /// \brief Returns a pointer to the first character of the filename component of \p path. -/// O(n) inline const char* path_get_filename_start( const char* path ){ - { - const char* last_forward_slash = strrchr( path, '/' ); - if ( last_forward_slash != 0 ) { - return last_forward_slash + 1; - } - } + const char *src = path + string_length( path ); - // not strictly necessary,since paths should not contain '\' - { - const char* last_backward_slash = strrchr( path, '\\' ); - if ( last_backward_slash != 0 ) { - return last_backward_slash + 1; - } + while ( src != path && !path_separator( src[-1] ) ){ + --src; } + return src; +} - return path; +inline char* path_get_filename_start( char* path ){ + return const_cast( path_get_filename_start( const_cast( path ) ) ); } /// \brief Returns a pointer to the character after the end of the filename component of \p path - either the extension separator or the terminating null character. -/// O(n) inline const char* path_get_filename_base_end( const char* path ){ - const char* last_period = strrchr( path_get_filename_start( path ), '.' ); - return ( last_period != 0 ) ? last_period : path + string_length( path ); + const char *end = path + string_length( path ); + const char *src = end; + + while ( src != path && !path_separator( *--src ) ){ + if( *src == '.' ) + return src; + } + return end; +} + +inline char* path_get_filename_base_end( char* path ){ + return const_cast( path_get_filename_base_end( const_cast( path ) ) ); } /// \brief Returns the length of the filename component (not including extension) of \p path. @@ -157,14 +163,20 @@ inline const char* path_make_relative( const char* path, const char* base ){ return path; } -/// \brief Returns a pointer to the first character of the file extension of \p path, or "" if not found. -/// O(n) +/// \brief Returns a pointer to the first character of the file extension of \p path, or to terminating null character if not found. inline const char* path_get_extension( const char* path ){ - const char* last_period = strrchr( path_get_filename_start( path ), '.' ); - if ( last_period != 0 ) { - return ++last_period; + const char *end = path + string_length( path ); + const char *src = end; + + while ( src != path && !path_separator( *--src ) ){ + if( *src == '.' ) + return src + 1; } - return ""; + return end; +} + +inline char* path_get_extension( char* path ){ + return const_cast( path_get_extension( const_cast( path ) ) ); } /// \brief Returns true if \p extension is of the same type as \p other. diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 9692e794..f28dc90f 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -1384,13 +1384,7 @@ void BackgroundImage::set( const VIEWTYPE viewtype ){ free_tex(); const char *filename = background_image_dialog(); if( filename ){ - StringOutputStream filename_noext( 1024 ); - const char* ext = path_get_extension( filename ); - if( string_empty( ext ) ) - filename_noext << filename; - else - filename_noext << StringRange( filename, ext - 1 ); - + const auto filename_noext = StringOutputStream( 256 )( StringRange( filename, path_get_filename_base_end( filename ) ) ); Image *image = QERApp_LoadImage( 0, filename_noext.c_str() ); if ( !image ) { globalErrorStream() << "Could not load texture " << filename_noext.c_str() << "\n"; diff --git a/tools/quake3/common/cmdlib.cpp b/tools/quake3/common/cmdlib.cpp index 38b07f58..ab24a341 100644 --- a/tools/quake3/common/cmdlib.cpp +++ b/tools/quake3/common/cmdlib.cpp @@ -564,16 +564,6 @@ void SaveFile( const char *filename, const void *buffer, int count ){ ==================== */ -/// \brief Returns true if \p path is a fully qualified file-system path. -bool path_is_absolute( const char* path ){ -#if defined( WIN32 ) - return path[0] == '/' - || ( path[0] != '\0' && path[1] == ':' ); // local drive -#elif defined( POSIX ) - return path[0] == '/'; -#endif -} - /// \brief Returns a pointer to the last slash or to terminating null character if not found. const char* path_get_last_separator( const char* path ){ const char *end = path + strlen( path ); @@ -590,52 +580,6 @@ char* path_get_last_separator( char* path ){ return const_cast( path_get_last_separator( const_cast( path ) ) ); } -/// \brief Returns a pointer to the first character of the filename component of \p path. -const char* path_get_filename_start( const char* path ){ - const char *src = path + strlen( path ); - - while ( src != path && !path_separator( src[-1] ) ){ - --src; - } - return src; -} - -char* path_get_filename_start( char* path ){ - return const_cast( path_get_filename_start( const_cast( path ) ) ); -} - -/// \brief Returns a pointer to the character after the end of the filename component of \p path - either the extension separator or the terminating null character. -const char* path_get_filename_base_end( const char* path ){ - const char *end = path + strlen( path ); - const char *src = end; - - while ( src != path && !path_separator( *--src ) ){ - if( *src == '.' ) - return src; - } - return end; -} - -char* path_get_filename_base_end( char* path ){ - return const_cast( path_get_filename_base_end( const_cast( path ) ) ); -} - -/// \brief Returns a pointer to the first character of the file extension of \p path, or to terminating null character if not found. -const char* path_get_extension( const char* path ){ - const char *end = path + strlen( path ); - const char *src = end; - - while ( src != path && !path_separator( *--src ) ){ - if( *src == '.' ) - return src + 1; - } - return end; -} - -char* path_get_extension( char* path ){ - return const_cast( path_get_extension( const_cast( path ) ) ); -} - /// \brief Appends trailing slash, unless \p path is empty or already has slash. void path_add_slash( char *path ){ char* end = path + strlen( path ); diff --git a/tools/quake3/common/cmdlib.h b/tools/quake3/common/cmdlib.h index 0a658b84..69ee7c86 100644 --- a/tools/quake3/common/cmdlib.h +++ b/tools/quake3/common/cmdlib.h @@ -46,6 +46,8 @@ #include #include +#include "os/path.h" + #ifdef _MSC_VER #pragma intrinsic( memset, memcpy ) @@ -185,18 +187,8 @@ void SaveFile( const char *filename, const void *buffer, int count ); bool FileExists( const char *filename ); -static inline bool path_separator( const char c ){ - return c == '/' || c == '\\'; -} -bool path_is_absolute( const char* path ); const char* path_get_last_separator( const char* path ); char* path_get_last_separator( char* path ); -const char* path_get_filename_start( const char* path ); - char* path_get_filename_start( char* path ); -const char* path_get_filename_base_end( const char* path ); - char* path_get_filename_base_end( char* path ); -const char* path_get_extension( const char* path ); - char* path_get_extension( char* path ); void path_add_slash( char *path ); void path_set_extension( char *path, const char *extension ); void DefaultExtension( char *path, const char *extension );