From: hama Date: Wed, 4 Mar 2015 12:23:49 +0000 (+0100) Subject: ReDirRandom, ReDirDelete X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=4fe2a21812d1115e549bf82db69ac1d8de7ec0f9;p=crepublib ReDirRandom, ReDirDelete --- diff --git a/base/ReSeqArray.hpp b/base/ReSeqArray.hpp index eeee484..7505d79 100644 --- a/base/ReSeqArray.hpp +++ b/base/ReSeqArray.hpp @@ -38,7 +38,7 @@ public: ReSeqArray(const ReSeqArray& source); ReSeqArray& operator =(const ReSeqArray& source); public: - Index add(Index index, const Byte* source, size_t sourceLength, + Index add(Index index, const Byte* source, size_t sourceLength = (size_t)-1, Tag tag = 0); bool binarySearch(const Byte* toFind, int length, Index& index, Tag* tag = NULL) const; @@ -51,7 +51,7 @@ public: return m_list.length() / m_entrySize; } void dump(FILE* fp, const char* prefix) const; - Index find(const Byte* toFind, size_t length, Tag* tag = NULL) const; + Index find(const Byte* toFind, size_t length = -1, Tag* tag = NULL) const; bool get(Index index, ReByteBuffer& value, Tag* tag = NULL) const; /** Returns whether the comparisons inside the list are case insensitive. * @return true the comparisons inside the list are case insensitive @@ -67,7 +67,8 @@ public: return m_sorted; } void remove(Index index); - void set(Index index, const Byte* source, size_t sourceLength, Tag tag); + void set(Index index, const Byte* source, size_t sourceLength = -1, + Tag tag = 0); void setCapacity(int maxIndices, int maxStringSpace); void setSizes(int sizeOfTag, int sizeOfLength, size_t constantLength = INDIVIDUAL_SIZE); diff --git a/cunit/cuReDirTools.cpp b/cunit/cuReDirTools.cpp index 2ee6c15..851eec4 100644 --- a/cunit/cuReDirTools.cpp +++ b/cunit/cuReDirTools.cpp @@ -14,6 +14,20 @@ static const char* s_empty[] = { NULL }; // count of seconds from 1.1.1970 until 1.1.1980: const int tenYear = (365 * 10 + 2) * 24 * 3600; +const char* s_allFiles[] = { // + " 1.txt", // + "*dir1", // + "*dir2", // + "*dir1/cache", // + "*dir1/dir1_1", // + "*dir1/dir1_2", // + "*dir1/dir1_2/dir1_2_1", // + " dir1/dir1_2/dir1_2_1/x1.txt", // + " dir1/dir1_2/dir1_2_1/x2.txt", // + " dir2/2.x", // + " dir1/cache/cache.txt", // + NULL }; + class TestReDirTools: public ReTestUnit { public: TestReDirTools() : @@ -37,6 +51,101 @@ private: bool m_testAll; ReLogger* m_logger; private: + void run() { + testRandom(); + testDelete(); + testChecksumBuild(); + if (m_testAll) { + testDirOptions(); + checkSetFilterFromProgramArgs(); + testList2(); + testToolStatistic(); + testBasic(); + testDirStatistic(); + testCopyFile(); + testList(); + testToolSync(); + testBatch(); + testChecksumBuild(); + testDelete(); + testRandom(); + } + } + void testRandom(){ + const char* argv[] = { "random", "-l10", "-s", "90", "100", + NULL }; + ReDirRandom(m_logger).run(-1, argv); + } + void testDelete() { + rebuildTree(); + ReByteBuffer nameCurrent; + buildFilename("current", nameCurrent); + ReByteBuffer optOutput("--output-file="); + optOutput.append(nameCurrent); + const char* argv[] = { "delete", "-p;x*.txt", optOutput.str(), m_base + .str(), NULL }; + const char* existing[] = { // + " 1.txt", // + "*dir1", // + "*dir2", // + "*dir1/cache", // + "*dir1/dir1_1", // + "*dir1/dir1_2", // + "*dir1/dir1_2/dir1_2_1", // + " dir2/2.x", // + " dir1/cache/cache.txt", // + NULL }; + const char* notExisting[] = { // + " dir1/dir1_2/dir1_2_1/x1.txt", // + " dir1/dir1_2/dir1_2_1/x2.txt", // + NULL }; + ReDirDelete(m_logger).run(-1, argv); + mustExist(existing); + mayNotExist(notExisting); + + const char* argv2[] = { "delete", optOutput.str(), m_base + .str(), NULL }; + ReDirDelete(m_logger).run(-1, argv2); + mayNotExist(s_allFiles); + } + void mustExist(const char** names){ + ReByteBuffer name; + struct stat info; + for (int ix = 0; names[ix] != NULL; ix++){ + const char* arg = names[ix]; + name = m_base; + name.ensureLastChar(OS_SEPARATOR_CHAR); + name.append(arg + 1); + name.replaceAll("/", -1, OS_SEPARATOR, -1); + if (stat(name.str(), &info) != 0) + checkEqu("missing", name); + bool isDir = arg[0] == '*'; + if (isDir && ! S_ISDIR(info.st_mode)) + checkEqu("file not dir", name); + if (! isDir && S_ISDIR(info.st_mode)) + checkEqu("dir not file", name); + } + } + void mayNotExist(const char** names){ + ReByteBuffer name; + struct stat info; + for (int ix = 0; names[ix] != NULL; ix++){ + const char* arg = names[ix]; + name = m_base; + name.ensureLastChar(OS_SEPARATOR_CHAR); + name.append(arg + 1); + name.replaceAll("/", -1, OS_SEPARATOR, -1); + if (stat(name.str(), &info) == 0) + checkEqu("exists", name); + } + } + int secOfFileTime(ReFileTime_t data) { +#if defined __linux__ + return data.tv_sec; +#elif defined __WIN32__ + return (int) ReDirStatus_t::filetimeToTime(&data); +#endif + } const char* makeDir(const char* relPath) { m_buffer = m_base; m_buffer.append(relPath); @@ -59,68 +168,49 @@ private: } } void initTree() { - makeFile("1.txt"); - makeDir("dir1"); - makeDir("dir2"); - makeDir("dir1/cache"); - makeDir("dir1/dir1_1"); - makeDir("dir1/dir1_2"); - makeDir("dir1/dir1_2/dir1_2_1"); - makeFile("dir1/dir1_2/dir1_2_1/x1.txt"); - makeFile("dir1/dir1_2/dir1_2_1/x2.txt"); - makeFile("dir2/2.x"); - makeFile("dir1/cache/cache.txt"); + for (int ix = 0; s_allFiles[ix] != 0; ix++){ + const char* name = s_allFiles[ix]; + if (name[0] == '*') + makeDir(name + 1); + else + makeFile(name + 1); + } } - void run() { + void rebuildTree() { + ReDirectory::deleteTree(m_base.str(), false); initTree(); - if (m_testAll) { - testChecksumBuild(); - testList2(); - testToolStatistic(); - testBasic(); - testDirOptions(); - checkSetFilterFromProgramArgs(); - testDirStatistic(); - testCopyFile(); - testList(); - testToolSync(); - testBatch(); - } } - void testChecksumBuild(){ + void testChecksumBuild() { + rebuildTree(); ReByteBuffer nameCurrent; buildFilename("current", nameCurrent); ReByteBuffer optOutput("--output-file="); optOutput.append(nameCurrent); - const char* argv[] = { "dt", "checksum", "-P;*;-cache", "-tr", "-p;*.txt", - "-s4711", "-arpd64", "-cBuild", - optOutput.str(), m_base.str(), NULL }; + const char* argv[] = { "dt", "checksum", "-P;*;-cache", "-tr", + "-p;*.txt", "-s4711", "-arpd64", "-cBuild", optOutput.str(), m_base + .str(), NULL }; ReDirTools tools; tools.main(-1, (char**) argv); // checkFile(nameCurrent, ""); - const char* argv2[] = { "dt", "checksum", "-P;*;-cache", "-tr", "-p;*.txt", - "-s4711", "-arpd64", "-cCompare", - optOutput.str(), m_base.str(), NULL }; + const char* argv2[] = { "dt", "checksum", "-P;*;-cache", "-tr", + "-p;*.txt", "-s4711", "-arpd64", "-cCompare", optOutput.str(), + m_base.str(), NULL }; tools.main(-1, (char**) argv2); } // F:\temp\retestunit\dirtool void testList2() { + rebuildTree(); const char* argv[] = { "dt", "list", "-r", m_base.str(), NULL }; ReDirTools tools; tools.main(4, (char**) argv); } void testList() { + rebuildTree(); const char* argv[] = { "list", m_base.str(), NULL }; ReDirList(m_logger).run(2, argv); } - int secOfFileTime(ReFileTime_t data) { -#if defined __linux__ - return data.tv_sec; -#elif defined __WIN32__ - return (int) ReDirStatus_t::filetimeToTime(&data); -#endif - } void testCopyFile() { + rebuildTree(); #if defined __linux__ ReByteBuffer src(m_base); src.append("dir1/dir1_2/dir1_2_1/x1.txt"); @@ -129,7 +219,7 @@ private: ReByteBuffer buffer; buffer.ensureSize(5); ReDirSync::copyFile(src.str(), NULL, trg.str(), buffer, - ReLogger::globalLogger()); + ReLogger::globalLogger()); checkFileEqu(src.str(), trg.str()); #else log(false, "testCopyFile not implemented"); @@ -225,6 +315,7 @@ private: checkT(false); } void testBasic() { + rebuildTree(); ReTraverser traverser(m_base.str()); RePatternList patterns; // exclude */cache/* @@ -247,6 +338,7 @@ private: checkF(hash.get("cache.txt", buffer)); } void testDirStatistic() { + rebuildTree(); ReDirStatistic stat(m_logger); const ReStringList& list = stat.calculate(m_base.str(), 1); ReByteBuffer buffer; @@ -257,7 +349,7 @@ private: buffer.set(list.strOf(0), list.strLengthOf(0)); checkT(buffer.startsWith("1\t")); expected.set(m_base.str(), m_base.length()).append("dir1", -1).append( - OS_SEPARATOR); + OS_SEPARATOR); // .append(OS_SEPARATOR, -1) checkT(buffer.endsWith(expected.str())); @@ -269,13 +361,13 @@ private: buffer.set(list.strOf(0), list.strLengthOf(0)); checkT(buffer.startsWith(" 0.000074 MB 3 4\t")); expected.set(m_base.str(), m_base.length()).append("dir1", -1).append( - OS_SEPARATOR); + OS_SEPARATOR); checkT(buffer.endsWith(expected.str())); buffer.set(list.strOf(1), list.strLengthOf(1)); checkT(buffer.startsWith(" 0.000008 MB 1 0\t")); expected.set(m_base.str(), m_base.length()).append("dir2", -1).append( - OS_SEPARATOR); + OS_SEPARATOR); checkT(buffer.endsWith(expected.str())); buffer.set(list.strOf(2), list.strLengthOf(2)); @@ -313,6 +405,7 @@ private: } } void testTouch() { + rebuildTree(); ReByteBuffer nameCurrent; buildFilename("current", nameCurrent); ReByteBuffer optOutput("--output-file="); @@ -342,6 +435,7 @@ private: } void testBatch() { + rebuildTree(); ReByteBuffer nameCurrent; buildFilename("current", nameCurrent); ReByteBuffer optOutput("--output-file="); @@ -351,15 +445,16 @@ private: "-cmyscript", optOutput.str(), m_base.str(), NULL }; tools.main(7, (char**) argv); #if defined __linux__ - static const char* content = "#! /bin/sh*\n" - "myscript '*dirtool/dir1'\n" - "myscript '*dirtool/dir2'\n" - "myscript '*dirtool/dir1/dir1_1'\n" - "myscript '*dirtool/dir1/dir1_2'\n" - "myscript '*dirtool/dir1/cache'\n" - "myscript '*dirtool/dir1/dir1_2/dir1_2_1'\n" - "# === filtered: 0 file(s) 0.000000 MByte 6 dirs(s) */sec\n" - "# === total: 4 file(s) 0.000067 MByte 6 dirs(s) * sec"; + static const char* content = + "#! /bin/s*h\n" + "myscript '*dirtool/dir1'\n" + "myscript '*dirtool/dir2'\n" + "myscript '*dirtool/dir1/dir1_1'\n" + "myscript '*dirtool/dir1/dir1_2'\n" + "myscript '*dirtool/dir1/cache'\n" + "myscript '*dirtool/dir1/dir1_2/dir1_2_1'\n" + "# === filtered: 0 file(s) 0.000000 MByte 6 dirs(s) */sec\n" + "# === total: 4 file(s) 0.000067 MByte 6 dirs(s) * sec"; #elif defined __WIN32__ static const char* content = "rem this batch is created by*dirtool\n" "call myscript *dirtool\\dir1\"\n" @@ -374,11 +469,13 @@ private: checkFile(nameCurrent, content); } void testToolStatistic() { + rebuildTree(); ReDirTools tools; const char* argv[] = { "dt", "stat", "-P;*;-cache", m_base.str(), "2" }; tools.main(5, (char**) argv); } void testToolSync() { + rebuildTree(); ReDirTools tools; ReByteBuffer source(m_base); source.append("dir1"); diff --git a/cunit/cuReTraverser.cpp b/cunit/cuReTraverser.cpp index 01e2c24..708f8ab 100644 --- a/cunit/cuReTraverser.cpp +++ b/cunit/cuReTraverser.cpp @@ -115,18 +115,30 @@ private: traverser.setDirPattern(&patterns); int level = 0; ReDirStatus_t* entry; - ReHashList hash; + ReHashList hashPath; + ReSeqArray listChanged; + int state = 0; while ((entry = traverser.rawNextFile(level)) != NULL) { - hash.put(ReByteBuffer(entry->node(), -1), entry->m_path); - logF(false, "%d: %-12s %2d %s", level, entry->node(), + const char* node = entry->node(); + hashPath.put(ReByteBuffer(node, -1), entry->m_path); + if (traverser.hasChangedPath(state)) + listChanged.add(-1, node); + logF(false, "%d: %-12s %2d %s", level, node, int(entry->fileSize()), entry->m_path.str()); } - checkOneFile("x1.txt", "dir1_2_1", hash); - checkOneFile("x2.txt", "dir1_2_1", hash); - checkOneFile("dir1_2_1", "dir1_2", hash); - checkOneFile("dir1_1", "dir1", hash); - checkOneFile("dir1_2", "dir1", hash); - checkF(hash.get("cache.txt", buffer)); + checkOneFile("x1.txt", "dir1_2_1", hashPath); + checkOneFile("x2.txt", "dir1_2_1", hashPath); + bool changed1 = listChanged.find("x1.txt") != (size_t) -1; + bool changed2 = listChanged.find("x2.txt") != (size_t) -1; + checkT(changed1 != changed2); + checkOneFile("dir1_2_1", "dir1_2", hashPath); + checkT(listChanged.find("dir1_2_1") >= 0); + checkOneFile("dir1_1", "dir1", hashPath); + checkOneFile("dir1_2", "dir1", hashPath); + changed1 = listChanged.find("dir1_1") != (size_t) -1; + changed2 = listChanged.find("dir1_2") != (size_t) -1; + checkT(changed1 != changed2); + checkF(hashPath.get("cache.txt", buffer)); } }; extern void testReTraverser(void); diff --git a/cunit/testall.cpp b/cunit/testall.cpp index f853161..38f4fb9 100644 --- a/cunit/testall.cpp +++ b/cunit/testall.cpp @@ -60,6 +60,8 @@ void testString() { void testOs() { void testReDirTools(); testReDirTools(); + void testReTraverser(); + testReTraverser(); if (s_testAll) { void testReTraverser(); diff --git a/os/ReDirTools.cpp b/os/ReDirTools.cpp index 89b64c6..7f45b22 100644 --- a/os/ReDirTools.cpp +++ b/os/ReDirTools.cpp @@ -34,6 +34,7 @@ enum LOCATION_DIRTOOL { LC_COMPARE_STORAGE_6, // 50120 LC_COMPARE_STORAGE_7, // 50121 LC_COMPARE_DIR_1, // 50122 + LC_DELETE_1, // 50123 }; const char* ReDirTools::m_version = "2015.02.25"; ReLogger* ReDirTools::m_logger = NULL; @@ -61,6 +62,15 @@ const char* s_batchUsage[] = { " then it follows the full filename of the found file", " use --arguments or --script to configure the output line", NULL }; +const char* s_deleteExamples[] = { + "dirtool delete --basename-pattern=;*~;*.bak e:\\data", + "dirtool delete /tmp/log", + NULL }; + +const char* s_deleteUsage[] = { + ": delete [] [ ...]", + " delete the specified files", + NULL }; const char* s_batchExamples[] = { "dirtool batch -cbackup.bat --basename-pattern=;*.txt;*.doc e:\\data", "dirtool batch --type=r '--arguments=backup.sh !basename! !path!' usr etc", @@ -85,6 +95,17 @@ const char* s_checksumExamples[] = { "dirtool ch --buffer-size=512 e:\\data", "dirtool checksum --command=Compare /home", "dirtool checksum -cUpdate -O/var/log/checksum.log /home", NULL }; +const char* s_randomUsage[] = { + ": r(andom) count until [from]", + " displays random numbers.", + " count of generated numbers", + " the maximum (including) value of the numbers", + " the minimum (including) value of the numbers. Default: 1", + NULL }; +const char* s_randomExamples[] = { "dirtool ra --multiple -w3 10 33", + "dirtool rand -s 6 49", + "dirtool rand --sort --width=1 5 50", + NULL }; static const char* s_statisticUsage[] = { ": st(atistic) [] [ ...] []", @@ -701,12 +722,17 @@ bool ReTool::trace(const char* currentFile) { /** * Evaluates the arguments and calls the main function. * - * @param argc number of arguments + * @param argc number of arguments. If -1: argv ends with NULL * @param argv program arguments * @param minArguments the command needs at least so many non option arguments */ void ReTool::run(int argc, const char** argv) { try { + if (argc < 0){ + for (argc = 0; argv[argc] != NULL; argc++){ + // nothing to do + } + } m_programArgs.init(argc, argv); if (m_programArgs.getArgCount() < m_minArguments) m_programArgs.help(i18n("too few arguments"), false, stdout); @@ -1402,7 +1428,47 @@ ReDigest& ReDirChecksum::calculateChecksum(const char* name, return digest; } +/** + * Constructor. + * + * @param logger logger for error handling + */ +ReDirDelete::ReDirDelete(ReLogger* logger) : + ReTool(s_deleteUsage, s_deleteExamples, 0, 0, 0, true, logger) { + addStandardFilterOptions(); +} +/** + * Deletes the specified files/directories. + */ +void ReDirDelete::doIt() { + m_traverser.setDepthFirst(true); + processFileArguments(); + printSummary(); +} + +/** + * Processes one directory. + * + * @param entry the properties of the directory to process + */ +void ReDirDelete::processDir(ReDirStatus_t* entry) { + _rmdir(entry->fullName()); +} +/** + * Processes one file. + * + * @param entry the properties of the file to process + */ +void ReDirDelete::processFile(ReDirStatus_t* entry) { + const char* name = entry->fullName(); + if (m_verboseLevel >= V_NORMAL){ + fprintf(m_output, "%s\n", name); + } + if (unlink(name) != 0) + m_logger->sayF(LOG_ERROR | CAT_FILE, LC_DELETE_1, + i18n("cannot delete ($1): $2")).arg(errno).arg(name).end(); +} /** * Constructor. @@ -1468,6 +1534,72 @@ void ReDirList::processFile(ReDirStatus_t* entry) { } } +/** + * Constructor. + * + * @param logger logger for error handling + */ +ReDirRandom::ReDirRandom(ReLogger* logger) : + ReTool(s_randomUsage, s_randomExamples, 2, 0, 0, true, logger) { + m_hasStandardArgs = false; + m_programArgs.addBool("multiple", i18n("result can contain a value multiple times"), + 'm', "--multiple", false); + m_programArgs.addInt("perline", i18n("number of values per line"), + 'l', "--values-per-line", 10); + m_programArgs.addBool("sort", i18n("the result is sorted"), + 's', "--sort", false); + m_programArgs.addInt("width", i18n("output format: minimum width of the numbers" + " 0: width of the maximum"), + 'w', "--min-width", 0); +} + +/** + * Lists the metadata of the specified files. + */ +void ReDirRandom::doIt() { + bool multiple = m_programArgs.getBool("multiple"); + bool sort = m_programArgs.getBool("sort"); + int count = atol(m_programArgs.getArg(0)); + int to = atol(m_programArgs.getArg(1)); + int from = 1; + if (m_programArgs.getArgCount() > 2) + from = atol(m_programArgs.getArg(2)); + ReShiftRandom rand; + rand.setSeed(rand.nearTrueRandom()); + int factor = to <= 1000 ? 1000 * 1000 : 1; + int numbersPerLine = m_programArgs.getInt("perline"); + int width = m_programArgs.getInt("width"); + if (width <= 0) + width = ReByteBuffer("").appendInt(to).length(); + ReByteBuffer format("%"); + format.appendInt(width).append("d%s"); + int found = 0; + ReSeqArray values(count); + ReByteBuffer value; + if (! multiple && count >= to - from + 1) + help(i18n("not realy random: all possible values requested. Do you mean '--multiple'?")); + while(found < count){ + value.setLength(0).appendInt(rand.nextInt(from * factor, to * factor) + / factor, "%010d"); + int ix = (int) values.find(value.str()); + if (! multiple && ix != -1) + continue; + found++; + values.add(-1, value.str()); + } + if (sort) + values.sort(); + for (int ii = 0; ii < count; ii++){ + values.get(ii, value); + int val = atol(value.str()); + printf(format.str(), val, + ii % numbersPerLine == numbersPerLine - 1 ? "\n" : " "); + } + if (count % numbersPerLine != 0) + printf("\n"); +} + + /** * Calculates the statistic of a directory tree. * @@ -2305,28 +2437,26 @@ void ReDirTools::help(int argc, const char* argv[]) { argv++; const char* arg0 = argv[0]; if (isArg("batch", arg0)) { - ReDirBatch batch(m_logger); - batch.help(NULL); + ReDirBatch(m_logger).help(NULL); } else if (isArg("checksum", arg0)) { - ReDirChecksum sum(m_logger); - sum.help(NULL); + ReDirChecksum(m_logger).help(NULL); + } else if (_stricmp("delete", arg0) == 0) { + ReDirDelete(m_logger).help(NULL); } else if (isArg("list", arg0)) { - ReDirList list(m_logger); - list.help(NULL); + ReDirList(m_logger).help(NULL); } else if (isArg("help", arg0)) { printField(s_helpSummary); + } else if (isArg("random", arg0)) { + ReDirRandom(m_logger).help(NULL); } else if (isArg("statistic", arg0)) { - ReDirStatistic stat(m_logger); - stat.help(NULL); + ReDirStatistic(m_logger).help(NULL); } else if (isArg("test", arg0)) { void testAll(); testAll(); } else if (isArg("touch", arg0)) { - ReDirTouch touch(m_logger); - touch.help(NULL); + ReDirTouch(m_logger).help(NULL); } else if (isArg("which", arg0)) { - ReDirWhich which(m_logger); - which.help(NULL); + ReDirWhich(m_logger).help(NULL); } else printf("+++ unknown sub command: %s\n", arg0); } @@ -2368,10 +2498,14 @@ int ReDirTools::main(int argc, char* orgArgv[]) { ReDirBatch(m_logger).run(argc, argv); else if (isArg("checksum", arg0)) ReDirChecksum(m_logger).run(argc, argv); + else if (_stricmp("delete", arg0) == 0) + ReDirDelete(m_logger).run(argc, argv); else if (isArg("help", arg0)) tools.help(argc, argv); else if (isArg("list", arg0)) ReDirList(m_logger).run(argc, argv); + else if (isArg("random", arg0)) + ReDirRandom(m_logger).run(argc, argv); else if (isArg("statistic", arg0)) ReDirStatistic(m_logger).run(argc, argv); else if (isArg("synchronize", arg0)) diff --git a/os/ReDirTools.hpp b/os/ReDirTools.hpp index 3777e5c..9e4cde2 100644 --- a/os/ReDirTools.hpp +++ b/os/ReDirTools.hpp @@ -145,23 +145,6 @@ protected: bool m_isExe; }; -/** - * List file attributes of files. - */ -class ReDirList: public ReTool { -public: - ReDirList(ReLogger* logger); -protected: - virtual void doIt(); - virtual void processDir(ReDirStatus_t* entry); - virtual void processFile(ReDirStatus_t* entry); -protected: - int m_widthOwner; - bool m_shortFormat; - bool m_withRights; - bool m_numerical; - -}; class ReDigest; /** * Calculates / compares the checksum of files. @@ -202,25 +185,42 @@ protected: }; /** - * Sychronizes two directory trees. + * List file attributes of files. */ -class ReDirSync: public ReTool { +class ReDirDelete: public ReTool { public: - ReDirSync(ReLogger* logger); + ReDirDelete(ReLogger* logger); protected: virtual void doIt(); - void copyFile(ReDirStatus_t* entry, const char* target); - void makeDirWithParents(ReByteBuffer& path, int minWidth, - ReTraverser& traverser); + virtual void processDir(ReDirStatus_t* entry); + virtual void processFile(ReDirStatus_t* entry); +}; + +/** + * List file attributes of files. + */ +class ReDirList: public ReTool { public: - static bool copyFile(const char* source, ReFileProperties_t* properties, - const char* target, ReByteBuffer& buffer, ReLogger* logger = NULL); - static bool makeDirectory(const char* directory, int minLength, - ReFileProperties_t* properties, ReLogger* logger = NULL); - static bool setProperties(const char* fullName, - ReFileProperties_t* properties, ReLogger* logger = NULL); + ReDirList(ReLogger* logger); protected: - ReByteBuffer m_buffer; + virtual void doIt(); + virtual void processDir(ReDirStatus_t* entry); + virtual void processFile(ReDirStatus_t* entry); +protected: + int m_widthOwner; + bool m_shortFormat; + bool m_withRights; + bool m_numerical; +}; + +/** + * Displays random numbers. + */ +class ReDirRandom: public ReTool { +public: + ReDirRandom(ReLogger* logger); +protected: + virtual void doIt(); }; class ReDirStatisticData: public ReDirTreeStatistic { @@ -260,6 +260,28 @@ private: time_t m_lastTrace; }; +/** + * Sychronizes two directory trees. + */ +class ReDirSync: public ReTool { +public: + ReDirSync(ReLogger* logger); +protected: + virtual void doIt(); + void copyFile(ReDirStatus_t* entry, const char* target); + void makeDirWithParents(ReByteBuffer& path, int minWidth, + ReTraverser& traverser); +public: + static bool copyFile(const char* source, ReFileProperties_t* properties, + const char* target, ReByteBuffer& buffer, ReLogger* logger = NULL); + static bool makeDirectory(const char* directory, int minLength, + ReFileProperties_t* properties, ReLogger* logger = NULL); + static bool setProperties(const char* fullName, + ReFileProperties_t* properties, ReLogger* logger = NULL); +protected: + ReByteBuffer m_buffer; +}; + /** * Changes the filetime of files. */ diff --git a/os/ReTraverser.hpp b/os/ReTraverser.hpp index d97add5..ba65297 100644 --- a/os/ReTraverser.hpp +++ b/os/ReTraverser.hpp @@ -201,12 +201,28 @@ public: inline int files() const { return m_files; } + /** Returns whether the current directory has changed since the last call. + * @param state IN/OUT: stored info about the current directory. + * The value has no interest for the caller + * @return true: the path has been changed + */ + inline bool hasChangedPath(int& state){ + bool rc = m_directories > state; state = m_directories; + return rc; + } ReDirStatus_t* rawNextFile(int& level); ReDirStatus_t* nextFile(int& level, ReDirEntryFilter_t* filter = NULL); + /** Sets the tree traversal algorithm. + * @param depthFirst true: files of the subdirectories will + * be returned earlier + */ + void setDepthFirst(bool depthFirst){ + m_passNoForDirSearch = depthFirst ? 1 : 2; + } /** Sets directory filter (pattern list). * @param pattern pattern list for the subdirs to be entered */ - void setDirPattern(RePatternList* pattern) { + inline void setDirPattern(RePatternList* pattern) { m_dirPatterns = pattern; if (pattern != NULL) m_dirPatterns->setIgnoreCase(true); @@ -214,13 +230,13 @@ public: /** Sets the maximal depth. * @param value the value to set */ - void setMaxLevel(int value) { + inline void setMaxLevel(int value) { m_maxLevel = value; } /** Sets the minimal depth. * @param value the value to set */ - void setMinLevel(int value) { + inline void setMinLevel(int value) { m_minLevel = value; } void setPropertiesFromFilter(ReDirEntryFilter_t* filter);