From 812bc85b8237d1ffdd4ac714ec7a08d438274b62 Mon Sep 17 00:00:00 2001 From: hama Date: Wed, 28 Jan 2015 00:20:12 +0100 Subject: [PATCH] corrections in ReDirSync + ReMatcher --- base/ReStringList.cpp | 13 +++--- os/ReDirTools.cpp | 93 +++++++++++++++++++++++-------------------- os/ReTraverser.cpp | 47 +++++++++++++--------- os/ReTraverser.hpp | 24 +++++++++++ string/ReMatcher.cpp | 6 +-- string/ReMatcher.hpp | 9 ++++- 6 files changed, 120 insertions(+), 72 deletions(-) diff --git a/base/ReStringList.cpp b/base/ReStringList.cpp index ab0d5a8..f13a5ea 100644 --- a/base/ReStringList.cpp +++ b/base/ReStringList.cpp @@ -271,21 +271,20 @@ void ReStringList::split(const char* list, char separator, bool append){ item.setLength(0); size_t length = end2 - list; item.append(list, length); - // Append '\0': - item.append("", 1); - add(-1, item.buffer(), length + 1); + // Store with '\0': + add(-1, item.str(), length + 1); list = end + 1; if (separator == '\n' && list[0] == '\r') list++; end = strchr(list, separator); } if (list[0] != '\0') - add(-1, list, -1); + add(-1, list, strlen(list) + 1); } -/** @brief Joins all string of the array into a string. +/** @brief Joins all string members into a string. * - * @param separator This string was put between the substrings. May be NULL or "" - * @param result Out: the result buffer + * @param separator this string was put between the substrings. May be NULL or "" + * @param result OUT: the result buffer * @return buffer (for chaining) */ ReByteBuffer& ReStringList::join(const char* separator, ReByteBuffer& result) const{ diff --git a/os/ReDirTools.cpp b/os/ReDirTools.cpp index ce6c5cf..7f4c6a1 100644 --- a/os/ReDirTools.cpp +++ b/os/ReDirTools.cpp @@ -1113,7 +1113,7 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties, properties = &info; else { if (logger != NULL) - logger->sayF(LOG_ERROR, LC_COPY_FILE_1, + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1, i18n("could not find: $ (errno: $2)")).arg(source) .arg(errno).end(); } @@ -1121,7 +1121,7 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties, FILE* fpSource = fopen(source, "rb"); if (fpSource == NULL){ if (logger != NULL) - logger->sayF(LOG_ERROR, LC_COPY_FILE_2, + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2, i18n("cannot open $1 (errno: $2)")) .arg(source).arg(errno).end(); } else { @@ -1129,7 +1129,7 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties, FILE* fpTarget = fopen(target, "w"); if (fpTarget == NULL){ if (logger != NULL) - logger->sayF(LOG_ERROR, LC_COPY_FILE_3, + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3, i18n("cannot open $1 (errno: $2)")) .arg(target).arg(errno).end(); } else{ @@ -1139,7 +1139,7 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties, blockSize = size; if (fread(buffer.buffer(), blockSize, 1, fpSource) != 1){ if (logger != NULL) - logger->sayF(LOG_ERROR, LC_COPY_FILE_5, + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5, i18n("cannot read $1 (errno: $2)")) .arg(source).arg(errno).end(); break; @@ -1148,7 +1148,7 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties, if ((written = fwrite(buffer.buffer(), 1, blockSize, fpTarget)) != blockSize){ if (logger != NULL) - logger->sayF(LOG_ERROR, LC_COPY_FILE_6, + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6, i18n("cannot write $1 [$2] (errno: $3)")) .arg(target).arg(written).arg(errno).end(); break; @@ -1186,21 +1186,22 @@ bool ReDirSync::setProperties(const char* fullName, times.modtime = properties->st_mtime; if (utime(fullName, ×) != 0){ if (logger != NULL) - logger->sayF(LOG_ERROR, LC_SET_PROPERTIES_1, + logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1, i18n("cannot change file times: $1 (errno: $2)")) .arg(fullName).arg(errno).end(); rc = false; } - if (chmod(fullName, properties->st_mode) != 0) { + int rights = properties->st_mode & (S_IRWXO | S_IRWXG | S_IRWXU); + if (chmod(fullName, rights) != 0) { if (logger != NULL) - logger->sayF(LOG_ERROR, LC_SET_PROPERTIES_2, + logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2, i18n("cannot change file modes: $1 (errno: $2)")) .arg(fullName).arg(errno).end(); rc = false; } if (chown(fullName, properties->st_uid, properties->st_gid) != 0){ if (logger != NULL) - logger->sayF(LOG_ERROR, LC_SET_PROPERTIES_3, + logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3, i18n("cannot change file owner: $1 (errno: $2)")) .arg(fullName).arg(errno).end(); rc = false; @@ -1244,7 +1245,7 @@ bool ReDirSync::makeDirectory(const char* directory, int minLength, // no, then we make it: if (_mkdir(path.str(), ALLPERMS) != 0){ if (logger != NULL) - logger->sayF(LOG_ERROR, LC_MAKE_DIR_1, + logger->sayF(LOG_ERROR | CAT_FILE, LC_MAKE_DIR_1, i18n("could not make directory $1 (errno: $2)")) .arg(path.str()).arg(errno).end(); rc = false; @@ -1297,9 +1298,10 @@ void ReDirSync::synchronize(int argc, const char* argv[]){ setFilterFromProgramArgs(filter); int64_t sumSizes = 0; int files = 0; - int dirs = 0; - ReByteBuffer source; - ReByteBuffer targetFile; + int treeFiles = 0; + int treeDirs = 0; + int64_t treeSumSizes = 0ll; + ReByteBuffer source, targetFile; for (int ix = 0; ix < m_programArgs.getArgCount() - 1; ix++){ source.set(m_programArgs.getArg(ix), -1); target.setLength(lengthTargetBase); @@ -1322,53 +1324,58 @@ void ReDirSync::synchronize(int argc, const char* argv[]){ ReDirStatus_t* entry; ReByteBuffer line; while( (entry = traverser.nextFile(level, &filter)) != NULL){ + if (entry->isDirectory()) + continue; // append the new relative path from source to target: target.setLength(ixTargetRelative); - const char* targetRelativePath = target.str() + ixTargetRelative; target.append(entry->m_path.str() + ixSourceRelative, -1); if (stat(target.str(), &info) != 0) makeDirWithParents(target, ixTargetRelative, traverser); targetFile.set(target).append(entry->node(), -1); + const char* targetRelativePath = targetFile.str() + ixTargetRelative + 1; bool exists = stat(targetFile.str(), &info) == 0; - if (! exists && ! mustExist){ + if (! exists && mustExist){ if (chatterMode) fprintf(m_output, "-ignored: %s does not exist\n", targetRelativePath); continue; } - if (exists && addOnly){ - if (chatterMode) - fprintf(m_output, "~ignored: %s exists\n", targetRelativePath); - continue; - } - if (ignoreDate && entry->fileSize() == info.st_size){ - if (chatterMode) - fprintf(m_output, "_ignored: %s same size\n", targetRelativePath); - continue; - } - if (! ignoreDate && entry->filetimeToTime(entry->modified()) - info.st_mtime - > maxFileTimeDiff) { - if (chatterMode) - fprintf(m_output, "=ignored: %s same time\n", targetRelativePath); - continue; - } else { - if (entry->isDirectory()) - dirs++; - else{ - files++; - sumSizes += entry->fileSize(); + if (exists){ + if (addOnly){ + if (chatterMode) + fprintf(m_output, "~ignored: %s exists\n", targetRelativePath); + continue; + } + if (ignoreDate && entry->fileSize() == info.st_size){ + if (chatterMode) + fprintf(m_output, "_ignored: %s same size\n", targetRelativePath); + continue; + } + // target younger than source? + if (! ignoreDate && info.st_mtime - entry->filetimeToTime(entry->modified()) + > maxFileTimeDiff) { + if (chatterMode) + fprintf(m_output, "=ignored: %s same time\n", targetRelativePath); + continue; } - if (verbose || chatterMode || dry) - fprintf(m_output, "%c%s%s\n", exists ? '!' : '+', targetRelativePath, - dry ? " would be copied" : ""); - if (! dry) - copyFile(entry, target.str()); } + files++; + sumSizes += entry->fileSize(); + if (verbose || chatterMode) + fprintf(m_output, "%c%s%s\n", exists ? '!' : '+', targetRelativePath, + dry ? " would be copied" : ""); + if (! dry) + copyFile(entry, targetFile.str()); } + treeFiles += traverser.files(); + treeDirs += traverser.directories(); + treeSumSizes+= traverser.sizes(); } if (verbose){ int duration = int(time(NULL) - start); - fprintf(m_output, "=== %d dir(s) and %d file(s) with %.6f MByte in %02d:%02d sec\n", - dirs, files, sumSizes / 1E6, duration / 60, duration % 60); + fprintf(m_output, i18n( + "=== copied: %d file(s) with %.6f MByte in %02d:%02d sec. Tree: %d dir(s) %d file(s) %.6f MByte\n"), + files, sumSizes / 1E6, duration / 60, duration % 60, + treeDirs, treeFiles, treeSumSizes / 1E6); } } catch(ReOptionException& exc){ help(exc.getMessage()); diff --git a/os/ReTraverser.cpp b/os/ReTraverser.cpp index 6c0923e..d3620d7 100644 --- a/os/ReTraverser.cpp +++ b/os/ReTraverser.cpp @@ -406,7 +406,11 @@ ReTraverser::ReTraverser(const char* base) : m_base(base), // m_dirs m_passNoForDirSearch(2), - m_dirPatterns(NULL) + m_dirPatterns(NULL), + m_directories(0), + m_files(0), + m_sizes(0ll) + { memset(m_dirs, 0, sizeof m_dirs); m_dirs[0] = new ReDirStatus_t(); @@ -442,27 +446,28 @@ ReTraverser::~ReTraverser() { ReDirStatus_t* ReTraverser::rawNextFile(int& level) { ReDirStatus_t* rc = NULL; - bool alreadyRead = false; + bool alreadyRead = false; bool again; do{ again = false; if (m_level < 0){ - // Not yet initialized? - if (m_dirs[0]->m_passNo == 2) - rc = NULL; - else { - // first call: + // Not yet initialized? + if (m_dirs[0]->m_passNo == 2) + rc = NULL; + else { + // first call: if (initEntry(m_base.str(), NULL, 0)){ - if (1 != m_passNoForDirSearch) + m_directories++; + if (1 != m_passNoForDirSearch) rc = m_dirs[0]; - else - again = alreadyRead = true; - } - } + else + again = alreadyRead = true; + } + } } else { ReDirStatus_t* current = m_dirs[m_level]; if (alreadyRead || current->findNext()){ - alreadyRead = false; + alreadyRead = false; // a file or directory found: if (current->m_passNo != m_passNoForDirSearch){ // we search for any file: @@ -476,6 +481,7 @@ ReDirStatus_t* ReTraverser::rawNextFile(int& level) current->node()))){ // open a new level alreadyRead = initEntry(current->m_path, current->node() , m_level + 1); + m_directories++; } } } else { @@ -494,10 +500,15 @@ ReDirStatus_t* ReTraverser::rawNextFile(int& level) } } } - if (rc != NULL && rc->isDotDir()) - again = true; + if (rc != NULL && rc->isDotDir()) + again = true; } while(again); - level = m_level; + if (rc != NULL && ! rc->isDirectory()){ + m_files++; + if (m_sizes >= 0) + m_sizes += rc->fileSize(); + } + level = m_level; return rc; } /** @@ -576,7 +587,7 @@ void ReTraverser::setPropertiesFromFilter(ReDirEntryFilter_t* filter){ */ ReDirStatus_t* ReTraverser::topOfStack(int offsetFromTop){ ReDirStatus_t* rc = NULL; - if (offsetFromTop >= 0 && m_level - offsetFromTop >= 0) - rc = m_dirs[m_level - offsetFromTop]; + if (offsetFromTop >= 0 && m_level - 1 - offsetFromTop >= 0) + rc = m_dirs[m_level - 1 - offsetFromTop]; return rc; } diff --git a/os/ReTraverser.hpp b/os/ReTraverser.hpp index 0e0ce3d..90f562f 100644 --- a/os/ReTraverser.hpp +++ b/os/ReTraverser.hpp @@ -105,6 +105,20 @@ public: ReTraverser(const char* base); virtual ~ReTraverser(); public: + /** + * Return the number of entered directories . + * @return the number of directories entered until now + */ + inline int directories() const { + return m_directories; + } + /** + * Return the number of found files. + * @return the number of files found until now + */ + inline int files() const { + return m_files; + } ReDirStatus_t* rawNextFile(int& level); ReDirStatus_t* nextFile(int& level, ReDirEntryFilter_t* filter = NULL); /** Sets directory filter (pattern list). @@ -123,6 +137,13 @@ public: void setMinLevel(int value) { m_minLevel = value; } void setPropertiesFromFilter(ReDirEntryFilter_t* filter); + /** + * Return the sum of file lengths of the found files. + * @return the sum of file lengths of the files found until now + */ + inline int64_t sizes() const { + return m_sizes; + } ReDirStatus_t* topOfStack(int offset = 0); protected: bool initEntry(const ReByteBuffer& parent, const char* node, int level); @@ -150,6 +171,9 @@ protected: /// a subdirectory will be entered only if this pattern list matches /// if NULL any directory will be entered RePatternList* m_dirPatterns; + int m_directories; + int m_files; + int64_t m_sizes; }; #endif /* OS_RETRAVERSER_HPP_ */ diff --git a/string/ReMatcher.cpp b/string/ReMatcher.cpp index 4ebae0d..d76e047 100644 --- a/string/ReMatcher.cpp +++ b/string/ReMatcher.cpp @@ -64,14 +64,14 @@ ReSimpleMatcher::~ReSimpleMatcher(){ /** * Compiles the pattern into a internal structure. * - * @param pattern pattern to compile + * @param pattern pattern to compile * @return true: success
* false: error occurred */ bool ReSimpleMatcher::compile(const char* pattern){ bool rc = true; m_pattern.set(pattern, -1); - if (strcmp(pattern, "*") == 0){ + if (pattern[0] == '*' && pattern[1] == '\0'){ m_findAll = true; } else { m_tokens.split(pattern, '*'); @@ -228,7 +228,7 @@ void RePatternList::destroy(){ * false: no pattern matches or at least one * "not-pattern" matches */ -bool RePatternList::match(const char* name){ +bool RePatternList::match(const ReByteBuffer& name){ bool rc = false; int count = m_startNot < 0 ? m_count : m_count - m_startNot + 1; // matches at least one positive pattern? diff --git a/string/ReMatcher.hpp b/string/ReMatcher.hpp index 9e7b0e5..6908f87 100644 --- a/string/ReMatcher.hpp +++ b/string/ReMatcher.hpp @@ -96,7 +96,14 @@ public: return m_count; } void destroy(); - bool match(const char* pattern); + bool match(const ReByteBuffer& name); + /** @brief Tests whether a string matches the patterns. + * @param name the string to Test + * @return true: the string matches + */ + inline bool match(const char* name){ + return match(ReByteBuffer(name)); + } /** Returns the original pattern string. * @return the string describing the patterns. */ -- 2.39.5