stroll(nicer walk)のC++バージョンを書いた
ディレクトリを幅優先探索で掘っていき、ディレクトリやファイルに対する条件を適用し、それらを与えた条件(関数)によってソートし、見つけたファイルパスを返すライブラリを書いた。ちょうどPythonのos.walkを高機能にしたもので、所望のファイルだけを取り出したいときに使える。
boost不要で、C++11/C++14も不要なので、古いバージョンのg++(clang)でもコンパイルできる(はず)。Cでファイル処理を書くことはほとんど無いはずなので、C++で使えれば良いかなと。CとC++がごっちゃになっていてなんとなく居心地が悪いけどこんなもんなのだろうか。ちなみに、directory_iteratorは#incude <filesystem>
が必要でMac(clang)だとコンパイルできないようなので、Cを使うことにした。
正規表現マッチをする際に、matchとsearchの違いを忘れてしまいがち。matchは先頭からマッチするが、searchはどこでもマッチする。
$ cat main.cpp #include <iostream> #include "stroll.cpp" using namespace std; using namespace stroll; void ex1(){ cout<<"=== ex1 (mtime) ==="<<endl; Stroll stroll = Stroll("basedir"); stroll.set_sortby(sortByMtime); while(stroll.read()){ cout<< stroll.get() << endl; } } void ex2(){ cout<<"=== ex2 (mtime/reverse) ==="<<endl; Stroll stroll = Stroll("basedir"); stroll.set_sortby(sortByMtimeDesc); while(stroll.read()){ cout<< stroll.get() << endl; } } void ex3(){ cout<<"=== ex3 (no_file) ==="<<endl; vstr no_file; no_file.push_back("1$"); no_file.push_back("2$"); Stroll stroll = Stroll("basedir"); stroll.set_no_file(no_file); while(stroll.read()){ cout<< stroll.get() << endl; } } void ex4(){ cout<<"=== ex4 (yes_path) ==="<<endl; vstr yes_path; yes_path.push_back("1$"); Stroll stroll = Stroll("basedir"); stroll.set_yes_path(yes_path); while(stroll.read()){ cout<< stroll.get() << endl; } } void ex5(){ cout<<"=== ex5 (no_root/len/reverse) ==="<<endl; vstr no_root; no_root.push_back("2$"); Stroll stroll = Stroll("basedir"); stroll.set_no_root(no_root); stroll.set_sortby(sortByLenDesc); while(stroll.read()){ cout<< stroll.get() << endl; } } void ex6(){ cout<<"=== ex6 (yes_file/yes_root) ==="<<endl; vstr yes_file; yes_file.push_back("2$"); vstr yes_root; yes_root.push_back("2$"); Stroll stroll = Stroll("basedir"); stroll.set_yes_file(yes_file); stroll.set_yes_root(yes_root); while(stroll.read()){ cout<< stroll.get() << endl; } } int main(int argc, char* argv[]){ ex1(); ex2(); ex3(); ex4(); ex5(); ex6(); return 0; }
$ cat Makefile main:main.o g++ -L./ -lstroll -o main main.o main.o:libstroll.a g++ -c main.cpp libstroll.a:stroll.o ar r libstroll.a stroll.o stroll.o:stroll.cpp g++ -Wall -O2 -c stroll.cpp .PHONY: clean clean: rm -f libstroll.a stroll.o main
$ ./main === ex1 (mtime) === basedir/file0 basedir/dir1/file11 basedir/dir1/file12 basedir/dir1/file13 basedir/dir1/file111 basedir/dir1/file1111 basedir/dir2/file21 basedir/dir2/file22 basedir/dir2/file23 basedir/dir2/file222 basedir/dir2/file2222 basedir/dir3/file31 basedir/dir3/file32 basedir/dir3/file33 basedir/dir3/file333 basedir/dir3/file3333 === ex2 (mtime/reverse) === basedir/file0 basedir/dir3/file3333 basedir/dir3/file333 basedir/dir3/file33 basedir/dir3/file32 basedir/dir3/file31 basedir/dir2/file2222 basedir/dir2/file222 basedir/dir2/file23 basedir/dir2/file21 basedir/dir2/file22 basedir/dir1/file1111 basedir/dir1/file111 basedir/dir1/file13 basedir/dir1/file12 basedir/dir1/file11 === ex3 (no_file) === basedir/file0 basedir/dir1/file13 basedir/dir2/file23 basedir/dir3/file33 basedir/dir3/file333 basedir/dir3/file3333 === ex4 (yes_path) === basedir/file0 basedir/dir1/file11 basedir/dir1/file111 basedir/dir1/file1111 basedir/dir1/file12 basedir/dir1/file13 === ex5 (no_root/len/reverse) === basedir/file0 basedir/dir1/file1111 basedir/dir1/file111 basedir/dir1/file11 basedir/dir1/file12 basedir/dir1/file13 basedir/dir3/file3333 basedir/dir3/file333 basedir/dir3/file31 basedir/dir3/file32 basedir/dir3/file33 === ex6 (yes_file/yes_root) === basedir/dir2/file22 basedir/dir2/file222 basedir/dir2/file2222