diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/core/slang-io.cpp | 96 | ||||
| -rw-r--r-- | source/core/slang-io.h | 31 |
2 files changed, 127 insertions, 0 deletions
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp index 1717c8354..5cbe021a2 100644 --- a/source/core/slang-io.cpp +++ b/source/core/slang-io.cpp @@ -19,6 +19,11 @@ #if defined(__linux__) || defined(__CYGWIN__) || SLANG_APPLE_FAMILY # include <unistd.h> +// For Path::find +# include <fnmatch.h> + +# include <dirent.h> +# include <sys/stat.h> #endif #if SLANG_APPLE_FAMILY @@ -552,6 +557,97 @@ namespace Slang #endif } +#if defined(_WIN32) + /* static */SlangResult Path::find(const String& directoryPath, const char* pattern, Visitor* visitor) + { + pattern = pattern ? pattern : "*"; + String searchPath = Path::combine(directoryPath, pattern); + + WIN32_FIND_DATAW fileData; + + HANDLE findHandle = FindFirstFileW(searchPath.toWString(), &fileData); + if (!findHandle) + { + return SLANG_E_NOT_FOUND; + } + + do + { + if (!((wcscmp(fileData.cFileName, L".") == 0) || + (wcscmp(fileData.cFileName, L"..") == 0))) + { + const Type type = (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? Type::Directory : Type::File; + + String filename = String::fromWString(fileData.cFileName); + visitor->accept(type, filename.getUnownedSlice()); + } + } + while (FindNextFileW(findHandle, &fileData) != 0); + + ::FindClose(findHandle); + return SLANG_OK; + } +#else + /* static */SlangResult Path::find(const String& directoryPath, const char* pattern, Visitor* visitor) + { + DIR* directory = opendir(directoryPath.getBuffer()); + + if (!directory) + { + return SLANG_E_NOT_FOUND; + } + + StringBuilder builder; + for (;;) + { + dirent* entry = readdir(directory); + if (entry == nullptr) + { + break; + } + + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + { + continue; + } + + // If there is a pattern, check if it matches, and if it doesn't ignore it + if (pattern && fnmatch(pattern, entry->d_name, 0) != 0) + { + continue; + } + + const UnownedStringSlice filename(entry->d_name); + + // Produce the full path, to do stat + Path::combineIntoBuilder(directoryPath.getUnownedSlice(), filename, builder); + + // fprintf(stderr, "stat(%s)\n", path.getBuffer()); + struct stat fileInfo; + if (stat(builder.getBuffer(), &fileInfo) != 0) + { + continue; + } + + Type type = Type::Unknown; + if (S_ISDIR(fileInfo.st_mode)) + { + type = Type::Directory; + } + else if (S_ISREG(fileInfo.st_mode)) + { + type = Type::File; + } + + visitor->accept(type, filename); + } + + closedir(directory); + return SLANG_OK; + } +#endif + /// Gets the path to the executable that was invoked that led to the current threads execution /// If run from a shared library/dll will be the path of the executable that loaded said library /// @param outPath Pointer to buffer to hold the path. diff --git a/source/core/slang-io.h b/source/core/slang-io.h index b3d03d9a4..492723602 100644 --- a/source/core/slang-io.h +++ b/source/core/slang-io.h @@ -25,8 +25,39 @@ namespace Slang class Path { public: + + enum class Type + { + Unknown, + File, + Directory, + }; + + typedef uint32_t TypeFlags; + struct TypeFlag + { + enum Enum : TypeFlags + { + Unknown = TypeFlags(1) << int(Type::Unknown), + File = TypeFlags(1) << int(Type::File), + Directory = TypeFlags(1) << int(Type::Directory), + }; + }; + + class Visitor + { + public: + virtual void accept(Type type, const UnownedStringSlice& filename) = 0; + }; + static const char kPathDelimiter = '/'; + /// Finds all all the items in the specified directory, that matches the pattern. + /// + /// @param directoryPath The directory to do the search in. If the directory is not found, SLANG_E_NOT_FOUND is returned + /// @param pattern. The pattern to match against. The pattern matching is targtet specific (ie window matching is different to linux/unix). Passing nullptr means no matching. + /// @return is SLANG_E_NOT_FOUND if the directoryPath is not found + static SlangResult find(const String& directoryPath, const char* pattern, Visitor* visitor); /// Returns -1 if no separator is found static Index findLastSeparatorIndex(String const& path); |
