Add --plist-output argument
This commit is contained in:
parent
3ef2f825c7
commit
6967d68137
|
@ -268,6 +268,15 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
|||
}
|
||||
}
|
||||
|
||||
// Write results in results.plist
|
||||
else if (std::strncmp(argv[i], "--plist-output=", 15) == 0) {
|
||||
_settings->plistOutput = Path::simplifyPath(Path::fromNativeSeparators(argv[i] + 15));
|
||||
if (_settings->plistOutput.empty())
|
||||
_settings->plistOutput = "./";
|
||||
else if (!endsWith(_settings->plistOutput,'/'))
|
||||
_settings->plistOutput += '/';
|
||||
}
|
||||
|
||||
// Write results in results.xml
|
||||
else if (std::strcmp(argv[i], "--xml") == 0)
|
||||
_settings->xml = true;
|
||||
|
@ -937,6 +946,8 @@ void CmdLineParser::PrintHelp()
|
|||
" further assumptions.\n"
|
||||
" * unspecified\n"
|
||||
" Unknown type sizes\n"
|
||||
" --plist-output=<path>\n"
|
||||
" Generate Clang-plist output files in folder.\n"
|
||||
" -q, --quiet Do not show progress reports.\n"
|
||||
" -rp, --relative-paths\n"
|
||||
" -rp=<paths>, --relative-paths=<paths>\n"
|
||||
|
|
|
@ -123,6 +123,11 @@ unsigned int CppCheck::processFile(const std::string& filename, const std::strin
|
|||
}
|
||||
}
|
||||
|
||||
if (plistFile.is_open()) {
|
||||
plistFile << ErrorLogger::plistFooter();
|
||||
plistFile.close();
|
||||
}
|
||||
|
||||
CheckUnusedFunctions checkUnusedFunctions(0,0,0);
|
||||
|
||||
bool internalErrorFound(false);
|
||||
|
@ -135,6 +140,17 @@ unsigned int CppCheck::processFile(const std::string& filename, const std::strin
|
|||
simplecpp::TokenList tokens1(fileStream, files, filename, &outputList);
|
||||
preprocessor.loadFiles(tokens1, files);
|
||||
|
||||
if (!_settings.plistOutput.empty()) {
|
||||
std::string filename2;
|
||||
if (filename.find("/") != std::string::npos)
|
||||
filename2 = filename.substr(filename.rfind("/") + 1);
|
||||
else
|
||||
filename2 = filename;
|
||||
filename2 = _settings.plistOutput + filename2.substr(0, filename2.find(".")) + ".plist";
|
||||
plistFile.open(filename2);
|
||||
plistFile << ErrorLogger::plistHeader(version(), files);
|
||||
}
|
||||
|
||||
// write dump file xml prolog
|
||||
std::ofstream fdump;
|
||||
if (_settings.dump) {
|
||||
|
@ -428,7 +444,6 @@ void CppCheck::internalError(const std::string &filename, const std::string &msg
|
|||
false);
|
||||
|
||||
_errorLogger.reportErr(errmsg);
|
||||
|
||||
} else {
|
||||
// Report on stdout
|
||||
_errorLogger.reportOut(fullmsg);
|
||||
|
@ -692,6 +707,9 @@ void CppCheck::reportErr(const ErrorLogger::ErrorMessage &msg)
|
|||
|
||||
_errorLogger.reportErr(msg);
|
||||
analyzerInformation.reportErr(msg, _settings.verbose);
|
||||
if (!_settings.plistOutput.empty() && plistFile.is_open()) {
|
||||
plistFile << ErrorLogger::plistData(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void CppCheck::reportOut(const std::string &outmsg)
|
||||
|
|
|
@ -449,7 +449,7 @@ std::string ErrorLogger::callStackToString(const std::list<ErrorLogger::ErrorMes
|
|||
|
||||
|
||||
ErrorLogger::ErrorMessage::FileLocation::FileLocation(const Token* tok, const TokenList* list)
|
||||
: line(tok->linenr()), _file(list->file(tok))
|
||||
: line(tok->linenr()), fileNumber(tok->fileIndex()), _file(list->file(tok))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -509,3 +509,106 @@ std::string ErrorLogger::toxml(const std::string &str)
|
|||
}
|
||||
return xml.str();
|
||||
}
|
||||
|
||||
std::string ErrorLogger::plistHeader(const std::string &version, const std::vector<std::string> &files)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
|
||||
<< "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\r\n"
|
||||
<< "<plist version=\"1.0\">\r\n"
|
||||
<< "<dict>\r\n"
|
||||
<< " <key>clang_version</key>\r\n"
|
||||
<< "<string>cppcheck version " << version << "</string>\r\n"
|
||||
<< " <key>files</key>\r\n"
|
||||
<< " <array>\r\n";
|
||||
for (unsigned int i = 0; i < files.size(); ++i)
|
||||
ostr << " <string>" << ErrorLogger::toxml(files[i]) << "</string>\r\n";
|
||||
ostr << " </array>\r\n"
|
||||
<< " <key>diagnostics</key>\r\n"
|
||||
<< " <array>\r\n";
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
static std::string plistLoc(const char indent[], const ErrorLogger::ErrorMessage::FileLocation &loc)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << indent << "<dict>\r\n"
|
||||
<< indent << ' ' << "<key>line</key><integer>" << loc.line << "</integer>\r\n"
|
||||
<< indent << ' ' << "<key>col</key><integer>1</integer>\r\n"
|
||||
<< indent << ' ' << "<key>file</key><integer>" << loc.fileNumber << "</integer>\r\n"
|
||||
<< indent << "</dict>\r\n";
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
std::string ErrorLogger::plistData(const ErrorLogger::ErrorMessage &msg)
|
||||
{
|
||||
std::ostringstream plist;
|
||||
plist << " <dict>\r\n"
|
||||
<< " <key>path</key>\r\n"
|
||||
<< " <array>\r\n";
|
||||
|
||||
std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator prev = msg._callStack.begin();
|
||||
|
||||
for (std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator it = msg._callStack.begin(); it != msg._callStack.end(); ++it) {
|
||||
if (prev != it) {
|
||||
plist << " <dict>\r\n"
|
||||
<< " <key>kind</key><string>control</string>\r\n"
|
||||
<< " <key>edges</key>\r\n"
|
||||
<< " <array>\r\n"
|
||||
<< " <dict>\r\n"
|
||||
<< " <key>start</key>\r\n"
|
||||
<< " <array>\r\n"
|
||||
<< plistLoc(" ", *prev)
|
||||
<< plistLoc(" ", *prev)
|
||||
<< " </array>\r\n"
|
||||
<< " <key>end</key>\r\n"
|
||||
<< " <array>\r\n"
|
||||
<< plistLoc(" ", *it)
|
||||
<< plistLoc(" ", *it)
|
||||
<< " </array>\r\n"
|
||||
<< " </dict>\r\n"
|
||||
<< " </array>\r\n"
|
||||
<< " </dict>\r\n";
|
||||
prev = it;
|
||||
}
|
||||
|
||||
std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator next = it;
|
||||
++next;
|
||||
const std::string shortMessage = (next == msg._callStack.end() ? msg.shortMessage() : std::string());
|
||||
const std::string verboseMessage = (next == msg._callStack.end() ? msg.verboseMessage() : std::string());
|
||||
|
||||
plist << " <dict>\r\n"
|
||||
<< " <key>kind</key><string>event</string>\r\n"
|
||||
<< " <key>location</key>\r\n"
|
||||
<< plistLoc(" ", *it)
|
||||
<< " <key>ranges</key>\r\n"
|
||||
<< " <array>\r\n"
|
||||
<< " <array>\r\n"
|
||||
<< plistLoc(" ", *it)
|
||||
<< plistLoc(" ", *it)
|
||||
<< " </array>\r\n"
|
||||
<< " </array>\r\n"
|
||||
<< " <key>depth</key><integer>0</integer>\r\n"
|
||||
<< " <key>extended_message</key>\r\n"
|
||||
<< " <string>" << ErrorLogger::toxml(verboseMessage) << "</string>\r\n"
|
||||
<< " <key>message</key>\r"
|
||||
<< " <string>" << ErrorLogger::toxml(shortMessage) << "</string>\r\n"
|
||||
<< " </dict>\r\n";
|
||||
}
|
||||
|
||||
plist << " </array>\r\n"
|
||||
<< " <key>description</key><string>" << ErrorLogger::toxml(msg.shortMessage()) << "</string>\r\n"
|
||||
<< " <key>category</key><string>" << Severity::toString(msg._severity) << "</string>\r\n"
|
||||
<< " <key>type</key><string>" << ErrorLogger::toxml(msg.shortMessage()) << "</string>\r\n"
|
||||
<< " <key>check_name</key><string>" << msg._id << "</string>\r\n"
|
||||
<< " <!-- This hash is experimental and going to change! -->\r\n"
|
||||
<< " <key>issue_hash_content_of_line_in_context</key><string>" << 0 << "</string>\r\n"
|
||||
<< " <key>issue_context_kind</key><string></string>\r\n"
|
||||
<< " <key>issue_context</key><string></string>\r\n"
|
||||
<< " <key>issue_hash_function_offset</key><string></string>\r\n"
|
||||
<< " <key>location</key>\r\n"
|
||||
<< plistLoc(" ", msg._callStack.back())
|
||||
<< " </dict>\r\n";
|
||||
return plist.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@
|
|||
#include "config.h"
|
||||
#include "suppressions.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* CWE id (Common Weakness Enumeration)
|
||||
|
@ -163,6 +165,8 @@ public:
|
|||
* should implement.
|
||||
*/
|
||||
class CPPCHECKLIB ErrorLogger {
|
||||
protected:
|
||||
std::ofstream plistFile;
|
||||
public:
|
||||
|
||||
/**
|
||||
|
@ -178,11 +182,11 @@ public:
|
|||
class CPPCHECKLIB FileLocation {
|
||||
public:
|
||||
FileLocation()
|
||||
: line(0) {
|
||||
: line(0), fileNumber(0) {
|
||||
}
|
||||
|
||||
FileLocation(const std::string &file, unsigned int aline)
|
||||
: line(aline), _file(file) {
|
||||
: line(aline), fileNumber(0), _file(file) {
|
||||
}
|
||||
|
||||
FileLocation(const Token* tok, const TokenList* list);
|
||||
|
@ -206,6 +210,7 @@ public:
|
|||
std::string stringify() const;
|
||||
|
||||
unsigned int line;
|
||||
unsigned int fileNumber;
|
||||
|
||||
private:
|
||||
std::string _file;
|
||||
|
@ -283,7 +288,12 @@ public:
|
|||
};
|
||||
|
||||
ErrorLogger() { }
|
||||
virtual ~ErrorLogger() { }
|
||||
virtual ~ErrorLogger() {
|
||||
if (plistFile.is_open()) {
|
||||
plistFile << ErrorLogger::plistFooter();
|
||||
plistFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about progress is directed here.
|
||||
|
@ -335,6 +345,14 @@ public:
|
|||
* @return The output string containing XML entities
|
||||
*/
|
||||
static std::string toxml(const std::string &str);
|
||||
|
||||
static std::string plistHeader(const std::string &version, const std::vector<std::string> &files);
|
||||
static std::string plistData(const ErrorLogger::ErrorMessage &msg);
|
||||
static const char *plistFooter() {
|
||||
return " </array>\r\n"
|
||||
"</dict>\r\n"
|
||||
"</plist>";
|
||||
}
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -131,10 +131,13 @@ public:
|
|||
/** @brief Paths used as base for conversion to relative paths. */
|
||||
std::vector<std::string> basePaths;
|
||||
|
||||
/** @brief write XML results (--plist-output=<dir>) */
|
||||
std::string plistOutput;
|
||||
|
||||
/** @brief write XML results (--xml) */
|
||||
bool xml;
|
||||
|
||||
/** @brief XML version (--xmlver=..) */
|
||||
/** @brief XML version (--xml-version=..) */
|
||||
int xml_version;
|
||||
|
||||
/** @brief How many processes/threads should do checking at the same
|
||||
|
|
Loading…
Reference in New Issue