diff --git a/idlib/Str.cpp b/idlib/Str.cpp index b37e1a9..4ccfb96 100644 --- a/idlib/Str.cpp +++ b/idlib/Str.cpp @@ -753,6 +753,26 @@ idStr &idStr::SetFileExtension( const char *extension ) { return *this; } +// DG: helper-function that returns true if the character c is a directory separator +// on the current platform +static ID_INLINE bool isDirSeparator( int c ) +{ + if ( c == '/' ) { + return true; + } +#ifdef _WIN32 + if ( c == '\\' ) { + return true; + } +#elif defined(__AROS__) + if ( c == ':' ) { + return true; + } +#endif + return false; +} +// DG end + /* ============ idStr::StripFileExtension @@ -762,6 +782,10 @@ idStr &idStr::StripFileExtension( void ) { int i; for ( i = len-1; i >= 0; i-- ) { + // DG: we're at a directory separator, nothing to strip at filename + if ( isDirSeparator( data[i] ) ) { + break; + } // DG end if ( data[i] == '.' ) { data[i] = '\0'; len = i; @@ -778,7 +802,9 @@ idStr::StripAbsoluteFileExtension */ idStr &idStr::StripAbsoluteFileExtension( void ) { int i; - + // FIXME DG: seems like this is unused, but it probably doesn't do what's expected + // (if you wanna strip .tar.gz this will fail with dots in path, + // if you indeed wanna strip the first dot in *path* (even in some directory) this is right) for ( i = 0; i < len; i++ ) { if ( data[i] == '.' ) { data[i] = '\0'; @@ -800,6 +826,10 @@ idStr &idStr::DefaultFileExtension( const char *extension ) { // do nothing if the string already has an extension for ( i = len-1; i >= 0; i-- ) { + // DG: we're at a directory separator, there was no file extension + if ( isDirSeparator( data[i] ) ) { + break; + } // DG end if ( data[i] == '.' ) { return *this; } @@ -817,11 +847,7 @@ idStr::DefaultPath ================== */ idStr &idStr::DefaultPath( const char *basepath ) { -#if defined(__AROS__) - if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) || ( ( *this )[ 0 ] == ':' ) ) { -#else - if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) ) { -#endif + if ( isDirSeparator( ( *this )[ 0 ] ) ) { // absolute path location return *this; } @@ -844,19 +870,12 @@ void idStr::AppendPath( const char *text ) { EnsureAlloced( len + strlen( text ) + 2 ); if ( pos ) { -#if defined(__AROS__) - if (( data[ pos-1 ] != '/' ) || ( data[ pos-1 ] != ':' )) { -#else - if ( data[ pos-1 ] != '/' ) { -#endif + if ( !isDirSeparator( data[ pos-1 ] ) ) { data[ pos++ ] = '/'; } } -#if defined(__AROS__) - if (( text[i] == '/' ) || ( text[i] == ':' )) { -#else - if ( text[i] == '/' ) { -#endif + + if ( isDirSeparator( text[ i ] ) ) { i++; } @@ -881,11 +900,7 @@ idStr &idStr::StripFilename( void ) { int pos; pos = Length() - 1; -#if defined(__AROS__) - while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) && ( ( *this )[ pos ] != ':' ) ) { -#else - while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) ) { -#endif + while( ( pos > 0 ) && !isDirSeparator( ( *this )[ pos ] ) ) { pos--; } @@ -906,11 +921,7 @@ idStr &idStr::StripPath( void ) { int pos; pos = Length(); -#if defined(__AROS__) - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) && ( ( *this )[ pos - 1 ] != ':' ) ) { -#else - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { -#endif + while( ( pos > 0 ) && !isDirSeparator( ( *this )[ pos - 1 ] ) ) { pos--; } @@ -930,11 +941,7 @@ void idStr::ExtractFilePath( idStr &dest ) const { // back up until a \ or the start // pos = Length(); -#if defined(__AROS__) - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) && ( ( *this )[ pos - 1 ] != ':' ) ) { -#else - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { -#endif + while( ( pos > 0 ) && !isDirSeparator( ( *this )[ pos - 1 ] ) ) { pos--; } @@ -953,11 +960,7 @@ void idStr::ExtractFileName( idStr &dest ) const { // back up until a \ or the start // pos = Length() - 1; -#if defined(__AROS__) - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) && ( ( *this )[ pos - 1 ] != ':' ) ) { -#else - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { -#endif + while( ( pos > 0 ) && !isDirSeparator( ( *this )[ pos - 1 ] ) ) { pos--; } @@ -977,11 +980,7 @@ void idStr::ExtractFileBase( idStr &dest ) const { // back up until a \ or the start // pos = Length() - 1; -#if defined(__AROS__) - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) && ( ( *this )[ pos - 1 ] != ':' ) ) { -#else - while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) { -#endif + while( ( pos > 0 ) && !isDirSeparator( ( *this )[ pos - 1 ] ) ) { pos--; } @@ -1007,6 +1006,10 @@ void idStr::ExtractFileExtension( idStr &dest ) const { pos = Length() - 1; while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '.' ) ) { pos--; + if( isDirSeparator( ( *this )[ pos ] ) ) { // DG: check for directory separator + // no extension in the whole filename + dest.Empty(); + } // DG end } if ( !pos ) {