19
19
#include " threadexecutor.h"
20
20
21
21
#include " color.h"
22
+ #include " config.h"
22
23
#include " cppcheck.h"
23
24
#include " cppcheckexecutor.h"
24
25
#include " errorlogger.h"
@@ -45,97 +46,158 @@ ThreadExecutor::ThreadExecutor(const std::map<std::string, std::size_t> &files,
45
46
ThreadExecutor::~ThreadExecutor ()
46
47
{}
47
48
48
- class ThreadExecutor ::SyncLogForwarder : public ErrorLogger
49
+ class Data
49
50
{
50
51
public:
51
- explicit SyncLogForwarder (ThreadExecutor &threadExecutor)
52
- : mThreadExecutor(threadExecutor), mProcessedFiles(0 ), mTotalFiles(0 ), mProcessedSize(0 ) {
53
-
54
- const std::map<std::string, std::size_t >& files = mThreadExecutor .mFiles ;
55
- mItNextFile = files.begin ();
56
- mItNextFileSettings = mThreadExecutor .mSettings .project .fileSettings .begin ();
52
+ Data (const std::map<std::string, std::size_t > &files, const std::list<ImportProject::FileSettings> &fileSettings)
53
+ : mFiles (files), mFileSettings (fileSettings), mProcessedFiles (0 ), mProcessedSize (0 )
54
+ {
55
+ mItNextFile = mFiles .begin ();
56
+ mItNextFileSettings = mFileSettings .begin ();
57
57
58
- mTotalFiles = files .size () + mThreadExecutor . mSettings . project . fileSettings .size ();
59
- mTotalFileSize = std::accumulate (files .cbegin (), files .cend (), std::size_t (0 ), [](std::size_t v, const std::pair<std::string, std::size_t >& p) {
58
+ mTotalFiles = mFiles .size () + mFileSettings .size ();
59
+ mTotalFileSize = std::accumulate (mFiles .cbegin (), mFiles .cend (), std::size_t (0 ), [](std::size_t v, const std::pair<std::string, std::size_t >& p) {
60
60
return v + p.second ;
61
61
});
62
62
}
63
63
64
- void reportOut (const std::string &outmsg, Color c) override
65
- {
66
- std::lock_guard<std::mutex> lg (mReportSync );
67
-
68
- mThreadExecutor .mErrorLogger .reportOut (outmsg, c);
64
+ bool finished () {
65
+ std::lock_guard<std::mutex> l (mFileSync );
66
+ return mItNextFile == mFiles .cend () && mItNextFileSettings == mFileSettings .cend ();
69
67
}
70
68
71
- void reportErr (const ErrorMessage &msg) override {
72
- report (msg, MessageType::REPORT_ERROR);
73
- }
69
+ bool next (const std::string *&file, const ImportProject::FileSettings *&fs, std::size_t &fileSize) {
70
+ std::lock_guard<std::mutex> l (mFileSync );
71
+ if (mItNextFile != mFiles .end ()) {
72
+ file = &mItNextFile ->first ;
73
+ fileSize = mItNextFile ->second ;
74
+ ++mItNextFile ;
75
+ return true ;
76
+ }
77
+ if (mItNextFileSettings != mFileSettings .end ()) {
78
+ fs = &(*mItNextFileSettings );
79
+ fileSize = 0 ;
80
+ ++mItNextFileSettings ;
81
+ return true ;
82
+ }
74
83
75
- void reportInfo (const ErrorMessage &msg) override {
76
- report (msg, MessageType::REPORT_INFO);
84
+ return false ;
77
85
}
78
86
79
- ThreadExecutor & mThreadExecutor ;
80
-
87
+ private:
88
+ const std::map<std::string, std:: size_t > & mFiles ;
81
89
std::map<std::string, std::size_t >::const_iterator mItNextFile ;
90
+ const std::list<ImportProject::FileSettings> &mFileSettings ;
82
91
std::list<ImportProject::FileSettings>::const_iterator mItNextFileSettings ;
83
92
93
+ public:
84
94
std::size_t mProcessedFiles ;
85
95
std::size_t mTotalFiles ;
86
96
std::size_t mProcessedSize ;
87
97
std::size_t mTotalFileSize ;
88
98
89
99
std::mutex mFileSync ;
90
- std::mutex mErrorSync ;
100
+ };
101
+
102
+ class SyncLogForwarder : public ErrorLogger
103
+ {
104
+ public:
105
+ explicit SyncLogForwarder (ThreadExecutor &threadExecutor, ErrorLogger &errorLogger)
106
+ : mThreadExecutor(threadExecutor), mErrorLogger(errorLogger) {}
107
+
108
+ void reportOut (const std::string &outmsg, Color c) override
109
+ {
110
+ std::lock_guard<std::mutex> lg (mReportSync );
111
+
112
+ mErrorLogger .reportOut (outmsg, c);
113
+ }
114
+
115
+ void reportErr (const ErrorMessage &msg) override {
116
+ report (msg, MessageType::REPORT_ERROR);
117
+ }
118
+
119
+ void reportInfo (const ErrorMessage &msg) override {
120
+ report (msg, MessageType::REPORT_INFO);
121
+ }
122
+
91
123
std::mutex mReportSync ;
92
124
93
125
private:
94
126
enum class MessageType {REPORT_ERROR, REPORT_INFO};
95
127
96
128
void report (const ErrorMessage &msg, MessageType msgType)
97
129
{
98
- if (mThreadExecutor .mSettings . nomsg . isSuppressed (msg))
130
+ if (! mThreadExecutor .hasToLog (msg))
99
131
return ;
100
132
101
- // Alert only about unique errors
102
- bool reportError = false ;
133
+ std::lock_guard<std::mutex> lg (mReportSync );
103
134
104
- {
105
- std::string errmsg = msg.toString (mThreadExecutor .mSettings .verbose );
135
+ switch (msgType) {
136
+ case MessageType::REPORT_ERROR:
137
+ mErrorLogger .reportErr (msg);
138
+ break ;
139
+ case MessageType::REPORT_INFO:
140
+ mErrorLogger .reportInfo (msg);
141
+ break ;
142
+ }
143
+ }
106
144
107
- std::lock_guard<std::mutex> lg (mErrorSync );
108
- if (std::find (mThreadExecutor .mErrorList .cbegin (), mThreadExecutor .mErrorList .cend (), errmsg) == mThreadExecutor .mErrorList .cend ()) {
109
- mThreadExecutor .mErrorList .emplace_back (std::move (errmsg));
110
- reportError = true ;
111
- }
145
+ ThreadExecutor &mThreadExecutor ;
146
+ ErrorLogger &mErrorLogger ;
147
+ };
148
+
149
+ static unsigned int STDCALL threadProc (Data *data, SyncLogForwarder* logForwarder, const Settings &settings)
150
+ {
151
+ unsigned int result = 0 ;
152
+
153
+ for (;;) {
154
+ if (data->finished ()) {
155
+ break ;
112
156
}
113
157
114
- if (reportError) {
115
- std::lock_guard<std::mutex> lg (mReportSync );
158
+ const std::string *file = nullptr ;
159
+ const ImportProject::FileSettings *fs = nullptr ;
160
+ std::size_t fileSize;
161
+ if (!data->next (file, fs, fileSize))
162
+ break ;
116
163
117
- switch (msgType) {
118
- case MessageType::REPORT_ERROR:
119
- mThreadExecutor .mErrorLogger .reportErr (msg);
120
- break ;
121
- case MessageType::REPORT_INFO:
122
- mThreadExecutor .mErrorLogger .reportInfo (msg);
123
- break ;
164
+ CppCheck fileChecker (*logForwarder, false , CppCheckExecutor::executeCommand);
165
+ fileChecker.settings () = settings;
166
+
167
+ if (fs) {
168
+ // file settings..
169
+ result += fileChecker.check (*fs);
170
+ if (settings.clangTidy )
171
+ fileChecker.analyseClangTidy (*fs);
172
+ } else {
173
+ // Read file from a file
174
+ result += fileChecker.check (*file);
175
+ }
176
+
177
+ {
178
+ std::lock_guard<std::mutex> l (data->mFileSync );
179
+ data->mProcessedSize += fileSize;
180
+ data->mProcessedFiles ++;
181
+ if (!settings.quiet ) {
182
+ std::lock_guard<std::mutex> lg (logForwarder->mReportSync );
183
+ CppCheckExecutor::reportStatus (data->mProcessedFiles , data->mTotalFiles , data->mProcessedSize , data->mTotalFileSize );
124
184
}
125
185
}
126
186
}
127
- };
187
+ return result;
188
+ }
128
189
129
190
unsigned int ThreadExecutor::check ()
130
191
{
131
192
std::vector<std::future<unsigned int >> threadFutures;
132
193
threadFutures.reserve (mSettings .jobs );
133
194
134
- SyncLogForwarder logforwarder (*this );
195
+ Data data (mFiles , mSettings .project .fileSettings );
196
+ SyncLogForwarder logforwarder (*this , mErrorLogger );
135
197
136
198
for (unsigned int i = 0 ; i < mSettings .jobs ; ++i) {
137
199
try {
138
- threadFutures.emplace_back (std::async (std::launch::async, threadProc, &logforwarder));
200
+ threadFutures.emplace_back (std::async (std::launch::async, & threadProc, &data, & logforwarder, mSettings ));
139
201
}
140
202
catch (const std::system_error &e) {
141
203
std::cerr << " #### ThreadExecutor::check exception :" << e.what () << std::endl;
@@ -147,53 +209,3 @@ unsigned int ThreadExecutor::check()
147
209
return v + f.get ();
148
210
});
149
211
}
150
-
151
- unsigned int STDCALL ThreadExecutor::threadProc (SyncLogForwarder* logForwarder)
152
- {
153
- unsigned int result = 0 ;
154
-
155
- std::map<std::string, std::size_t >::const_iterator &itFile = logForwarder->mItNextFile ;
156
- std::list<ImportProject::FileSettings>::const_iterator &itFileSettings = logForwarder->mItNextFileSettings ;
157
-
158
- // guard static members of CppCheck against concurrent access
159
- logForwarder->mFileSync .lock ();
160
-
161
- for (;;) {
162
- if (itFile == logForwarder->mThreadExecutor .mFiles .cend () && itFileSettings == logForwarder->mThreadExecutor .mSettings .project .fileSettings .cend ()) {
163
- logForwarder->mFileSync .unlock ();
164
- break ;
165
- }
166
-
167
- CppCheck fileChecker (*logForwarder, false , CppCheckExecutor::executeCommand);
168
- fileChecker.settings () = logForwarder->mThreadExecutor .mSettings ;
169
-
170
- std::size_t fileSize = 0 ;
171
- if (itFile != logForwarder->mThreadExecutor .mFiles .end ()) {
172
- const std::string &file = itFile->first ;
173
- fileSize = itFile->second ;
174
- ++itFile;
175
-
176
- logForwarder->mFileSync .unlock ();
177
-
178
- // Read file from a file
179
- result += fileChecker.check (file);
180
- } else { // file settings..
181
- const ImportProject::FileSettings &fs = *itFileSettings;
182
- ++itFileSettings;
183
- logForwarder->mFileSync .unlock ();
184
- result += fileChecker.check (fs);
185
- if (logForwarder->mThreadExecutor .mSettings .clangTidy )
186
- fileChecker.analyseClangTidy (fs);
187
- }
188
-
189
- logForwarder->mFileSync .lock ();
190
-
191
- logForwarder->mProcessedSize += fileSize;
192
- logForwarder->mProcessedFiles ++;
193
- if (!logForwarder->mThreadExecutor .mSettings .quiet ) {
194
- std::lock_guard<std::mutex> lg (logForwarder->mReportSync );
195
- CppCheckExecutor::reportStatus (logForwarder->mProcessedFiles , logForwarder->mTotalFiles , logForwarder->mProcessedSize , logForwarder->mTotalFileSize );
196
- }
197
- }
198
- return result;
199
- }
0 commit comments