mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2025-08-17 15:19:48 +00:00
First import
This commit is contained in:
commit
31a70945bb
7 changed files with 1071 additions and 0 deletions
156
src/filesearcher.cpp
Normal file
156
src/filesearcher.cpp
Normal file
|
@ -0,0 +1,156 @@
|
|||
/* Copyright 2015, Michele Santullo
|
||||
* This file is part of "dindexer".
|
||||
*
|
||||
* "dindexer" is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* "dindexer" is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "filesearcher.hpp"
|
||||
|
||||
#if !defined(_XOPEN_SOURCE)
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <ftw.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace fastf {
|
||||
extern "C" int PrintName ( const char* parPath, const struct stat* parStat, int parType, FTW* parBuff );
|
||||
|
||||
namespace {
|
||||
struct SearchOptions {
|
||||
FileSearcher::CallbackType* callback;
|
||||
const FileSearcher::ConstCharVecType* extensions;
|
||||
const FileSearcher::ConstCharVecType* ignorePaths;
|
||||
int search_flags;
|
||||
};
|
||||
|
||||
__thread SearchOptions g_searchOptions;
|
||||
|
||||
bool print_def_callback (const char* parPath, int parLevel, bool parDir, bool parSymlink) {
|
||||
std::cout << parPath;
|
||||
if (parDir) {
|
||||
std::cout << '/';
|
||||
}
|
||||
if (parSymlink) {
|
||||
std::cout << " (symlink)";
|
||||
}
|
||||
std::cout << " (" << parLevel << ')';
|
||||
std::cout << '\n';
|
||||
return true;
|
||||
}
|
||||
|
||||
int HandleDir (const char* parPath, const struct stat*, FTW* parBuff, bool parCanBeRead, bool parSymlink) {
|
||||
if (not (*g_searchOptions.callback)(parPath, parBuff->level, true, parSymlink))
|
||||
return FTW_STOP;
|
||||
if (!parCanBeRead)
|
||||
return FTW_SKIP_SUBTREE;
|
||||
|
||||
const FileSearcher::ConstCharVecType& ignorePaths = *g_searchOptions.ignorePaths;
|
||||
for (int z = 0; z < static_cast<int>(ignorePaths.size()); ++z) {
|
||||
if (std::strncmp(ignorePaths[z].str, parPath + parBuff->base, ignorePaths[z].len) == 0)
|
||||
return FTW_SKIP_SUBTREE;
|
||||
}
|
||||
return FTW_CONTINUE;
|
||||
}
|
||||
|
||||
int HandleFile (const char* parPath, const struct stat*, FTW* parBuff, bool parSymlink) {
|
||||
const FileSearcher::ConstCharVecType& extensions = *g_searchOptions.extensions;
|
||||
if (extensions.empty()) {
|
||||
if (not (*g_searchOptions.callback)(parPath, parBuff->level, false, parSymlink)) {
|
||||
return FTW_STOP;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int z = 0; z < static_cast<int>(extensions.size()); ++z) {
|
||||
const int& extLen = extensions[z].len;
|
||||
const int pathLen = parBuff->base + std::strlen(parPath + parBuff->base);
|
||||
if (std::strncmp(extensions[z].str, parPath + pathLen - extLen, extensions[z].len) == 0) {
|
||||
if (not (*g_searchOptions.callback)(parPath, parBuff->level, false, parSymlink)) {
|
||||
return FTW_STOP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FTW_CONTINUE;
|
||||
}
|
||||
|
||||
int HandleLink (const char* parPath, const struct stat* parStat, FTW* parBuff, bool parBroken) {
|
||||
if (parBroken)
|
||||
return FTW_CONTINUE;
|
||||
else
|
||||
return HandleFile(parPath, parStat, parBuff, true);
|
||||
}
|
||||
|
||||
extern "C" int PrintName (const char* parPath, const struct stat* parStat, int parType, FTW* parBuff) {
|
||||
struct stat st;
|
||||
lstat(parPath, &st);
|
||||
const bool is_symlink = S_ISLNK(st.st_mode);
|
||||
|
||||
switch (parType) {
|
||||
//parPath is a directory which can't be read
|
||||
case FTW_DNR:
|
||||
//parPath is a directory
|
||||
case FTW_D:
|
||||
return HandleDir(parPath, parStat, parBuff, static_cast<bool>(FTW_DNR != parType), is_symlink);
|
||||
|
||||
//parPath is a regular file
|
||||
case FTW_F:
|
||||
return HandleFile(parPath, parStat, parBuff, is_symlink);
|
||||
|
||||
//The stat(2) call failed on parPath, which is not a symbolic link
|
||||
case FTW_NS:
|
||||
return FTW_CONTINUE;
|
||||
|
||||
//parPath is a symbolic link pointing to a nonexistent file (This occurs only if FTW_PHYS is not set)
|
||||
case FTW_SLN:
|
||||
//parPath is a symbolic link, and FTW_PHYS was set in flags
|
||||
case FTW_SL:
|
||||
return HandleLink(parPath, parStat, parBuff, static_cast<bool>(FTW_SLN == parType));
|
||||
}
|
||||
|
||||
return FTW_CONTINUE;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
FileSearcher::FileSearcher (const char* parBaseDir) :
|
||||
callback_(&print_def_callback),
|
||||
baseDir_(parBaseDir),
|
||||
followSymlinks_(false),
|
||||
remainInFilesystem_(true)
|
||||
{
|
||||
}
|
||||
|
||||
FileSearcher::~FileSearcher() noexcept {
|
||||
}
|
||||
|
||||
void FileSearcher::Search (const ConstCharVecType& parExtensions, const ConstCharVecType& parIgnorePaths) {
|
||||
g_searchOptions.search_flags = FTW_ACTIONRETVAL;
|
||||
if (remainInFilesystem_)
|
||||
g_searchOptions.search_flags |= FTW_MOUNT;
|
||||
if (!followSymlinks_)
|
||||
g_searchOptions.search_flags |= FTW_PHYS;
|
||||
|
||||
g_searchOptions.extensions = &parExtensions;
|
||||
g_searchOptions.ignorePaths = &parIgnorePaths;
|
||||
g_searchOptions.callback = &callback_;
|
||||
nftw(baseDir_, &PrintName, 15, g_searchOptions.search_flags);
|
||||
}
|
||||
|
||||
void FileSearcher::SetCallback (CallbackType parCallback) {
|
||||
callback_ = parCallback;
|
||||
}
|
||||
} //namespace fastf
|
60
src/filesearcher.hpp
Normal file
60
src/filesearcher.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* Copyright 2015, Michele Santullo
|
||||
* This file is part of "dindexer".
|
||||
*
|
||||
* "dindexer" is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* "dindexer" is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef idB6D385B7779240308449D6081CB790F1
|
||||
#define idB6D385B7779240308449D6081CB790F1
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace fastf {
|
||||
struct StringWithLength {
|
||||
StringWithLength ( const char* parStr, int parLen ) :
|
||||
str(parStr),
|
||||
len(parLen)
|
||||
{
|
||||
}
|
||||
|
||||
const char* const str;
|
||||
const int len;
|
||||
};
|
||||
|
||||
class FileSearcher {
|
||||
public:
|
||||
typedef std::vector<StringWithLength> ConstCharVecType;
|
||||
typedef std::function<bool(const char*, int, bool, bool)> CallbackType;
|
||||
|
||||
explicit FileSearcher ( const char* parBaseDir );
|
||||
~FileSearcher ( void ) noexcept;
|
||||
|
||||
void Search ( const ConstCharVecType& parExtensions, const ConstCharVecType& parIgnorePaths );
|
||||
|
||||
void SetFollowSymlinks ( bool parFollow ) noexcept { followSymlinks_ = parFollow; }
|
||||
bool FollowSymlinks ( void ) const noexcept { return followSymlinks_; }
|
||||
void SetRemainInFilesystem ( bool parRemain ) noexcept { remainInFilesystem_ = parRemain; }
|
||||
bool RemainInFilesystem ( void ) const noexcept { return remainInFilesystem_; }
|
||||
void SetCallback ( CallbackType parCallback );
|
||||
|
||||
private:
|
||||
CallbackType callback_;
|
||||
const char* const baseDir_;
|
||||
bool followSymlinks_;
|
||||
bool remainInFilesystem_;
|
||||
};
|
||||
} //namespace fastf
|
||||
|
||||
#endif
|
54
src/main.cpp
Normal file
54
src/main.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* Copyright 2015, Michele Santullo
|
||||
* This file is part of "dindexer".
|
||||
*
|
||||
* "dindexer" is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* "dindexer" is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <ciso646>
|
||||
#include "filesearcher.hpp"
|
||||
#include "pathname.hpp"
|
||||
|
||||
bool my_callback (const char* parPath, int parLevel, bool parDir, bool parSymlink) {
|
||||
if (parLevel > 0 and not parDir)
|
||||
std::cout << parPath << '\n';
|
||||
return true;
|
||||
}
|
||||
|
||||
int main (int parArgc, char* parArgv[]) {
|
||||
std::cout << "argc: " << parArgc << '\n';
|
||||
for (int z = 0; z < parArgc; ++z) {
|
||||
std::cout << "argv[" << z << "]: " << parArgv[z] << '\n';
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
fastf::FileSearcher searcher("/home/duckz/dev/code/cpp/dindexer/test");
|
||||
fastf::FileSearcher::ConstCharVecType ext, ignore;
|
||||
searcher.SetFollowSymlinks(true);
|
||||
searcher.SetCallback(fastf::FileSearcher::CallbackType(&my_callback));
|
||||
//searcher.Search(ext, ignore);
|
||||
|
||||
din::PathName pn("/home/duckz/dev/code/cpp/dindexer/test");
|
||||
din::PathName pn1("///home/duckz/dev/code/cpp/dindexer/test");
|
||||
din::PathName pn2("home/duckz////dev/code/cpp/dindexer/test");
|
||||
din::PathName pn3("/home/duckz/dev/code/cpp/dindexer/test/");
|
||||
din::PathName pn4("/home/duckz/dev/code/cpp/dindexer/test////");
|
||||
|
||||
std::cout << pn.path() << '\n';
|
||||
std::cout << pn1.path() << '\n';
|
||||
std::cout << pn2.path() << '\n';
|
||||
std::cout << pn3.path() << '\n';
|
||||
std::cout << pn4.path() << '\n';
|
||||
return 0;
|
||||
}
|
77
src/pathname.cpp
Normal file
77
src/pathname.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* Copyright 2015, Michele Santullo
|
||||
* This file is part of "dindexer".
|
||||
*
|
||||
* "dindexer" is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* "dindexer" is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pathname.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
namespace din {
|
||||
namespace {
|
||||
void split_path (std::vector<std::string>* parOut, const char* parPath, std::size_t parLen) {
|
||||
parOut->clear();
|
||||
const char* from = parPath;
|
||||
const char* next;
|
||||
while (parPath + parLen != (next = std::find(from, parPath + parLen, '/'))) {
|
||||
if (next != from) {
|
||||
parOut->push_back(std::string(from, next));
|
||||
from = next;
|
||||
}
|
||||
++from;
|
||||
}
|
||||
if (next != from) {
|
||||
parOut->push_back(std::string(from, next));
|
||||
}
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
PathName::PathName (const char* parPath) {
|
||||
if (not parPath) {
|
||||
m_absolute = false;
|
||||
}
|
||||
else {
|
||||
m_absolute = ('/' == *parPath);
|
||||
split_path(&m_atoms, parPath, std::strlen(parPath));
|
||||
}
|
||||
}
|
||||
|
||||
std::string PathName::path() const {
|
||||
if (m_atoms.empty()) {
|
||||
if (m_absolute) {
|
||||
return std::string("/");
|
||||
}
|
||||
else {
|
||||
return std::string("");
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t reserve = (m_absolute ? 1 : 0);
|
||||
for (const auto& itm : m_atoms) {
|
||||
reserve += itm.size();
|
||||
}
|
||||
reserve += m_atoms.size() - 1;
|
||||
|
||||
std::string out;
|
||||
out.reserve(reserve);
|
||||
const char* slash = (m_absolute ? "/" : "");
|
||||
for (const auto& itm : m_atoms) {
|
||||
out += slash;
|
||||
out += itm;
|
||||
slash = "/";
|
||||
}
|
||||
return std::move(out);
|
||||
}
|
||||
} //namespace din
|
39
src/pathname.hpp
Normal file
39
src/pathname.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* Copyright 2015, Michele Santullo
|
||||
* This file is part of "dindexer".
|
||||
*
|
||||
* "dindexer" is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* "dindexer" is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef id279E04E31E2C4D98B8C902781A3CE018
|
||||
#define id279E04E31E2C4D98B8C902781A3CE018
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace din {
|
||||
class PathName {
|
||||
public:
|
||||
explicit PathName ( const char* parPath );
|
||||
~PathName ( void ) noexcept = default;
|
||||
|
||||
bool is_absolute ( void ) const;
|
||||
std::string path ( void ) const;
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_atoms;
|
||||
bool m_absolute;
|
||||
};
|
||||
} //namespace din
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue