Skip to content

Commit d04e78c

Browse files
authored
fix #14: Support --version option (#15)
1 parent 1d1491e commit d04e78c

File tree

4 files changed

+85
-37
lines changed

4 files changed

+85
-37
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,7 @@ The configuration file is written in json, as **run-cppcheck-config.json**. It i
3636
and `%LOCALAPPDATA%\run-cppcheck` on Windows. The log file may provide more information than the editor plugin if analysis fails.
3737
- **enable_logging**: Default is `true`.
3838
- **extra_args**: Extra arguments to pass to cppcheck. Example: `["--enable=style"]`.
39+
40+
**NOTE:** Some plugins use the `--version` flag to determine the version of cppcheck. For these plugin, you need
41+
to place a run-cppcheck-config.json in the directory where the plugin runs the command, providing the **cppcheck** field.
42+
If this configuration is not found, run-cppcheck tries to find cppcheck in PATH.

config.cpp

Lines changed: 70 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -95,23 +95,27 @@ std::string Config::command() const
9595

9696
cmd += "\"" + m_cppcheck + "\"";
9797

98-
for (const auto &arg : m_args) {
99-
// If arg contains double quotes, escape them
100-
std::string escapedArg = arg;
101-
size_t pos = 0;
102-
while ((pos = escapedArg.find("\"", pos)) != std::string::npos) {
103-
escapedArg.replace(pos, 1, "\\\"");
104-
pos += 2;
105-
}
106-
cmd += " \"" + escapedArg + "\"";
98+
if (m_printVersion) {
99+
cmd += " \"--version\"";
100+
} else {
101+
for (const auto &arg : m_args) {
102+
// If arg contains double quotes, escape them
103+
std::string escapedArg = arg;
104+
size_t pos = 0;
105+
while ((pos = escapedArg.find("\"", pos)) != std::string::npos) {
106+
escapedArg.replace(pos, 1, "\\\"");
107+
pos += 2;
108+
}
109+
cmd += " \"" + escapedArg + "\"";
107110

108-
}
111+
}
109112

110113

111-
if (!m_projectFilePath.empty()) {
112-
cmd += " \"--project=" + m_projectFilePath.string() + "\" \"--file-filter=" + m_filename.string() + "\"";
113-
} else {
114-
cmd += " \"" + m_filename.string() + "\"";
114+
if (!m_projectFilePath.empty()) {
115+
cmd += " \"--project=" + m_projectFilePath.string() + "\" \"--file-filter=" + m_filename.string() + "\"";
116+
} else {
117+
cmd += " \"" + m_filename.string() + "\"";
118+
}
115119
}
116120

117121
cmd += " 2>&1";
@@ -185,6 +189,15 @@ std::string Config::matchFilenameFromCompileCommand()
185189
return "";
186190
}
187191

192+
static bool fileExists(const std::filesystem::path &path)
193+
{
194+
#ifdef _WIN32
195+
return !_access(path.string().c_str(), 0);
196+
#else
197+
return !access(path.string().c_str(), F_OK);
198+
#endif
199+
}
200+
188201
std::string Config::parseArgs(int argc, char **argv)
189202
{
190203
(void) argc;
@@ -204,6 +217,11 @@ std::string Config::parseArgs(int argc, char **argv)
204217
continue;
205218
}
206219

220+
if (std::string(arg) == "--version") {
221+
m_printVersion = true;
222+
continue;
223+
}
224+
207225
if (arg[0] == '-') {
208226
m_args.push_back(arg);
209227
continue;
@@ -215,35 +233,51 @@ std::string Config::parseArgs(int argc, char **argv)
215233
m_filename = arg;
216234
}
217235

218-
if (m_filename.empty())
219-
return "Missing filename";
236+
if (!m_printVersion) {
237+
if (m_filename.empty())
238+
return "Missing filename";
220239

221-
if (m_logFilePath.empty()) {
222-
const std::string error = getDefaultLogFilePath(m_logFilePath);
223-
if (!error.empty())
224-
return error;
225-
}
226-
if (m_configPath.empty())
227-
m_configPath = findFile(m_filename, "run-cppcheck-config.json");
240+
if (m_logFilePath.empty()) {
241+
const std::string error = getDefaultLogFilePath(m_logFilePath);
242+
if (!error.empty())
243+
return error;
244+
}
228245

229-
if (m_configPath.empty())
230-
return "Failed to find 'run-cppcheck-config.json' in any parent directory of analyzed file";
246+
if (m_configPath.empty())
247+
m_configPath = findFile(m_filename, "run-cppcheck-config.json");
231248

232-
std::string err = load(m_configPath);
233-
if (!err.empty())
234-
return "Failed to load '" + m_configPath.string() + "': " + err;
249+
if (m_configPath.empty())
250+
return "Failed to find 'run-cppcheck-config.json' in any parent directory of analyzed file";
235251

236-
if (!m_projectFilePath.empty() && m_projectFilePath.is_relative())
237-
m_projectFilePath = m_configPath.parent_path() / m_projectFilePath;
252+
std::string err = load(m_configPath);
253+
if (!err.empty())
254+
return "Failed to load '" + m_configPath.string() + "': " + err;
238255

239-
if (m_filename.is_relative())
240-
m_filename = normalizePath(std::filesystem::current_path() / m_filename);
256+
if (!m_projectFilePath.empty() && m_projectFilePath.is_relative())
257+
m_projectFilePath = m_configPath.parent_path() / m_projectFilePath;
241258

242-
err = matchFilenameFromCompileCommand();
259+
if (m_filename.is_relative())
260+
m_filename = normalizePath(std::filesystem::current_path() / m_filename);
243261

244-
// Only warn if compile_commands.json is corrupted
245-
if (!err.empty())
246-
return "Failed to process compile_commands.json: " + err;
262+
err = matchFilenameFromCompileCommand();
263+
264+
// Only warn if compile_commands.json is corrupted
265+
if (!err.empty())
266+
return "Failed to process compile_commands.json: " + err;
267+
} else {
268+
269+
// If --version is used there is no input file, so check for config
270+
// in current working directory
271+
if (m_configPath.empty())
272+
m_configPath = std::filesystem::current_path() / "run-cppcheck-config.json";
273+
274+
if (!fileExists(m_configPath))
275+
return "";
276+
277+
std::string err = load(m_configPath);
278+
if (!err.empty())
279+
return "Failed to load '" + m_configPath.string() + "': " + err;
280+
}
247281

248282
return "";
249283
}

config.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Config {
1515
, m_cppcheck("cppcheck")
1616
, m_filename("")
1717
, m_args({})
18+
, m_printVersion(false)
1819
{
1920
}
2021

@@ -41,6 +42,11 @@ class Config {
4142
return m_configPath;
4243
}
4344

45+
bool printVersion() const
46+
{
47+
return m_printVersion;
48+
}
49+
4450
private:
4551
static std::filesystem::path findFile(const std::filesystem::path &input_path, const std::string &filename);
4652
static std::string getDefaultLogFilePath(std::filesystem::path &path);
@@ -53,6 +59,7 @@ class Config {
5359
std::string m_cppcheck;
5460
std::filesystem::path m_filename;
5561
std::vector<std::string> m_args;
62+
bool m_printVersion;
5663
};
5764

5865
#endif

main.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ int main(int argc, char** argv) {
8282
std::string output;
8383
int res = executeCommand(cmd, output);
8484

85-
std::cerr << output;
85+
if (config.printVersion())
86+
std::cout << output;
87+
else
88+
std::cerr << output;
8689
logfile << output;
8790

8891
return res;

0 commit comments

Comments
 (0)