Report percentage complete based on file size

This patch makes the (reasonable) assumption that the total size of all checked
files fits in a 'long' type.
This commit is contained in:
Greg Hewgill 2011-04-19 23:52:32 +12:00
parent 46645ab327
commit 6d858b63a1
17 changed files with 113 additions and 37 deletions

View File

@ -85,13 +85,14 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
std::vector<std::string> pathnames = parser.GetPathNames(); std::vector<std::string> pathnames = parser.GetPathNames();
std::vector<std::string> filenames; std::vector<std::string> filenames;
std::map<std::string, long> filesizes;
if (!pathnames.empty()) if (!pathnames.empty())
{ {
// Execute recursiveAddFiles() to each given file parameter // Execute recursiveAddFiles() to each given file parameter
std::vector<std::string>::const_iterator iter; std::vector<std::string>::const_iterator iter;
for (iter = pathnames.begin(); iter != pathnames.end(); ++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()) if (!filenames.empty())
@ -114,7 +115,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
{ {
std::vector<std::string>::iterator iter; std::vector<std::string>::iterator iter;
for (iter = filenames.begin(); iter != filenames.end(); ++iter) for (iter = filenames.begin(); iter != filenames.end(); ++iter)
{
_filenames.push_back(*iter); _filenames.push_back(*iter);
_filesizes[*iter] = filesizes[*iter];
}
return true; return true;
} }
@ -146,10 +150,22 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
if (_settings._jobs == 1) if (_settings._jobs == 1)
{ {
// Single process // Single process
long totalfilesize = 0;
for (std::map<std::string, long>::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i)
{
totalfilesize += i->second;
}
long processedsize = 0;
for (unsigned int c = 0; c < _filenames.size(); c++) for (unsigned int c = 0; c < _filenames.size(); c++)
{ {
returnValue += cppCheck.check(_filenames[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()) else if (!ThreadExecutor::isEnabled())
@ -160,7 +176,7 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
{ {
// Multiple processes // Multiple processes
Settings &settings = cppCheck.settings(); Settings &settings = cppCheck.settings();
ThreadExecutor executor(_filenames, settings, *this); ThreadExecutor executor(_filenames, _filesizes, settings, *this);
returnValue = executor.check(); 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; std::ostringstream oss;
oss << index << "/" << max oss << fileindex << "/" << filecount
<< " files checked " << << " files checked " <<
static_cast<int>(static_cast<double>(index) / max*100) (sizetotal > 0 ? static_cast<long>(static_cast<double>(sizedone) / sizetotal*100) : 0)
<< "% done"; << "% done";
std::cout << oss.str() << std::endl; std::cout << oss.str() << std::endl;
} }

View File

@ -72,7 +72,7 @@ public:
void reportProgress(const std::string &filename, const char stage[], const unsigned int value); 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: protected:
@ -113,6 +113,11 @@ private:
* List of files to check. * List of files to check.
*/ */
std::vector<std::string> _filenames; std::vector<std::string> _filenames;
/**
* Sizes of files in _filenames.
*/
std::map<std::string, long> _filesizes;
}; };
#endif // CPPCHECKEXECUTOR_H #endif // CPPCHECKEXECUTOR_H

View File

@ -129,7 +129,7 @@ static HANDLE MyFindFirstFile(std::string path, LPWIN32_FIND_DATA findData)
#endif // defined(UNICODE) #endif // defined(UNICODE)
void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, const std::string &path) void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map<std::string, long> &filesizes, const std::string &path)
{ {
// oss is the search string passed into FindFirst and FindNext. // oss is the search string passed into FindFirst and FindNext.
// bdir is the base directory which is used to form pathnames. // bdir is the base directory which is used to form pathnames.
@ -201,12 +201,14 @@ void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, const st
{ {
const std::string nativename = Path::fromNativeSeparators(fname.str()); const std::string nativename = Path::fromNativeSeparators(fname.str());
filenames.push_back(nativename); filenames.push_back(nativename);
// Limitation: file sizes are assumed to fit in a 'long'
filesizes[nativename] = ffd.nFileSizeLow;
} }
} }
else else
{ {
// Directory // Directory
FileLister::recursiveAddFiles(filenames, fname.str()); FileLister::recursiveAddFiles(filenames, filesizes, fname.str());
} }
#if defined(UNICODE) #if defined(UNICODE)
delete [] ansiFfd; delete [] ansiFfd;
@ -239,9 +241,11 @@ bool FileLister::isDirectory(const std::string &path)
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <sys/stat.h>
void FileLister::recursiveAddFiles2(std::vector<std::string> &relative, void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
std::vector<std::string> &absolute, std::vector<std::string> &absolute,
std::map<std::string, long> &filesizes,
const std::string &path) const std::string &path)
{ {
std::ostringstream oss; std::ostringstream oss;
@ -284,6 +288,14 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
{ {
relative.push_back(filename); relative.push_back(filename);
absolute.push_back(fname); 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<long>(size);
} }
#ifndef PATH_MAX #ifndef PATH_MAX
@ -293,17 +305,17 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
else else
{ {
// Directory // Directory
recursiveAddFiles2(relative, absolute, filename); recursiveAddFiles2(relative, absolute, filesizes, filename);
} }
} }
globfree(&glob_results); globfree(&glob_results);
} }
void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, const std::string &path) void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map<std::string, long> &filesizes, const std::string &path)
{ {
std::vector<std::string> abs; std::vector<std::string> abs;
recursiveAddFiles2(filenames, abs, path); recursiveAddFiles2(filenames, abs, filesizes, path);
} }
bool FileLister::isDirectory(const std::string &path) bool FileLister::isDirectory(const std::string &path)

View File

@ -21,6 +21,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <map>
/// @addtogroup CLI /// @addtogroup CLI
/// @{ /// @{
@ -35,9 +36,11 @@ public:
* given vector. Only files with accepted extensions * given vector. Only files with accepted extensions
* (*.c;*.cpp;*.cxx;*.c++;*.cc;*.txx) are added. * (*.c;*.cpp;*.cxx;*.c++;*.cc;*.txx) are added.
* @param filenames output vector that filenames are written to * @param filenames output vector that filenames are written to
* @param filesizes output map that contains the size of each file
* @param path root path * @param path root path
*/ */
static void recursiveAddFiles(std::vector<std::string> &filenames, static void recursiveAddFiles(std::vector<std::string> &filenames,
std::map<std::string, long> &filesizes,
const std::string &path); const std::string &path);
/** /**
@ -57,6 +60,7 @@ public:
#ifndef _WIN32 #ifndef _WIN32
static void recursiveAddFiles2(std::vector<std::string> &relative, static void recursiveAddFiles2(std::vector<std::string> &relative,
std::vector<std::string> &absolute, std::vector<std::string> &absolute,
std::map<std::string, long> &filesizes,
const std::string &path); const std::string &path);
#endif #endif
}; };

View File

@ -31,8 +31,8 @@
#include <time.h> #include <time.h>
#endif #endif
ThreadExecutor::ThreadExecutor(const std::vector<std::string> &filenames, Settings &settings, ErrorLogger &errorLogger) ThreadExecutor::ThreadExecutor(const std::vector<std::string> &filenames, const std::map<std::string, long> &filesizes, Settings &settings, ErrorLogger &errorLogger)
: _filenames(filenames), _settings(settings), _errorLogger(errorLogger), _fileCount(0) : _filenames(filenames), _filesizes(filesizes), _settings(settings), _errorLogger(errorLogger), _fileCount(0)
{ {
#ifdef THREADING_MODEL_FORK #ifdef THREADING_MODEL_FORK
_wpipe = 0; _wpipe = 0;
@ -116,12 +116,10 @@ int ThreadExecutor::handleRead(int rpipe, unsigned int &result)
} }
else if (type == '3') else if (type == '3')
{ {
_fileCount++;
std::istringstream iss(buf); std::istringstream iss(buf);
unsigned int fileResult = 0; unsigned int fileResult = 0;
iss >> fileResult; iss >> fileResult;
result += fileResult; result += fileResult;
_errorLogger.reportStatus(_fileCount, _filenames.size());
delete [] buf; delete [] buf;
return -1; return -1;
} }
@ -135,8 +133,16 @@ unsigned int ThreadExecutor::check()
_fileCount = 0; _fileCount = 0;
unsigned int result = 0; unsigned int result = 0;
long totalfilesize = 0;
for (std::map<std::string, long>::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i)
{
totalfilesize += i->second;
}
std::list<int> rpipes; std::list<int> rpipes;
std::map<pid_t, std::string> childFile; std::map<pid_t, std::string> childFile;
std::map<int, std::string> pipeFile;
long processedsize = 0;
unsigned int i = 0; unsigned int i = 0;
while (true) while (true)
{ {
@ -199,6 +205,7 @@ unsigned int ThreadExecutor::check()
close(pipes[1]); close(pipes[1]);
rpipes.push_back(pipes[0]); rpipes.push_back(pipes[0]);
childFile[pid] = _filenames[i]; childFile[pid] = _filenames[i];
pipeFile[pipes[0]] = _filenames[i];
++i; ++i;
} }
@ -221,6 +228,23 @@ unsigned int ThreadExecutor::check()
int readRes = handleRead(*rp, result); int readRes = handleRead(*rp, result);
if (readRes == -1) if (readRes == -1)
{ {
long size = 0;
std::map<int, std::string>::iterator p = pipeFile.find(*rp);
if (p != pipeFile.end())
{
std::string name = p->second;
pipeFile.erase(p);
std::map<std::string, long>::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); close(*rp);
rp = rpipes.erase(rp); rp = rpipes.erase(rp);
} }
@ -299,7 +323,7 @@ void ThreadExecutor::reportErr(const ErrorLogger::ErrorMessage &msg)
writeToPipe('2', msg.serialize()); 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 // 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*/)
{ {
} }

View File

@ -39,12 +39,12 @@
class ThreadExecutor : public ErrorLogger class ThreadExecutor : public ErrorLogger
{ {
public: public:
ThreadExecutor(const std::vector<std::string> &filenames, Settings &settings, ErrorLogger &_errorLogger); ThreadExecutor(const std::vector<std::string> &filenames, const std::map<std::string, long> &filesizes, Settings &settings, ErrorLogger &_errorLogger);
virtual ~ThreadExecutor(); virtual ~ThreadExecutor();
unsigned int check(); unsigned int check();
virtual void reportOut(const std::string &outmsg); virtual void reportOut(const std::string &outmsg);
virtual void reportErr(const ErrorLogger::ErrorMessage &msg); 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. * @brief Add content to a file, to be used in unit testing.
* *
@ -56,6 +56,7 @@ public:
private: private:
const std::vector<std::string> &_filenames; const std::vector<std::string> &_filenames;
const std::map<std::string, long> &_filesizes;
Settings &_settings; Settings &_settings;
ErrorLogger &_errorLogger; ErrorLogger &_errorLogger;
unsigned int _fileCount; unsigned int _fileCount;

View File

@ -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(fileindex);
Q_UNUSED(max); Q_UNUSED(filecount);
Q_UNUSED(sizedone);
Q_UNUSED(sizetotal);
} }
void ThreadResult::SetFiles(const QStringList &files) void ThreadResult::SetFiles(const QStringList &files)

View File

@ -71,7 +71,7 @@ public:
*/ */
void reportOut(const std::string &outmsg); void reportOut(const std::string &outmsg);
void reportErr(const ErrorLogger::ErrorMessage &msg); 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: public slots:
/** /**

View File

@ -433,7 +433,7 @@ void CppCheck::reportProgress(const std::string &filename, const char stage[], c
_errorLogger.reportProgress(filename, stage, value); _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*/)
{ {
} }

View File

@ -99,7 +99,7 @@ public:
*/ */
static const char * version(); 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. * @brief Terminate checking. The checking will be terminated as soon as possible.

View File

@ -275,10 +275,12 @@ public:
/** /**
* Information about how many files have been checked * Information about how many files have been checked
* *
* @param index This many files have been checked. * @param fileindex This many files have been checked.
* @param max This many files there are in total. * @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 * Report progress to client

View File

@ -59,7 +59,7 @@ private:
id.push_back(msg._id); 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*/)
{ {
} }
}; };

View File

@ -52,7 +52,15 @@ private:
{ {
// Recursively add add files.. // Recursively add add files..
std::vector<std::string> filenames; std::vector<std::string> filenames;
FileLister::recursiveAddFiles(filenames, "."); std::map<std::string, long> filesizes;
FileLister::recursiveAddFiles(filenames, filesizes, ".");
// Ensure a nonzero size is present for each listed file
for (std::vector<std::string>::const_iterator i = filenames.begin(); i != filenames.end(); ++i)
{
ASSERT(filesizes.find(*i) != filesizes.end());
ASSERT(filesizes[*i] > 0);
}
// In case there are leading "./".. // In case there are leading "./"..
for (unsigned int i = 0; i < filenames.size(); ++i) for (unsigned int i = 0; i < filenames.size(); ++i)

View File

@ -179,9 +179,9 @@ private:
if (!msg._callStack.empty() && !_settings.nomsg.isSuppressed(msg._id, msg._callStack.begin()->getfile(), msg._callStack.begin()->line)) if (!msg._callStack.empty() && !_settings.nomsg.isSuppressed(msg._id, msg._callStack.begin()->getfile(), msg._callStack.begin()->line))
_next->reportErr(msg); _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: private:
Settings &_settings; Settings &_settings;

View File

@ -61,7 +61,7 @@ protected:
public: public:
virtual void reportOut(const std::string &outmsg); virtual void reportOut(const std::string &outmsg);
virtual void reportErr(const ErrorLogger::ErrorMessage &msg); 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); void run(const std::string &str);
TestFixture(const std::string &_name); TestFixture(const std::string &_name);

View File

@ -71,6 +71,7 @@ private:
} }
std::vector<std::string> filenames; std::vector<std::string> filenames;
std::map<std::string, long> filesizes;
filenames.push_back("test.cpp"); filenames.push_back("test.cpp");
Settings settings; Settings settings;
@ -81,7 +82,7 @@ private:
std::string r = settings.nomsg.addSuppressionLine(suppression); std::string r = settings.nomsg.addSuppressionLine(suppression);
ASSERT_EQUALS("", r); ASSERT_EQUALS("", r);
} }
ThreadExecutor executor(filenames, settings, *this); ThreadExecutor executor(filenames, filesizes, settings, *this);
for (unsigned int i = 0; i < filenames.size(); ++i) for (unsigned int i = 0; i < filenames.size(); ++i)
executor.addFileContent(filenames[i], code); executor.addFileContent(filenames[i], code);

View File

@ -56,6 +56,7 @@ private:
} }
std::vector<std::string> filenames; std::vector<std::string> filenames;
std::map<std::string, long> filesizes;
for (int i = 1; i <= files; ++i) for (int i = 1; i <= files; ++i)
{ {
std::ostringstream oss; std::ostringstream oss;
@ -65,7 +66,7 @@ private:
Settings settings; Settings settings;
settings._jobs = jobs; settings._jobs = jobs;
ThreadExecutor executor(filenames, settings, *this); ThreadExecutor executor(filenames, filesizes, settings, *this);
for (unsigned int i = 0; i < filenames.size(); ++i) for (unsigned int i = 0; i < filenames.size(); ++i)
executor.addFileContent(filenames[i], data); executor.addFileContent(filenames[i], data);