Exemplo n.º 1
0
void Path::visit(VisitCallback callback, void *userData) const
{
    if (!callback || !isDir())
        return;
    Set<Path> seenDirs;
    visitorWrapper(*this, callback, seenDirs, userData);
}
Exemplo n.º 2
0
void Path::visit(const std::function<VisitResult(const Path &path)> &callback) const
{
    if (!callback || !isDir())
        return;
    Set<Path> seenDirs;
    visitorWrapper(*this, callback, seenDirs);
}
Exemplo n.º 3
0
static void visitorWrapper(Path path, Path::VisitCallback callback, Set<Path> &seen, void *userData)
{
    if (!seen.insert(path.resolved())) {
        return;
    }
    DIR *d = opendir(path.constData());
    if (!d)
        return;

    char buf[PATH_MAX + sizeof(dirent) + 1];
    dirent *dbuf = reinterpret_cast<dirent*>(buf);

    dirent *p;
    if (!path.endsWith('/'))
        path.append('/');
    const int s = path.size();
    path.reserve(s + 128);
    List<String> recurseDirs;
    while (!readdir_r(d, dbuf, &p) && p) {
        if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
            continue;
        path.truncate(s);
        path.append(p->d_name);
#if defined(_DIRENT_HAVE_D_TYPE) && defined(_BSD_SOURCE)
        if (p->d_type == DT_DIR)
            path.append('/');
#else
        if (path.isDir())
            path.append('/');
#endif
        switch (callback(path, userData)) {
        case Path::Abort:
            p = 0;
            break;
        case Path::Recurse:
            if (path.isDir())
                recurseDirs.append(p->d_name);
            break;
        case Path::Continue:
            break;
        }
    }
    closedir(d);
    const int count = recurseDirs.size();
    for (int i=0; i<count; ++i) {
        path.truncate(s);
        path.append(recurseDirs.at(i));
        visitorWrapper(path, callback, seen, userData);
    }
}