diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 637406de5..cf8e97729 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -85,13 +85,14 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c std::vector pathnames = parser.GetPathNames(); std::vector filenames; + std::map filesizes; if (!pathnames.empty()) { // Execute recursiveAddFiles() to each given file parameter std::vector::const_iterator iter; for (iter = pathnames.begin(); iter != pathnames.end(); ++iter) - FileLister::recursiveAddFiles(filenames, Path::toNativeSeparators(*iter)); + FileLister::recursiveAddFiles(filenames, filesizes, Path::toNativeSeparators(*iter)); } if (!filenames.empty()) @@ -114,7 +115,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c { std::vector::iterator iter; for (iter = filenames.begin(); iter != filenames.end(); ++iter) + { _filenames.push_back(*iter); + _filesizes[*iter] = filesizes[*iter]; + } return true; } @@ -146,10 +150,22 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) if (_settings._jobs == 1) { // Single process + + long totalfilesize = 0; + for (std::map::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i) + { + totalfilesize += i->second; + } + + long processedsize = 0; for (unsigned int c = 0; c < _filenames.size(); c++) { returnValue += cppCheck.check(_filenames[c]); - reportStatus(c + 1, _filenames.size()); + if (_filesizes.find(_filenames[c]) != _filesizes.end()) + { + processedsize += _filesizes[_filenames[c]]; + } + reportStatus(c + 1, _filenames.size(), processedsize, totalfilesize); } } else if (!ThreadExecutor::isEnabled()) @@ -160,7 +176,7 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) { // Multiple processes Settings &settings = cppCheck.settings(); - ThreadExecutor executor(_filenames, settings, *this); + ThreadExecutor executor(_filenames, _filesizes, settings, *this); returnValue = executor.check(); } @@ -216,14 +232,14 @@ void CppCheckExecutor::reportProgress(const std::string &filename, const char st } } -void CppCheckExecutor::reportStatus(unsigned int index, unsigned int max) +void CppCheckExecutor::reportStatus(unsigned int fileindex, unsigned int filecount, long sizedone, long sizetotal) { - if (max > 1 && !_settings._errorsOnly) + if (filecount > 1 && !_settings._errorsOnly) { std::ostringstream oss; - oss << index << "/" << max + oss << fileindex << "/" << filecount << " files checked " << - static_cast(static_cast(index) / max*100) + (sizetotal > 0 ? static_cast(static_cast(sizedone) / sizetotal*100) : 0) << "% done"; std::cout << oss.str() << std::endl; } diff --git a/cli/cppcheckexecutor.h b/cli/cppcheckexecutor.h index 3a0828024..d13f248f7 100644 --- a/cli/cppcheckexecutor.h +++ b/cli/cppcheckexecutor.h @@ -72,7 +72,7 @@ public: void reportProgress(const std::string &filename, const char stage[], const unsigned int value); - virtual void reportStatus(unsigned int index, unsigned int max); + virtual void reportStatus(unsigned int fileindex, unsigned int filecount, long sizedone, long sizetotal); protected: @@ -113,6 +113,11 @@ private: * List of files to check. */ std::vector _filenames; + + /** + * Sizes of files in _filenames. + */ + std::map _filesizes; }; #endif // CPPCHECKEXECUTOR_H diff --git a/cli/filelister.cpp b/cli/filelister.cpp index 4ce7a1b07..7efa64d2c 100644 --- a/cli/filelister.cpp +++ b/cli/filelister.cpp @@ -129,7 +129,7 @@ static HANDLE MyFindFirstFile(std::string path, LPWIN32_FIND_DATA findData) #endif // defined(UNICODE) -void FileLister::recursiveAddFiles(std::vector &filenames, const std::string &path) +void FileLister::recursiveAddFiles(std::vector &filenames, std::map &filesizes, const std::string &path) { // oss is the search string passed into FindFirst and FindNext. // bdir is the base directory which is used to form pathnames. @@ -201,12 +201,14 @@ void FileLister::recursiveAddFiles(std::vector &filenames, const st { const std::string nativename = Path::fromNativeSeparators(fname.str()); filenames.push_back(nativename); + // Limitation: file sizes are assumed to fit in a 'long' + filesizes[nativename] = ffd.nFileSizeLow; } } else { // Directory - FileLister::recursiveAddFiles(filenames, fname.str()); + FileLister::recursiveAddFiles(filenames, filesizes, fname.str()); } #if defined(UNICODE) delete [] ansiFfd; @@ -239,9 +241,11 @@ bool FileLister::isDirectory(const std::string &path) #include #include #include +#include void FileLister::recursiveAddFiles2(std::vector &relative, std::vector &absolute, + std::map &filesizes, const std::string &path) { std::ostringstream oss; @@ -284,6 +288,14 @@ void FileLister::recursiveAddFiles2(std::vector &relative, { relative.push_back(filename); absolute.push_back(fname); + struct stat sb; + off_t size = 0; + if (stat(fname, &sb) == 0) + { + size = sb.st_size; + } + // Limitation: file sizes are assumed to fit in a 'long' + filesizes[filename] = static_cast(size); } #ifndef PATH_MAX @@ -293,17 +305,17 @@ void FileLister::recursiveAddFiles2(std::vector &relative, else { // Directory - recursiveAddFiles2(relative, absolute, filename); + recursiveAddFiles2(relative, absolute, filesizes, filename); } } globfree(&glob_results); } -void FileLister::recursiveAddFiles(std::vector &filenames, const std::string &path) +void FileLister::recursiveAddFiles(std::vector &filenames, std::map &filesizes, const std::string &path) { std::vector abs; - recursiveAddFiles2(filenames, abs, path); + recursiveAddFiles2(filenames, abs, filesizes, path); } bool FileLister::isDirectory(const std::string &path) diff --git a/cli/filelister.h b/cli/filelister.h index b2ee6569e..24ab07a17 100644 --- a/cli/filelister.h +++ b/cli/filelister.h @@ -21,6 +21,7 @@ #include #include +#include /// @addtogroup CLI /// @{ @@ -35,9 +36,11 @@ public: * given vector. Only files with accepted extensions * (*.c;*.cpp;*.cxx;*.c++;*.cc;*.txx) are added. * @param filenames output vector that filenames are written to + * @param filesizes output map that contains the size of each file * @param path root path */ static void recursiveAddFiles(std::vector &filenames, + std::map &filesizes, const std::string &path); /** @@ -57,6 +60,7 @@ public: #ifndef _WIN32 static void recursiveAddFiles2(std::vector &relative, std::vector &absolute, + std::map &filesizes, const std::string &path); #endif }; diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index b5daae65c..6d22ea2fc 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -31,8 +31,8 @@ #include #endif -ThreadExecutor::ThreadExecutor(const std::vector &filenames, Settings &settings, ErrorLogger &errorLogger) - : _filenames(filenames), _settings(settings), _errorLogger(errorLogger), _fileCount(0) +ThreadExecutor::ThreadExecutor(const std::vector &filenames, const std::map &filesizes, Settings &settings, ErrorLogger &errorLogger) + : _filenames(filenames), _filesizes(filesizes), _settings(settings), _errorLogger(errorLogger), _fileCount(0) { #ifdef THREADING_MODEL_FORK _wpipe = 0; @@ -116,12 +116,10 @@ int ThreadExecutor::handleRead(int rpipe, unsigned int &result) } else if (type == '3') { - _fileCount++; std::istringstream iss(buf); unsigned int fileResult = 0; iss >> fileResult; result += fileResult; - _errorLogger.reportStatus(_fileCount, _filenames.size()); delete [] buf; return -1; } @@ -135,8 +133,16 @@ unsigned int ThreadExecutor::check() _fileCount = 0; unsigned int result = 0; + long totalfilesize = 0; + for (std::map::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i) + { + totalfilesize += i->second; + } + std::list rpipes; std::map childFile; + std::map pipeFile; + long processedsize = 0; unsigned int i = 0; while (true) { @@ -199,6 +205,7 @@ unsigned int ThreadExecutor::check() close(pipes[1]); rpipes.push_back(pipes[0]); childFile[pid] = _filenames[i]; + pipeFile[pipes[0]] = _filenames[i]; ++i; } @@ -221,6 +228,23 @@ unsigned int ThreadExecutor::check() int readRes = handleRead(*rp, result); if (readRes == -1) { + long size = 0; + std::map::iterator p = pipeFile.find(*rp); + if (p != pipeFile.end()) + { + std::string name = p->second; + pipeFile.erase(p); + std::map::const_iterator fs = _filesizes.find(name); + if (fs != _filesizes.end()) + { + size = fs->second; + } + } + + _fileCount++; + processedsize += size; + _errorLogger.reportStatus(_fileCount, _filenames.size(), processedsize, totalfilesize); + close(*rp); rp = rpipes.erase(rp); } @@ -299,7 +323,7 @@ void ThreadExecutor::reportErr(const ErrorLogger::ErrorMessage &msg) writeToPipe('2', msg.serialize()); } -void ThreadExecutor::reportStatus(unsigned int /*index*/, unsigned int /*max*/) +void ThreadExecutor::reportStatus(unsigned int /*fileindex*/, unsigned int /*filecount*/, long /*sizedone*/, long /*sizetotal*/) { // Not used } @@ -319,7 +343,7 @@ void ThreadExecutor::reportErr(const ErrorLogger::ErrorMessage &/*msg*/) } -void ThreadExecutor::reportStatus(unsigned int /*index*/, unsigned int /*max*/) +void ThreadExecutor::reportStatus(unsigned int /*fileindex*/, unsigned int /*filecount*/, long /*sizedone*/, long /*sizetotal*/) { } diff --git a/cli/threadexecutor.h b/cli/threadexecutor.h index bbbabe076..acb590f62 100644 --- a/cli/threadexecutor.h +++ b/cli/threadexecutor.h @@ -39,12 +39,12 @@ class ThreadExecutor : public ErrorLogger { public: - ThreadExecutor(const std::vector &filenames, Settings &settings, ErrorLogger &_errorLogger); + ThreadExecutor(const std::vector &filenames, const std::map &filesizes, Settings &settings, ErrorLogger &_errorLogger); virtual ~ThreadExecutor(); unsigned int check(); virtual void reportOut(const std::string &outmsg); virtual void reportErr(const ErrorLogger::ErrorMessage &msg); - virtual void reportStatus(unsigned int index, unsigned int max); + virtual void reportStatus(unsigned int fileindex, unsigned int filecount, long sizedone, long sizetotal); /** * @brief Add content to a file, to be used in unit testing. * @@ -56,6 +56,7 @@ public: private: const std::vector &_filenames; + const std::map &_filesizes; Settings &_settings; ErrorLogger &_errorLogger; unsigned int _fileCount; diff --git a/gui/threadresult.cpp b/gui/threadresult.cpp index fb2712dbf..369a20e56 100644 --- a/gui/threadresult.cpp +++ b/gui/threadresult.cpp @@ -92,10 +92,12 @@ QString ThreadResult::GetNextFile() } -void ThreadResult::reportStatus(unsigned int index, unsigned int max) +void ThreadResult::reportStatus(unsigned int fileindex, unsigned int filecount, FileLister::filesize_t sizedone, FileLister::filesize_t sizetotal) { - Q_UNUSED(index); - Q_UNUSED(max); + Q_UNUSED(fileindex); + Q_UNUSED(filecount); + Q_UNUSED(sizedone); + Q_UNUSED(sizetotal); } void ThreadResult::SetFiles(const QStringList &files) diff --git a/gui/threadresult.h b/gui/threadresult.h index 170bc19f1..996d998f5 100644 --- a/gui/threadresult.h +++ b/gui/threadresult.h @@ -71,7 +71,7 @@ public: */ void reportOut(const std::string &outmsg); void reportErr(const ErrorLogger::ErrorMessage &msg); - void reportStatus(unsigned int index, unsigned int max); + void reportStatus(unsigned int fileindex, unsigned int filecount, FileLister::filesize_t sizedone, FileLister::filesize_t sizetotal); public slots: /** diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 13d34bcc9..d219870ab 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -433,7 +433,7 @@ void CppCheck::reportProgress(const std::string &filename, const char stage[], c _errorLogger.reportProgress(filename, stage, value); } -void CppCheck::reportStatus(unsigned int /*index*/, unsigned int /*max*/) +void CppCheck::reportStatus(unsigned int /*fileindex*/, unsigned int /*filecount*/, long /*sizedone*/, long /*sizetotal*/) { } diff --git a/lib/cppcheck.h b/lib/cppcheck.h index b921bba6a..77b029c13 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -99,7 +99,7 @@ public: */ static const char * version(); - virtual void reportStatus(unsigned int index, unsigned int max); + virtual void reportStatus(unsigned int fileindex, unsigned int filecount, long sizedone, long sizetotal); /** * @brief Terminate checking. The checking will be terminated as soon as possible. diff --git a/lib/errorlogger.h b/lib/errorlogger.h index bf2c01b1d..bfbde8caa 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -275,10 +275,12 @@ public: /** * Information about how many files have been checked * - * @param index This many files have been checked. - * @param max This many files there are in total. + * @param fileindex This many files have been checked. + * @param filecount This many files there are in total. + * @param sizedone The sum of sizes of the files checked. + * @param sizetotal The total sizes of the files. */ - virtual void reportStatus(unsigned int index, unsigned int max) = 0; + virtual void reportStatus(unsigned int fileindex, unsigned int filecount, long sizedone, long sizetotal) = 0; /** * Report progress to client diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index f4fbb3f13..56a033efc 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -59,7 +59,7 @@ private: id.push_back(msg._id); } - void reportStatus(unsigned int /*index*/, unsigned int /*max*/) + void reportStatus(unsigned int /*fileindex*/, unsigned int /*filecount*/, long /*sizedone*/, long /*sizetotal*/) { } }; diff --git a/test/testfilelister.cpp b/test/testfilelister.cpp index f52d40bb2..62533ecbb 100644 --- a/test/testfilelister.cpp +++ b/test/testfilelister.cpp @@ -52,7 +52,15 @@ private: { // Recursively add add files.. std::vector filenames; - FileLister::recursiveAddFiles(filenames, "."); + std::map filesizes; + FileLister::recursiveAddFiles(filenames, filesizes, "."); + + // Ensure a nonzero size is present for each listed file + for (std::vector::const_iterator i = filenames.begin(); i != filenames.end(); ++i) + { + ASSERT(filesizes.find(*i) != filesizes.end()); + ASSERT(filesizes[*i] > 0); + } // In case there are leading "./".. for (unsigned int i = 0; i < filenames.size(); ++i) diff --git a/test/testother.cpp b/test/testother.cpp index 1e30adf07..ee46ad0af 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -179,9 +179,9 @@ private: if (!msg._callStack.empty() && !_settings.nomsg.isSuppressed(msg._id, msg._callStack.begin()->getfile(), msg._callStack.begin()->line)) _next->reportErr(msg); } - virtual void reportStatus(unsigned int index, unsigned int max) + virtual void reportStatus(unsigned int fileindex, unsigned int filecount, long sizedone, long sizetotal) { - _next->reportStatus(index, max); + _next->reportStatus(fileindex, filecount, sizedone, sizetotal); } private: Settings &_settings; diff --git a/test/testsuite.h b/test/testsuite.h index 78a52f9d0..2a6fedfe9 100644 --- a/test/testsuite.h +++ b/test/testsuite.h @@ -61,7 +61,7 @@ protected: public: virtual void reportOut(const std::string &outmsg); virtual void reportErr(const ErrorLogger::ErrorMessage &msg); - virtual void reportStatus(unsigned int /*index*/, unsigned int /*max*/) {} + virtual void reportStatus(unsigned int /*fileindex*/, unsigned int /*filecount*/, long /*sizedone*/, long /*sizetotal*/) {} void run(const std::string &str); TestFixture(const std::string &_name); diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 4631e1d4a..7a71ed5f9 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -71,6 +71,7 @@ private: } std::vector filenames; + std::map filesizes; filenames.push_back("test.cpp"); Settings settings; @@ -81,7 +82,7 @@ private: std::string r = settings.nomsg.addSuppressionLine(suppression); ASSERT_EQUALS("", r); } - ThreadExecutor executor(filenames, settings, *this); + ThreadExecutor executor(filenames, filesizes, settings, *this); for (unsigned int i = 0; i < filenames.size(); ++i) executor.addFileContent(filenames[i], code); diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp index 77be42bfc..e6d14e482 100644 --- a/test/testthreadexecutor.cpp +++ b/test/testthreadexecutor.cpp @@ -56,6 +56,7 @@ private: } std::vector filenames; + std::map filesizes; for (int i = 1; i <= files; ++i) { std::ostringstream oss; @@ -65,7 +66,7 @@ private: Settings settings; settings._jobs = jobs; - ThreadExecutor executor(filenames, settings, *this); + ThreadExecutor executor(filenames, filesizes, settings, *this); for (unsigned int i = 0; i < filenames.size(); ++i) executor.addFileContent(filenames[i], data);