[logging] Fix log folder creation from same directory

Expand find_base_path to support unix-style and local files.
Remove trailing path separators from find_base_path output.
Fix cases of local files such as `find_base_path("local_file")`
Fix logger creating directories such as xenia.log/ when run from a local
directory such as with ./build/bin/xenia under linux creating a directory
called xenia.log/ and then being unable to create a log of the same name.

Add tests to validate find_base_path.
This commit is contained in:
Sandy Carter 2019-01-20 21:34:59 -05:00
parent 738eb65643
commit 6cde4f9e12
2 changed files with 121 additions and 7 deletions
src/xenia/base

View File

@ -154,10 +154,13 @@ std::basic_string<T> find_name_from_path(const std::basic_string<T>& path,
if (!path.empty()) {
typename std::basic_string<T>::size_type from(std::basic_string<T>::npos);
if (path.back() == sep) {
if (path.length() == 1) {
return path;
}
from = path.size() - 2;
}
auto pos(path.find_last_of(sep, from));
if (pos != std::basic_string<T>::npos) {
if (pos != std::basic_string<T>::npos && pos != from) {
if (from == std::basic_string<T>::npos) {
name = path.substr(pos + 1);
} else {
@ -178,18 +181,28 @@ inline std::basic_string<T> find_name_from_path(const T* path,
template <typename T>
std::basic_string<T> find_base_path(const std::basic_string<T>& path,
T sep = xe::kPathSeparator<T>) {
auto path_start = path.find_first_of(T(':'));
if (path_start == std::basic_string<T>::npos) {
path_start = 0; // Unix-like or local file
} else {
path_start++; // Win32-like absolute path, i.e search after C:
}
auto last_slash = path.find_last_of(sep);
if (last_slash == std::basic_string<T>::npos) {
return path;
return std::basic_string<T>();
} else if (last_slash == path_start) { // Root directory
return path.substr(0, path_start + 1);
} else if (last_slash == path.length() - 1) {
auto prev_slash = path.find_last_of(sep, last_slash - 1);
if (prev_slash == std::basic_string<T>::npos) {
return std::basic_string<T>();
} else if (prev_slash == path_start) {
return path.substr(0, path_start + 1);
} else {
return path.substr(0, prev_slash + 1);
return path.substr(0, prev_slash);
}
} else {
return path.substr(0, last_slash + 1);
return path.substr(0, last_slash);
}
}
template <typename T>

View File

@ -15,9 +15,110 @@ namespace xe {
namespace base {
namespace test {
TEST_CASE("find_base_path") {
// TODO(bwrsandman):
REQUIRE(false);
TEST_CASE("find_name_from_path", "string") {
REQUIRE(find_name_from_path("", '\\') == "");
REQUIRE(find_name_from_path(L"", L'\\') == L"");
REQUIRE(find_name_from_path("xe:\\\\xam.xex", '\\') == "xam.xex");
REQUIRE(find_name_from_path(L"xe:\\\\xam.xex", L'\\') == L"xam.xex");
REQUIRE(find_name_from_path("xe:\\\\", '\\') == "xe:\\\\");
REQUIRE(find_name_from_path(L"xe:\\\\", L'\\') == L"xe:\\\\");
REQUIRE(find_name_from_path("C:\\filename.txt", '\\') == "filename.txt");
REQUIRE(find_name_from_path(L"C:\\filename.txt", L'\\') == L"filename.txt");
REQUIRE(find_name_from_path("C:\\Windows\\Users\\filename.txt", '\\') ==
"filename.txt");
REQUIRE(find_name_from_path(L"C:\\Windows\\Users\\filename.txt", L'\\') ==
L"filename.txt");
REQUIRE(find_name_from_path("C:\\", '\\') == "C:\\");
REQUIRE(find_name_from_path(L"C:\\", L'\\') == L"C:\\");
REQUIRE(find_name_from_path("C:\\Windows\\Users/filename.txt", '\\') ==
"Users/filename.txt");
REQUIRE(find_name_from_path(L"C:\\Windows\\Users/filename.txt", L'\\') ==
L"Users/filename.txt");
REQUIRE(find_name_from_path("C:/Windows/Users/filename.txt", '/') ==
"filename.txt");
REQUIRE(find_name_from_path(L"C:/Windows/Users/filename.txt", L'/') ==
L"filename.txt");
REQUIRE(find_name_from_path("/", '/') == "/");
REQUIRE(find_name_from_path(L"/", L'/') == L"/");
REQUIRE(find_name_from_path("/usr", '/') == "usr");
REQUIRE(find_name_from_path(L"/usr", L'/') == L"usr");
REQUIRE(find_name_from_path("~/filename.txt", '/') == "filename.txt");
REQUIRE(find_name_from_path(L"~/filename.txt", L'/') == L"filename.txt");
REQUIRE(find_name_from_path("~/.local/share/xenia/filename.txt", '/') ==
"filename.txt");
REQUIRE(find_name_from_path(L"~/.local/share/xenia/filename.txt", L'/') ==
L"filename.txt");
REQUIRE(find_name_from_path("~/.local/share/xenia", '/') == "xenia");
REQUIRE(find_name_from_path(L"~/.local/share/xenia", L'/') == L"xenia");
REQUIRE(find_name_from_path("~/.local/share/xenia/", '/') == "xenia");
REQUIRE(find_name_from_path(L"~/.local/share/xenia/", L'/') == L"xenia");
REQUIRE(find_name_from_path("filename.txt", '/') == "filename.txt");
REQUIRE(find_name_from_path(L"filename.txt", L'/') == L"filename.txt");
REQUIRE(find_name_from_path("C:\\New Volume\\filename.txt", '\\') ==
"filename.txt");
REQUIRE(find_name_from_path(L"C:\\New Volume\\filename.txt", L'\\') ==
L"filename.txt");
REQUIRE(find_name_from_path("C:\\New Volume\\dir\\filename.txt", '\\') ==
"filename.txt");
REQUIRE(find_name_from_path(L"C:\\New Volume\\dir\\filename.txt", L'\\') ==
L"filename.txt");
REQUIRE(find_name_from_path("C:\\New Volume\\file name.txt", '\\') ==
"file name.txt");
REQUIRE(find_name_from_path(L"C:\\New Volume\\file name.txt", L'\\') ==
L"file name.txt");
REQUIRE(find_name_from_path("/home/xenia/New Volume/file name.txt", '/') ==
"file name.txt");
REQUIRE(find_name_from_path(L"/home/xenia/New Volume/file name.txt", L'/') ==
L"file name.txt");
}
TEST_CASE("find_base_path", "string") {
REQUIRE(find_base_path("C:\\Windows\\Users", '\\') == "C:\\Windows");
REQUIRE(find_base_path(L"C:\\Windows\\Users", L'\\') == L"C:\\Windows");
REQUIRE(find_base_path("C:\\Windows\\Users\\", '\\') == "C:\\Windows");
REQUIRE(find_base_path(L"C:\\Windows\\Users\\", L'\\') == L"C:\\Windows");
REQUIRE(find_base_path("C:\\Windows", '\\') == "C:\\");
REQUIRE(find_base_path(L"C:\\Windows", L'\\') == L"C:\\");
REQUIRE(find_base_path("C:\\", '\\') == "C:\\");
REQUIRE(find_base_path(L"C:\\", L'\\') == L"C:\\");
REQUIRE(find_base_path("C:/Windows/Users", '/') == "C:/Windows");
REQUIRE(find_base_path(L"C:/Windows/Users", L'/') == L"C:/Windows");
REQUIRE(find_base_path("C:\\Windows/Users", '/') == "C:\\Windows");
REQUIRE(find_base_path(L"C:\\Windows/Users", L'/') == L"C:\\Windows");
REQUIRE(find_base_path("C:\\Windows/Users", '\\') == "C:\\");
REQUIRE(find_base_path(L"C:\\Windows/Users", L'\\') == L"C:\\");
REQUIRE(find_base_path("/usr/bin/bash", '/') == "/usr/bin");
REQUIRE(find_base_path(L"/usr/bin/bash", L'/') == L"/usr/bin");
REQUIRE(find_base_path("/usr/bin", '/') == "/usr");
REQUIRE(find_base_path(L"/usr/bin", L'/') == L"/usr");
REQUIRE(find_base_path("/usr/bin/", '/') == "/usr");
REQUIRE(find_base_path(L"/usr/bin/", L'/') == L"/usr");
REQUIRE(find_base_path("/usr", '/') == "/");
REQUIRE(find_base_path(L"/usr", L'/') == L"/");
REQUIRE(find_base_path("/usr/", '/') == "/");
REQUIRE(find_base_path(L"/usr/", L'/') == L"/");
REQUIRE(find_base_path("~/filename.txt", '/') == "~");
REQUIRE(find_base_path(L"~/filename.txt", L'/') == L"~");
REQUIRE(find_base_path("local_dir/subdirectory", '/') == "local_dir");
REQUIRE(find_base_path(L"local_dir/subdirectory", L'/') == L"local_dir");
REQUIRE(find_base_path("local_dir", '/') == "");
REQUIRE(find_base_path(L"local_dir", L'/') == L"");
REQUIRE(find_base_path("C:\\New Volume\\filename.txt", '\\') ==
"C:\\New Volume");
REQUIRE(find_base_path(L"C:\\New Volume\\filename.txt", L'\\') ==
L"C:\\New Volume");
REQUIRE(find_base_path("C:\\New Volume\\dir\\filename.txt", '\\') ==
"C:\\New Volume\\dir");
REQUIRE(find_base_path(L"C:\\New Volume\\dir\\filename.txt", L'\\') ==
L"C:\\New Volume\\dir");
REQUIRE(find_base_path("C:\\New Volume\\file name.txt", '\\') ==
"C:\\New Volume");
REQUIRE(find_base_path(L"C:\\New Volume\\file name.txt", L'\\') ==
L"C:\\New Volume");
REQUIRE(find_base_path("/home/xenia/New Volume/file name.txt", '/') ==
"/home/xenia/New Volume");
REQUIRE(find_base_path(L"/home/xenia/New Volume/file name.txt", L'/') ==
L"/home/xenia/New Volume");
}
} // namespace test