test/cli: execute addon
This commit is contained in:
parent
964c2a237a
commit
b94f4176f1
|
@ -120,6 +120,8 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
|||
bool def = false;
|
||||
bool maxconfigs = false;
|
||||
|
||||
mSettings->exename = argv[0];
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
if (std::strcmp(argv[i], "--version") == 0) {
|
||||
|
|
|
@ -59,12 +59,14 @@ static const CWE CWE398(398U); // Indicator of Poor Code Quality
|
|||
|
||||
namespace {
|
||||
struct AddonInfo {
|
||||
std::string script;
|
||||
std::string name;
|
||||
std::string scriptFile;
|
||||
std::string args;
|
||||
|
||||
std::string getAddonInfo(const std::string &fileName) {
|
||||
std::string getAddonInfo(const std::string &fileName, const std::string &exename) {
|
||||
if (!endsWith(fileName, ".json", 5)) {
|
||||
script = fileName;
|
||||
name = fileName;
|
||||
scriptFile = Path::getPathFromFilename(exename) + "/addons/" + fileName + ".py";
|
||||
return "";
|
||||
}
|
||||
std::ifstream fin(fileName);
|
||||
|
@ -81,12 +83,32 @@ namespace {
|
|||
for (const picojson::value &v : obj["args"].get<picojson::array>())
|
||||
args += " " + v.get<std::string>();
|
||||
}
|
||||
script = obj["script"].get<std::string>();
|
||||
name = obj["script"].get<std::string>();
|
||||
scriptFile = Path::getPathFromFilename(exename) + "/addons/" + fileName + ".py";
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static std::string executeAddon(const AddonInfo &addonInfo, const std::string &dumpFile)
|
||||
{
|
||||
const std::string cmd = "python " + addonInfo.scriptFile + " --cli" + addonInfo.args + " " + dumpFile;
|
||||
|
||||
#ifdef _WIN32
|
||||
std::unique_ptr<FILE, decltype(&_pclose)> pipe(_popen(cmd.c_str(), "r"), _pclose);
|
||||
#else
|
||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
|
||||
#endif
|
||||
if (!pipe)
|
||||
return "";
|
||||
char buffer[1024];
|
||||
std::string result;
|
||||
while (fgets(buffer, sizeof(buffer), pipe.get()) != nullptr) {
|
||||
result += buffer;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::vector<std::string> split(const std::string &str, const std::string &sep)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
|
@ -553,12 +575,12 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
|
|||
|
||||
for (const std::string &addon : mSettings.addons) {
|
||||
struct AddonInfo addonInfo;
|
||||
const std::string errmsg = addonInfo.getAddonInfo(addon);
|
||||
const std::string errmsg = addonInfo.getAddonInfo(addon, mSettings.exename);
|
||||
if (!errmsg.empty()) {
|
||||
reportOut(errmsg);
|
||||
continue;
|
||||
}
|
||||
const std::string &results = executeAddon(addonInfo.script, addonInfo.args, dumpFile);
|
||||
const std::string &results = executeAddon(addonInfo, dumpFile);
|
||||
for (std::string::size_type pos = 0; pos < results.size();) {
|
||||
const std::string::size_type pos2 = results.find("\n", pos);
|
||||
if (pos2 == std::string::npos)
|
||||
|
@ -597,7 +619,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
|
|||
continue;
|
||||
|
||||
// line must end with [addon-x]
|
||||
const std::string::size_type id1 = line.rfind("[" + addonInfo.script + "-");
|
||||
const std::string::size_type id1 = line.rfind("[" + addonInfo.name + "-");
|
||||
if (id1 == std::string::npos || id1 < sev2)
|
||||
continue;
|
||||
|
||||
|
@ -999,26 +1021,6 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
|
|||
#endif
|
||||
}
|
||||
|
||||
std::string CppCheck::executeAddon(const std::string &addon, const std::string &args, const std::string &dumpFile)
|
||||
{
|
||||
const std::string addonFile = "addons/" + addon + ".py";
|
||||
const std::string cmd = "python " + addonFile + " --cli" + args + " " + dumpFile;
|
||||
|
||||
#ifdef _WIN32
|
||||
std::unique_ptr<FILE, decltype(&_pclose)> pipe(_popen(cmd.c_str(), "r"), _pclose);
|
||||
#else
|
||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
|
||||
#endif
|
||||
if (!pipe)
|
||||
return "";
|
||||
char buffer[1024];
|
||||
std::string result;
|
||||
while (fgets(buffer, sizeof(buffer), pipe.get()) != nullptr) {
|
||||
result += buffer;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Settings &CppCheck::settings()
|
||||
{
|
||||
return mSettings;
|
||||
|
|
|
@ -179,12 +179,6 @@ private:
|
|||
*/
|
||||
void executeRules(const std::string &tokenlist, const Tokenizer &tokenizer);
|
||||
|
||||
/**
|
||||
* @brief Execute a given addon
|
||||
* @return results in std::string
|
||||
*/
|
||||
std::string executeAddon(const std::string &addon, const std::string &args, const std::string &dumpFile);
|
||||
|
||||
/**
|
||||
* @brief Errors and warnings are directed here.
|
||||
*
|
||||
|
|
|
@ -121,6 +121,9 @@ public:
|
|||
/** @brief Is --exception-handling given */
|
||||
bool exceptionHandling;
|
||||
|
||||
// argv[0]
|
||||
std::string exename;
|
||||
|
||||
/** @brief If errors are found, this value is returned from main().
|
||||
Default value is 0. */
|
||||
int exitCode;
|
||||
|
|
|
@ -37,6 +37,32 @@ def test_absolute_path():
|
|||
assert stdout == 'Checking %s/main.c ...\n' % (prjpath)
|
||||
assert stderr == '[%s/main.c:5]: (error) Division by zero.\n' % (prjpath)
|
||||
|
||||
def test_addon_local_path():
|
||||
cwd = os.getcwd()
|
||||
os.chdir('1-helloworld')
|
||||
ret, stdout, stderr = cppcheck('--addon=misra .')
|
||||
os.chdir(cwd)
|
||||
assert ret == 0
|
||||
assert stdout == 'Checking main.c ...\n'
|
||||
assert stderr == ('[main.c:5]: (error) Division by zero.\n'
|
||||
'[main.c:1]: (style) misra violation (use --rule-texts=<file> to get proper output)\n')
|
||||
|
||||
def test_addon_absolute_path():
|
||||
prjpath = '%s/1-helloworld' % (os.getcwd())
|
||||
ret, stdout, stderr = cppcheck('--addon=misra %s' % (prjpath))
|
||||
assert ret == 0
|
||||
assert stdout == 'Checking %s/main.c ...\n' % (prjpath)
|
||||
assert stderr == ('[%s/main.c:5]: (error) Division by zero.\n'
|
||||
'[%s/main.c:1]: (style) misra violation (use --rule-texts=<file> to get proper output)\n' % (prjpath, prjpath))
|
||||
|
||||
def test_addon_relative_path():
|
||||
prjpath = '1-helloworld'
|
||||
ret, stdout, stderr = cppcheck('--addon=misra %s' % (prjpath))
|
||||
assert ret == 0
|
||||
assert stdout == 'Checking %s/main.c ...\n' % (prjpath)
|
||||
assert stderr == ('[%s/main.c:5]: (error) Division by zero.\n'
|
||||
'[%s/main.c:1]: (style) misra violation (use --rule-texts=<file> to get proper output)\n' % (prjpath, prjpath))
|
||||
|
||||
def test_basepath_relative_path():
|
||||
prjpath = '1-helloworld'
|
||||
ret, stdout, stderr = cppcheck('%s -rp=%s' % (prjpath, prjpath))
|
||||
|
|
Loading…
Reference in New Issue