diff options
| -rw-r--r-- | slang.h | 13 | ||||
| -rw-r--r-- | source/core/slang-io.cpp | 43 | ||||
| -rw-r--r-- | source/core/slang-io.h | 2 | ||||
| -rw-r--r-- | source/slang/default-file-system.cpp | 23 | ||||
| -rw-r--r-- | source/slang/default-file-system.h | 10 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 7 | ||||
| -rw-r--r-- | tests/front-end/import-subdir-search-path.slang | 7 |
7 files changed, 99 insertions, 6 deletions
@@ -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 |
