separate path manipulating functions

unlimit VFS_MAXDIRS
This commit is contained in:
Garux 2021-09-15 08:07:05 +03:00
parent e1186dd734
commit 97ad9bf5c5
17 changed files with 177 additions and 255 deletions

View File

@ -272,8 +272,7 @@ TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Direct
ostream << *i;
}
}
--i;
if ( *i != '/' && *i != '\\' ) {
if ( !path_separator( *--i ) ) {
ostream << '/';
}
}

View File

@ -24,6 +24,7 @@
#include "cmdlib.h"
#include "inout.h"
#include "qstringops.h"
#include "qpathops.h"
#include <assert.h>
#include <stdio.h>

View File

@ -31,8 +31,10 @@
#include "cmdlib.h"
#include "inout.h"
#include "qstringops.h"
#include "qpathops.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#ifdef WIN32
#include <direct.h>
@ -424,35 +426,6 @@ int LoadFile( const char *filename, void **bufferptr ){
}
/*
==============
LoadFileBlock
-
rounds up memory allocation to 4K boundary
-
==============
*/
int LoadFileBlock( const char *filename, void **bufferptr ){
FILE *f;
int length, nBlock, nAllocSize;
void *buffer;
f = SafeOpenRead( filename );
length = Q_filelength( f );
nAllocSize = length;
nBlock = nAllocSize % MEM_BLOCKSIZE;
if ( nBlock > 0 ) {
nAllocSize += MEM_BLOCKSIZE - nBlock;
}
buffer = safe_calloc( nAllocSize + 1 );
SafeRead( f, buffer, length );
fclose( f );
*bufferptr = buffer;
return length;
}
/*
==============
TryLoadFile
@ -496,86 +469,6 @@ void SaveFile( const char *filename, const void *buffer, int count ){
}
/*
====================
Extract file parts
====================
*/
/// \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 );
const char *src = end;
while ( src != path ){
if( path_separator( *--src ) )
return src;
}
return end;
}
char* path_get_last_separator( char* path ){
return const_cast<char*>( path_get_last_separator( const_cast<const char*>( 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 );
if ( end != path && !path_separator( end[-1] ) )
strcat( end, "/" );
}
/// \brief Appends or replaces .EXT part of \p path with \p extension.
void path_set_extension( char *path, const char *extension ){
strcpy( path_get_filename_base_end( path ), extension );
}
//
// if path doesnt have a .EXT, append extension
// (extension should include the .)
//
void DefaultExtension( char *path, const char *extension ){
char* ext = path_get_filename_base_end( path );
if( strEmpty( ext ) )
strcpy( ext, extension );
}
void DefaultPath( char *path, const char *basepath ){
if( !path_is_absolute( path ) ){
char* temp = strdup( path );
sprintf( path, "%s%s", basepath, temp );
free( temp );
}
}
void StripFilename( char *path ){
strClear( path_get_filename_start( path ) );
}
void StripExtension( char *path ){
strClear( path_get_filename_base_end( path ) );
}
// NOTE: includes the slash, otherwise
// backing to an empty path will be wrong when appending a slash
void ExtractFilePath( const char *path, char *dest ){
strcpyQ( dest, path, path_get_filename_start( path ) - path + 1 ); // +1 for '\0'
}
void ExtractFileBase( const char *path, char *dest ){
const char* start = path_get_filename_start( path );
const char* end = path_get_filename_base_end( start );
strcpyQ( dest, start, end - start + 1 ); // +1 for '\0'
}
void ExtractFileExtension( const char *path, char *dest ){
strcpy( dest, path_get_extension( path ) );
}
/*
==============
ParseNum / ParseHex

View File

@ -21,38 +21,12 @@
// cmdlib.h
#ifndef __CMDLIB__
#define __CMDLIB__
#pragma once
#include "bytebool.h"
#ifdef _MSC_VER
#pragma warning(disable : 4244) // MIPS
#pragma warning(disable : 4136) // X86
#pragma warning(disable : 4051) // ALPHA
#pragma warning(disable : 4018) // signed/unsigned mismatch
#pragma warning(disable : 4305) // truncate from double to float
#pragma check_stack(off)
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>
#include "os/path.h"
#ifdef _MSC_VER
#pragma intrinsic( memset, memcpy )
#endif
#ifdef PATH_MAX
@ -60,7 +34,6 @@
#else
#define MAX_OS_PATH 4096
#endif
#define MEM_BLOCKSIZE 4096
#define SAFE_MALLOC
#ifdef SAFE_MALLOC
@ -115,31 +88,11 @@ void SafeRead( FILE *f, void *buffer, int count );
void SafeWrite( FILE *f, const void *buffer, int count );
int LoadFile( const char *filename, void **bufferptr );
int LoadFileBlock( const char *filename, void **bufferptr );
int TryLoadFile( const char *filename, void **bufferptr );
void SaveFile( const char *filename, const void *buffer, int count );
bool FileExists( const char *filename );
const char* path_get_last_separator( const char* path );
char* path_get_last_separator( char* path );
void path_add_slash( char *path );
void path_set_extension( char *path, const char *extension );
void DefaultExtension( char *path, const char *extension );
void DefaultPath( char *path, const char *basepath );
void StripFilename( char *path );
void StripExtension( char *path );
static inline void FixDOSName( char *src ){
for ( ; *src; ++src )
if ( *src == '\\' )
*src = '/';
}
void ExtractFilePath( const char *path, char *dest ); // file directory with trailing slash
void ExtractFileBase( const char *path, char *dest ); // file name w/o extension
void ExtractFileExtension( const char *path, char *dest );
int ParseNum( const char *str );
short BigShort( short l );
@ -159,13 +112,3 @@ void QCopyFile( const char *from, const char *to );
// sleep for the given amount of milliseconds
void Sys_Sleep( int n );
// for compression routines
typedef struct
{
void *data;
int count, width, height;
} cblock_t;
#endif

View File

@ -24,6 +24,7 @@
#include "inout.h"
#include "cmdlib.h"
#include "qstringops.h"
#include "qpathops.h"
#include "etclib.h"
#include "imagelib.h"
#include "vfs.h"

View File

@ -30,6 +30,7 @@
#include "inout.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <algorithm>
#include "generic/vector.h"
#ifdef WIN32

View File

@ -21,6 +21,7 @@
#include <stddef.h>
#include <cstring>
#include "cmdlib.h"
#include "inout.h"

View File

@ -0,0 +1,105 @@
/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// cmdlib.h
#pragma once
#include "os/path.h"
#include "qstringops.h"
/*
====================
Extract file parts
====================
*/
/// \brief Returns a pointer to the last slash or to terminating null character if not found.
inline const 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;
}
inline char* path_get_last_separator( char* path ){
return const_cast<char*>( path_get_last_separator( const_cast<const char*>( path ) ) );
}
/// \brief Appends trailing slash, unless \p path is empty or already has slash.
inline void path_add_slash( char *path ){
char* end = path + strlen( path );
if ( end != path && !path_separator( end[-1] ) )
strcat( end, "/" );
}
/// \brief Appends or replaces .EXT part of \p path with \p extension.
inline void path_set_extension( char *path, const char *extension ){
strcpy( path_get_filename_base_end( path ), extension );
}
//
// if path doesnt have a .EXT, append extension
// (extension should include the .)
//
inline void DefaultExtension( char *path, const char *extension ){
char* ext = path_get_filename_base_end( path );
if( strEmpty( ext ) )
strcpy( ext, extension );
}
inline void StripFilename( char *path ){
strClear( path_get_filename_start( path ) );
}
inline void StripExtension( char *path ){
strClear( path_get_filename_base_end( path ) );
}
inline void FixDOSName( char *src ){
for ( ; *src; ++src )
if ( *src == '\\' )
*src = '/';
}
// file directory with trailing slash
// NOTE: includes the slash, otherwise
// backing to an empty path will be wrong when appending a slash
inline void ExtractFilePath( const char *path, char *dest ){
strcpyQ( dest, path, path_get_filename_start( path ) - path + 1 ); // +1 for '\0'
}
// file name w/o extension
inline void ExtractFileBase( const char *path, char *dest ){
const char* start = path_get_filename_start( path );
const char* end = path_get_filename_base_end( start );
strcpyQ( dest, start, end - start + 1 ); // +1 for '\0'
}
inline void ExtractFileExtension( const char *path, char *dest ){
strcpy( dest, path_get_extension( path ) );
}

View File

@ -24,6 +24,7 @@
#include "cmdlib.h"
#include "inout.h"
#include "qstringops.h"
#include "qpathops.h"
#include "scriplib.h"
#include "vfs.h"

View File

@ -41,12 +41,27 @@
// Leonardo Zide (leo@lokigames.com)
//
#if defined ( __linux__ ) || defined ( __APPLE__ )
#include <dirent.h>
#include <unistd.h>
#include <limits.h>
#else
#include <io.h>
#ifndef R_OK
#define R_OK 04
#endif
#endif
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <glib.h>
#include "cmdlib.h"
#include "qstringops.h"
#include "qpathops.h"
#include "filematch.h"
#include "inout.h"
#include "vfs.h"
@ -80,10 +95,8 @@ struct VFS_PAKFILE
static std::forward_list<VFS_PAK> g_paks;
static std::forward_list<VFS_PAKFILE> g_pakFiles;
static char g_strDirs[VFS_MAXDIRS][PATH_MAX + 1];
static int g_numDirs;
char g_strForbiddenDirs[VFS_MAXDIRS][PATH_MAX + 1];
int g_numForbiddenDirs = 0;
static std::vector<CopiedString> g_strDirs;
std::vector<CopiedString> g_strForbiddenDirs;
static constexpr bool g_bUsePak = true;
char g_strLoadedFileLocation[1024];
@ -147,31 +160,26 @@ static void vfsInitPakFile( const char *filename ){
// reads all pak files from a dir
void vfsInitDirectory( const char *path ){
GDir *dir;
int j;
for ( j = 0; j < g_numForbiddenDirs; ++j )
const auto path_is_forbidden = []( const char *path ){
for ( const auto& forbidden : g_strForbiddenDirs )
if ( matchpattern( path_get_filename_start( path ), forbidden.c_str(), TRUE ) )
return true;
return false;
};
{
char* dbuf = strdup( path );
if ( !strEmpty( dbuf ) && path_separator( dbuf[strlen( dbuf ) - 1] ) ) // del trailing slash
strClear( &dbuf[strlen( dbuf ) - 1] );
if ( matchpattern( path_get_filename_start( dbuf ), g_strForbiddenDirs[j], TRUE ) ) {
free( dbuf );
StringBuffer buf( path );
if ( !buf.empty() && path_separator( buf.back() ) ) // del trailing slash
buf.pop_back();
if ( path_is_forbidden( buf.c_str() ) )
return;
}
free( dbuf );
}
if ( g_numDirs == VFS_MAXDIRS ) {
return;
}
Sys_Printf( "VFS Init: %s\n", path );
strncpy( g_strDirs[g_numDirs], path, PATH_MAX );
g_strDirs[g_numDirs][PATH_MAX] = 0;
FixDOSName( g_strDirs[g_numDirs] );
path_add_slash( g_strDirs[g_numDirs] );
g_numDirs++;
// clean and store copy to be safe of original's reallocation
const CopiedString pathCleaned = g_strDirs.emplace_back( StringOutputStream( 256 )( DirectoryCleaned( path ) ) );
if ( g_bUsePak ) {
dir = g_dir_open( path, 0, NULL );
@ -181,29 +189,16 @@ void vfsInitDirectory( const char *path ){
const char* name;
while ( ( name = g_dir_read_name( dir ) ) )
{
for ( j = 0; j < g_numForbiddenDirs; ++j )
{
if ( matchpattern( path_get_filename_start( name ), g_strForbiddenDirs[j], TRUE ) ) {
break;
}
}
if ( j < g_numForbiddenDirs ) {
if ( path_is_forbidden( name ) )
continue;
}
const char *ext = path_get_filename_base_end( name );
if ( striEqual( ext, ".pk3" ) ) {
paks.push_back( StringOutputStream( 256 )( path, '/', name ) );
paks.push_back( StringOutputStream( 256 )( pathCleaned.c_str(), name ) );
}
else if ( striEqual( ext, ".pk3dir" ) ) {
if ( g_numDirs == VFS_MAXDIRS ) {
continue;
}
snprintf( g_strDirs[g_numDirs], PATH_MAX, "%s/%s", path, name );
FixDOSName( g_strDirs[g_numDirs] );
path_add_slash( g_strDirs[g_numDirs] );
++g_numDirs;
g_strDirs.emplace_back( StringOutputStream( 256 )( pathCleaned.c_str(), name, '/' ) );
}
}
g_dir_close( dir );
@ -233,8 +228,8 @@ std::vector<CopiedString> vfsListShaderFiles( const char *shaderPath ){
list.emplace_back( name );
};
/* search in dirs */
for ( int i = 0; i < g_numDirs; i++ ){
GDir *dir = g_dir_open( StringOutputStream( 256 )( g_strDirs[ i ], shaderPath, "/" ), 0, NULL );
for ( const auto& strdir : g_strDirs ){
GDir *dir = g_dir_open( StringOutputStream( 256 )( strdir.c_str(), shaderPath, "/" ), 0, NULL );
if ( dir != NULL ) {
const char* name;
@ -268,7 +263,7 @@ void vfsShutdown(){
// return the number of files that match
int vfsGetFileCount( const char *filename ){
int i, count = 0;
int count = 0;
char fixed[NAME_MAX], tmp[NAME_MAX];
strcpy( fixed, filename );
@ -282,9 +277,9 @@ int vfsGetFileCount( const char *filename ){
}
}
for ( i = 0; i < g_numDirs; i++ )
for ( const auto& dir : g_strDirs )
{
strcpy( tmp, g_strDirs[i] );
strcpy( tmp, dir.c_str() );
strcat( tmp, fixed );
if ( access( tmp, R_OK ) == 0 ) {
count++;
@ -296,7 +291,7 @@ int vfsGetFileCount( const char *filename ){
// NOTE: when loading a file, you have to allocate one extra byte and set it to \0
int vfsLoadFile( const char *filename, void **bufferptr, int index ){
int i, count = 0;
int count = 0;
char tmp[NAME_MAX], fixed[NAME_MAX];
// filename is a full path
@ -331,9 +326,9 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){
FixDOSName( fixed );
strLower( fixed );
for ( i = 0; i < g_numDirs; i++ )
for ( const auto& dir : g_strDirs )
{
strcpy( tmp, g_strDirs[i] );
strcpy( tmp, dir.c_str() );
strcat( tmp, filename );
if ( access( tmp, R_OK ) == 0 ) {
if ( count == index ) {
@ -386,9 +381,9 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){
// we need to end the buffer with a 0
( (char*) ( *bufferptr ) )[file.size] = 0;
i = unzReadCurrentFile( zipfile, *bufferptr, file.size );
const int size = unzReadCurrentFile( zipfile, *bufferptr, file.size );
unzCloseCurrentFile( zipfile );
if ( i < 0 ) {
if ( size < 0 ) {
return -1;
}
else{
@ -406,7 +401,6 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){
bool vfsPackFile( const char *filename, const char *packname, const int compLevel ){
int i;
char tmp[NAME_MAX], fixed[NAME_MAX];
byte *bufferptr = NULL;
@ -414,9 +408,9 @@ bool vfsPackFile( const char *filename, const char *packname, const int compLeve
FixDOSName( fixed );
strLower( fixed );
for ( i = 0; i < g_numDirs; i++ )
for ( const auto& dir : g_strDirs )
{
strcpy( tmp, g_strDirs[i] );
strcpy( tmp, dir.c_str() );
strcat( tmp, filename );
if ( access( tmp, R_OK ) == 0 ) {
if ( access( packname, R_OK ) == 0 ) {
@ -468,14 +462,14 @@ bool vfsPackFile( const char *filename, const char *packname, const int compLeve
// we need to end the buffer with a 0
bufferptr[file.size] = 0;
i = unzReadCurrentFile( zipfile, bufferptr, file.size );
const int size = unzReadCurrentFile( zipfile, bufferptr, file.size );
unzCloseCurrentFile( zipfile );
if ( i < 0 ) {
if ( size < 0 ) {
return false;
}
else{
mz_bool success = MZ_TRUE;
success &= mz_zip_add_mem_to_archive_file_in_place_with_time( packname, filename, bufferptr, i, 0, 0, compLevel, file.zipinfo.cur_file_info.dosDate );
success &= mz_zip_add_mem_to_archive_file_in_place_with_time( packname, filename, bufferptr, size, 0, 0, compLevel, file.zipinfo.cur_file_info.dosDate );
if ( !success ){
Error( "Failed creating zip archive \"%s\"!\n", packname );
}

View File

@ -28,29 +28,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _VFS_H_
#define _VFS_H_
// to get PATH_MAX
#include <stdio.h>
#if defined ( __linux__ ) || defined ( __APPLE__ )
#include <dirent.h>
#include <unistd.h>
#include <limits.h>
#else
#include <wtypes.h>
#include <io.h>
#ifndef R_OK
#define R_OK 04
#endif
//#define S_ISDIR( mode ) ( mode & _S_IFDIR )
#define PATH_MAX 260
#endif
#include <glib.h>
#define VFS_MAXDIRS 64
#pragma once
void vfsInitDirectory( const char *path );
void vfsShutdown();
@ -60,8 +38,5 @@ std::vector<CopiedString> vfsListShaderFiles( const char *shaderPath );
bool vfsPackFile( const char *filename, const char *packname, const int compLevel );
bool vfsPackFile_Absolute_Path( const char *filepath, const char *filename, const char *packname, const int compLevel );
extern char g_strForbiddenDirs[VFS_MAXDIRS][PATH_MAX + 1];
extern int g_numForbiddenDirs;
extern std::vector<CopiedString> g_strForbiddenDirs;
extern char g_strLoadedFileLocation[1024];
#endif // _VFS_H_

View File

@ -22,6 +22,7 @@
#include "md3lib.h"
#include "inout.h"
#include "../common/cmdlib.h"
#include <cstring>
/*
** MD3_ComputeTagFromTri

View File

@ -27,6 +27,7 @@
#include "../common/cmdlib.h"
#include "../common/qstringops.h"
#include "../common/qpathops.h"
#define MAX_POLYSETS 64

View File

@ -31,6 +31,7 @@
#include "../common/cmdlib.h"
#include "../common/inout.h"
#include "../common/qstringops.h"
#include "../common/qpathops.h"
#include "scriplib.h"
#include "mathlib.h"
#include "polyset.h"

View File

@ -20,6 +20,7 @@
*/
#include <assert.h>
#include <time.h>
#include "q3data.h"
static int s_resample_width = 256;
@ -39,6 +40,13 @@ static byte *s_soundtrack;
static char s_base[32];
static char s_output_base[32];
// for compression routines
typedef struct
{
void *data;
int count, width, height;
} cblock_t;
/*
===============================================================================

View File

@ -401,11 +401,7 @@ void InitPaths( int *argc, char **argv ){
Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
}
argv[ i - 1 ] = NULL;
if ( g_numForbiddenDirs < VFS_MAXDIRS ) {
strncpy( g_strForbiddenDirs[g_numForbiddenDirs], argv[i], PATH_MAX );
g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = 0;
++g_numForbiddenDirs;
}
g_strForbiddenDirs.emplace_back( argv[i] );
argv[ i ] = NULL;
}

View File

@ -70,6 +70,7 @@
#include "cmdlib.h"
#include "qstringops.h"
#include "qpathops.h"
#include "md5lib.h"
#include "ddslib.h"