OpenClonk
StdFile.cpp File Reference
#include "C4Include.h"
#include "platform/StdFile.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <zlib.h>
Include dependency graph for StdFile.cpp:

Go to the source code of this file.

Classes

struct  DirectoryIteratorP
 

Functions

char * GetFilename (char *szPath)
 
const char * GetFilename (const char *szPath)
 
const char * GetFilenameOnly (const char *strFilename)
 
const char * GetC4Filename (const char *szPath)
 
int GetTrailingNumber (const char *strString)
 
char * GetFilenameWeb (char *szPath)
 
const char * GetFilenameWeb (const char *szPath)
 
char * GetExtension (char *szFilename)
 
const char * GetExtension (const char *szFilename)
 
void RealPath (const char *szFilename, char *pFullFilename)
 
bool GetParentPath (const char *szFilename, char *szBuffer)
 
bool GetParentPath (const char *szFilename, StdStrBuf *outBuf)
 
const char * GetRelativePathS (const char *strPath, const char *strRelativeTo)
 
bool IsGlobalPath (const char *szPath)
 
bool TruncatePath (char *szPath)
 
void AppendBackslash (char *szFilename)
 
void TruncateBackslash (char *szFilename)
 
void DefaultExtension (char *szFilename, const char *szExtension)
 
void DefaultExtension (StdStrBuf *sFilename, const char *szExtension)
 
void EnforceExtension (char *szFilename, const char *szExtension)
 
void EnforceExtension (StdStrBuf *sFilename, const char *szExtension)
 
void RemoveExtension (char *szFilename)
 
void RemoveExtension (StdStrBuf *psFileName)
 
void MakeTempFilename (char *szFilename)
 
void MakeTempFilename (StdStrBuf *sFilename)
 
bool WildcardListMatch (const char *szWildcardList, const char *szString)
 
bool IsWildcardString (const char *szString)
 
bool WildcardMatch (const char *szWildcard, const char *szString)
 
void MakeFilenameFromTitle (char *szTitle)
 
const char * GetWorkingDirectory ()
 
bool SetWorkingDirectory (const char *path)
 
bool CreatePath (const std::string &path)
 
bool DirectoryExists (const char *szFilename)
 
bool CopyDirectory (const char *szSource, const char *szTarget, bool fResetAttributes)
 
bool EraseDirectory (const char *szDirName)
 
bool RenameItem (const char *szItemName, const char *szNewItemName)
 
bool EraseItem (const char *szItemName)
 
bool CreateItem (const char *szItemname)
 
bool CopyItem (const char *szSource, const char *szTarget, bool fResetAttributes)
 
bool MoveItem (const char *szSource, const char *szTarget)
 
bool ItemIdentical (const char *szFilename1, const char *szFilename2)
 
int ForEachFile (const char *szDirName, bool(*fnCallback)(const char *))
 

Function Documentation

◆ AppendBackslash()

void AppendBackslash ( char *  szFilename)

Definition at line 254 of file StdFile.cpp.

255 {
256  int i=SLen(szFilename);
257  if (i>0) if (szFilename[i-1]==DirectorySeparator) return;
258  SAppendChar(DirectorySeparator,szFilename);
259 }
#define DirectorySeparator
void SAppendChar(char cChar, char *szStr)
Definition: Standard.cpp:271
size_t SLen(const char *sptr)
Definition: Standard.h:74

References DirectorySeparator, SAppendChar(), and SLen().

Referenced by C4Group_SetTempPath(), CopyDirectory(), C4Network2ResList::CreateNetworkFolder(), C4ConfigGeneral::DeterminePaths(), EraseDirectory(), C4Group::ExtractEntry(), ForEachFile(), C4Game::QuickSave(), and C4Group::Rename().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CopyDirectory()

bool CopyDirectory ( const char *  szSource,
const char *  szTarget,
bool  fResetAttributes 
)

Definition at line 737 of file StdFile.cpp.

738 {
739  // Source check
740  if (!szSource || !szTarget) return false;
741  if (!DirectoryExists(szSource)) return false;
742  // Do not process system navigation directories
743  if (SEqual(GetFilename(szSource),".")
744  || SEqual(GetFilename(szSource),".."))
745  return true;
746  // Overwrite target
747  if (!EraseItem(szTarget)) return false;
748  // Create target directory
749  bool status=true;
750 #ifdef _WIN32
751  if (_wmkdir(GetWideChar(szTarget))!=0) return false;
752  // Copy contents to target directory
753  char contents[_MAX_PATH_LEN];
754  SCopy(szSource,contents); AppendBackslash(contents);
755  SAppend("*",contents);
756  _wfinddata_t fdt; intptr_t hfdt;
757  if ( (hfdt=_wfindfirst(GetWideChar(contents),&fdt)) > -1 )
758  {
759  do
760  {
761  char itemsource[_MAX_PATH_LEN],itemtarget[_MAX_PATH_LEN];
762  SCopy(szSource,itemsource); AppendBackslash(itemsource); SAppend(StdStrBuf(fdt.name).getData(),itemsource);
763  SCopy(szTarget,itemtarget); AppendBackslash(itemtarget); SAppend(StdStrBuf(fdt.name).getData(),itemtarget);
764  if (!CopyItem(itemsource,itemtarget, fResetAttributes)) status=false;
765  }
766  while (_wfindnext(hfdt,&fdt)==0);
767  _findclose(hfdt);
768  }
769 #else
770  if (mkdir(szTarget,0777)!=0) return false;
771  DIR * d = opendir(szSource);
772  dirent * ent;
773  char itemsource[_MAX_PATH_LEN],itemtarget[_MAX_PATH_LEN];
774  while ((ent = readdir(d)))
775  {
776  SCopy(szSource,itemsource); AppendBackslash(itemsource); SAppend(ent->d_name,itemsource);
777  SCopy(szTarget,itemtarget); AppendBackslash(itemtarget); SAppend(ent->d_name,itemtarget);
778  if (!CopyItem(itemsource,itemtarget, fResetAttributes)) status=false;
779  }
780  closedir(d);
781 #endif
782  return status;
783 }
StdStrBuf::wchar_t_holder GetWideChar(const char *utf8, bool double_null_terminate=false)
#define _MAX_PATH_LEN
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
void SAppend(const char *szSource, char *szTarget, int iMaxL)
Definition: Standard.cpp:263
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
bool EraseItem(const char *szItemName)
Definition: StdFile.cpp:833
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:708
char * GetFilename(char *szPath)
Definition: StdFile.cpp:42
void AppendBackslash(char *szFilename)
Definition: StdFile.cpp:254
bool CopyItem(const char *szSource, const char *szTarget, bool fResetAttributes)
Definition: StdFile.cpp:855
const char * getData() const
Definition: StdBuf.h:442

References _MAX_PATH_LEN, AppendBackslash(), CopyItem(), DirectoryExists(), EraseItem(), StdStrBuf::getData(), GetFilename(), GetWideChar(), SAppend(), SCopy(), and SEqual().

Referenced by CopyItem().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CopyItem()

bool CopyItem ( const char *  szSource,
const char *  szTarget,
bool  fResetAttributes 
)

Definition at line 855 of file StdFile.cpp.

856 {
857  // Check for identical source and target
858  if (ItemIdentical(szSource,szTarget)) return true;
859  // Copy directory
860  if (DirectoryExists(szSource))
861  return CopyDirectory(szSource,szTarget,fResetAttributes);
862  // Copy file
863  if (!CopyFile(szSource,szTarget,false)) return false;
864  // Reset any attributes if desired
865 #ifdef _WIN32
866  if (fResetAttributes) if (!SetFileAttributesW(GetWideChar(szTarget), FILE_ATTRIBUTE_NORMAL)) return false;
867 #else
868  if (fResetAttributes) if (chmod(szTarget, S_IRWXU)) return false;
869 #endif
870  return true;
871 }
bool CopyFile(const char *szSource, const char *szTarget, bool FailIfExists)
bool CopyDirectory(const char *szSource, const char *szTarget, bool fResetAttributes)
Definition: StdFile.cpp:737
bool ItemIdentical(const char *szFilename1, const char *szFilename2)
Definition: StdFile.cpp:879

References CopyDirectory(), CopyFile(), DirectoryExists(), GetWideChar(), and ItemIdentical().

Referenced by C4Record::AddFile(), C4Group_CopyItem(), CopyDirectory(), and C4Group::ExtractEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CreateItem()

bool CreateItem ( const char *  szItemname)

Definition at line 839 of file StdFile.cpp.

840 {
841  // Overwrite any old item
842  EraseItem(szItemname);
843  // Create dummy item
844  FILE *fhnd;
845 #ifdef _WIN32
846  if (!(fhnd=_wfopen(GetWideChar(szItemname), L"wb"))) return false;
847 #else
848  if (!(fhnd=fopen(szItemname,"wb"))) return false;
849 #endif
850  fclose(fhnd);
851  // Success
852  return true;
853 }

References EraseItem(), and GetWideChar().

Referenced by C4Group_CopyItem(), and C4Group_MoveItem().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CreatePath()

bool CreatePath ( const std::string &  path)

Create a directory and all of its parents. [in] path Directory to create

Returns
true on success, false otherwise.

Definition at line 656 of file StdFile.cpp.

657 {
658  assert(!path.empty());
659 #ifdef _WIN32
660  if (CreateDirectoryW(GetWideChar(path.c_str()), nullptr))
661  {
662  return true;
663  }
664  else
665  {
666  DWORD err = GetLastError();
667  switch (err)
668  {
669  case ERROR_PATH_NOT_FOUND:
670  break;
671  case ERROR_ALREADY_EXISTS:
672  return true;
673  default:
674  // Something major has happened: Log
675  {
676  wchar_t * str;
677  if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
678  nullptr, err, 0, (LPWSTR)&str, 0, nullptr))
679  {
680  LogF("CreateDirectory failed: %s", StdStrBuf(str).getData());
681  LocalFree(str);
682  }
683  return false;
684  }
685  }
686  }
687 #else
688  if (!mkdir(path.c_str(), S_IREAD | S_IWRITE | S_IEXEC))
689  return true;
690  switch (errno)
691  {
692  case ENOENT:
693  break;
694  case EEXIST:
695  // FIXME: Check whether the path is blocked by a non-directory
696  return true;
697  default:
698  return false;
699  }
700 #endif
701  // Recursively create parent path
702  std::string::size_type slash = path.find_last_of(DirectorySeparators);
703  if (slash == 0 || slash == std::string::npos)
704  return false;
705  return CreatePath(path.substr(0, slash)) && CreatePath(path);
706 }
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
uint32_t DWORD
bool CreatePath(const std::string &path)
Definition: StdFile.cpp:656

References GetWideChar(), and LogF().

Referenced by C4Group_UnpackDirectory(), C4Network2ResList::CreateNetworkFolder(), C4ConfigGeneral::CreateSaveFolder(), C4ConfigGeneral::DeterminePaths(), C4ScenarioSection::EnsureTempStore(), C4UpdatePackage::Execute(), C4Config::Load(), and C4Config::MakeTempUpdateFolder().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DefaultExtension() [1/2]

void DefaultExtension ( char *  szFilename,
const char *  szExtension 
)

Definition at line 271 of file StdFile.cpp.

272 {
273  if (!(*GetExtension(szFilename)))
274  { SAppend(".",szFilename); SAppend(szExtension,szFilename); }
275 }
char * GetExtension(char *szFilename)
Definition: StdFile.cpp:118

References GetExtension(), and SAppend().

Referenced by C4Console::FileSaveAs(), C4SoundSystem::FindInstance(), C4SoundSystem::GetEffect(), MakeTempFilename(), and C4MusicSystem::Play().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DefaultExtension() [2/2]

void DefaultExtension ( StdStrBuf sFilename,
const char *  szExtension 
)

Definition at line 277 of file StdFile.cpp.

278 {
279  assert(sFilename);
280  if (!(*GetExtension(sFilename->getData())))
281  { sFilename->AppendChar('.'); sFilename->Append(szExtension); }
282 }
void AppendChar(char cChar)
Definition: StdBuf.h:588
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519

References StdStrBuf::Append(), StdStrBuf::AppendChar(), StdStrBuf::getData(), and GetExtension().

Here is the call graph for this function:

◆ DirectoryExists()

bool DirectoryExists ( const char *  szFilename)

Definition at line 708 of file StdFile.cpp.

709 {
710  // Ignore trailing slash or backslash, except when we are probing the
711  // root directory '/'.
712  char bufFilename[_MAX_PATH_LEN];
713  if (szFilename && szFilename[0])
714  {
715  unsigned int len = SLen(szFilename);
716  if (len > 1 && ((szFilename[len - 1] == '\\') || (szFilename[len - 1] == '/')))
717  {
718  SCopy(szFilename, bufFilename, _MAX_PATH);
719  bufFilename[SLen(bufFilename) - 1] = 0;
720  szFilename = bufFilename;
721  }
722  }
723  // Check file attributes
724 #ifdef _WIN32
725  struct _wfinddata_t fdt; intptr_t shnd;
726  if ((shnd=_wfindfirst(GetWideChar(szFilename),&fdt))<0) return false;
727  _findclose(shnd);
728  if (fdt.attrib & _A_SUBDIR) return true;
729 #else
730  struct stat stStats;
731  if (stat(szFilename,&stStats)!=0) return 0;
732  return (S_ISDIR(stStats.st_mode));
733 #endif
734  return false;
735 }
#define _MAX_PATH

References _MAX_PATH, _MAX_PATH_LEN, GetWideChar(), SCopy(), and SLen().

Referenced by C4MainMenu::ActivateNewPlayer(), C4FileSelDlg::AddCheckedLocation(), C4ControlJoinPlayer::C4ControlJoinPlayer(), C4Group_PackDirectoryTo(), C4Group_UnpackDirectory(), CopyDirectory(), CopyItem(), C4ScenarioListLoader::Entry::CreateEntryForFile(), C4Network2ResList::CreateNetworkFolder(), DirContainsScenarios(), C4ScenarioListLoader::RegularFolder::DoLoadContents(), C4Group::ExtractEntry(), C4Console::FileOpenWPlrs(), C4Network2Res::GetStandalone(), C4Language::Init(), C4Reloc::Init(), C4Network2Res::IsBinaryCompatible(), C4Group::OpenAsChild(), C4Reloc::const_iterator::operator++(), C4Console::PlayerJoin(), C4Network2Res::SetByCore(), C4Record::Start(), and C4Record::Stop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EnforceExtension() [1/2]

void EnforceExtension ( char *  szFilename,
const char *  szExtension 
)

Definition at line 286 of file StdFile.cpp.

287 {
288  char *ext = GetExtension(szFilename);
289  if (ext[0]) { SCopy(szExtension,ext); }
290  else { SAppend(".",szFilename); SAppend(szExtension,szFilename); }
291 }

References GetExtension(), SAppend(), and SCopy().

Referenced by C4GroupSet::FindSuitableFile(), C4FacetSurface::Load(), C4DefGraphics::Load(), C4Surface::LoadAny(), MakeTempFilename(), and C4ObjectInfo::Save().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EnforceExtension() [2/2]

void EnforceExtension ( StdStrBuf sFilename,
const char *  szExtension 
)

Definition at line 293 of file StdFile.cpp.

294 {
295  assert(sFilename);
296  const char *ext = GetExtension(sFilename->getData());
297  if (ext[0]) { sFilename->ReplaceEnd(ext - sFilename->getData(), szExtension); }
298  else { sFilename->AppendChar('.'); sFilename->Append(szExtension); }
299 }
void ReplaceEnd(size_t iPos, const char *szNewEnd)
Definition: StdBuf.cpp:351

References StdStrBuf::Append(), StdStrBuf::AppendChar(), StdStrBuf::getData(), GetExtension(), and StdStrBuf::ReplaceEnd().

Here is the call graph for this function:

◆ EraseDirectory()

bool EraseDirectory ( const char *  szDirName)

Definition at line 785 of file StdFile.cpp.

786 {
787  // Do not process system navigation directories
788  if (SEqual(GetFilename(szDirName),".")
789  || SEqual(GetFilename(szDirName),".."))
790  return true;
791  char path[_MAX_PATH_LEN];
792 #ifdef _WIN32
793  // Get path to directory contents
794  SCopy(szDirName,path); SAppend(R"(\*.*)",path);
795  // Erase subdirectories and files
796  ForEachFile(path,&EraseItem);
797 #else
798  DIR * d = opendir(szDirName);
799  dirent * ent;
800  while ((ent = readdir(d)))
801  {
802  SCopy(szDirName,path); AppendBackslash(path); SAppend(ent->d_name,path);
803  if (!EraseItem(path)) return false;
804  }
805  closedir(d);
806 #endif
807  // Check working directory
808  if (SEqual(szDirName,GetWorkingDirectory()))
809  {
810  // Will work only if szDirName is full path and correct case!
811  SCopy(GetWorkingDirectory(),path);
812  int lbacks = SCharLastPos(DirectorySeparator,path);
813  if (lbacks > -1)
814  {
815  path[lbacks]=0; SetWorkingDirectory(path);
816  }
817  }
818  // Remove directory
819 #ifdef _WIN32
820  return !!RemoveDirectoryW(GetWideChar(szDirName));
821 #else
822  return (rmdir(szDirName)==0 || errno == ENOENT);
823 #endif
824 }
int SCharLastPos(char cTarget, const char *szInStr)
Definition: Standard.cpp:253
bool SetWorkingDirectory(const char *path)
Definition: StdFile.cpp:647
int ForEachFile(const char *szDirName, bool(*fnCallback)(const char *))
Definition: StdFile.cpp:1068
const char * GetWorkingDirectory()
Definition: StdFile.cpp:627

References _MAX_PATH_LEN, AppendBackslash(), DirectorySeparator, EraseItem(), ForEachFile(), GetFilename(), GetWideChar(), GetWorkingDirectory(), SAppend(), SCharLastPos(), SCopy(), SEqual(), and SetWorkingDirectory().

Referenced by C4Group_PackDirectory(), EraseItem(), C4Network2Res::GetStandalone(), and C4Network2::RetrieveScenario().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EraseItem()

bool EraseItem ( const char *  szItemName)

Definition at line 833 of file StdFile.cpp.

834 {
835  if (!EraseFile(szItemName)) return EraseDirectory(szItemName);
836  else return true;
837 }
bool EraseDirectory(const char *szDirName)
Definition: StdFile.cpp:785
bool EraseFile(const char *szFileName)

References EraseDirectory(), and EraseFile().

Referenced by C4Record::AddFile(), C4Group_CopyItem(), C4Group_DeleteItem(), C4Group_MoveItem(), C4Group_PackDirectoryTo(), C4Group_UnpackDirectory(), C4Config::CleanupTempUpdateFolder(), C4Game::CloseScenario(), CopyDirectory(), CreateItem(), C4Group::DeleteEntry(), C4PlayerInfo::DeleteTempFile(), C4ScenarioSection::EnsureTempStore(), EraseDirectory(), C4Group::ExtractEntry(), C4Network2Res::GetStandalone(), C4UpdatePackage::MakeUpdate(), C4UpdatePackage::MkUp(), ProcessGroup(), C4Player::Save(), C4Console::SaveScenario(), C4Landscape::SaveTextures(), C4Player::Strip(), and C4ScenarioSection::~C4ScenarioSection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ForEachFile()

int ForEachFile ( const char *  szDirName,
bool(*)(const char *)  fnCallback 
)

Definition at line 1068 of file StdFile.cpp.

1069 {
1070  if (!szDirName || !fnCallback)
1071  return 0;
1072  char szFilename[_MAX_PATH_LEN];
1073  SCopy(szDirName,szFilename);
1074  bool fHasWildcard = (SCharPos('*', szFilename)>=0);
1075  if (!fHasWildcard) // parameter without wildcard: Append "/*.*" or "\*.*"
1076  AppendBackslash(szFilename);
1077  int iFileCount = 0;
1078 #ifdef _WIN32
1079  struct _wfinddata_t fdt; intptr_t fdthnd;
1080  if (!fHasWildcard) // parameter without wildcard: Append "/*.*" or "\*.*"
1081  SAppend("*",szFilename,_MAX_PATH);
1082  if ((fdthnd = _wfindfirst (GetWideChar(szFilename), &fdt)) < 0)
1083  return 0;
1084  do
1085  {
1086  if (!wcscmp(fdt.name, L".") || !wcscmp(fdt.name, L"..")) continue;
1087  StdStrBuf name(fdt.name);
1088  SCopy(name.getData(),GetFilename(szFilename));
1089  if ((*fnCallback)(szFilename))
1090  iFileCount++;
1091  }
1092  while (_wfindnext(fdthnd,&fdt)==0);
1093  _findclose(fdthnd);
1094 #else
1095  if (fHasWildcard) fprintf(stderr, "Warning: ForEachFile with * (%s)\n", szDirName);
1096  DIR * d = opendir(szDirName);
1097  if (!d) return 0;
1098  dirent * ent;
1099  while ((ent = readdir(d)))
1100  {
1101  SCopy(ent->d_name,GetFilename(szFilename));
1102  if ((*fnCallback)(szFilename))
1103  iFileCount++;
1104  }
1105  closedir(d);
1106 #endif
1107  return iFileCount;
1108 }
int SCharPos(char cTarget, const char *szInStr, int iIndex)
Definition: Standard.cpp:239

References _MAX_PATH, _MAX_PATH_LEN, AppendBackslash(), StdStrBuf::getData(), GetFilename(), GetWideChar(), SAppend(), SCharPos(), and SCopy().

Referenced by C4Group_ExplodeDirectory(), EraseDirectory(), DirSizeHelper::GetDirSize(), and main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetC4Filename()

const char* GetC4Filename ( const char *  szPath)

Definition at line 68 of file StdFile.cpp.

69 {
70  // returns path to file starting at first .c4*-directory.
71  if (!szPath) return nullptr;
72  const char *pPos,*pFilename=szPath;
73  for (pPos=szPath; *pPos; pPos++)
74  {
75  if (*pPos==DirectorySeparator || *pPos=='/')
76  {
77  if (pPos >= szPath+4 && SEqual2NoCase(pPos-4, ".oc")) return pFilename;
78  pFilename = pPos+1;
79  }
80  }
81  return pFilename;
82 }
bool SEqual2NoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:226

References DirectorySeparator, and SEqual2NoCase().

Referenced by C4Config::ForceRelativePath(), and C4Network2Res::SetByCore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetExtension() [1/2]

char* GetExtension ( char *  szFilename)

◆ GetExtension() [2/2]

const char* GetExtension ( const char *  szFilename)

Definition at line 127 of file StdFile.cpp.

128 {
129  int pos, end;
130  for (end=0; szFilename[end]; end++) {}
131  pos = end;
132  while ((pos>0) && (szFilename[pos-1] != '.') && (szFilename[pos-1] != DirectorySeparator)) pos--;
133  if ((pos > 0) && szFilename[pos-1] == '.') return szFilename+pos;
134  return szFilename+end;
135 }

References DirectorySeparator.

◆ GetFilename() [1/2]

char* GetFilename ( char *  szPath)

Definition at line 42 of file StdFile.cpp.

43 {
44  if (!szPath) return nullptr;
45  char *pPos,*pFilename=szPath;
46  for (pPos=szPath; *pPos; pPos++) if (*pPos==DirectorySeparator || *pPos=='/') pFilename = pPos+1;
47  return pFilename;
48 }

References DirectorySeparator.

Referenced by C4MainMenu::ActivateSavegame(), C4DefGraphicsPtrBackup::Add(), C4Group::Add(), C4MusicFile::Announce(), C4Group_CopyItem(), C4Group_DeleteItem(), C4Group_IsExcluded(), C4Group_MoveItem(), C4Group_PackDirectoryTo(), C4Group_ReadFile(), C4Group_TestIgnore(), CopyDirectory(), C4Network2::CreateDynamic(), C4ScenarioListLoader::RegularFolder::DoLoadContents(), C4DownloadDlg::DownloadFile(), C4Game::DropFile(), C4ScenarioSection::EnsureTempStore(), EraseDirectory(), C4PlayerList::FileInUse(), C4ScenarioListLoader::Folder::FindEntryByName(), C4PlayerInfoList::FindSavegameResumePlayerInfo(), C4Network2ResList::FindTempResFileName(), ForEachFile(), GetFilenameOnly(), C4FileSelDlg::GetSelection(), C4Network2Res::GetStandalone(), C4Extra::Init(), C4DefinitionSelDlg::IsItemGrayed(), C4ObjectInfo::Load(), C4DefList::Load(), C4ScenarioListLoader::Entry::Load(), C4ScenarioListLoader::SubFolder::LoadCustom(), C4MusicSystem::LoadDir(), C4UpdatePackage::MakeUpdate(), C4Group::Merge(), C4Group::Move(), C4StartupPlrSelDlg::PlayerListItem::MoveFilename(), C4DownloadDlg::OnIdle(), C4StartupMainDlg::OnPlayerSelContextAdd(), C4StartupMainDlg::OnShown(), C4Game::OpenScenario(), C4Network2Res::OptimizeStandalone(), C4Application::ParseCommandLine(), C4MusicSystem::Play(), C4ControlJoinPlayer::PreRec(), C4MessageInput::ProcessCommand(), ProcessGroup(), C4PlayerInfoList::RecreatePlayerFiles(), C4Shader::Refresh(), C4Game::ReloadDef(), C4Game::ReloadParticle(), C4ScenarioListLoader::Entry::RenameTo(), C4GameResList::RetrieveFiles(), C4Group::Save(), C4Surface::SavePNG(), C4Console::SaveScenario(), C4GroupEntry::Set(), C4PlayerInfoList::SetAsRestoreInfos(), C4Network2Res::SetByCore(), C4Console::SetCaptionToFilename(), SetClientPrefix(), C4MusicSystem::SetPlayList(), C4Game::SetScenarioFilename(), C4FileSelDlg::SetSelection(), C4ScenarioListLoader::Entry::SetTitleInGroup(), C4Group::SortByList(), C4ControlJoinPlayer::Strip(), and C4StartupPlrSelDlg::PlayerListItem::UpdateCore().

Here is the caller graph for this function:

◆ GetFilename() [2/2]

const char* GetFilename ( const char *  szPath)

Definition at line 49 of file StdFile.cpp.

50 {
51  if (!szPath) return nullptr;
52  const char *pPos,*pFilename=szPath;
53  for (pPos=szPath; *pPos; pPos++) if (*pPos==DirectorySeparator || *pPos=='/') pFilename = pPos+1;
54  return pFilename;
55 }

References DirectorySeparator.

◆ GetFilenameOnly()

const char* GetFilenameOnly ( const char *  strFilename)

Definition at line 57 of file StdFile.cpp.

58 {
59  // Get filename to static buffer
60  static char strBuffer[_MAX_PATH_LEN];
61  SCopy(GetFilename(strFilename), strBuffer);
62  // Truncate extension
63  RemoveExtension(strBuffer);
64  // Return buffer
65  return strBuffer;
66 }
void RemoveExtension(char *szFilename)
Definition: StdFile.cpp:303

References _MAX_PATH_LEN, GetFilename(), RemoveExtension(), and SCopy().

Referenced by C4MainMenu::ActivateSavegame(), C4GameSaveSavegame::AdjustCore(), C4ControlJoinPlayer::C4ControlJoinPlayer(), C4StartupPlrSelDlg::PlayerListItem::Load(), C4TextureMap::LoadTextures(), C4StartupMainDlg::OnPlayerSelContextAdd(), C4StartupMainDlg::OnPlayerSelContextRemove(), C4Record::Start(), StdMeshSkeletonLoader::StoreSkeleton(), and C4StartupMainDlg::UpdateParticipants().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetFilenameWeb() [1/2]

char* GetFilenameWeb ( char *  szPath)

Definition at line 101 of file StdFile.cpp.

102 {
103  if (!szPath) return nullptr;
104  char *pPos, *pFilename=szPath;
105  for (pPos=szPath; *pPos; pPos++) if (*pPos == '/') pFilename = pPos+1;
106  return pFilename;
107 }

◆ GetFilenameWeb() [2/2]

const char* GetFilenameWeb ( const char *  szPath)

Definition at line 108 of file StdFile.cpp.

109 {
110  if (!szPath) return nullptr;
111  const char *pPos, *pFilename=szPath;
112  for (pPos=szPath; *pPos; pPos++) if (*pPos == '/') pFilename = pPos+1;
113  return pFilename;
114 }

◆ GetParentPath() [1/2]

bool GetParentPath ( const char *  szFilename,
char *  szBuffer 
)

Definition at line 186 of file StdFile.cpp.

187 {
188  // Prepare filename
189  SCopy(szFilename,szBuffer,_MAX_PATH);
190  // Extend relative single filenames
191 #ifdef _WIN32
192  if (!SCharCount(DirectorySeparator,szFilename)) _fullpath(szBuffer,szFilename,_MAX_PATH);
193 #else
194  if (!SCharCount(DirectorySeparator,szFilename)) RealPath(szFilename,szBuffer);
195 #endif
196  // Truncate path
197  return TruncatePath(szBuffer);
198 }
unsigned int SCharCount(char cTarget, const char *szInStr, const char *cpUntil)
Definition: Standard.cpp:326
bool TruncatePath(char *szPath)
Definition: StdFile.cpp:237
void RealPath(const char *szFilename, char *pFullFilename)
Definition: StdFile.cpp:138

References _MAX_PATH, DirectorySeparator, RealPath(), SCharCount(), SCopy(), and TruncatePath().

Referenced by C4Group_CopyItem(), C4Group_DeleteItem(), C4Group_MoveItem(), C4Group_ReadFile(), C4Group_UnpackDirectory(), C4ConfigGeneral::DeterminePaths(), GetParentPath(), C4Shader::Refresh(), C4GroupSet::RegisterParentFolders(), C4ScriptHost::ReloadScript(), and StdMeshSkeletonLoader::RemoveSkeletonsInGroup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetParentPath() [2/2]

bool GetParentPath ( const char *  szFilename,
StdStrBuf outBuf 
)

Definition at line 200 of file StdFile.cpp.

201 {
202  char buf[_MAX_PATH_LEN]; *buf='\0';
203  if (!GetParentPath(szFilename, buf)) return false;
204  outBuf->Copy(buf);
205  return true;
206 }
bool GetParentPath(const char *szFilename, char *szBuffer)
Definition: StdFile.cpp:186
void Copy()
Definition: StdBuf.h:467

References _MAX_PATH_LEN, StdStrBuf::Copy(), and GetParentPath().

Here is the call graph for this function:

◆ GetRelativePathS()

const char* GetRelativePathS ( const char *  strPath,
const char *  strRelativeTo 
)

Definition at line 208 of file StdFile.cpp.

209 {
210  // Specified path is relative to base path
211 #ifdef _WIN32
212  if (SEqual2NoCase(strPath, strRelativeTo))
213 #else
214  if (SEqual2(strPath, strRelativeTo))
215 #endif
216  {
217  // return relative section
218  return strPath + SLen(strRelativeTo) + ((strPath[SLen(strRelativeTo)] == DirectorySeparator) ? +1 : 0);
219  }
220  // Not relative: return full path
221  return strPath;
222 }
bool SEqual2(const char *szStr1, const char *szStr2)
Definition: Standard.cpp:204

References DirectorySeparator, SEqual2(), SEqual2NoCase(), and SLen().

Referenced by C4Config::AtRelativePath(), C4Config::AtSystemDataRelativePath(), C4Config::AtUserDataRelativePath(), C4Config::ForceRelativePath(), C4Language::GetPackGroups(), and C4SDefinitions::SetModules().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTrailingNumber()

int GetTrailingNumber ( const char *  strString)

Definition at line 84 of file StdFile.cpp.

85 {
86  // Default
87  int iNumber = 0;
88  // Start from end
89  const char *cpPos = strString + SLen(strString);
90  // Walk back while number
91  while ((cpPos > strString) && Inside(*(cpPos - 1), '0', '9')) cpPos--;
92  // Scan number
93  sscanf(cpPos, "%d", &iNumber);
94  // Return result
95  return iNumber;
96 }
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:43

References Inside(), and SLen().

Referenced by C4GameSaveSavegame::AdjustCore(), and C4ObjectInfo::Save().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetWorkingDirectory()

const char* GetWorkingDirectory ( )

Definition at line 627 of file StdFile.cpp.

628 {
629 #ifdef _WIN32
630  static StdStrBuf buffer;
631  wchar_t *widebuf = nullptr;
632  DWORD widebufsz = GetCurrentDirectoryW(0, nullptr);
633  widebuf = new wchar_t[widebufsz];
634  if (GetCurrentDirectoryW(widebufsz, widebuf) == 0) {
635  delete[] widebuf;
636  return nullptr;
637  }
638  buffer.Take(StdStrBuf(widebuf));
639  delete[] widebuf;
640  return buffer.getData();
641 #else
642  static char buf[_MAX_PATH_LEN];
643  return getcwd(buf,_MAX_PATH);
644 #endif
645 }
void Take(char *pnData)
Definition: StdBuf.h:457

References _MAX_PATH, _MAX_PATH_LEN, StdStrBuf::getData(), and StdStrBuf::Take().

Referenced by C4ConfigGeneral::DeterminePaths(), EraseDirectory(), and C4Application::ParseCommandLine().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsGlobalPath()

bool IsGlobalPath ( const char *  szPath)

Definition at line 224 of file StdFile.cpp.

225 {
226 #ifdef _WIN32
227  // C:\...
228  if (*szPath && szPath[1] == ':') return true;
229 #endif
230  // /usr/bin, \Temp\, ...
231  if (*szPath == DirectorySeparator) return true;
232  return false;
233 }

References DirectorySeparator.

Referenced by C4Reloc::AddPath(), C4Config::ForceRelativePath(), C4Reloc::LocateItem(), C4Reloc::Open(), and C4Application::ParseCommandLine().

Here is the caller graph for this function:

◆ IsWildcardString()

bool IsWildcardString ( const char *  szString)

Definition at line 363 of file StdFile.cpp.

364 {
365  // safety
366  if (!szString) return false;
367  // known wildcard characters: *?[
368  return (SCharCount('?', szString)>0) || (SCharCount('*', szString)>0) || (SCharCount('[', szString)>0);
369 }

References SCharCount().

Referenced by C4SoundSystem::GetEffect(), and C4PlayerControlAssignmentSet::IsWildcardName().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ItemIdentical()

bool ItemIdentical ( const char *  szFilename1,
const char *  szFilename2 
)

Definition at line 879 of file StdFile.cpp.

880 {
881  char szFullFile1[_MAX_PATH_LEN],szFullFile2[_MAX_PATH_LEN];
882  RealPath(szFilename1, szFullFile1); RealPath(szFilename2, szFullFile2);
883 #ifdef _WIN32
884  if (SEqualNoCase(szFullFile1,szFullFile2)) return true;
885 #else
886  if (SEqual(szFullFile1,szFullFile2)) return true;
887 #endif
888  return false;
889 }
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:213

References _MAX_PATH_LEN, RealPath(), SEqual(), and SEqualNoCase().

Referenced by C4FileSelDlg::AddCheckedLocation(), C4Group_CopyItem(), C4Group_MoveItem(), C4StartupPlrSelDlg::CheckPlayerName(), C4Language::CloseGroup(), CopyItem(), C4PlayerList::FileInUse(), C4StartupPlrSelDlg::PlayerListItem::MoveFilename(), MoveItem(), C4Game::OpenScenario(), C4Game::QuickSave(), C4ScenarioListLoader::Entry::RenameTo(), C4Console::SaveScenario(), and C4Network2Res::SetByCore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeFilenameFromTitle()

void MakeFilenameFromTitle ( char *  szTitle)

Definition at line 426 of file StdFile.cpp.

427 {
428  // copy all chars but those to be stripped
429  char *szFilename=szTitle, *szTitle2=szTitle;
430  while (*szTitle2)
431  {
432  bool fStrip;
433  if (IsWhiteSpace(*szTitle2))
434  fStrip = (szFilename==szTitle);
435  else if (static_cast<unsigned int>(*szTitle2) > 127)
436  fStrip = true;
437  else
438  fStrip = (SCharPos(*szTitle2, R"(!"'%&/=?+*#:;<>\.)") >= 0);
439  if (!fStrip) *szFilename++ = *szTitle2;
440  ++szTitle2;
441  }
442  // truncate spaces from end
443  while (IsWhiteSpace(*--szFilename)) if (szFilename==szTitle) { --szFilename; break; }
444  // terminate
445  *++szFilename=0;
446  // no name? (only invalid chars)
447  if (!*szTitle) SCopy("unnamed", szTitle, 50);
448  // done
449 }
450 
451 /* Files */
452 
453 bool FileExists(const char *szFilename)
454 {
455 #ifdef _WIN32
456  return GetFileAttributes(GetWideChar(szFilename)) != INVALID_FILE_ATTRIBUTES;
457 #else
458  return (!access(szFilename,F_OK));
459 #endif
460 }
461 
462 size_t FileSize(const char *szFilename)
463 {
464 #if defined(_WIN32) || defined(_WIN64)
465  auto attributes = WIN32_FILE_ATTRIBUTE_DATA();
466  if (GetFileAttributesEx(GetWideChar(szFilename), GetFileExInfoStandard, &attributes) == 0)
467  return 0;
468 #ifdef _WIN64
469  return (static_cast<size_t>(attributes.nFileSizeHigh) << (sizeof(attributes.nFileSizeLow) * 8)) | attributes.nFileSizeLow;
470 #else
471  return attributes.nFileSizeLow;
472 #endif
473 #else
474  struct stat stStats;
475  if (stat(szFilename,&stStats)) return 0;
476  return stStats.st_size;
477 #endif
478 }
479 
480 // operates on a filedescriptor from open or fileno
481 size_t FileSize(int fdes)
482 {
483 #ifdef _WIN32
484  return _filelength(fdes);
485 #else
486  struct stat stStats;
487  if (fstat(fdes,&stStats)) return 0;
488  return stStats.st_size;
489 #endif
490 }
491 
492 int FileTime(const char *szFilename)
493 {
494 #ifdef _WIN32
495  auto attributes = WIN32_FILE_ATTRIBUTE_DATA();
496  if (GetFileAttributesEx(GetWideChar(szFilename), GetFileExInfoStandard, &attributes) == 0)
497  return 0;
498  int64_t ft = (static_cast<int64_t>(attributes.ftLastWriteTime.dwHighDateTime) << (sizeof(attributes.ftLastWriteTime.dwLowDateTime) * 8)) | attributes.ftLastWriteTime.dwLowDateTime;
499  ft -= 116444736000000000;
500  ft /= 10000000;
501  return ft;
502 #else
503  struct stat stStats;
504  if (stat(szFilename,&stStats)!=0) return 0;
505  return stStats.st_mtime;
506 #endif
507 }
508 
509 bool EraseFile(const char *szFilename)
510 {
511 #ifdef _WIN32
512  SetFileAttributesW(GetWideChar(szFilename), FILE_ATTRIBUTE_NORMAL);
513  if (DeleteFileW(GetWideChar(szFilename)) == 0)
514  {
515  switch (GetLastError())
516  {
517  case ERROR_PATH_NOT_FOUND:
518  case ERROR_FILE_NOT_FOUND:
519  // While deleting it didn't work, the file doesn't exist (anymore).
520  // Pretend everything is fine.
521  return true;
522  default:
523  // Some other error left us unable to delete the file.
524  return false;
525  }
526  }
527  return true;
528 #else
529  // either unlink or remove could be used. Well, stick to ANSI C where possible.
530  if (remove(szFilename))
531  {
532  if (errno == ENOENT)
533  {
534  // Hah, here the wrapper actually makes sense:
535  // The engine only cares about the file not being there after this call.
536  return true;
537  }
538  return false;
539  }
540  return true;
541 #endif
542 }
543 
544 #ifndef _WIN32
545 bool CopyFile(const char *szSource, const char *szTarget, bool FailIfExists)
546 {
547  int fds = open (szSource, O_RDONLY | O_CLOEXEC);
548  if (!fds) return false;
549  struct stat info; fstat(fds, &info);
550  int fdt = open (szTarget, O_CLOEXEC | O_WRONLY | O_CREAT | (FailIfExists? O_EXCL : O_TRUNC), info.st_mode);
551  if (!fdt)
552  {
553  close (fds);
554  return false;
555  }
556  char buffer[1024]; ssize_t l;
557  while ((l = read(fds, buffer, sizeof(buffer))) > 0)
558  if (write(fdt, buffer, l) < l)
559  {
560  l = -1;
561  break;
562  }
563  close (fds);
564  close (fdt);
565  // On error, return false
566  return l != -1;
567 }
568 
569 bool RenameFile(const char *szFilename, const char *szNewFilename)
570 {
571  if (rename(szFilename,szNewFilename) < 0)
572  {
573  if (errno != EXDEV) return false;
574  if (CopyFile(szFilename, szNewFilename, false))
575  {
576  return EraseFile(szFilename);
577  }
578  return false;
579  }
580  return true;
581 }
582 #else
583 
584 #undef CopyFile
585 bool CopyFile(const char *szSource, const char *szTarget, bool FailIfExists)
586 {
587  return !!CopyFileW(GetWideChar(szSource), GetWideChar(szTarget), FailIfExists);
588 }
589 
590 bool RenameFile(const char *szFilename, const char *szNewFilename)
591 {
592  return !!MoveFileExW(GetWideChar(szFilename), GetWideChar(szNewFilename), MOVEFILE_COPY_ALLOWED);
593 }
594 
595 #endif
596 
597 bool MakeOriginalFilename(char *szFilename)
598 {
599  // safety
600  if (!szFilename) return false;
601 #ifdef _WIN32
602  // root-directory?
603  if (Inside(SLen(szFilename), 2u, 3u)) if (szFilename[1]==':')
604  {
605  szFilename[2]='\\'; szFilename[3]=0;
606  if (GetDriveTypeW(GetWideChar(szFilename)) == DRIVE_NO_ROOT_DIR) return false;
607  return true;
608  }
609  struct _wfinddata_t fdt; intptr_t shnd;
610  if ((shnd=_wfindfirst(GetWideChar(szFilename),&fdt))<0) return false;
611  _findclose(shnd);
612  StdStrBuf name(fdt.name);
613  SCopy(GetFilename(name.getData()),GetFilename(szFilename),_MAX_FNAME);
614 #else
615  if (SCharPos('*', szFilename) != -1)
616  {
617  fputs ("Warning: MakeOriginalFilename with \"", stderr);
618  fputs (szFilename, stderr);
619  fputs ("\"!\n", stderr);
620  }
621 #endif
622  return true;
623 }
#define _MAX_FNAME
ptrdiff_t ssize_t
#define O_CLOEXEC
bool IsWhiteSpace(char cChar)
Definition: Standard.h:72
int FileTime(const char *fname)
bool FileExists(const char *szFileName)
size_t FileSize(const char *fname)
bool RenameFile(const char *szFileName, const char *szNewFileName)
bool MakeOriginalFilename(char *szFilename)

References IsWhiteSpace(), SCharPos(), and SCopy().

Referenced by C4ScenarioListLoader::Entry::RenameTo(), and C4ObjectInfo::Save().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeTempFilename() [1/2]

void MakeTempFilename ( char *  szFilename)

Definition at line 320 of file StdFile.cpp.

321 {
322  DefaultExtension(szFilename,"tmp");
323  char *fn_ext=GetExtension(szFilename);
324  int cnum=-1;
325  do
326  {
327  cnum++;
328  osprintf(fn_ext,"%03d",cnum);
329  }
330  while (FileExists(szFilename) && (cnum<999));
331 }
int osprintf(char *str, const char *fmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: Standard.h:155
void DefaultExtension(char *szFilename, const char *szExtension)
Definition: StdFile.cpp:271

References DefaultExtension(), FileExists(), GetExtension(), and osprintf().

Referenced by C4Record::AddFile(), C4ControlJoinPlayer::C4ControlJoinPlayer(), C4ControlReInitScenario::C4ControlReInitScenario(), C4Group_CopyItem(), C4Group_MoveItem(), C4Group_PackDirectory(), C4Group_PackDirectoryTo(), C4Group_UnpackDirectory(), C4StartupNetDlg::DoOK(), C4ScenarioSection::EnsureTempStore(), C4Group::ExtractEntry(), C4Config::MakeTempUpdateFolder(), C4UpdatePackage::MkUp(), C4ControlJoinPlayer::PreRec(), C4Player::Save(), C4Group::Save(), C4Landscape::P::SaveInternal(), C4Surface::SavePNG(), C4Record::StartStreaming(), and C4Playback::StreamToRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeTempFilename() [2/2]

void MakeTempFilename ( StdStrBuf sFilename)

Definition at line 333 of file StdFile.cpp.

334 {
335  assert(sFilename);
336  if (!sFilename->getLength()) sFilename->Copy("temp.tmp");
337  EnforceExtension(sFilename, "tmp");
338  char *fn_ext=GetExtension(sFilename->getMData());
339  int cnum=-1;
340  do
341  {
342  cnum++;
343  osprintf(fn_ext,"%03d",cnum);
344  }
345  while (FileExists(sFilename->getData()) && (cnum<999));
346 }
void EnforceExtension(char *szFilename, const char *szExtension)
Definition: StdFile.cpp:286
char * getMData()
Definition: StdBuf.h:443
size_t getLength() const
Definition: StdBuf.h:445

References StdStrBuf::Copy(), EnforceExtension(), FileExists(), StdStrBuf::getData(), GetExtension(), StdStrBuf::getLength(), StdStrBuf::getMData(), and osprintf().

Here is the call graph for this function:

◆ MoveItem()

bool MoveItem ( const char *  szSource,
const char *  szTarget 
)

Definition at line 873 of file StdFile.cpp.

874 {
875  if (ItemIdentical(szSource,szTarget)) return true;
876  return RenameFile(szSource, szTarget);
877 }

References ItemIdentical(), and RenameFile().

Referenced by C4Group_MoveItem(), and C4StartupPlrSelDlg::PlayerListItem::MoveFilename().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RealPath()

void RealPath ( const char *  szFilename,
char *  pFullFilename 
)

Definition at line 138 of file StdFile.cpp.

139 {
140 #ifdef _WIN32
141  wchar_t *wpath = _wfullpath(nullptr, GetWideChar(szFilename), 0);
142  StdStrBuf path(wpath);
143  // I'm pretty sure pFullFilename will always have at least a size of _MAX_PATH, but ughh
144  // This should return a StdStrBuf
145  SCopy(path.getData(), pFullFilename, _MAX_PATH);
146  free(wpath);
147 #else
148  char *pSuffix = nullptr;
149  char szCopy[_MAX_PATH_LEN];
150  for (;;)
151  {
152  // Try to convert to full filename. Note this might fail if the given file doesn't exist
153  if (realpath(szFilename, pFullFilename))
154  break;
155  // ... which is undesired behaviour here. Try to reduce the filename until it works.
156  if (!pSuffix)
157  {
158  SCopy(szFilename, szCopy, _MAX_PATH);
159  szFilename = szCopy;
160  pSuffix = szCopy + SLen(szCopy);
161  }
162  else
163  *pSuffix = '/';
164  while (pSuffix > szCopy)
165  if (*--pSuffix == '/')
166  break;
167  if (pSuffix <= szCopy)
168  {
169  // Give up: Just copy whatever we got
170  SCopy(szFilename, pFullFilename, _MAX_PATH);
171  return;
172  }
173  *pSuffix = 0;
174  }
175  // Append suffix
176  if (pSuffix)
177  {
178  *pSuffix = '/';
179  SAppend(pSuffix, pFullFilename, _MAX_PATH);
180  }
181 #endif
182 }

References _MAX_PATH, _MAX_PATH_LEN, StdStrBuf::getData(), GetWideChar(), SAppend(), SCopy(), and SLen().

Referenced by GetParentPath(), and ItemIdentical().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemoveExtension() [1/2]

void RemoveExtension ( char *  szFilename)

Definition at line 303 of file StdFile.cpp.

304 {
305  char *ext = GetExtension(szFilename);
306  if (ext[0]) ext[-1]=0;
307 }

References GetExtension().

Referenced by C4MainMenu::ActivateSavegame(), C4FileSelDlg::DefaultListItem::DefaultListItem(), C4Console::FileSaveAs(), GetFilenameOnly(), C4AchievementGraphics::Init(), C4Surface::Load(), C4DefGraphics::Load(), C4ScenarioListLoader::Entry::Load(), C4Game::LoadScenarioComponents(), RemoveExtension(), C4ObjectInfo::Save(), and C4ScenarioListLoader::Entry::SetTitleInGroup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemoveExtension() [2/2]

void RemoveExtension ( StdStrBuf psFileName)

Definition at line 309 of file StdFile.cpp.

310 {
311  if (psFileName && *psFileName)
312  {
313  RemoveExtension(psFileName->getMData());
314  psFileName->SetLength(strlen(psFileName->getData()));
315  }
316 }
void SetLength(size_t iLength)
Definition: StdBuf.h:509

References StdStrBuf::getData(), StdStrBuf::getMData(), RemoveExtension(), and StdStrBuf::SetLength().

Here is the call graph for this function:

◆ RenameItem()

bool RenameItem ( const char *  szItemName,
const char *  szNewItemName 
)

Definition at line 827 of file StdFile.cpp.

828 {
829  // FIXME: What if the directory would have to be copied?
830  return RenameFile(szItemName,szNewItemName);
831 }

References RenameFile().

Referenced by C4Group::ExtractEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetWorkingDirectory()

bool SetWorkingDirectory ( const char *  path)

Definition at line 647 of file StdFile.cpp.

648 {
649 #ifdef _WIN32
650  return SetCurrentDirectoryW(GetWideChar(path)) != 0;
651 #else
652  return (chdir(path)==0);
653 #endif
654 }

References GetWideChar().

Referenced by EraseDirectory().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TruncateBackslash()

void TruncateBackslash ( char *  szFilename)

Definition at line 263 of file StdFile.cpp.

264 {
265  int i=SLen(szFilename);
266  if (i>0) if (szFilename[i-1]==DirectorySeparator) szFilename[i-1]=0;
267 }

References DirectorySeparator, and SLen().

Referenced by C4PortraitSelDlg::C4PortraitSelDlg(), C4Network2ResList::CreateNetworkFolder(), and C4Network2Res::SetByCore().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TruncatePath()

bool TruncatePath ( char *  szPath)

Definition at line 237 of file StdFile.cpp.

238 {
239  if (!szPath) return false;
240  int iBSPos;
241  iBSPos=SCharLastPos(DirectorySeparator,szPath);
242 #ifndef _WIN32
243  int iBSPos2;
244  iBSPos2=SCharLastPos('\\',szPath);
245  if (iBSPos2 > iBSPos) fprintf(stderr, "Warning: TruncatePath with a \\ (%s)\n", szPath);
246 #endif
247  if (iBSPos<0) return false;
248  szPath[iBSPos]=0;
249  return true;
250 }

References DirectorySeparator, and SCharLastPos().

Referenced by C4ConfigGeneral::DeterminePaths(), GetParentPath(), and C4Group::Open().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WildcardListMatch()

bool WildcardListMatch ( const char *  szWildcardList,
const char *  szString 
)

Definition at line 348 of file StdFile.cpp.

349 {
350  // safety
351  if (!szString || !szWildcardList) return false;
352  // match any item in list
353  StdStrBuf sWildcard, sWildcardList(szWildcardList);
354  int32_t i=0;
355  while (sWildcardList.GetSection(i++, &sWildcard, '|'))
356  {
357  if (WildcardMatch(sWildcard.getData(), szString)) return true;
358  }
359  // none matched
360  return false;
361 }
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:396

References StdStrBuf::getData(), StdStrBuf::GetSection(), and WildcardMatch().

Referenced by C4Group::PreCacheEntries().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WildcardMatch()

bool WildcardMatch ( const char *  szWildcard,
const char *  szString 
)

Definition at line 396 of file StdFile.cpp.

397 {
398  // safety
399  if (!szString || !szWildcard) return false;
400  // match char-wise
401  const char *pWild = szWildcard, *pPos = szString;
402  const char *pLWild = nullptr, *pLPos = nullptr; // backtracking
403  while (*pWild || pLWild)
404  // string wildcard?
405  if (*pWild == '*')
406  { pLWild = ++pWild; pLPos = pPos; }
407  // nothing left to match?
408  else if (!*pPos)
409  break;
410  // character class, equal or one-character-wildcard? proceed
411  else if ((*pWild == '[' && WildcardMatchCharacterClass(&pWild, *pPos))
412  || *pWild == '?'
413  || tolower(*pWild) == tolower(*pPos))
414  { pWild++; pPos++; }
415  // backtrack possible?
416  else if (pLPos)
417  { pWild = pLWild; pPos = ++pLPos; }
418  // match failed
419  else
420  return false;
421  // match complete if both strings are fully matched
422  return !*pWild && !*pPos;
423 }

Referenced by C4MainMenu::ActivateNewPlayer(), C4Group_ApplyUpdate(), C4Group_IsExcluded(), C4Effect::ClearAll(), C4ScenarioListLoader::Entry::CreateEntryForFile(), DirContainsScenarios(), DisplayGroup(), C4ScenarioSection::EnsureTempStore(), C4SoundSystem::FindInstance(), C4SoundSystem::GetEffect(), C4Group::GetEntry(), C4PlayerControlAssignmentSets::GetSetByName(), C4Effect::Init(), InitCoreFunctionMap(), C4Effect::Kill(), C4DefGraphics::Load(), C4ScenarioListLoader::SubFolder::LoadCustom(), C4TextureMap::LoadTextures(), C4PlayerControlAssignmentSets::MergeFrom(), C4StartupMainDlg::OnPlayerSelContextAdd(), C4StartupMainDlg::OnShown(), C4MessageInput::ProcessCommand(), C4GroupSet::RegisterParentFolders(), C4SoundSystem::RemoveEffect(), C4MusicSystem::SetPlayList(), C4Group::SortByList(), SortRank(), C4Record::Start(), C4Effect::TempReaddUpperEffects(), C4Effect::TempRemoveUpperEffects(), and WildcardListMatch().

Here is the caller graph for this function: