manage path routines
This commit is contained in:
parent
b0e62198ba
commit
d734199601
|
|
@ -207,34 +207,36 @@ inline MatchFileExtension<Functor> matchFileExtension( const char* extension, co
|
|||
return MatchFileExtension<Functor>( extension, functor );
|
||||
}
|
||||
|
||||
class PathExtensionless
|
||||
{
|
||||
public:
|
||||
const char* m_path;
|
||||
PathExtensionless( const char* path ) : m_path( path ){
|
||||
/// \brief Returns portion of \p path without .ext part.
|
||||
inline StringRange PathExtensionless( const char *path ){
|
||||
return StringRange( path, path_get_filename_base_end( path ) );
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Writes \p path to \p ostream without .ext part.
|
||||
template<typename TextOutputStreamType>
|
||||
TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const PathExtensionless& path ){
|
||||
ostream << StringRange( path.m_path, path_get_filename_base_end( path.m_path ) );
|
||||
return ostream;
|
||||
/// \brief Returns portion of \p path without directory and .ext parts.
|
||||
inline StringRange PathFilename( const char *path ){
|
||||
return StringRange( path_get_filename_start( path ), path_get_filename_base_end( path ) );
|
||||
}
|
||||
|
||||
/// \brief Returns portion of \p path without filename part.
|
||||
inline StringRange PathFilenameless( const char *path ){
|
||||
return StringRange( path, path_get_filename_start( path ) );
|
||||
}
|
||||
|
||||
class PathCleaned
|
||||
{
|
||||
public:
|
||||
const char* m_path;
|
||||
PathCleaned( const char* path ) : m_path( path ){
|
||||
const char* m_end;
|
||||
PathCleaned( const char* path ) : m_path( path ), m_end( path + std::strlen( path ) ){
|
||||
}
|
||||
PathCleaned( const StringRange& range ) : m_path( range.first ), m_end( range.last ){
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Writes \p path to \p ostream with dos-style separators replaced by unix-style separators.
|
||||
template<typename TextOutputStreamType>
|
||||
TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const PathCleaned& path ){
|
||||
const char* i = path.m_path;
|
||||
for (; *i != '\0'; ++i )
|
||||
for ( const char* i = path.m_path; i != path.m_end; ++i )
|
||||
{
|
||||
if ( *i == '\\' ) {
|
||||
ostream << '/';
|
||||
|
|
|
|||
|
|
@ -67,9 +67,7 @@ class RemapKeysObserver : public Entity::Observer, public ModelSkin
|
|||
const char* split = strchr( value, ';' );
|
||||
if( split != nullptr ){
|
||||
m_from = { value, split };
|
||||
StringOutputStream stream( 64 );
|
||||
stream << PathCleaned( split + 1 );
|
||||
m_to = stream.c_str();
|
||||
m_to = StringOutputStream( 64 )( PathCleaned( split + 1 ) ).c_str();
|
||||
}
|
||||
else{
|
||||
m_from = "";
|
||||
|
|
|
|||
|
|
@ -31,9 +31,7 @@
|
|||
#include "traverselib.h"
|
||||
|
||||
inline void parseTextureName( CopiedString& name, const char* token ){
|
||||
StringOutputStream cleaned( 256 );
|
||||
cleaned << PathCleaned( token );
|
||||
name = StringRange( cleaned.c_str(), path_get_filename_base_end( cleaned.c_str() ) ); // remove extension
|
||||
name = StringOutputStream( 256 )( PathCleaned( PathExtensionless( token ) ) ).c_str(); // remove extension
|
||||
}
|
||||
|
||||
class ModelSkinKey : public ModuleObserver
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@
|
|||
#include "stringio.h"
|
||||
|
||||
void parseShaderName( CopiedString& name, const char* token ){
|
||||
StringOutputStream cleaned( 256 );
|
||||
cleaned << PathCleaned( token );
|
||||
name = cleaned.c_str();
|
||||
name = StringOutputStream( 256 )( PathCleaned( token ) ).c_str();
|
||||
}
|
||||
|
||||
class Doom3ModelSkin
|
||||
|
|
|
|||
|
|
@ -66,9 +66,7 @@ inline VertexPointer vertexpointer_arbitrarymeshvertex( const ArbitraryMeshVerte
|
|||
}
|
||||
|
||||
inline void parseTextureName( CopiedString& name, const char* token ){
|
||||
StringOutputStream cleaned( 256 );
|
||||
cleaned << PathCleaned( token );
|
||||
name = StringRange( cleaned.c_str(), path_get_filename_base_end( cleaned.c_str() ) ); // remove extension
|
||||
name = StringOutputStream( 256 )( PathCleaned( PathExtensionless( token ) ) ).c_str(); // remove extension
|
||||
}
|
||||
|
||||
// generic renderable triangle surface
|
||||
|
|
|
|||
|
|
@ -232,9 +232,7 @@ typedef CopiedString TextureExpression;
|
|||
//++timo FIXME: we need to put code somewhere to detect when two shaders that are case insensitive equal are present
|
||||
template<typename StringType>
|
||||
void parseTextureName( StringType& name, const char* token ){
|
||||
StringOutputStream cleaned( 256 );
|
||||
cleaned << PathCleaned( token );
|
||||
name = CopiedString( StringRange( cleaned.c_str(), path_get_filename_base_end( cleaned.c_str() ) ) ).c_str(); // remove extension
|
||||
name = StringOutputStream( 256 )( PathCleaned( PathExtensionless( token ) ) ).c_str(); // remove extension
|
||||
}
|
||||
|
||||
bool Tokeniser_parseTextureName( Tokeniser& tokeniser, TextureExpression& name ){
|
||||
|
|
@ -1610,12 +1608,9 @@ void ShaderList_addFromArchive( const char *archivename ){
|
|||
return;
|
||||
}
|
||||
|
||||
StringOutputStream shaderlist( 256 );
|
||||
shaderlist << DirectoryCleaned( shaderpath ) << "shaderlist.txt";
|
||||
|
||||
Archive *archive = GlobalFileSystem().getArchive( archivename, false );
|
||||
if ( archive ) {
|
||||
ArchiveTextFile *file = archive->openTextFile( shaderlist.c_str() );
|
||||
ArchiveTextFile *file = archive->openTextFile( StringOutputStream( 64 )( DirectoryCleaned( shaderpath ), "shaderlist.txt" ).c_str() );
|
||||
if ( file ) {
|
||||
globalOutputStream() << "Found shaderlist.txt in " << archivename << "\n";
|
||||
BuildShaderList( file->getInputStream() );
|
||||
|
|
@ -1658,8 +1653,7 @@ void Shaders_Load(){
|
|||
|
||||
const char* shaderPath = GlobalRadiant().getGameDescriptionKeyValue( "shaderpath" );
|
||||
if ( !string_empty( shaderPath ) ) {
|
||||
StringOutputStream path( 256 );
|
||||
path << DirectoryCleaned( shaderPath );
|
||||
const auto path = StringOutputStream( 64 )( DirectoryCleaned( shaderPath ) );
|
||||
|
||||
if ( g_useShaderList ) {
|
||||
// preload shader files that have been listed in shaderlist.txt
|
||||
|
|
|
|||
|
|
@ -53,31 +53,24 @@ void Map_Snapshot(){
|
|||
// 1. make sure the snapshot directory exists (create it if it doesn't)
|
||||
// 2. find out what the lastest save is based on number
|
||||
// 3. inc that and save the map
|
||||
const char* path = Map_Name( g_map );
|
||||
const char* name = path_get_filename_start( path );
|
||||
|
||||
StringOutputStream snapshotsDir( 256 );
|
||||
snapshotsDir << StringRange( path, name ) << "snapshots";
|
||||
const char* mapname = Map_Name( g_map );
|
||||
const auto snapshotsDir = StringOutputStream( 256 )( PathFilenameless( mapname ), "snapshots" );
|
||||
|
||||
if ( file_exists( snapshotsDir.c_str() ) || Q_mkdir( snapshotsDir.c_str() ) ) {
|
||||
std::size_t lSize = 0;
|
||||
StringOutputStream strNewPath( 256 );
|
||||
strNewPath << snapshotsDir.c_str() << '/' << name;
|
||||
const auto strNewPath = StringOutputStream( 256 )( snapshotsDir.c_str(), '/', mapname );
|
||||
const char* ext = path_get_filename_base_end( strNewPath.c_str() );
|
||||
|
||||
StringOutputStream snapshotFilename( 256 );
|
||||
|
||||
for ( int nCount = 0; ; ++nCount )
|
||||
{
|
||||
// The original map's filename is "<path>/<name>.<ext>"
|
||||
// The snapshot's filename will be "<path>/snapshots/<name>.<count>.<ext>"
|
||||
const char* end = path_get_filename_base_end( strNewPath.c_str() );
|
||||
snapshotFilename << StringRange( strNewPath.c_str(), end ) << '.' << nCount << end;
|
||||
snapshotFilename( StringRange( strNewPath.c_str(), ext ), '.', nCount, ext );
|
||||
|
||||
if ( !DoesFileExist( snapshotFilename.c_str(), lSize ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
snapshotFilename.clear();
|
||||
}
|
||||
|
||||
// save in the next available slot
|
||||
|
|
@ -159,8 +152,7 @@ void QE_CheckAutoSave( void ){
|
|||
{
|
||||
const char* name = Map_Name( g_map );
|
||||
const char* extension = path_get_filename_base_end( name );
|
||||
StringOutputStream autosave( 256 );
|
||||
autosave << StringRange( name, extension ) << ".autosave" << extension;
|
||||
const auto autosave = StringOutputStream( 256 )( StringRange( name, extension ), ".autosave", extension );
|
||||
Map_SaveFile( autosave.c_str() );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,9 +275,7 @@ EntityClass *Eclass_InitFromText( const char *text ){
|
|||
e->m_comments = text;
|
||||
|
||||
setSpecialLoad( e, "model=", e->m_modelpath );
|
||||
StringOutputStream buffer( string_length( e->m_modelpath.c_str() ) );
|
||||
buffer << PathCleaned( e->m_modelpath.c_str() );
|
||||
e->m_modelpath = buffer.c_str();
|
||||
e->m_modelpath = StringOutputStream( 256 )( PathCleaned( e->m_modelpath.c_str() ) ).c_str();
|
||||
|
||||
if ( !e->fixedsize ) {
|
||||
EntityClass_insertAttribute( *e, "angle", EntityClassAttribute( "direction", "Direction" ) );
|
||||
|
|
|
|||
|
|
@ -359,9 +359,7 @@ static bool EntityClass_parse( EntityClass& entityClass, Tokeniser& tokeniser ){
|
|||
const char* token;
|
||||
PARSE_RETURN_FALSE_IF_FAIL( EntityClassDoom3_parseString( tokeniser, token ) );
|
||||
entityClass.fixedsize = true;
|
||||
StringOutputStream buffer( 256 );
|
||||
buffer << PathCleaned( token );
|
||||
entityClass.m_modelpath = buffer.c_str();
|
||||
entityClass.m_modelpath = StringOutputStream( 256 )( PathCleaned( token ) ).c_str();
|
||||
}
|
||||
else if ( string_equal( key, "editor_color" ) ) {
|
||||
const char* value;
|
||||
|
|
|
|||
|
|
@ -166,9 +166,7 @@ void EntityClassFGD_parseClass( Tokeniser& tokeniser, bool fixedsize, bool isBas
|
|||
}
|
||||
else if ( string_equal( property, "iconsprite" ) ) {
|
||||
ASSERT_MESSAGE( EntityClassFGD_parseToken( tokeniser, "(" ), PARSE_ERROR );
|
||||
StringOutputStream buffer( 256 );
|
||||
buffer << PathCleaned( tokeniser.getToken() );
|
||||
entityClass->m_modelpath = buffer.c_str();
|
||||
entityClass->m_modelpath = StringOutputStream( 256 )( PathCleaned( tokeniser.getToken() ) ).c_str();
|
||||
ASSERT_MESSAGE( EntityClassFGD_parseToken( tokeniser, ")" ), PARSE_ERROR );
|
||||
}
|
||||
else if ( string_equal( property, "sprite" )
|
||||
|
|
@ -504,10 +502,7 @@ void EntityClassFGD_parse( TextInputStream& inputStream, const char* path ){
|
|||
}
|
||||
// hl2 below
|
||||
else if ( string_equal( blockType, "@include" ) ) {
|
||||
StringOutputStream includePath( 256 );
|
||||
includePath << StringRange( path, path_get_filename_start( path ) );
|
||||
includePath << tokeniser.getToken();
|
||||
EntityClassFGD_loadFile( includePath.c_str() );
|
||||
EntityClassFGD_loadFile( StringOutputStream( 256 )( PathFilenameless( path ), tokeniser.getToken() ).c_str() );
|
||||
}
|
||||
else if ( string_equal( blockType, "@mapsize" ) ) {
|
||||
ASSERT_MESSAGE( EntityClassFGD_parseToken( tokeniser, "(" ), PARSE_ERROR );
|
||||
|
|
|
|||
|
|
@ -293,9 +293,7 @@ ClassImporter( EntityClassCollector& collector, ListAttributeTypes& listTypes, c
|
|||
|
||||
const char* model = element.attribute( "model" );
|
||||
if ( !string_empty( model ) ) {
|
||||
StringOutputStream buffer( 256 );
|
||||
buffer << PathCleaned( model );
|
||||
m_eclass->m_modelpath = buffer.c_str();
|
||||
m_eclass->m_modelpath = StringOutputStream( 256 )( PathCleaned( model ) ).c_str();
|
||||
}
|
||||
|
||||
const char* type = element.name();
|
||||
|
|
|
|||
|
|
@ -198,9 +198,7 @@ CopiedString g_openMapByCmd;
|
|||
void cmdMap(){
|
||||
for ( int i = 1; i < g_argc; ++i )
|
||||
if( extension_equal( path_get_extension( g_argv[i] ), "map" ) ){
|
||||
StringOutputStream stream( 256 );
|
||||
stream << PathCleaned( g_argv[i] );
|
||||
g_openMapByCmd = stream.c_str();
|
||||
g_openMapByCmd = StringOutputStream( 256 )( PathCleaned( g_argv[i] ) ).c_str();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -257,14 +255,12 @@ void environment_init( int argc, char* argv[] ){
|
|||
ASSERT_MESSAGE( !string_empty( app_filepath.c_str() ), "failed to deduce app path" );
|
||||
// NOTE: we build app path with a trailing '/'
|
||||
// it's a general convention in Radiant to have the slash at the end of directories
|
||||
app_path = StringRange( real, path_get_filename_start( real ) );
|
||||
app_path = PathFilenameless( real );
|
||||
}
|
||||
|
||||
if ( !portable_app_setup() ) {
|
||||
StringOutputStream home( 256 );
|
||||
home << DirectoryCleaned( g_get_home_dir() ) << ".netradiant/";
|
||||
Q_mkdir( home.c_str() );
|
||||
home_path = home.c_str();
|
||||
home_path = StringOutputStream( 256 )( DirectoryCleaned( g_get_home_dir() ), ".netradiant/" ).c_str();
|
||||
Q_mkdir( home_path.c_str() );
|
||||
}
|
||||
gamedetect();
|
||||
cmdMap();
|
||||
|
|
@ -282,10 +278,8 @@ void environment_init( int argc, char* argv[] ){
|
|||
char filename[MAX_PATH + 1];
|
||||
GetModuleFileName( 0, filename, MAX_PATH );
|
||||
|
||||
StringOutputStream stream( 256 );
|
||||
stream << PathCleaned( filename );
|
||||
app_filepath = stream.c_str();
|
||||
app_path = StringRange( stream.c_str(), path_get_filename_start( stream.c_str() ) );
|
||||
app_filepath = StringOutputStream( 256 )( PathCleaned( filename ) ).c_str();
|
||||
app_path = PathFilenameless( app_filepath.c_str() );
|
||||
}
|
||||
|
||||
if ( !portable_app_setup() ) {
|
||||
|
|
|
|||
|
|
@ -79,11 +79,8 @@ static bool g_bFindActive = true;
|
|||
namespace
|
||||
{
|
||||
void FindTextureDialog_apply(){
|
||||
StringOutputStream find( 256 );
|
||||
StringOutputStream replace( 256 );
|
||||
|
||||
find << "textures/" << g_FindTextureDialog.m_strFind.c_str();
|
||||
replace << "textures/" << PathCleaned( g_FindTextureDialog.m_strReplace.c_str() );
|
||||
const auto find = StringOutputStream( 256 )( "textures/", g_FindTextureDialog.m_strFind.c_str() );
|
||||
const auto replace = StringOutputStream( 256 )( "textures/", PathCleaned( g_FindTextureDialog.m_strReplace.c_str() ) );
|
||||
FindReplaceTextures( find.c_str(), replace.c_str(), g_FindTextureDialog.m_bSelectedOnly );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -332,8 +332,7 @@ void EnginePath_Unrealise(){
|
|||
}
|
||||
|
||||
void setEnginePath( CopiedString& self, const char* value ){
|
||||
StringOutputStream buffer( 256 );
|
||||
buffer << DirectoryCleaned( value );
|
||||
const auto buffer = StringOutputStream( 256 )( DirectoryCleaned( value ) );
|
||||
if ( !path_equal( buffer.c_str(), self.c_str() ) ) {
|
||||
#if 0
|
||||
while ( !ConfirmModified( "Paths Changed" ) )
|
||||
|
|
@ -3736,9 +3735,7 @@ void MainFrame_Construct(){
|
|||
#error "unknown platform"
|
||||
#endif
|
||||
;
|
||||
StringOutputStream path( 256 );
|
||||
path << DirectoryCleaned( g_pGameDescription->getRequiredKeyValue( ENGINEPATH_ATTRIBUTE ) );
|
||||
g_strEnginePath = path.c_str();
|
||||
g_strEnginePath = StringOutputStream( 256 )( DirectoryCleaned( g_pGameDescription->getRequiredKeyValue( ENGINEPATH_ATTRIBUTE ) ) ).c_str();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1156,8 +1156,7 @@ public:
|
|||
// parse string of format *pathToLoad/depth*path2ToLoad/depth*
|
||||
// */depth* for root path
|
||||
ModelFolders( const char* pathsString ){
|
||||
StringOutputStream str( 128 );
|
||||
str << PathCleaned( pathsString );
|
||||
const auto str = StringOutputStream( 128 )( PathCleaned( pathsString ) );
|
||||
|
||||
const char* start = str.c_str();
|
||||
while( 1 ){
|
||||
|
|
|
|||
|
|
@ -184,9 +184,7 @@ void bsp_init(){
|
|||
}
|
||||
|
||||
{
|
||||
StringOutputStream name( 256 );
|
||||
name << StringRange( path_get_filename_start( mapname ), path_get_filename_base_end( mapname ) );
|
||||
build_set_variable( "MapName", name.c_str() );
|
||||
build_set_variable( "MapName", StringOutputStream( 64 )( PathFilename( mapname ) ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,8 +283,7 @@ void RunBSP( const char* name ){
|
|||
if ( g_WatchBSP_Enabled && monitor ) {
|
||||
// grab the file name for engine running
|
||||
const char* fullname = Map_Name( g_map );
|
||||
StringOutputStream bspname( 64 );
|
||||
bspname << StringRange( path_get_filename_start( fullname ), path_get_filename_base_end( fullname ) );
|
||||
const auto bspname = StringOutputStream( 64 )( PathFilename( fullname ) );
|
||||
BuildMonitor_Run( listener.array(), bspname.c_str() );
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1373,8 +1373,7 @@ void SurfaceInspector::Update(){
|
|||
===============
|
||||
*/
|
||||
void SurfaceInspector::ApplyShader(){
|
||||
StringOutputStream name( 256 );
|
||||
name << GlobalTexturePrefix_get() << PathCleaned( gtk_entry_get_text( m_texture ) );
|
||||
const auto name = StringOutputStream( 256 )( GlobalTexturePrefix_get(), PathCleaned( gtk_entry_get_text( m_texture ) ) );
|
||||
|
||||
// TTimo: detect and refuse invalid texture names (at least the ones with spaces)
|
||||
if ( !texdef_name_valid( name.c_str() ) ) {
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ void TextureGroups_addWad( TextureGroups& groups, const char* archive ){
|
|||
#if 1
|
||||
groups.insert( archive );
|
||||
#else
|
||||
CopiedString archiveBaseName( path_get_filename_start( archive ), path_get_filename_base_end( archive ) );
|
||||
CopiedString archiveBaseName( PathFilename( archive ) );
|
||||
groups.insert( archiveBaseName );
|
||||
#endif
|
||||
}
|
||||
|
|
@ -696,7 +696,7 @@ class LoadShaderVisitor : public Archive::Visitor
|
|||
{
|
||||
public:
|
||||
void visit( const char* name ){
|
||||
IShader* shader = QERApp_Shader_ForName( CopiedString( StringRange( name, path_get_filename_base_end( name ) ) ).c_str() );
|
||||
IShader* shader = QERApp_Shader_ForName( CopiedString( PathExtensionless( name ) ).c_str() );
|
||||
shader->DecRef();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user