From da7c1cab8c083e3370cc94a23bc396cd75b7f2a7 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Wed, 5 Jan 2011 16:38:57 +0000 Subject: [PATCH] Support/PathV2: Implement directory iteration on POSIX. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122879 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Unix/PathV2.inc | 54 +++++++++++++++++++++++++++++++++++++ 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 0facd6f4623..80e75ecbf5a 100644 --- a/lib/Support/Unix/PathV2.inc +++ b/lib/Support/Unix/PathV2.inc @@ -23,6 +23,22 @@ #if HAVE_FCNTL_H #include #endif +#if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif #if HAVE_STDIO_H #include #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(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(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(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 e958c1f4dae..a4fb518255b 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