diff --git a/Makefile b/Makefile index 22cff7582a6..a3a7b806fa8 100644 --- a/Makefile +++ b/Makefile @@ -688,7 +688,7 @@ frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/addoninfo.h l cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp -cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp cli/executor.o: cli/executor.cpp cli/executor.h lib/addoninfo.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index acac0b5f8cd..0c91672ea67 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -38,6 +38,7 @@ #include "settings.h" #include "singleexecutor.h" #include "suppressions.h" +#include "timer.h" #include "utils.h" #if defined(HAS_THREADING_MODEL_THREAD) @@ -259,6 +260,7 @@ namespace { int CppCheckExecutor::check(int argc, const char* const argv[]) { + Timer realTimeClock("", SHOWTIME_MODES::SHOWTIME_SUMMARY); Settings settings; CmdLineLoggerStd logger; Suppressions supprs; @@ -277,6 +279,9 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) const int ret = check_wrapper(settings, supprs); + if (settings.showtime == SHOWTIME_MODES::SHOWTIME_NONE) + realTimeClock.cancelRealTimeMeasurement(); + return ret; } diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 2048d6f8098..0bbe92cbf03 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -895,7 +895,9 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str if (Settings::terminated()) return mLogger->exitcode(); - const Timer fileTotalTimer(mSettings.showtime == SHOWTIME_MODES::SHOWTIME_FILE_TOTAL, file.spath()); + Timer WholeFileTimer{file.spath()}; + if (mSettings.showtime != SHOWTIME_MODES::SHOWTIME_FILE_TOTAL) + WholeFileTimer.cancelRealTimeMeasurement(); if (!mSettings.quiet) { std::string fixedpath = Path::toNativeSeparators(file.spath()); @@ -1505,7 +1507,9 @@ void CppCheck::executeAddons(const std::string& dumpFile, const FileWithDetails& { if (!dumpFile.empty()) { std::vector f{dumpFile}; - executeAddons(f, file.spath()); + Timer::run("CppCheck::executeAddons", mSettings.showtime, &s_timerResults, [&]() { + executeAddons(f, file.spath()); + }); } } diff --git a/lib/timer.cpp b/lib/timer.cpp index 4b1f07d5de3..fc697dc0858 100644 --- a/lib/timer.cpp +++ b/lib/timer.cpp @@ -83,9 +83,6 @@ void TimerResults::showResults(SHOWTIME_MODES mode) const } ++ordinal; } - - const double secOverall = overallData.seconds(); - std::cout << "Overall time: " << secOverall << "s" << std::endl; } void TimerResults::addResults(const std::string& str, std::clock_t clocks) @@ -108,11 +105,13 @@ Timer::Timer(std::string str, SHOWTIME_MODES showtimeMode, TimerResultsIntf* tim , mStart(std::clock()) , mShowTimeMode(showtimeMode) , mStopped(showtimeMode == SHOWTIME_MODES::SHOWTIME_NONE || showtimeMode == SHOWTIME_MODES::SHOWTIME_FILE_TOTAL) + , mStartTimePoint(Clock::now()) {} -Timer::Timer(bool fileTotal, std::string filename) - : mStr(std::move(filename)) - , mStopped(!fileTotal) +Timer::Timer(std::string str) + : mStr(std::move(str)) + , mShowTimeMode(SHOWTIME_MODES::SHOWTIME_FILE_TOTAL) + , mStartTimePoint(Clock::now()) {} Timer::~Timer() @@ -130,15 +129,41 @@ void Timer::stop() const double sec = static_cast(diff) / CLOCKS_PER_SEC; std::lock_guard l(stdCoutLock); std::cout << mStr << ": " << sec << "s" << std::endl; - } else if (mShowTimeMode == SHOWTIME_MODES::SHOWTIME_FILE_TOTAL) { - const double sec = static_cast(diff) / CLOCKS_PER_SEC; + } else if (mShowTimeMode == SHOWTIME_MODES::SHOWTIME_FILE_TOTAL && mStartTimePoint != TimePoint{}) { std::lock_guard l(stdCoutLock); - std::cout << "Check time: " << mStr << ": " << sec << "s" << std::endl; + std::cout << "Check time: " << mStr << ": " << getRealTimePassed() << std::endl; } else { if (mTimerResults) mTimerResults->addResults(mStr, diff); + else if (mStr.empty() && mStartTimePoint != TimePoint{}) { // Get real time + std::lock_guard l(stdCoutLock); + std::cout << "Overall time: " << getRealTimePassed() << std::endl; + } } } mStopped = true; } + +std::string Timer::getRealTimePassed() +{ + auto diff = std::chrono::duration_cast(Clock::now() - mStartTimePoint); + + // Extract hours + auto hours = std::chrono::duration_cast(diff); + diff -= hours; // Subtract the extracted hours + + // Extract minutes + auto minutes = std::chrono::duration_cast(diff); + diff -= minutes; // Subtract the extracted minutes + + // Extract seconds + auto seconds = static_cast(diff.count()) / std::chrono::microseconds::period::den; + + std::string ellapsedTime; + if (hours.count() > 0) + ellapsedTime += std::to_string(hours.count()) + "h "; + if (minutes.count() > 0) + ellapsedTime += std::to_string(minutes.count()) + "m "; + return (ellapsedTime + std::to_string(seconds) + "s "); +} diff --git a/lib/timer.h b/lib/timer.h index d2603d4eb55..87962bb5234 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -22,6 +22,7 @@ #include "config.h" +#include #include #include #include @@ -73,25 +74,37 @@ class CPPCHECKLIB TimerResults : public TimerResultsIntf { class CPPCHECKLIB Timer { public: Timer(std::string str, SHOWTIME_MODES showtimeMode, TimerResultsIntf* timerResults = nullptr); - Timer(bool fileTotal, std::string filename); + Timer(std::string str); ~Timer(); Timer(const Timer&) = delete; Timer& operator=(const Timer&) = delete; + using Clock = std::chrono::high_resolution_clock; + using TimePoint = std::chrono::time_point; + void stop(); + void cancelRealTimeMeasurement() { + mStartTimePoint = TimePoint{}; + } + static void run(std::string str, SHOWTIME_MODES showtimeMode, TimerResultsIntf* timerResults, const std::function& f) { Timer t(std::move(str), showtimeMode, timerResults); f(); } private: + + std::string getRealTimePassed(); + const std::string mStr; TimerResultsIntf* mTimerResults{}; std::clock_t mStart = std::clock(); const SHOWTIME_MODES mShowTimeMode = SHOWTIME_MODES::SHOWTIME_FILE_TOTAL; bool mStopped{}; + TimePoint mStartTimePoint{}; }; + //--------------------------------------------------------------------------- #endif // timerH diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 1f725673874..a039fea47f0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -112,7 +112,6 @@ #include #include #include -#include #include #include #include diff --git a/test/testprocessexecutor.cpp b/test/testprocessexecutor.cpp index c0c19ae2b1f..031048fa84e 100644 --- a/test/testprocessexecutor.cpp +++ b/test/testprocessexecutor.cpp @@ -248,7 +248,7 @@ class TestProcessExecutorBase : public TestFixture { $.showtime = SHOWTIME_MODES::SHOWTIME_TOP5_SUMMARY)); const std::string output_s = GET_REDIRECT_OUTPUT; // once: top5 results + overall + empty line - TODO_ASSERT_EQUALS(5 + 1 + 1, 2, cppcheck::count_all_of(output_s, '\n')); + TODO_ASSERT_EQUALS(5 + 1 + 1, 1, cppcheck::count_all_of(output_s, '\n')); // should only report the top5 once ASSERT(output_s.find("1 result(s)") == std::string::npos); TODO_ASSERT(output_s.find("2 result(s)") != std::string::npos); diff --git a/test/testsingleexecutor.cpp b/test/testsingleexecutor.cpp index 4f0665ff12e..9bcedd1bc92 100644 --- a/test/testsingleexecutor.cpp +++ b/test/testsingleexecutor.cpp @@ -242,8 +242,8 @@ class TestSingleExecutorBase : public TestFixture { dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_TOP5_FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; - // for each file: top5 results + overall + empty line - ASSERT_EQUALS((5 + 1 + 1) * 2LL, cppcheck::count_all_of(output_s, '\n')); + // for each file: top5 results + overall + ASSERT_EQUALS((5 + 1) * 2LL, cppcheck::count_all_of(output_s, '\n')); } void showtime_top5_summary() { @@ -253,8 +253,8 @@ class TestSingleExecutorBase : public TestFixture { dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_TOP5_SUMMARY)); const std::string output_s = GET_REDIRECT_OUTPUT; - // once: top5 results + overall + empty line - ASSERT_EQUALS(5 + 1 + 1, cppcheck::count_all_of(output_s, '\n')); + // once: top5 results + overall + ASSERT_EQUALS(5 + 1, cppcheck::count_all_of(output_s, '\n')); // should only report the top5 once ASSERT(output_s.find("1 result(s)") == std::string::npos); ASSERT(output_s.find("2 result(s)") != std::string::npos); @@ -267,7 +267,7 @@ class TestSingleExecutorBase : public TestFixture { dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; - ASSERT_EQUALS(2, cppcheck::count_all_of(output_s, "Overall time:")); + ASSERT_EQUALS(0, cppcheck::count_all_of(output_s, "Overall time:")); } void showtime_summary() { diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp index ad260727d01..f783367c11b 100644 --- a/test/testthreadexecutor.cpp +++ b/test/testthreadexecutor.cpp @@ -233,10 +233,9 @@ class TestThreadExecutorBase : public TestFixture { "int main() {}", dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_TOP5_FILE)); - // for each file: top5 results + overall + empty line const std::string output_s = GET_REDIRECT_OUTPUT; - // for each file: top5 results + overall + empty line - ASSERT_EQUALS((5 + 1 + 1) * 2LL, cppcheck::count_all_of(output_s, '\n')); + // for each file: top5 results + overall + ASSERT_EQUALS((5 + 1) * 2LL, cppcheck::count_all_of(output_s, '\n')); } void showtime_top5_summary() { @@ -246,8 +245,8 @@ class TestThreadExecutorBase : public TestFixture { dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_TOP5_SUMMARY)); const std::string output_s = GET_REDIRECT_OUTPUT; - // once: top5 results + overall + empty line - ASSERT_EQUALS(5 + 1 + 1, cppcheck::count_all_of(output_s, '\n')); + // once: top5 results + overall + ASSERT_EQUALS(5 + 1, cppcheck::count_all_of(output_s, '\n')); // should only report the top5 once ASSERT(output_s.find("1 result(s)") == std::string::npos); ASSERT(output_s.find("2 result(s)") != std::string::npos); @@ -260,7 +259,7 @@ class TestThreadExecutorBase : public TestFixture { dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_FILE)); const std::string output_s = GET_REDIRECT_OUTPUT; - ASSERT_EQUALS(2, cppcheck::count_all_of(output_s, "Overall time:")); + ASSERT_EQUALS(0, cppcheck::count_all_of(output_s, "Overall time:")); } void showtime_summary() {