summaryrefslogtreecommitdiffstats
path: root/source/core/slang-io.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-10-26 08:16:54 -0400
committerGitHub <noreply@github.com>2018-10-26 08:16:54 -0400
commitcb9d679a3a93c65c44904bf77811b9d74e431e23 (patch)
treebdc78bc01351f6eeed4714d01cd3aef6cf067109 /source/core/slang-io.cpp
parentad47fe71defcc96a7bed87a4c3a40543978f0fb8 (diff)
Feature/file system cache (#692)
* First pass at caching file system. * default-file-system -> slang-file-system fix problem with location("build.linux") confusing windows build for now. * Added CompressedResult Fix problem in Result construction with it being unsigned * Add support for Path simplification. * Testing for Path::Simplify. * Refactored CacheFileSystem - automatically handles ISlangFileSystem or ISlangFileSystemExt appropriately. Removed WrapFileSystem - because wasn't possible to emulate some of the behavior if just loadFile is implemented. Split out StringBlob - so that no need to convert between ISlangBlob and String repeatidly. * Remove unwanted code in ~CompileRequest
Diffstat (limited to 'source/core/slang-io.cpp')
-rw-r--r--source/core/slang-io.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index 2b443a62b..f1948200c 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -123,6 +123,105 @@ namespace Slang
return sb.ProduceString();
}
+ /* static */ bool Path::IsDriveSpecification(const UnownedStringSlice& element)
+ {
+ switch (element.size())
+ {
+ case 0:
+ {
+ // We'll just assume it is
+ return true;
+ }
+ case 2:
+ {
+ // Look for a windows like drive spec
+ const char firstChar = element[0];
+ return element[1] == ':' && ((firstChar >= 'a' && firstChar <= 'z') || (firstChar >= 'A' && firstChar <= 'Z'));
+ }
+ default: return false;
+ }
+
+ }
+
+ /* static */void Path::Split(const UnownedStringSlice& path, List<UnownedStringSlice>& splitOut)
+ {
+ splitOut.Clear();
+
+ const char* start = path.begin();
+ const char* end = path.end();
+
+ while (start < end)
+ {
+ const char* cur = start;
+ // Find the split
+ while (cur < end && !IsDelimiter(*cur)) cur++;
+
+ splitOut.Add(UnownedStringSlice(start, cur));
+
+ // Next
+ start = cur + 1;
+ }
+
+ // Okay if the end is empty. And we aren't with a spec like // or c:/ , then drop the final slash
+ if (splitOut.Count() > 1 && splitOut.Last().size() == 0)
+ {
+ if (splitOut.Count() == 2 && IsDriveSpecification(splitOut[0]))
+ {
+ return;
+ }
+ // Remove the last
+ splitOut.RemoveLast();
+ }
+ }
+
+ /* static */String Path::Simplify(const UnownedStringSlice& path)
+ {
+ List<UnownedStringSlice> split;
+ Split(path, split);
+
+ // Strictly speaking we could do something about case on platforms like window, but here we won't worry about that
+ for (int i = 0; i < int(split.Count()); i++)
+ {
+ const UnownedStringSlice& cur = split[i];
+ if (cur == "." && split.Count() > 1)
+ {
+ // Just remove it
+ split.RemoveAt(i);
+ i--;
+ }
+ else if (cur == ".." && i > 0)
+ {
+ // Can we remove this and the one before ?
+ UnownedStringSlice& before = split[i - 1];
+ if (before == ".." || (i == 1 && IsDriveSpecification(before)))
+ {
+ // Can't do it
+ continue;
+ }
+ split.RemoveRange(i - 1, 2);
+ i -= 2;
+ }
+ }
+
+ // If its empty it must be .
+ if (split.Count() == 0)
+ {
+ split.Add(UnownedStringSlice::fromLiteral("."));
+ }
+
+ // Reconstruct the string
+ StringBuilder builder;
+ for (int i = 0; i < int(split.Count()); i++)
+ {
+ if (i > 0)
+ {
+ builder.Append(PathDelimiter);
+ }
+ builder.Append(split[i]);
+ }
+ return builder;
+ }
+
bool Path::CreateDir(const String & path)
{
#if defined(_WIN32)