refactor paths related codes

This commit is contained in:
Garux 2020-01-24 02:47:33 +03:00
parent 437004713f
commit 80e95ac165
12 changed files with 132 additions and 191 deletions

View File

@ -413,7 +413,6 @@ static void ASE_SkipRestOfLine( void ){
static void ASE_KeyMAP_DIFFUSE( const char *token ){ static void ASE_KeyMAP_DIFFUSE( const char *token ){
char bitmap[1024]; char bitmap[1024];
char filename[1024]; char filename[1024];
int i = 0;
strcpy( filename, gl_filename ); strcpy( filename, gl_filename );
@ -429,36 +428,18 @@ static void ASE_KeyMAP_DIFFUSE( const char *token ){
} }
/* convert backslash to slash */ /* convert backslash to slash */
while ( bitmap[i] ) FixDOSName( bitmap );
{
if ( bitmap[i] == '\\' ) {
bitmap[i] = '/';
}
i++;
}
/* remove filename from path */ /* remove filename from path */
for ( i = strlen( filename ); i > 0; i-- ) strclear( path_get_last_separator( filename ) );
{
if ( filename[i] == '/' ) {
filename[i] = '\0';
break;
}
}
/* replaces a relative path with a full path */ /* replaces a relative path with a full path */
if ( bitmap[0] == '.' && bitmap[1] == '.' && bitmap[2] == '/' ) { if ( !strncmp( bitmap, "../", 3 ) ) {
while ( bitmap[0] == '.' && bitmap[1] == '.' && bitmap[2] == '/' ) while ( !strncmp( bitmap, "../", 3 ) )
{ {
/* remove last item from path */ /* remove last item from path */
for ( i = strlen( filename ); i > 0; i-- ) strclear( path_get_last_separator( filename ) );
{ memmove( bitmap, &bitmap[3], sizeof( bitmap ) - 3 );
if ( filename[i] == '/' ) {
filename[i] = '\0';
break;
}
}
strcpy( bitmap, &bitmap[3] );
} }
strcat( filename, "/" ); strcat( filename, "/" );
strcat( filename, bitmap ); strcat( filename, bitmap );
@ -467,7 +448,7 @@ static void ASE_KeyMAP_DIFFUSE( const char *token ){
if ( strstr( bitmap, gamedir ) ) { if ( strstr( bitmap, gamedir ) ) {
strcpy( ase.materials[ase.numMaterials].name, strstr( bitmap, gamedir ) + strlen( gamedir ) ); strcpy( ase.materials[ase.numMaterials].name, strstr( bitmap, gamedir ) + strlen( gamedir ) );
Sys_Printf( "material name: \'%s\'\n", strstr( bitmap, gamedir ) + strlen( gamedir ) ); Sys_Printf( "material name: \'%s\'\n", ase.materials[ase.numMaterials].name );
} }
else else
{ {

View File

@ -48,7 +48,6 @@
#endif #endif
#define BASEDIRNAME "quake" // assumed to have a 2 or 3 following #define BASEDIRNAME "quake" // assumed to have a 2 or 3 following
#define PATHSEPERATOR '/'
#ifdef SAFE_MALLOC #ifdef SAFE_MALLOC
// FIXME switch to -std=c99 or above to use proper %zu format specifier for size_t // FIXME switch to -std=c99 or above to use proper %zu format specifier for size_t
@ -166,16 +165,11 @@ char gamedir[1024];
char writedir[1024]; char writedir[1024];
void SetQdirFromPath( const char *path ){ void SetQdirFromPath( const char *path ){
char temp[1024];
const char *c; const char *c;
const char *sep; const char *sep;
int len, count; int len, count;
if ( !( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) ) { // path is partial path = ExpandArg( path );
Q_getwd( temp );
strcat( temp, path );
path = temp;
}
// search for "quake2" in path // search for "quake2" in path
@ -190,7 +184,7 @@ void SetQdirFromPath( const char *path ){
// so we need to add up how much to the next separator // so we need to add up how much to the next separator
sep = c + len; sep = c + len;
count = 1; count = 1;
while ( *sep && *sep != '/' && *sep != '\\' ) while ( !strempty( sep ) && !path_separator( *sep ) )
{ {
sep++; sep++;
count++; count++;
@ -202,17 +196,16 @@ void SetQdirFromPath( const char *path ){
c += len + count; c += len + count;
while ( *c ) while ( *c )
{ {
if ( *c == '/' || *c == '\\' ) { if ( path_separator( *c ) ) {
strncpy( gamedir, path, c + 1 - path ); strncpy( gamedir, path, c + 1 - path );
FixDOSName( gamedir ); FixDOSName( gamedir );
Sys_Printf( "gamedir: %s\n", gamedir ); Sys_Printf( "gamedir: %s\n", gamedir );
if ( !writedir[0] ) { if ( strempty( writedir ) ) {
strcpy( writedir, gamedir ); strcpy( writedir, gamedir );
} }
else if ( writedir[strlen( writedir ) - 1] != '/' ) { else{
writedir[strlen( writedir )] = '/'; path_add_slash( writedir );
writedir[strlen( writedir ) + 1] = 0;
} }
return; return;
@ -229,31 +222,27 @@ void SetQdirFromPath( const char *path ){
char *ExpandArg( const char *path ){ char *ExpandArg( const char *path ){
static char full[1024]; static char full[1024];
if ( path[0] != '/' && path[0] != '\\' && path[1] != ':' ) { if ( path_is_absolute( path ) ) {
Q_getwd( full ); strcpy( full, path );
strcat( full, path );
} }
else{ else{
strcpy( full, path ); Q_getwd( full );
strcat( full, path );
} }
return full; return full;
} }
char *ExpandPath( const char *path ){ char *ExpandPath( const char *path ){
static char full[1024]; static char full[1024];
if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) { if ( path_is_absolute( path ) ) {
strcpy( full, path ); strcpy( full, path );
return full;
} }
sprintf( full, "%s%s", qdir, path ); else{
sprintf( full, "%s%s", qdir, path );
}
return full; return full;
} }
char *copystring( const char *src ){
const size_t size = strlen( src ) + 1;
return memcpy( safe_malloc( size ), src, size );
}
/* /*
@ -287,14 +276,13 @@ double I_FloatTime( void ){
void Q_getwd( char *out ){ void Q_getwd( char *out ){
#ifdef WIN32 #ifdef WIN32
_getcwd( out, 256 ); _getcwd( out, 256 );
strcat( out, "\\" );
#else #else
// Gef: Changed from getwd() to getcwd() to avoid potential buffer overflow // Gef: Changed from getwd() to getcwd() to avoid potential buffer overflow
if ( !getcwd( out, 256 ) ) { if ( !getcwd( out, 256 ) ) {
*out = 0; strclear( out );
} }
strcat( out, "/" );
#endif #endif
path_add_slash( out );
FixDOSName( out ); FixDOSName( out );
} }
@ -306,29 +294,20 @@ void Q_mkdir( const char *path ){
while ( retry-- ) while ( retry-- )
{ {
#ifdef WIN32 #ifdef WIN32
const char *q = NULL;
if ( _mkdir( path ) != -1 ) { if ( _mkdir( path ) != -1 ) {
return; return;
} }
if ( errno == ENOENT ) {
p = strrchr( path, '/' );
q = strrchr( path, '\\' );
if ( q && ( !p || q < p ) ) {
p = q;
}
}
#else #else
if ( mkdir( path, 0777 ) != -1 ) { if ( mkdir( path, 0777 ) != -1 ) {
return; return;
} }
if ( errno == ENOENT ) {
p = strrchr( path, '/' );
}
#endif #endif
if ( p ) { if ( errno == ENOENT ) {
strncpy( parentbuf, path, sizeof( parentbuf ) ); p = path_get_last_separator( path );
if ( (int) ( p - path ) < (int) sizeof( parentbuf ) ) { }
parentbuf[p - path] = 0; if ( !strempty( p ) ) {
strcpyQ( parentbuf, path, p - path + 1 );
if ( ( p - path ) < (ptrdiff_t) sizeof( parentbuf ) ) {
Sys_Printf( "mkdir: %s: creating parent %s first\n", path, parentbuf ); Sys_Printf( "mkdir: %s: creating parent %s first\n", path, parentbuf );
Q_mkdir( parentbuf ); Q_mkdir( parentbuf );
continue; continue;
@ -337,7 +316,7 @@ void Q_mkdir( const char *path ){
break; break;
} }
if ( errno != EEXIST ) { if ( errno != EEXIST ) {
Error( "mkdir %s: %s",path, strerror( errno ) ); Error( "mkdir %s: %s", path, strerror( errno ) );
} }
} }
@ -436,15 +415,23 @@ skipwhite:
return data; return data;
} }
char *strlower( char *start ){
char *in;
in = start; //http://stackoverflow.com/questions/27303062/strstr-function-like-that-ignores-upper-or-lower-case
while ( *in ) //chux: Somewhat tricky to match the corner cases of strstr() with inputs like "x","", "","x", "",""
{ char *stristr( const char* haystack, const char* needle ) {
*in = tolower( *in ); do {
in++; const char* h = haystack;
} const char* n = needle;
return start; while ( tolower( (unsigned char)*h ) == tolower( (unsigned char)*n ) && *n ) {
h++;
n++;
}
if ( *n == 0 ) {
return (char *)haystack;
}
} while ( *haystack++ );
return 0;
} }
/* /*
@ -698,15 +685,23 @@ qboolean path_is_absolute( const char* path ){
#endif #endif
} }
static inline qboolean path_separator( const char c ){ /// \brief Returns a pointer to the last slash or to terminating null character if not found.
return c == '/' || c == '\\'; char* path_get_last_separator( const char* path ){
const char *end = path + strlen( path );
const char *src = end;
while ( src != path ){
if( path_separator( *--src ) )
return src;
}
return end;
} }
/// \brief Returns a pointer to the first character of the filename component of \p path. /// \brief Returns a pointer to the first character of the filename component of \p path.
char* path_get_filename_start( const char* path ){ char* path_get_filename_start( const char* path ){
const char *src = path + strlen( path ); const char *src = path + strlen( path );
while ( src != path && !path_separator( *( src - 1 ) ) ){ while ( src != path && !path_separator( src[-1] ) ){
--src; --src;
} }
return src; return src;
@ -717,10 +712,9 @@ char* path_get_filename_base_end( const char* path ){
const char *end = path + strlen( path ); const char *end = path + strlen( path );
const char *src = end; const char *src = end;
while ( src != path && !path_separator( *src ) ){ while ( src != path && !path_separator( *--src ) ){
if( *src == '.' ) if( *src == '.' )
return src; return src;
--src;
} }
return end; return end;
} }
@ -731,14 +725,20 @@ char* path_get_extension( const char* path ){
const char *end = path + strlen( path ); const char *end = path + strlen( path );
const char *src = end; const char *src = end;
while ( src != path && !path_separator( *src ) ){ while ( src != path && !path_separator( *--src ) ){
if( *src == '.' ) if( *src == '.' )
return src + 1; return src + 1;
--src;
} }
return end; return end;
} }
/// \brief Appends trailing slash, unless \p path is empty or already has slash.
void path_add_slash( char *path ){
char* end = path + strlen( path );
if ( end != path && !path_separator( end[-1] ) )
strcat( end, "/" );
}
// //
// if path doesnt have a .EXT, append extension // if path doesnt have a .EXT, append extension
// (extension should include the .) // (extension should include the .)
@ -1012,7 +1012,6 @@ unsigned short CRC_Value( unsigned short crcvalue ){
*/ */
void CreatePath( const char *path ){ void CreatePath( const char *path ){
const char *ofs; const char *ofs;
char c;
char dir[1024]; char dir[1024];
#ifdef _WIN32 #ifdef _WIN32
@ -1030,8 +1029,7 @@ void CreatePath( const char *path ){
for ( ofs = path + 1 ; *ofs ; ofs++ ) for ( ofs = path + 1 ; *ofs ; ofs++ )
{ {
c = *ofs; if ( path_separator( *ofs ) ) { // create the directory
if ( c == '/' || c == '\\' ) { // create the directory
memcpy( dir, path, ofs - path ); memcpy( dir, path, ofs - path );
dir[ ofs - path ] = 0; dir[ ofs - path ] = 0;
Q_mkdir( dir ); Q_mkdir( dir );

View File

@ -86,7 +86,16 @@ static inline qboolean strempty( const char* string ){
static inline void strclear( char* string ){ static inline void strclear( char* string ){
*string = '\0'; *string = '\0';
} }
char *strlower( char *in ); static inline char *strlower( char *string ){
for( char *in = string; *in; ++in )
*in = tolower( *in );
return string;
}
static inline char *copystring( const char *src ){ // version of strdup() with safe_malloc()
const size_t size = strlen( src ) + 1;
return memcpy( safe_malloc( size ), src, size );
}
char* stristr( const char* haystack, const char* needle );
#ifdef WIN32 #ifdef WIN32
#define Q_stricmp stricmp #define Q_stricmp stricmp
#define Q_strncasecmp strnicmp #define Q_strncasecmp strnicmp
@ -136,10 +145,16 @@ int TryLoadFile( const char *filename, void **bufferptr );
void SaveFile( const char *filename, const void *buffer, int count ); void SaveFile( const char *filename, const void *buffer, int count );
qboolean FileExists( const char *filename ); qboolean FileExists( const char *filename );
static inline qboolean path_separator( const char c ){
return c == '/' || c == '\\';
}
qboolean path_is_absolute( const char* path ); qboolean path_is_absolute( const char* path );
char* path_get_last_separator( const char* path );
char* path_get_filename_start( const char* path ); char* path_get_filename_start( const char* path );
char* path_get_filename_base_end( const char* path ); char* path_get_filename_base_end( const char* path );
char* path_get_extension( const char* path ); char* path_get_extension( const char* path );
void path_add_slash( char *path );
void DefaultExtension( char *path, const char *extension ); void DefaultExtension( char *path, const char *extension );
void DefaultPath( char *path, const char *basepath ); void DefaultPath( char *path, const char *basepath );
void StripFilename( char *path ); void StripFilename( char *path );
@ -170,8 +185,6 @@ char *COM_Parse( char *data );
extern char com_token[1024]; extern char com_token[1024];
extern qboolean com_eof; extern qboolean com_eof;
char *copystring( const char *src ); // version of strdup() with safe_malloc()
void CRC_Init( unsigned short *crcvalue ); void CRC_Init( unsigned short *crcvalue );
void CRC_ProcessByte( unsigned short *crcvalue, byte data ); void CRC_ProcessByte( unsigned short *crcvalue, byte data );

View File

@ -77,15 +77,6 @@ char g_strLoadedFileLocation[1024];
// ============================================================================= // =============================================================================
// Static functions // Static functions
static void vfsAddSlash( char *str ){
int n = strlen( str );
if ( n > 0 ) {
if ( str[n - 1] != '\\' && str[n - 1] != '/' ) {
strcat( str, "/" );
}
}
}
//!\todo Define globally or use heap-allocated string. //!\todo Define globally or use heap-allocated string.
#define NAME_MAX 255 #define NAME_MAX 255
@ -152,20 +143,14 @@ void vfsInitDirectory( const char *path ){
for ( j = 0; j < g_numForbiddenDirs; ++j ) for ( j = 0; j < g_numForbiddenDirs; ++j )
{ {
char* dbuf = g_strdup( path ); char* dbuf = strdup( path );
if ( *dbuf && dbuf[strlen( dbuf ) - 1] == '/' ) { if ( !strempty( dbuf ) && path_separator( dbuf[strlen( dbuf ) - 1] ) ) // del trailing slash
dbuf[strlen( dbuf ) - 1] = 0; strclear( &dbuf[strlen( dbuf ) - 1] );
if ( matchpattern( path_get_filename_start( dbuf ), g_strForbiddenDirs[j], TRUE ) ) {
free( dbuf );
return;
} }
const char *p = strrchr( dbuf, '/' ); free( dbuf );
p = ( p ? ( p + 1 ) : dbuf );
if ( matchpattern( p, g_strForbiddenDirs[j], TRUE ) ) {
g_free( dbuf );
break;
}
g_free( dbuf );
}
if ( j < g_numForbiddenDirs ) {
return;
} }
if ( g_numDirs == VFS_MAXDIRS ) { if ( g_numDirs == VFS_MAXDIRS ) {
@ -177,7 +162,7 @@ void vfsInitDirectory( const char *path ){
strncpy( g_strDirs[g_numDirs], path, PATH_MAX ); strncpy( g_strDirs[g_numDirs], path, PATH_MAX );
g_strDirs[g_numDirs][PATH_MAX] = 0; g_strDirs[g_numDirs][PATH_MAX] = 0;
FixDOSName( g_strDirs[g_numDirs] ); FixDOSName( g_strDirs[g_numDirs] );
vfsAddSlash( g_strDirs[g_numDirs] ); path_add_slash( g_strDirs[g_numDirs] );
g_numDirs++; g_numDirs++;
if ( g_bUsePak ) { if ( g_bUsePak ) {
@ -209,7 +194,7 @@ void vfsInitDirectory( const char *path ){
} }
snprintf( g_strDirs[g_numDirs], PATH_MAX, "%s/%s", path, name ); snprintf( g_strDirs[g_numDirs], PATH_MAX, "%s/%s", path, name );
FixDOSName( g_strDirs[g_numDirs] ); FixDOSName( g_strDirs[g_numDirs] );
vfsAddSlash( g_strDirs[g_numDirs] ); path_add_slash( g_strDirs[g_numDirs] );
++g_numDirs; ++g_numDirs;
} }
} }

View File

@ -586,9 +586,7 @@ void _3DS_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets,
strcpy( pPSET[i].name, _3ds.editChunk.pNamedObjects[i].name ); strcpy( pPSET[i].name, _3ds.editChunk.pNamedObjects[i].name );
strcpy( matnamebuf, filename ); strcpy( matnamebuf, filename );
if ( strrchr( matnamebuf, '/' ) ) { StripFilename( matnamebuf );
*( strrchr( matnamebuf, '/' ) + 1 ) = 0;
}
strcat( matnamebuf, pTO->pMeshMaterialGroups[0].name ); strcat( matnamebuf, pTO->pMeshMaterialGroups[0].name );
if ( strstr( matnamebuf, gamedir ) ) { if ( strstr( matnamebuf, gamedir ) ) {

View File

@ -45,7 +45,7 @@ void Cmd_Grab( void ){
GetToken( qfalse ); GetToken( qfalse );
if ( token[0] == '/' || token[0] == '\\' ) { if ( path_separator( token[0] ) ) {
sprintf( savename, "%s%s.pcx", writedir, token + 1 ); sprintf( savename, "%s%s.pcx", writedir, token + 1 );
} }
else{ else{
@ -53,7 +53,7 @@ void Cmd_Grab( void ){
} }
if ( g_release ) { if ( g_release ) {
if ( token[0] == '/' || token[0] == '\\' ) { if ( path_separator( token[0] ) ) {
sprintf( dest, "%s.pcx", token + 1 ); sprintf( dest, "%s.pcx", token + 1 );
} }
else{ else{

View File

@ -653,9 +653,7 @@ static void BuildBaseFrame( const char *filename, ObjectAnimationFrame_t *pOAF )
strcpy( shaderName, filename ); strcpy( shaderName, filename );
} }
if ( strrchr( shaderName, '/' ) ) StripFilename( shaderName );
*( strrchr( shaderName, '/' ) + 1 ) = 0;
strcpy( shaderName, pOAF->surfaces[i]->materialname ); strcpy( shaderName, pOAF->surfaces[i]->materialname );
*/ */
@ -724,22 +722,18 @@ static void BuildBaseFrame( const char *filename, ObjectAnimationFrame_t *pOAF )
} }
static int LoadModelFile( const char *filename, polyset_t **psets, int *numpolysets ){ static int LoadModelFile( const char *filename, polyset_t **psets, int *numpolysets ){
int time1;
char file1[1024]; char file1[1024];
const char *frameFile;
printf( "---------------------\n" ); printf( "---------------------\n" );
if ( filename[1] != ':' ) { if ( !path_is_absolute( filename ) ) {
frameFile = filename; sprintf( file1, "%s/%s", g_cddir, filename );
sprintf( file1, "%s/%s", g_cddir, frameFile );
} }
else else
{ {
strcpy( file1, filename ); strcpy( file1, filename );
} }
time1 = FileTime( file1 ); if ( FileTime( file1 ) == -1 ) {
if ( time1 == -1 ) {
Error( "%s doesn't exist", file1 ); Error( "%s doesn't exist", file1 );
} }
@ -1176,8 +1170,7 @@ void SkinFrom3DS( const char *filename ){
strcpy( name, filename ); strcpy( name, filename );
} }
if ( strrchr( name, '/' ) ) StripFilename( name );
*( strrchr( name, '/' ) + 1 ) = 0;
*/ */
strcpy( name, psets[i].materialname ); strcpy( name, psets[i].materialname );
strcpy( g_data.surfData[i].shaders[g_data.surfData[i].header.numShaders].name, name ); strcpy( g_data.surfData[i].shaders[g_data.surfData[i].header.numShaders].name, name );
@ -1902,9 +1895,7 @@ static void ConvertASE( const char *filename, int type, qboolean grabAnims ){
numSurfaces = GetSurfaceAnimations( surfaceAnimations, "u_", -1, -1, g_data.maxUpperFrames ); numSurfaces = GetSurfaceAnimations( surfaceAnimations, "u_", -1, -1, g_data.maxUpperFrames );
numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces );
strcpy( outfilename, filename ); strcpy( outfilename, filename );
if ( strrchr( outfilename, '/' ) ) { StripFilename( outfilename );
*( strrchr( outfilename, '/' ) + 1 ) = 0;
}
if ( g_data.currentLod == 0 ) { if ( g_data.currentLod == 0 ) {
strcat( outfilename, "upper.md3" ); strcat( outfilename, "upper.md3" );
@ -1936,9 +1927,7 @@ static void ConvertASE( const char *filename, int type, qboolean grabAnims ){
numSurfaces = GetSurfaceAnimations( surfaceAnimations, "l_", g_data.lowerSkipFrameStart, g_data.lowerSkipFrameEnd, -1 ); numSurfaces = GetSurfaceAnimations( surfaceAnimations, "l_", g_data.lowerSkipFrameStart, g_data.lowerSkipFrameEnd, -1 );
numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces );
strcpy( outfilename, filename ); strcpy( outfilename, filename );
if ( strrchr( outfilename, '/' ) ) { StripFilename( outfilename );
*( strrchr( outfilename, '/' ) + 1 ) = 0;
}
if ( g_data.currentLod == 0 ) { if ( g_data.currentLod == 0 ) {
strcat( outfilename, "lower.md3" ); strcat( outfilename, "lower.md3" );
@ -1969,9 +1958,7 @@ static void ConvertASE( const char *filename, int type, qboolean grabAnims ){
numSurfaces = GetSurfaceAnimations( surfaceAnimations, "h_", -1, -1, g_data.maxHeadFrames ); numSurfaces = GetSurfaceAnimations( surfaceAnimations, "h_", -1, -1, g_data.maxHeadFrames );
numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces );
strcpy( outfilename, filename ); strcpy( outfilename, filename );
if ( strrchr( outfilename, '/' ) ) { StripFilename( outfilename );
*( strrchr( outfilename, '/' ) + 1 ) = 0;
}
if ( g_data.currentLod == 0 ) { if ( g_data.currentLod == 0 ) {
strcat( outfilename, "head.md3" ); strcat( outfilename, "head.md3" );

View File

@ -29,9 +29,6 @@
#define MAX_POLYSETS 64 #define MAX_POLYSETS 64
#if defined ( __linux__ ) || defined ( __APPLE__ )
#define strlwr strlower
#endif
typedef struct typedef struct
{ {
long len; long len;

View File

@ -104,7 +104,7 @@ static inline void tex2list( StrList* texlist, StrList* EXtex, StrList* rEXtex )
Check if newcoming res is unique Check if newcoming res is unique
*/ */
static inline void res2list( StrList* list, const char* res ){ static inline void res2list( StrList* list, const char* res ){
while ( *res == '\\' || *res == '/' ){ // kill prepended slashes while ( path_separator( *res ) ){ // kill prepended slashes
++res; ++res;
} }
if ( *res == '\0') // empty if ( *res == '\0') // empty

View File

@ -174,10 +174,10 @@ static void ConvertShaderToMTL( FILE *f, bspShader_t *shader, int shaderNum ){
} }
/* blender hates this, so let's not do it /* blender hates this, so let's not do it
for( c = filename; *c != '\0'; c++ ) for( c = filename; *c != '\0'; c++ )
if( *c == '/' ) if( *c == '/' )
*c = '\\'; *c = '\\';
*/ */
/* print shader info */ /* print shader info */
fprintf( f, "newmtl %s\r\n", shader->shader ); fprintf( f, "newmtl %s\r\n", shader->shader );

View File

@ -436,19 +436,19 @@ void MiniMapMakeSampleOffsets(){
void MergeRelativePath( char *out, const char *absolute, const char *relative ){ void MergeRelativePath( char *out, const char *absolute, const char *relative ){
const char *endpos = absolute + strlen( absolute ); const char *endpos = absolute + strlen( absolute );
while ( endpos != absolute && ( endpos[-1] == '/' || endpos[-1] == '\\' ) ) while ( endpos != absolute && path_separator( endpos[-1] ) )
--endpos; --endpos;
while ( relative[0] == '.' && relative[1] == '.' && ( relative[2] == '/' || relative[2] == '\\' ) ) while ( !strncmp( relative, "../", 3 ) || !strncmp( relative, "..\\", 3 ) )
{ {
relative += 3; relative += 3;
while ( endpos != absolute ) while ( endpos != absolute )
{ {
--endpos; --endpos;
if ( *endpos == '/' || *endpos == '\\' ) { if ( path_separator( *endpos ) ) {
break; break;
} }
} }
while ( endpos != absolute && ( endpos[-1] == '/' || endpos[-1] == '\\' ) ) while ( endpos != absolute && path_separator( endpos[-1] ) )
--endpos; --endpos;
} }
memcpy( out, absolute, endpos - absolute ); memcpy( out, absolute, endpos - absolute );

View File

@ -101,20 +101,12 @@ char *LokiGetHomeDir( void ){
*/ */
void LokiInitPaths( char *argv0 ){ void LokiInitPaths( char *argv0 ){
char *home;
if ( !homePath ) { if ( !homePath ) {
/* get home dir */ /* get home dir */
home = LokiGetHomeDir(); homePath = LokiGetHomeDir();
if ( home == NULL ) { if ( homePath == NULL ) {
home = "."; homePath = ".";
} }
/* set home path */
homePath = home;
}
else{
home = homePath;
} }
#ifndef Q_UNIX #ifndef Q_UNIX
@ -131,10 +123,7 @@ void LokiInitPaths( char *argv0 ){
/* do some path divining */ /* do some path divining */
strcpyQ( temp, argv0, sizeof( temp ) ); strcpyQ( temp, argv0, sizeof( temp ) );
if ( strrchr( temp, '/' ) ) { if ( strempty( path_get_last_separator( temp ) ) && path ) {
argv0 = strrchr( argv0, '/' ) + 1;
}
else if ( path ) {
/* /*
This code has a special behavior when q3map2 is a symbolic link. This code has a special behavior when q3map2 is a symbolic link.
@ -158,10 +147,10 @@ void LokiInitPaths( char *argv0 ){
last = path; last = path;
/* go through each : segment of path */ /* go through each : segment of path */
while ( last[ 0 ] != '\0' && found == qfalse ) while ( !strempty( last ) && found == qfalse )
{ {
/* null out temp */ /* null out temp */
temp[ 0 ] = '\0'; strclear( temp );
/* find next chunk */ /* find next chunk */
last = strchr( path, ':' ); last = strchr( path, ':' );
@ -171,7 +160,7 @@ void LokiInitPaths( char *argv0 ){
/* found home dir candidate */ /* found home dir candidate */
if ( *path == '~' ) { if ( *path == '~' ) {
strcpyQ( temp, home, sizeof( temp ) ); strcpyQ( temp, homePath, sizeof( temp ) );
path++; path++;
} }
@ -197,8 +186,8 @@ void LokiInitPaths( char *argv0 ){
if "q3map2" is "/opt/radiant/tools/q3map2", if "q3map2" is "/opt/radiant/tools/q3map2",
installPath is "/opt/radiant" installPath is "/opt/radiant"
*/ */
*( strrchr( installPath, '/' ) ) = '\0'; strclear( path_get_last_separator( installPath ) );
*( strrchr( installPath, '/' ) ) = '\0'; strclear( path_get_last_separator( installPath ) );
} }
#endif #endif
} }
@ -382,7 +371,7 @@ void AddPakPath( char *path ){
*/ */
void InitPaths( int *argc, char **argv ){ void InitPaths( int *argc, char **argv ){
int i, j, k, len, len2; int i, j, k;
char temp[ MAX_OS_PATH ]; char temp[ MAX_OS_PATH ];
@ -514,28 +503,21 @@ void InitPaths( int *argc, char **argv ){
/* if there is no base path set, figure it out */ /* if there is no base path set, figure it out */
if ( numBasePaths == 0 ) { if ( numBasePaths == 0 ) {
/* this is another crappy replacement for SetQdirFromPath() */ /* this is another crappy replacement for SetQdirFromPath() */
len2 = strlen( game->magic );
for ( i = 0; i < *argc && numBasePaths == 0; i++ ) for ( i = 0; i < *argc && numBasePaths == 0; i++ )
{ {
/* extract the arg */ /* extract the arg */
strcpy( temp, argv[ i ] ); strcpy( temp, argv[ i ] );
FixDOSName( temp ); FixDOSName( temp );
len = strlen( temp );
Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i ); Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game->magic, temp, i );
/* check for the game's magic word */
/* this is slow, but only done once */ char* found = stristr( temp, game->magic );
for ( j = 0; j < ( len - len2 ); j++ ) if( found ){
{ /* now find the next slash and nuke everything after it */
/* check for the game's magic word */ found = strchr( found, '/' );
if ( Q_strncasecmp( &temp[ j ], game->magic, len2 ) == 0 ) { if( found )
/* now find the next slash and nuke everything after it */ strclear( found );
while ( temp[ ++j ] != '/' && temp[ j ] != '\0' ) ; /* add this as a base path */
temp[ j ] = '\0'; AddBasePath( temp );
/* add this as a base path */
AddBasePath( temp );
break;
}
} }
} }