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:
parent
46645ab327
commit
6d858b63a1
|
@ -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> filenames;
|
||||
std::map<std::string, long> filesizes;
|
||||
|
||||
if (!pathnames.empty())
|
||||
{
|
||||
// Execute recursiveAddFiles() to each given file parameter
|
||||
std::vector<std::string>::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<std::string>::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<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++)
|
||||
{
|
||||
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<int>(static_cast<double>(index) / max*100)
|
||||
(sizetotal > 0 ? static_cast<long>(static_cast<double>(sizedone) / sizetotal*100) : 0)
|
||||
<< "% done";
|
||||
std::cout << oss.str() << std::endl;
|
||||
}
|
||||
|
|
|
@ -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<std::string> _filenames;
|
||||
|
||||
/**
|
||||
* Sizes of files in _filenames.
|
||||
*/
|
||||
std::map<std::string, long> _filesizes;
|
||||
};
|
||||
|
||||
#endif // CPPCHECKEXECUTOR_H
|
||||
|
|
|
@ -129,7 +129,7 @@ static HANDLE MyFindFirstFile(std::string path, LPWIN32_FIND_DATA findData)
|
|||
|
||||
#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.
|
||||
// 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());
|
||||
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 <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
|
||||
std::vector<std::string> &absolute,
|
||||
std::map<std::string, long> &filesizes,
|
||||
const std::string &path)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
@ -284,6 +288,14 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &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<long>(size);
|
||||
}
|
||||
|
||||
#ifndef PATH_MAX
|
||||
|
@ -293,17 +305,17 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
|
|||
else
|
||||
{
|
||||
// Directory
|
||||
recursiveAddFiles2(relative, absolute, filename);
|
||||
recursiveAddFiles2(relative, absolute, filesizes, filename);
|
||||
}
|
||||
}
|
||||
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;
|
||||
recursiveAddFiles2(filenames, abs, path);
|
||||
recursiveAddFiles2(filenames, abs, filesizes, path);
|
||||
}
|
||||
|
||||
bool FileLister::isDirectory(const std::string &path)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
/// @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<std::string> &filenames,
|
||||
std::map<std::string, long> &filesizes,
|
||||
const std::string &path);
|
||||
|
||||
/**
|
||||
|
@ -57,6 +60,7 @@ public:
|
|||
#ifndef _WIN32
|
||||
static void recursiveAddFiles2(std::vector<std::string> &relative,
|
||||
std::vector<std::string> &absolute,
|
||||
std::map<std::string, long> &filesizes,
|
||||
const std::string &path);
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#include <time.h>
|
||||
#endif
|
||||
|
||||
ThreadExecutor::ThreadExecutor(const std::vector<std::string> &filenames, Settings &settings, ErrorLogger &errorLogger)
|
||||
: _filenames(filenames), _settings(settings), _errorLogger(errorLogger), _fileCount(0)
|
||||
ThreadExecutor::ThreadExecutor(const std::vector<std::string> &filenames, const std::map<std::string, long> &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<std::string, long>::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i)
|
||||
{
|
||||
totalfilesize += i->second;
|
||||
}
|
||||
|
||||
std::list<int> rpipes;
|
||||
std::map<pid_t, std::string> childFile;
|
||||
std::map<int, std::string> 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<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);
|
||||
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*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -39,12 +39,12 @@
|
|||
class ThreadExecutor : public ErrorLogger
|
||||
{
|
||||
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();
|
||||
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<std::string> &_filenames;
|
||||
const std::map<std::string, long> &_filesizes;
|
||||
Settings &_settings;
|
||||
ErrorLogger &_errorLogger;
|
||||
unsigned int _fileCount;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
||||
/**
|
||||
|
|
|
@ -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*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -52,7 +52,15 @@ private:
|
|||
{
|
||||
// Recursively add add files..
|
||||
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 "./"..
|
||||
for (unsigned int i = 0; i < filenames.size(); ++i)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
}
|
||||
|
||||
std::vector<std::string> filenames;
|
||||
std::map<std::string, long> 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);
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
}
|
||||
|
||||
std::vector<std::string> filenames;
|
||||
std::map<std::string, long> 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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue