summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-10-22 20:48:59 -0400
committerTim Foley <tfoleyNV@users.noreply.github.com>2018-10-22 17:48:59 -0700
commit2700a89f8c80620f1d523563cc80ec0da39e9761 (patch)
tree375f29ffcc5ad4e0ced42b51f1cc214f7b37374a /source
parentcda9c3b1a712715209a3f4ba155c1425898334cb (diff)
Fix problem with __import not working (#688)
* Added getPathType to ISlangFileSystemExt. This is needed so that when searching for a file it's existance can be tested without loading the file. On some platforms a getCanonicalPath can do this - but depending on how getCanonicalPath is implemented, it may not do. This test is made after the relative path is produced before finding the canonical path. * Test for importing along search path. * Added comment to explain the issue around WrapFileSystem impl of getPathType. * Make search path use / not \
Diffstat (limited to 'source')
-rw-r--r--source/core/slang-io.cpp43
-rw-r--r--source/core/slang-io.h2
-rw-r--r--source/slang/default-file-system.cpp23
-rw-r--r--source/slang/default-file-system.h10
-rw-r--r--source/slang/slang.cpp7
5 files changed, 81 insertions, 4 deletions
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index ab093f577..2b443a62b 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -132,6 +132,49 @@ namespace Slang
#endif
}
+ /* static */SlangResult Path::GetPathType(const String & path, SlangPathType* pathTypeOut)
+ {
+#ifdef _WIN32
+ // https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx
+ struct _stat32 statVar;
+ if (::_wstat32(String(path).ToWString(), &statVar) == 0)
+ {
+ if (statVar.st_mode & _S_IFDIR)
+ {
+ *pathTypeOut = SLANG_PATH_TYPE_DIRECTORY;
+ return SLANG_OK;
+ }
+ else if (statVar.st_mode & _S_IFREG)
+ {
+ *pathTypeOut = SLANG_PATH_TYPE_FILE;
+ return SLANG_OK;
+ }
+ return SLANG_FAIL;
+ }
+
+ return SLANG_E_NOT_FOUND;
+#else
+ struct stat statVar;
+ if (::stat(path.Buffer(), &statVar) == 0)
+ {
+ if (S_ISDIR(statVar.st_mode))
+ {
+ *pathTypeOut = SLANG_PATH_TYPE_DIRECTORY;
+ return SLANG_OK;
+ }
+ if (S_ISREG(statVar.st_mode))
+ {
+ *pathTypeOut = SLANG_PATH_TYPE_FILE;
+ return SLANG_OK;
+ }
+ return SLANG_FAIL;
+ }
+
+ return SLANG_E_NOT_FOUND;
+#endif
+ }
+
+
/* static */SlangResult Path::GetCanonical(const String & path, String & canonicalPathOut)
{
#if defined(_WIN32)
diff --git a/source/core/slang-io.h b/source/core/slang-io.h
index 543b12adf..ff287254c 100644
--- a/source/core/slang-io.h
+++ b/source/core/slang-io.h
@@ -32,6 +32,8 @@ namespace Slang
static String Combine(const String & path1, const String & path2, const String & path3);
static bool CreateDir(const String & path);
+ static SlangResult GetPathType(const String & path, SlangPathType* pathTypeOut);
+
static SlangResult GetCanonical(const String & path, String& canonicalPathOut);
};
}
diff --git a/source/slang/default-file-system.cpp b/source/slang/default-file-system.cpp
index be171d37c..f9c66b7d7 100644
--- a/source/slang/default-file-system.cpp
+++ b/source/slang/default-file-system.cpp
@@ -51,10 +51,16 @@ SlangResult DefaultFileSystem::calcRelativePath(SlangPathType fromPathType, cons
return SLANG_OK;
}
+SlangResult SLANG_MCALL DefaultFileSystem::getPathType(
+ const char* path,
+ SlangPathType* pathTypeOut)
+{
+ return Path::GetPathType(path, pathTypeOut);
+}
+
SlangResult DefaultFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
{
- // Default implementation that uses the `core`
- // libraries facilities for talking to the OS filesystem.
+ // Default implementation that uses the `core` libraries facilities for talking to the OS filesystem.
//
// TODO: we might want to conditionally compile these in, so that
// a user could create a build of Slang that doesn't include any OS
@@ -93,7 +99,7 @@ SlangResult WrapFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
SlangResult WrapFileSystem::getCanoncialPath(const char* path, ISlangBlob** canonicalPathOut)
{
- // This isn't a very good 'canonical path' because the same file might be referenced
+ // This isn't a very good 'canonical path' because the same file might be referenced
// multiple ways - for example by using relative paths.
// But it's simple and matches slangs previous behavior.
String canonicalPath(path);
@@ -107,4 +113,15 @@ SlangResult WrapFileSystem::calcRelativePath(SlangPathType fromPathType, const c
return DefaultFileSystem::getSingleton()->calcRelativePath(fromPathType, fromPath, path, pathOut);
}
+SlangResult WrapFileSystem::getPathType(const char* path, SlangPathType* pathTypeOut)
+{
+ // TODO:
+ // This might be undesirable in the longer term because it means that ISlangFileSystem will not be used
+ // to test file existence - but the file system will be.
+ //
+ // It would probably be better to use some kind of cache that uses 'loadFile' to load files, but also
+ // to test for existence.
+ return DefaultFileSystem::getSingleton()->getPathType(path, pathTypeOut);
+}
+
} \ No newline at end of file
diff --git a/source/slang/default-file-system.h b/source/slang/default-file-system.h
index 62d7cbfc5..47644f5ad 100644
--- a/source/slang/default-file-system.h
+++ b/source/slang/default-file-system.h
@@ -33,11 +33,15 @@ public:
const char* path,
ISlangBlob** pathOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPathType(
+ const char* path,
+ SlangPathType* pathTypeOut) SLANG_OVERRIDE;
+
/// Get a default instance
static ISlangFileSystemExt* getSingleton() { return &s_singleton; }
private:
- /// Make so not constructable
+ /// Make so not constructible
DefaultFileSystem() {}
ISlangUnknown* getInterface(const Guid& guid);
@@ -75,6 +79,10 @@ public:
const char* path,
ISlangBlob** pathOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPathType(
+ const char* path,
+ SlangPathType* pathTypeOut) SLANG_OVERRIDE;
+
/// Ctor
WrapFileSystem(ISlangFileSystem* fileSystem):
m_fileSystem(fileSystem)
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 5461afbf7..996f8e32f 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -118,6 +118,13 @@ struct IncludeHandlerImpl : IncludeHandler
return SLANG_FAIL;
}
+ SlangPathType pathType;
+ SLANG_RETURN_ON_FAIL(fileSystemExt->getPathType(relPath.begin(), &pathType));
+ if (pathType != SLANG_PATH_TYPE_FILE)
+ {
+ return SLANG_E_NOT_FOUND;
+ }
+
// Get the canonical path
ComPtr<ISlangBlob> canonicalPathBlob;
SLANG_RETURN_ON_FAIL(fileSystemExt->getCanoncialPath(relPath.begin(), canonicalPathBlob.writeRef()));