summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--slang.h13
-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
-rw-r--r--tests/front-end/import-subdir-search-path.slang7
7 files changed, 99 insertions, 6 deletions
diff --git a/slang.h b/slang.h
index 4157f306d..d1a3803d1 100644
--- a/slang.h
+++ b/slang.h
@@ -685,7 +685,7 @@ extern "C"
typedef unsigned int SlangPathType;
enum
{
- SLANG_PATH_TYPE_DIRECTORY, /**< Path specified specifies a directory. */
+ SLANG_PATH_TYPE_DIRECTORY, /**< Path specified specifies a directory. */
SLANG_PATH_TYPE_FILE, /**< Path specified is to a file. */
};
@@ -734,7 +734,16 @@ extern "C"
SlangPathType fromPathType,
const char* fromPath,
const char* path,
- ISlangBlob** pathOut) = 0;
+ ISlangBlob** pathOut) = 0;
+
+ /** Gets the type of path that path is on the file system.
+ @param path
+ @param pathTypeOut
+ @returns SLANG_OK if located and type is known, else an error. SLANG_E_NOT_FOUND if not found.
+ */
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPathType(
+ const char* path,
+ SlangPathType* pathTypeOut) = 0;
};
#define SLANG_UUID_ISlangFileSystemExt { 0x5fb632d2, 0x979d, 0x4481, { 0x9f, 0xee, 0x66, 0x3c, 0x3f, 0x14, 0x49, 0xe1 } }
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()));
diff --git a/tests/front-end/import-subdir-search-path.slang b/tests/front-end/import-subdir-search-path.slang
new file mode 100644
index 000000000..e58736e8f
--- /dev/null
+++ b/tests/front-end/import-subdir-search-path.slang
@@ -0,0 +1,7 @@
+//TEST:SIMPLE: -Itests/front-end/subdir
+
+// Confirming import lookup via search paths work
+
+__import import_subdir_a;
+
+float bar(float x) { return foo(x); } \ No newline at end of file