1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*
* This file is part of Warzone 2100.
* Copyright (C) 2018-2020 Warzone 2100 Project
*
* Warzone 2100 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.
*
* Warzone 2100 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 Warzone 2100; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "frame.h"
#include "wzpaths.h"
#include <physfs.h>
#include <vector>
#include <algorithm>
std::vector<std::string> splitAtAnyDelimiter(const std::string& s, const std::string& delimiters)
{
std::vector<std::string> v;
auto pos = s.begin();
while(pos != s.end())
{
auto end = std::find_first_of(pos, s.end(), delimiters.begin(), delimiters.end());
v.emplace_back(pos, end);
pos = end;
if (pos != s.end())
{
++pos;
}
}
return v;
}
std::string getWZInstallPrefix()
{
const std::string dirSeparator(PHYSFS_getDirSeparator());
ASSERT(dirSeparator.length() > 0, "PHYSFS_getDirSeparator returned an empty string");
// Construct the install PREFIX path
std::string prefixDir(PHYSFS_getBaseDir());
while (!prefixDir.empty() && (prefixDir.rfind(dirSeparator, std::string::npos) == (prefixDir.length() - dirSeparator.length())))
{
prefixDir.resize(prefixDir.length() - dirSeparator.length()); // Remove trailing path separators
}
size_t binDirComponentsCount = 1;
#ifdef WZ_BINDIR
// Trim off as many path components as are in WZ_BINDIR
std::string binDir(WZ_BINDIR);
std::vector<std::string> binDirComponents = splitAtAnyDelimiter(binDir, "/");
binDirComponentsCount = std::count_if(binDirComponents.begin(), binDirComponents.end(), [](const std::string &s) { return !s.empty() && (s != "."); });
ASSERT(binDirComponentsCount > 0, "WZ_BINDIR unexpectedly has zero components?: \"%s\"", WZ_BINDIR);
#endif
for (size_t i = 0; i < binDirComponentsCount; ++i)
{
size_t lastSlash = prefixDir.rfind(dirSeparator, std::string::npos);
if (lastSlash != std::string::npos)
{
prefixDir = prefixDir.substr(0, lastSlash); // Trim off the last path component
}
}
return prefixDir;
}
// MARK: - WzPathInfo
WzPathInfo::WzPathInfo(const std::string &file)
: file(file)
{ }
WzPathInfo WzPathInfo::fromPlatformIndependentPath(const std::string& file)
{
return WzPathInfo(file);
}
// Returns the name of the file (excluding the path).
std::string WzPathInfo::fileName() const
{
auto lastSlashPos = file.rfind('/');
if (std::string::npos == lastSlashPos)
{
// no slash - treat the entire string as the filename
return file;
}
return file.substr(lastSlashPos + 1);
}
// Returns the file name, including the path.
std::string WzPathInfo::filePath() const
{
return file;
}
// Returns the base name of the file (without the path).
// The base name = all characters in the file up to (but not including) the first '.' character.
// ex.
// ```cpp
// WzPathInfo info("/autohost/example.js");
// auto result = info.baseName(); // result == "example"
// ```
std::string WzPathInfo::baseName() const
{
auto result = fileName();
auto firstPeriodPos = result.find('.');
if (std::string::npos == firstPeriodPos)
{
// no period
return result;
}
return result.substr(0, firstPeriodPos);
}
// Returns the file's path. Does *not* include the file name.
std::string WzPathInfo::path() const
{
auto lastSlashPos = file.rfind('/');
if (std::string::npos == lastSlashPos)
{
// no slash - return "." as the path
return ".";
}
return file.substr(0, std::max<size_t>(lastSlashPos, (size_t)1));
}
// Returns the path components as a vector
std::vector<std::string> WzPathInfo::pathComponents() const
{
return splitAtAnyDelimiter(file, "/");
}
|