Compare commits
5 Commits
357783a082
...
bf6de10073
Author | SHA1 | Date |
---|---|---|
mrbesen | bf6de10073 | |
mrbesen | 6337609f1b | |
mrbesen | c69b209dd4 | |
mrbesen | 00a2218d98 | |
mrbesen | fa59de25f7 |
23
Makefile
23
Makefile
|
@ -5,8 +5,8 @@
|
|||
# `make clean all` nicht mit -j verwenden! -> race condition im make file
|
||||
# statdessen: `make clean; make all -j` verwenden
|
||||
|
||||
NAME = libmrbesen.so
|
||||
NAMEINC = mrbesen
|
||||
NAMESHORT = mrbesen
|
||||
NAME = lib$(NAMESHORT).so
|
||||
NAMETEST = test
|
||||
CFLAGS = -fpic -std=c++17 -O2 -g -pipe -Wall -Wextra -Wno-unused-parameter -Wpedantic
|
||||
CXX = g++
|
||||
|
@ -15,6 +15,7 @@ BUILDDIR = build/
|
|||
INCF = inc/
|
||||
TESTF = tests/
|
||||
DEPF = $(BUILDDIR)deps/
|
||||
OUTF = ./
|
||||
|
||||
INCLUDES = -I$(INCF)
|
||||
LDFLAGS =
|
||||
|
@ -28,11 +29,11 @@ BUILDDIRS = $(patsubst $(SRCF)%, $(BUILDDIR)%, $(SOURCEDIRS))
|
|||
|
||||
INCLUDES += $(addprefix -I, $(SOURCEDIRS))
|
||||
|
||||
all: $(NAME) runtest
|
||||
all: $(OUTF)$(NAME) runtest
|
||||
|
||||
$(NAME): $(BUILDDIRS) $(DEPF) $(OBJFILES)
|
||||
$(OUTF)$(NAME): $(BUILDDIRS) $(DEPF) $(OBJFILES)
|
||||
@echo "Linking $@"
|
||||
@$(LD) -shared -o $@ $(filter %.o, $^)
|
||||
@$(CXX) -shared -o $@ $(filter %.o, $^)
|
||||
|
||||
$(BUILDDIR)%.o: $(SRCF)%.cpp
|
||||
@echo "Compiling: $@"
|
||||
|
@ -46,24 +47,24 @@ clean-depends:
|
|||
$(RM) -r $(DEPF)
|
||||
|
||||
clean:
|
||||
$(RM) -r $(NAME) $(BUILDDIR) $(NAMETEST)
|
||||
$(RM) -r $(OUTF)$(NAME) $(BUILDDIR) $(NAMETEST)
|
||||
|
||||
$(NAMETEST): $(NAME) $(TESTF)*.cpp
|
||||
@echo "Compiling tests"
|
||||
@$(CXX) -o $@ $(filter-out %.so, $^) $(CFLAGS) $(INCLUDES) $(LDFLAGS) -L./ -lmrbesen
|
||||
@$(CXX) -o $@ $(filter-out %.so, $^) $(CFLAGS) $(INCLUDES) $(LDFLAGS) -L$(OUTF) -l$(NAMESHORT)
|
||||
|
||||
runtest: $(NAMETEST)
|
||||
@echo "Running tests"
|
||||
LD_LIBRARY_PATH=./:$(LD_LIBRARY_PATH) ./$<
|
||||
LD_LIBRARY_PATH=$(OUTF):$(LD_LIBRARY_PATH) ./$<
|
||||
|
||||
install: $(NAME)
|
||||
cp -f ./$(NAME) /usr/lib/
|
||||
mkdir -p /usr/include/$(NAMEINC)/
|
||||
cp -rf $(INCF)* /usr/include/$(NAMEINC)/
|
||||
cp -rf $(INCF)* /usr/include/$(NAMESHORT)/
|
||||
|
||||
uninstall:
|
||||
$(RM) -r /usr/lib/$(NAME) /usr/include/$(NAMEINC)/
|
||||
$(RM) -r /usr/lib/$(NAME) /usr/include/$(NAMESHORT)/
|
||||
|
||||
.PHONY: clean all $(NAMETEST) clean-depends runtest install
|
||||
.PHONY: clean all clean-depends runtest install uninstall
|
||||
|
||||
include $(DEPFILES)
|
||||
|
|
20
inc/files.h
20
inc/files.h
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
namespace mrbesen::Files {
|
||||
|
@ -8,4 +10,22 @@ void parent(const std::string& child, std::string& out); //get the parent direct
|
|||
void file(const std::string& path, std::string& out); //get the filename without the path
|
||||
void extention(const std::string& path, std::string& ext); //get the files extenetion
|
||||
|
||||
enum class FileType : unsigned char {
|
||||
UNKNOWN = 0,
|
||||
FIFO = 1,
|
||||
CHARACTER = 2,
|
||||
DIRECTORY = 4,
|
||||
BLOCK = 6,
|
||||
REGULAR = 8,
|
||||
LINK = 10,
|
||||
SOCKET = 12,
|
||||
WHT = 14 ///????
|
||||
|
||||
//copied from dirent.h -> see man readdir
|
||||
};
|
||||
|
||||
typedef std::function<bool(const std::string&, FileType type)> fileNameFilter;
|
||||
template<class Container>
|
||||
bool scan(const std::string& path, std::insert_iterator<Container> it, bool prefixdir = false, fileNameFilter fnf = fileNameFilter(nullptr));
|
||||
|
||||
}
|
|
@ -14,7 +14,12 @@ void toLower(std::string& in); //inplace toLower
|
|||
bool endsWith(const std::string& str, const std::string& ending);
|
||||
bool startsWith(const std::string& str, const std::string& start);
|
||||
|
||||
void removeEnd(std::string& str, const std::string& ending);
|
||||
void removeStart(std::string& str, const std::string& start);
|
||||
//makes sure a string does NOT ends or starts with a specific sub string
|
||||
bool removeEnd(std::string& str, const std::string& ending); //returns true on change (ending = "" -> returns false)
|
||||
bool removeStart(std::string& str, const std::string& start);
|
||||
|
||||
//makes sure a string DOES ends or starts with a specific sub string
|
||||
bool insertEnd(std::string& str, const std::string& ending);
|
||||
bool insertStart(std::string& str, const std::string& start);
|
||||
|
||||
}
|
|
@ -1,5 +1,10 @@
|
|||
#include "files.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include "util.h"
|
||||
|
||||
void mrbesen::Files::parent(const std::string& child, std::string& out) {
|
||||
//letzten path trenner finden
|
||||
size_t pos = child.rfind('/', child.length() -2); //das erste Zeichen überspringen (könnte ein / sein)
|
||||
|
@ -35,3 +40,40 @@ void mrbesen::Files::extention(const std::string& path, std::string& ext) {
|
|||
ext = filestr.substr(pos+1);
|
||||
}
|
||||
|
||||
template<class Container>
|
||||
bool mrbesen::Files::scan(const std::string& path, std::insert_iterator<Container> it, bool prefixdir, fileNameFilter fnf) {
|
||||
std::string path_ = path;
|
||||
mrbesen::Util::insertEnd(path_, "/");
|
||||
|
||||
::DIR* dir = opendir(path_.c_str());
|
||||
if(!dir) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//read dir
|
||||
struct ::dirent* entr;
|
||||
while((entr = readdir(dir))) {
|
||||
std::string fname = entr->d_name;
|
||||
FileType type = (FileType) entr->d_type; //DT_BLK DT_CHR DT_DIR DT_FIFO DT_LNK DT_REG DT_SOCK DT_UNKNOWN (dirent.h, man readdir)
|
||||
if(fnf) {
|
||||
if(!fnf(fname, type)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(prefixdir)
|
||||
fname = path_ + fname;
|
||||
it = fname;
|
||||
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//curently only these are supported, because iterators may break on others upon insertion
|
||||
template bool mrbesen::Files::scan<std::list<std::string>>(const std::string&, std::insert_iterator<std::list<std::string>>, bool, fileNameFilter);
|
||||
template bool mrbesen::Files::scan<std::set<std::string>>(const std::string&, std::insert_iterator<std::set<std::string>>, bool, fileNameFilter);
|
||||
template bool mrbesen::Files::scan<std::multiset<std::string>>(const std::string&, std::insert_iterator<std::multiset<std::string>>, bool, fileNameFilter);
|
||||
|
||||
|
||||
|
|
31
src/Util.cpp
31
src/Util.cpp
|
@ -71,18 +71,41 @@ bool mrbesen::Util::startsWith(const std::string& str, const std::string& start)
|
|||
return str.find(start) == 0;
|
||||
}
|
||||
|
||||
void mrbesen::Util::removeEnd(std::string& str, const std::string& ending) {
|
||||
if(ending.empty()) return;
|
||||
bool mrbesen::Util::removeEnd(std::string& str, const std::string& ending) {
|
||||
if(ending.empty()) return false;
|
||||
|
||||
if(endsWith(str, ending)) {
|
||||
str.resize(str.size() - ending.length());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void mrbesen::Util::removeStart(std::string& str, const std::string& start) {
|
||||
if(start.empty()) return;
|
||||
bool mrbesen::Util::removeStart(std::string& str, const std::string& start) {
|
||||
if(start.empty()) return false;
|
||||
|
||||
if(startsWith(str, start)) {
|
||||
str = str.substr(start.length());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mrbesen::Util::insertEnd(std::string& str, const std::string& ending) {
|
||||
if(ending.empty()) return false;
|
||||
|
||||
if(endsWith(str, ending)) return false;
|
||||
|
||||
str.append(ending);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mrbesen::Util::insertStart(std::string& str, const std::string& start) {
|
||||
if(start.empty()) return false;
|
||||
|
||||
if(startsWith(str, start)) return false;
|
||||
|
||||
str = start + str;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include "test.h"
|
||||
#include "files.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
using namespace mrbesen;
|
||||
|
@ -99,3 +102,22 @@ int testFiles_extention() {
|
|||
|
||||
return TESTGOOD;
|
||||
}
|
||||
|
||||
|
||||
int testFiles_scan() {
|
||||
std::string path = "./tests";
|
||||
std::list<std::string> out, out2;
|
||||
|
||||
ASSERT(Files::scan(path, std::inserter(out, out.begin()), false), "");
|
||||
ASSERT(Files::scan(path, std::inserter(out2, out2.begin()), true), "");
|
||||
|
||||
ASSERT(out.size() == out2.size(), out.size() << " " << out2.size());
|
||||
|
||||
std::set<std::string> out3;
|
||||
ASSERT(Files::scan(path, std::inserter(out3, out3.begin()), false, [](const std::string& str, Files::FileType t){ return mrbesen::Util::startsWith(str, "."); }), "");
|
||||
ASSERT(out3.size() == 2, out3.size());
|
||||
ASSERT(out3.find(".") != out3.end(), "");
|
||||
ASSERT(out3.find("..") != out3.end(), "");
|
||||
|
||||
return TESTGOOD;
|
||||
}
|
||||
|
|
|
@ -5,14 +5,16 @@
|
|||
int testFiles_parent();
|
||||
int testFiles_file();
|
||||
int testFiles_extention();
|
||||
int testFiles_scan();
|
||||
|
||||
int testUtil_Count();
|
||||
int testUtil_equalsIgnoreCase();
|
||||
int testUtil_toLower();
|
||||
int testUtil_start_endWith();
|
||||
int testUtil_removeStart_End();
|
||||
int testUtil_insertStart_End();
|
||||
|
||||
test_t tests[] = {testFiles_parent, testFiles_file, testFiles_extention, testUtil_Count, testUtil_equalsIgnoreCase, testUtil_toLower, testUtil_start_endWith, testUtil_removeStart_End, NULL};
|
||||
test_t tests[] = {testFiles_parent, testFiles_file, testFiles_extention, testFiles_scan, testUtil_Count, testUtil_equalsIgnoreCase, testUtil_toLower, testUtil_start_endWith, testUtil_removeStart_End, testUtil_insertStart_End, NULL};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
|
@ -21,7 +23,7 @@ int main(int argc, char** argv) {
|
|||
int testcount = 0;
|
||||
for(; *current; current++) {
|
||||
testcount++;
|
||||
printf("\033[1mRunning test number: %d ", testcount);
|
||||
printf("\033[1mRunning test number: %02d ", testcount);
|
||||
if((*current)()) {
|
||||
printf("\033[1;92msucceeded\033[0;1m!\n");
|
||||
} else {
|
||||
|
|
|
@ -92,29 +92,59 @@ int testUtil_start_endWith() {
|
|||
|
||||
int testUtil_removeStart_End() {
|
||||
std::string a = "abcdefg";
|
||||
removeStart(a, "");
|
||||
ASSERT(!removeStart(a, ""), "");
|
||||
ASSERT(a == "abcdefg", "");
|
||||
|
||||
removeStart(a, "b");
|
||||
ASSERT(!removeStart(a, "b"), "");
|
||||
ASSERT(a == "abcdefg", "");
|
||||
|
||||
removeStart(a, "a");
|
||||
ASSERT(removeStart(a, "a"), "");
|
||||
ASSERT(a == "bcdefg", "");
|
||||
|
||||
removeStart(a, "bcd");
|
||||
ASSERT(removeStart(a, "bcd"), "");
|
||||
ASSERT(a == "efg", "");
|
||||
|
||||
removeEnd(a, "xyz");
|
||||
ASSERT(!removeEnd(a, "xyz"), "");
|
||||
ASSERT(a == "efg", "");
|
||||
|
||||
removeEnd(a, "");
|
||||
ASSERT(!removeEnd(a, ""), "");
|
||||
ASSERT(a == "efg", "");
|
||||
|
||||
removeEnd(a, "fg");
|
||||
ASSERT(removeEnd(a, "fg"), "");
|
||||
ASSERT(a == "e", "");
|
||||
|
||||
removeEnd(a, "e");
|
||||
ASSERT(removeEnd(a, "e"), "");
|
||||
ASSERT(a == "", "");
|
||||
|
||||
return TESTGOOD;
|
||||
}
|
||||
|
||||
int testUtil_insertStart_End() {
|
||||
std::string a = "";
|
||||
|
||||
ASSERT(!insertStart(a, ""), "");
|
||||
ASSERT(a == "", a);
|
||||
|
||||
ASSERT(insertStart(a, "abc"), "");
|
||||
ASSERT(a == "abc", a);
|
||||
|
||||
ASSERT(!insertStart(a, "a"), "");
|
||||
ASSERT(a == "abc", a);
|
||||
|
||||
ASSERT(insertStart(a, "bc"), "");
|
||||
ASSERT(a == "bcabc", a);
|
||||
|
||||
ASSERT(!insertStart(a, ""), "");
|
||||
ASSERT(a == "bcabc", a);
|
||||
|
||||
ASSERT(!insertEnd(a, ""), "");
|
||||
ASSERT(a == "bcabc", a);
|
||||
|
||||
ASSERT(!insertEnd(a, "bc"), "");
|
||||
ASSERT(a == "bcabc", a);
|
||||
|
||||
ASSERT(insertEnd(a, "def"), "");
|
||||
ASSERT(a == "bcabcdef", a);
|
||||
|
||||
return TESTGOOD;
|
||||
}
|
Loading…
Reference in New Issue