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 def = false;
|
||||||
bool maxconfigs = false;
|
bool maxconfigs = false;
|
||||||
|
|
||||||
|
mSettings->exename = argv[0];
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (argv[i][0] == '-') {
|
if (argv[i][0] == '-') {
|
||||||
if (std::strcmp(argv[i], "--version") == 0) {
|
if (std::strcmp(argv[i], "--version") == 0) {
|
||||||
|
|
|
@ -59,12 +59,14 @@ static const CWE CWE398(398U); // Indicator of Poor Code Quality
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct AddonInfo {
|
struct AddonInfo {
|
||||||
std::string script;
|
std::string name;
|
||||||
|
std::string scriptFile;
|
||||||
std::string args;
|
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)) {
|
if (!endsWith(fileName, ".json", 5)) {
|
||||||
script = fileName;
|
name = fileName;
|
||||||
|
scriptFile = Path::getPathFromFilename(exename) + "/addons/" + fileName + ".py";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
std::ifstream fin(fileName);
|
std::ifstream fin(fileName);
|
||||||
|
@ -81,12 +83,32 @@ namespace {
|
||||||
for (const picojson::value &v : obj["args"].get<picojson::array>())
|
for (const picojson::value &v : obj["args"].get<picojson::array>())
|
||||||
args += " " + v.get<std::string>();
|
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 "";
|
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)
|
static std::vector<std::string> split(const std::string &str, const std::string &sep)
|
||||||
{
|
{
|
||||||
std::vector<std::string> ret;
|
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) {
|
for (const std::string &addon : mSettings.addons) {
|
||||||
struct AddonInfo addonInfo;
|
struct AddonInfo addonInfo;
|
||||||
const std::string errmsg = addonInfo.getAddonInfo(addon);
|
const std::string errmsg = addonInfo.getAddonInfo(addon, mSettings.exename);
|
||||||
if (!errmsg.empty()) {
|
if (!errmsg.empty()) {
|
||||||
reportOut(errmsg);
|
reportOut(errmsg);
|
||||||
continue;
|
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();) {
|
for (std::string::size_type pos = 0; pos < results.size();) {
|
||||||
const std::string::size_type pos2 = results.find("\n", pos);
|
const std::string::size_type pos2 = results.find("\n", pos);
|
||||||
if (pos2 == std::string::npos)
|
if (pos2 == std::string::npos)
|
||||||
|
@ -597,7 +619,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// line must end with [addon-x]
|
// 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)
|
if (id1 == std::string::npos || id1 < sev2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -999,26 +1021,6 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
|
||||||
#endif
|
#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()
|
Settings &CppCheck::settings()
|
||||||
{
|
{
|
||||||
return mSettings;
|
return mSettings;
|
||||||
|
|
|
@ -179,12 +179,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void executeRules(const std::string &tokenlist, const Tokenizer &tokenizer);
|
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.
|
* @brief Errors and warnings are directed here.
|
||||||
*
|
*
|
||||||
|
|
|
@ -121,6 +121,9 @@ public:
|
||||||
/** @brief Is --exception-handling given */
|
/** @brief Is --exception-handling given */
|
||||||
bool exceptionHandling;
|
bool exceptionHandling;
|
||||||
|
|
||||||
|
// argv[0]
|
||||||
|
std::string exename;
|
||||||
|
|
||||||
/** @brief If errors are found, this value is returned from main().
|
/** @brief If errors are found, this value is returned from main().
|
||||||
Default value is 0. */
|
Default value is 0. */
|
||||||
int exitCode;
|
int exitCode;
|
||||||
|
|
|
@ -37,6 +37,32 @@ def test_absolute_path():
|
||||||
assert stdout == 'Checking %s/main.c ...\n' % (prjpath)
|
assert stdout == 'Checking %s/main.c ...\n' % (prjpath)
|
||||||
assert stderr == '[%s/main.c:5]: (error) Division by zero.\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():
|
def test_basepath_relative_path():
|
||||||
prjpath = '1-helloworld'
|
prjpath = '1-helloworld'
|
||||||
ret, stdout, stderr = cppcheck('%s -rp=%s' % (prjpath, prjpath))
|
ret, stdout, stderr = cppcheck('%s -rp=%s' % (prjpath, prjpath))
|
||||||
|
|
Loading…
Reference in New Issue