diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-08-05 16:12:55 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-05 16:12:55 -0400 |
| commit | 3231048b328551edff9a923dec3f7bd46ed5aff8 (patch) | |
| tree | 844e82463e964afb04bca1deb85acfda1bdc56a2 /source/core/slang-io.cpp | |
| parent | e713b56a63dcbf945e3e0e6d82666318795c74ff (diff) | |
Refactor enumerating directory contents (#1478)
* Use m_style for OSFindFilesResult
* Refactor of FindFilesResult.
* Fixes on linux for FindFiles.
* Simplify FindFilesState, and linux support for pattern matching.
* Small fixes to linux FindFilesState
* Fix typo on linux FindFiles
* Fix typo in linux FindFiles.
* Renamed some variables, and improved comments on FindFiles.
* Improve comments on FildFiles
* Small improvements around FindFiles.
* Refactor FindFiles again.. into a visitor and function in Path.
* Fix some problems on linux.
* Fix linux typo.
* Renamed os -> find-file-util
* find-file-utl -> directory-util
Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source/core/slang-io.cpp')
| -rw-r--r-- | source/core/slang-io.cpp | 96 |
1 files changed, 96 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. |
