forked from OctaForge/libostd
add a range to iterate a directory
This commit is contained in:
parent
1ade11b936
commit
4ef512effa
2
build.cc
2
build.cc
|
@ -14,6 +14,7 @@
|
|||
#include "ostd/range.hh"
|
||||
#include "ostd/format.hh"
|
||||
#include "ostd/string.hh"
|
||||
#include "ostd/path.hh"
|
||||
#include "ostd/filesystem.hh"
|
||||
#include "ostd/thread_pool.hh"
|
||||
#include "ostd/channel.hh"
|
||||
|
@ -24,6 +25,7 @@ namespace fs = ostd::filesystem;
|
|||
/* ugly, but do not explicitly compile */
|
||||
#include "src/io.cc"
|
||||
#include "src/process.cc"
|
||||
#include "srC/path.cc"
|
||||
#include "src/filesystem.cc"
|
||||
#include "src/thread_pool.cc"
|
||||
#include "src/channel.cc"
|
||||
|
|
82
ostd/path.hh
82
ostd/path.hh
|
@ -366,6 +366,10 @@ struct path {
|
|||
p_path = ".";
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return (p_path == ".");
|
||||
}
|
||||
|
||||
void swap(path &other) noexcept {
|
||||
p_path.swap(other.p_path);
|
||||
std::swap(p_fmt, other.p_fmt);
|
||||
|
@ -689,6 +693,84 @@ namespace fs {
|
|||
* @{
|
||||
*/
|
||||
|
||||
struct directory_entry {
|
||||
directory_entry() {}
|
||||
directory_entry(ostd::path const &p): p_path(p) {}
|
||||
|
||||
ostd::path const &path() const noexcept {
|
||||
return p_path;
|
||||
}
|
||||
|
||||
operator ostd::path const &() const noexcept {
|
||||
return p_path;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
p_path.clear();
|
||||
}
|
||||
|
||||
void assign(ostd::path const &p) {
|
||||
p_path = p;
|
||||
}
|
||||
|
||||
void assign(ostd::path &&p) {
|
||||
p_path = std::move(p);
|
||||
}
|
||||
|
||||
private:
|
||||
ostd::path p_path{};
|
||||
};
|
||||
|
||||
struct directory_range: input_range<directory_range> {
|
||||
using range_category = input_range_tag;
|
||||
using value_type = directory_entry;
|
||||
using reference = directory_entry const &;
|
||||
using size_type = std::size_t;
|
||||
|
||||
directory_range() = delete;
|
||||
directory_range(path const &p) {
|
||||
open(p);
|
||||
}
|
||||
|
||||
directory_range(directory_range const &r) noexcept:
|
||||
p_current(r.p_current), p_dir(r.p_dir),
|
||||
p_handle(r.p_handle), p_owned(false)
|
||||
{}
|
||||
|
||||
~directory_range() {
|
||||
close();
|
||||
}
|
||||
|
||||
directory_range &operator=(directory_range const &r) noexcept {
|
||||
close();
|
||||
p_handle = r.p_handle;
|
||||
p_owned = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const noexcept {
|
||||
return p_current.path().empty();
|
||||
}
|
||||
|
||||
void pop_front() {
|
||||
read_next();
|
||||
}
|
||||
|
||||
reference front() const noexcept {
|
||||
return p_current;
|
||||
}
|
||||
|
||||
private:
|
||||
void open(path const &p);
|
||||
void close() noexcept;
|
||||
void read_next();
|
||||
|
||||
directory_entry p_current{};
|
||||
path p_dir{};
|
||||
void *p_handle = nullptr;
|
||||
bool p_owned = false;
|
||||
};
|
||||
|
||||
OSTD_EXPORT path cwd();
|
||||
OSTD_EXPORT path home();
|
||||
|
||||
|
|
14
src/path.cc
Normal file
14
src/path.cc
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* Decides between POSIX and Windows for path.
|
||||
*
|
||||
* This file is part of libostd. See COPYING.md for futher information.
|
||||
*/
|
||||
|
||||
#include "ostd/platform.hh"
|
||||
|
||||
#if defined(OSTD_PLATFORM_WIN32)
|
||||
# include "src/win32/path.cc"
|
||||
#elif defined(OSTD_PLATFORM_POSIX)
|
||||
# include "src/posix/path.cc"
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
#endif
|
59
src/posix/path.cc
Normal file
59
src/posix/path.cc
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Path implementation bits.
|
||||
*
|
||||
* This file is part of libostd. See COPYING.md for futher information.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "ostd/path.hh"
|
||||
|
||||
namespace ostd {
|
||||
namespace fs {
|
||||
|
||||
void directory_range::open(path const &p) {
|
||||
DIR *d = opendir(p.string().data());
|
||||
if (!d) {
|
||||
/* FIXME: throw */
|
||||
abort();
|
||||
}
|
||||
p_dir = p;
|
||||
p_handle = d;
|
||||
p_owned = true;
|
||||
read_next();
|
||||
}
|
||||
|
||||
void directory_range::close() noexcept {
|
||||
if (!p_owned) {
|
||||
return;
|
||||
}
|
||||
closedir(static_cast<DIR *>(p_handle));
|
||||
p_owned = false;
|
||||
}
|
||||
|
||||
void directory_range::read_next() {
|
||||
struct dirent d;
|
||||
struct dirent *o;
|
||||
DIR *dh = static_cast<DIR *>(p_handle);
|
||||
for (;;) {
|
||||
if (readdir_r(dh, &d, &o)) {
|
||||
/* FIXME: throw */
|
||||
abort();
|
||||
}
|
||||
if (!o) {
|
||||
p_current.clear();
|
||||
return;
|
||||
}
|
||||
string_range nm{static_cast<char const *>(o->d_name)};
|
||||
if ((nm == ".") || (nm == "..")) {
|
||||
continue;
|
||||
}
|
||||
path p{p_dir};
|
||||
p.append(nm);
|
||||
p_current.assign(std::move(p));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namesapce fs */
|
||||
} /* namespace ostd */
|
6
src/win32/path.cc
Normal file
6
src/win32/path.cc
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* Path implementation bits.
|
||||
*
|
||||
* This file is part of libostd. See COPYING.md for futher information.
|
||||
*/
|
||||
|
||||
#error "path doesn't work on Windows at this time"
|
Loading…
Reference in a new issue