2017-11-15 15:59:39 +00:00
|
|
|
#include "utils/FileSystemUtil.h"
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#if defined(WIN32)
|
|
|
|
// because windows...
|
|
|
|
#include <direct.h>
|
|
|
|
#define snprintf _snprintf
|
|
|
|
#define mkdir(x,y) _mkdir(x)
|
|
|
|
#endif // WIN32
|
|
|
|
|
|
|
|
namespace Utils
|
|
|
|
{
|
|
|
|
namespace FileSystem
|
|
|
|
{
|
2017-11-22 21:29:52 +00:00
|
|
|
bool createDirectory(const std::string& _path)
|
2017-11-15 15:59:39 +00:00
|
|
|
{
|
|
|
|
// don't create if it already exists
|
2017-11-22 21:29:52 +00:00
|
|
|
if(exists(_path))
|
2017-11-15 15:59:39 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// convert '\\' to '/'
|
2017-11-22 21:29:52 +00:00
|
|
|
makeGeneric(_path);
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
// try to create directory
|
2017-11-22 21:29:52 +00:00
|
|
|
if(mkdir(_path.c_str(), 0755) == 0)
|
2017-11-15 15:59:39 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// failed to create directory, try to create the parent
|
2017-11-22 21:29:52 +00:00
|
|
|
std::string parent = getParent(_path);
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
// only try to create parent if it's not identical to path
|
2017-11-22 21:29:52 +00:00
|
|
|
if(parent != _path)
|
2017-11-15 15:59:39 +00:00
|
|
|
createDirectory(parent);
|
|
|
|
|
|
|
|
// try to create directory again now that the parent should exist
|
2017-11-22 21:29:52 +00:00
|
|
|
return (mkdir(_path.c_str(), 0755) == 0);
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
} // createDirectory
|
|
|
|
|
2017-11-22 21:29:52 +00:00
|
|
|
void makeGeneric(const std::string& _path)
|
2017-11-15 15:59:39 +00:00
|
|
|
{
|
|
|
|
char* p = nullptr;
|
|
|
|
|
|
|
|
// convert '\\' to '/'
|
2017-11-22 21:29:52 +00:00
|
|
|
for(p = (char*)_path.c_str() + 1; *p; ++p)
|
2017-11-15 15:59:39 +00:00
|
|
|
{
|
|
|
|
if(*p == '\\')
|
|
|
|
*p = '/';
|
|
|
|
}
|
|
|
|
|
2017-11-22 21:29:52 +00:00
|
|
|
} // makeGeneric
|
2017-11-15 15:59:39 +00:00
|
|
|
|
2017-11-22 21:29:52 +00:00
|
|
|
std::string escapePath(const std::string& _path)
|
2017-11-15 15:59:39 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
// windows escapes stuff by just putting everything in quotes
|
2017-11-22 21:29:52 +00:00
|
|
|
return '"' + _path + '"';
|
2017-11-15 15:59:39 +00:00
|
|
|
#else // WIN32
|
|
|
|
// insert a backslash before most characters that would mess up a bash path
|
2017-11-22 21:29:52 +00:00
|
|
|
std::string escapedPath = _path;
|
2017-11-15 15:59:39 +00:00
|
|
|
const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>";
|
2017-11-22 21:29:52 +00:00
|
|
|
const char* invalidChar = invalidChars;
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
while(*invalidChar)
|
|
|
|
{
|
|
|
|
for(size_t i = 0; i < escapedPath.length(); ++i)
|
|
|
|
{
|
|
|
|
if(escapedPath[i] == *invalidChar)
|
|
|
|
{
|
|
|
|
escapedPath.insert(i, 1, '\\');
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++invalidChar;
|
|
|
|
}
|
|
|
|
|
|
|
|
return escapedPath;
|
|
|
|
#endif // WIN32
|
|
|
|
|
|
|
|
} // escapePath
|
|
|
|
|
2017-11-22 21:29:52 +00:00
|
|
|
std::string getParent(const std::string& _path)
|
2017-11-15 15:59:39 +00:00
|
|
|
{
|
|
|
|
// convert '\\' to '/'
|
2017-11-22 21:29:52 +00:00
|
|
|
makeGeneric(_path);
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
// make a copy of the path
|
|
|
|
char temp[512];
|
2017-11-22 21:29:52 +00:00
|
|
|
size_t len = snprintf(temp, sizeof(temp), "%s", _path.c_str());
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
// find last '/' and end the new path
|
|
|
|
while(len > 1)
|
|
|
|
{
|
|
|
|
if(temp[--len] == '/')
|
|
|
|
{
|
|
|
|
temp[len] = 0;
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// no parent found
|
2017-11-22 21:29:52 +00:00
|
|
|
return _path;
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
} // getParent
|
|
|
|
|
2017-11-22 21:29:52 +00:00
|
|
|
std::string getFileName(const std::string& _path)
|
2017-11-15 15:59:39 +00:00
|
|
|
{
|
|
|
|
// convert '\\' to '/'
|
2017-11-22 21:29:52 +00:00
|
|
|
makeGeneric(_path);
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
// make a copy of the path
|
|
|
|
char temp[512];
|
2017-11-22 21:29:52 +00:00
|
|
|
size_t len = snprintf(temp, sizeof(temp), "%s", _path.c_str());
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
// find last '/' and return the filename
|
|
|
|
while(len > 1)
|
|
|
|
{
|
|
|
|
// return "." if this is the end of the path, otherwise return filename
|
|
|
|
if(temp[--len] == '/')
|
|
|
|
return ((temp[len + 1] == 0) ? "." : (temp + len + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
// no '/' found, entire path is a filename
|
2017-11-22 21:29:52 +00:00
|
|
|
return _path;
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
} // getFileName
|
|
|
|
|
2017-11-22 21:29:52 +00:00
|
|
|
std::string getStem(const std::string& _path)
|
2017-11-15 15:59:39 +00:00
|
|
|
{
|
2017-11-22 21:29:52 +00:00
|
|
|
std::string fileName = getFileName(_path);
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
// empty fileName
|
|
|
|
if(fileName == ".")
|
|
|
|
return fileName;
|
|
|
|
|
|
|
|
// make a copy of the filename
|
|
|
|
char temp[512];
|
|
|
|
size_t len = snprintf(temp, sizeof(temp), "%s", fileName.c_str());
|
|
|
|
|
|
|
|
// find last '.' and remove the extension
|
|
|
|
while(len > 1)
|
|
|
|
{
|
|
|
|
if(temp[--len] == '.')
|
|
|
|
{
|
|
|
|
temp[len] = 0;
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// no '.' found, filename has no extension
|
|
|
|
return fileName;
|
|
|
|
|
|
|
|
} // getStem
|
|
|
|
|
2017-11-22 21:29:52 +00:00
|
|
|
bool exists(const std::string& _path)
|
2017-11-15 15:59:39 +00:00
|
|
|
{
|
|
|
|
struct stat info;
|
2017-11-22 21:29:52 +00:00
|
|
|
return (stat(_path.c_str(), &info) == 0);
|
2017-11-15 15:59:39 +00:00
|
|
|
|
|
|
|
} // exists
|
|
|
|
|
|
|
|
} // FileSystem::
|
|
|
|
|
|
|
|
} // Utils::
|