diff options
author | Michael J. Spencer <bigcheesegs@gmail.com> | 2011-01-05 16:38:57 +0000 |
---|---|---|
committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2011-01-05 16:38:57 +0000 |
commit | da7c1cab8c083e3370cc94a23bc396cd75b7f2a7 (patch) | |
tree | 03e4103317d2865cbafaf28580957e9e08496856 | |
parent | 1901925b783f4ef0ee5b6bbb3faeea6813b00ee2 (diff) | |
download | external_llvm-da7c1cab8c083e3370cc94a23bc396cd75b7f2a7.zip external_llvm-da7c1cab8c083e3370cc94a23bc396cd75b7f2a7.tar.gz external_llvm-da7c1cab8c083e3370cc94a23bc396cd75b7f2a7.tar.bz2 |
Support/PathV2: Implement directory iteration on POSIX.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122879 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Support/Unix/PathV2.inc | 54 | ||||
-rw-r--r-- | unittests/Support/Path.cpp | 3 |
2 files changed, 54 insertions, 3 deletions
diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc index 0facd6f..80e75ec 100644 --- a/lib/Support/Unix/PathV2.inc +++ b/lib/Support/Unix/PathV2.inc @@ -23,6 +23,22 @@ #if HAVE_FCNTL_H #include <fcntl.h> #endif +#if HAVE_DIRENT_H +# include <dirent.h> +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# if HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# if HAVE_NDIR_H +# include <ndir.h> +# endif +#endif #if HAVE_STDIO_H #include <stdio.h> #endif @@ -408,6 +424,44 @@ rety_open_create: return success; } +error_code directory_iterator_construct(directory_iterator &it, StringRef path){ + SmallString<128> path_null(path); + DIR *directory = ::opendir(path_null.c_str()); + if (directory == 0) + return error_code(errno, system_category()); + + it.IterationHandle = reinterpret_cast<intptr_t>(directory); + // Add something for replace_filename to replace. + path::append(path_null, "."); + it.CurrentEntry = directory_entry(path_null.str()); + return directory_iterator_increment(it); +} + +error_code directory_iterator_destruct(directory_iterator& it) { + if (it.IterationHandle) + ::closedir(reinterpret_cast<DIR *>(it.IterationHandle)); + it.IterationHandle = 0; + it.CurrentEntry = directory_entry(); + return success; +} + +error_code directory_iterator_increment(directory_iterator& it) { + errno = 0; + dirent *cur_dir = ::readdir(reinterpret_cast<DIR *>(it.IterationHandle)); + if (cur_dir == 0 && errno != 0) { + return error_code(errno, system_category()); + } else if (cur_dir != 0) { + StringRef name(cur_dir->d_name, NAMLEN(cur_dir)); + if ((name.size() == 1 && name[0] == '.') || + (name.size() == 2 && name[0] == '.' && name[1] == '.')) + return directory_iterator_increment(it); + it.CurrentEntry.replace_filename(name); + } else + return directory_iterator_destruct(it); + + return success; +} + } // end namespace fs } // end namespace sys } // end namespace llvm diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp index e958c1f..a4fb518 100644 --- a/unittests/Support/Path.cpp +++ b/unittests/Support/Path.cpp @@ -176,8 +176,6 @@ TEST(Support, Path) { ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists)); EXPECT_FALSE(TempFileExists); - // I've yet to do directory iteration on Unix. -#ifdef LLVM_ON_WIN32 error_code ec; for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec)) { if (ec) { @@ -186,7 +184,6 @@ TEST(Support, Path) { report_fatal_error("Directory iteration failed!"); } } -#endif } } // anonymous namespace |