#include "path.hpp"
#include "filesystem.hpp"
#ifdef _WIN32
#include <windows.h>
#define PATH_MAX MAX_PATH
#define access _access
#include <io.h>
#define F_OK 0
#define R_OK 2
#define W_OK 4
#define X_OK 0 //X_OK equivalent to F_OK on Windows
#else
#include <limits.h>
#include <unistd.h>
#endif
sprawl::String sprawl::path::AbsolutePath(String const& path)
{
String cwd = filesystem::GetCwd();
String joined = Join(cwd, path);
return NormPath(joined);
}
sprawl::String sprawl::path::Basename(String const& path)
{
int i = int(path.length() - 1);
char const sep = Separator();
char const altSep = AltSeparator();
for( ; i >= 0; --i)
{
if(path[i] == sep || path[i] == altSep)
{
break;
}
}
if(i < 0)
{
return path;
}
return String(path.c_str() + i + 1, path.length() - i - 1);
}
sprawl::String sprawl::path::Dirname(String const& path)
{
int i = int(path.length() - 1);
char const sep = Separator();
char const altSep = AltSeparator();
for( ; i >= 0; --i)
{
if(path[i] == sep || path[i] == altSep)
{
break;
}
}
if(i < 0)
{
return "";
}
return String(path.c_str(), i + 1);
}
bool sprawl::path::Exists(String const& path)
{
return access(path.GetOwned().c_str(), F_OK) == 0;
}
sprawl::path::SplitResult sprawl::path::Split(String const& path)
{
int i = int(path.length() - 1);
char const sep = Separator();
char const altSep = AltSeparator();
for( ; i >= 0; --i)
{
if(path[i] == sep || path[i] == altSep)
{
break;
}
}
if(i < 0)
{
return { "", path };
}
return { String(path.c_str(), i + 1), String(path.c_str() + i + 1, path.length() - i - 1) };
}
sprawl::path::DriveResult sprawl::path::SplitDrive(String const& path)
{
int i = int(path.length() - 1);
char const sep = DriveSeparator();
if(sep == '\0')
{
return { String(), path };
}
for( ; i >= 0; --i)
{
if(path[i] == sep)
{
break;
}
}
if(i < 0)
{
return { "", path };
}
return { String(path.c_str(), i + 1), String(path.c_str() + i + 1, path.length() - i - 1) };
}
sprawl::path::ExtResult sprawl::path::SplitExt(String const& path)
{
int i = int(path.length() - 1);
char const sep = ExtSeparator();
for( ; i >= 0; --i)
{
if(path[i] == sep)
{
break;
}
}
if(i < 0)
{
return { path, "" };
}
return { String(path.c_str(), i), String(path.c_str() + i + 1, path.length() - i - 1) };
}
sprawl::String sprawl::path::NormPath(String const& path)
{
char out[PATH_MAX];
char const sep = Separator();
char const altSep = AltSeparator();
size_t length = 0;
for(size_t i = 0; i < path.length(); ++i)
{
char c = path[i];
if (c == altSep)
{
c = sep;
}
if(c == sep)
{
//Collapse redundant separators
if(i != 0)
{
if(path[i-1] == sep || path[i-1] == altSep)
{
continue;
}
if(path[i-1] == '.')
{
if(i > 2 && path[i-2] == '.' && (path[i-3] == sep || path[i-3] == altSep))
{
if(length < 4)
{
length = 1;
continue;
}
length -= 4;
if(out[length] == '.')
{
length += 4;
out[length++] = c;
continue;
}
while(length > 1 && out[length-1] != sep)
{
--length;
}
continue;
}
if(i > 1 && (path[i-2] == sep || path[i-2] == altSep))
{
--length;
continue;
}
}
}
}
out[length++] = c;
}
if (length > 1 && out[length - 1] == sep)
{
--length;
}
out[length] = '\0';
return String(out, length);
}
bool sprawl::path::IsAbsolute(String const& path)
{
if(path.empty())
{
return false;
}
DriveResult result = SplitDrive(path);
char c = result.tail[0];
return c == Separator() || (c != '\0' && c == AltSeparator());
}
sprawl::String sprawl::path::CommonPrefix(String const& path1, String const& path2)
{
size_t maxLengthToIterate = path1.length() < path2.length() ? path1.length() : path2.length();
char const* const path1ptr = path1.c_str();
char const* const path2ptr = path2.c_str();
for(size_t i = 0; i < maxLengthToIterate; ++i)
{
if(path1ptr[i] != path2ptr[i])
{
return sprawl::String(path1ptr, i);
}
}
return sprawl::String(path1ptr, maxLengthToIterate);
}
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 23398 | ququlala | "Forking branch Mainline of shadauxcat-libsprawl to ququlala-libsprawl." | ||
| //guest/ShadauxCat/Sprawl/Mainline/filesystem/path.cpp | |||||
| #4 | 14816 | ShadauxCat |
Filled in some more filesystem functions, added appropriate unit tests. Only a few remain. #review-14817 |
||
| #3 | 14785 | ShadauxCat |
-Fixed search/replace mishap in const movement -Fixed a couple of missing windows headers -Adjusted PutEnv() so that Linux and Windows have matching functionality - empty string is equivalent to UnsetEnv. #review-14786 |
||
| #2 | 14781 | ShadauxCat |
-Finished path library -Added some more functionality to filesystem library -Added a few more unit tests, still more needed for path #review-14782 |
||
| #1 | 14761 | ShadauxCat |
First drop of code for sprawl::filesystem and sprawl::path. Library will continue to grow. Also fixed a warning on linux. #review-14762 |
||