changed the astyle formatting flags
This commit is contained in:
parent
b792efb761
commit
6f8e42a5af
|
@ -47,22 +47,16 @@ static void AddFilesToList(const std::string& FileList, std::vector<std::string>
|
||||||
// drawback : creates a dependency
|
// drawback : creates a dependency
|
||||||
std::istream *Files;
|
std::istream *Files;
|
||||||
std::ifstream Infile;
|
std::ifstream Infile;
|
||||||
if (FileList.compare("-") == 0) // read from stdin
|
if (FileList.compare("-") == 0) { // read from stdin
|
||||||
{
|
|
||||||
Files = &std::cin;
|
Files = &std::cin;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Infile.open(FileList.c_str());
|
Infile.open(FileList.c_str());
|
||||||
Files = &Infile;
|
Files = &Infile;
|
||||||
}
|
}
|
||||||
if (Files)
|
if (Files) {
|
||||||
{
|
|
||||||
std::string FileName;
|
std::string FileName;
|
||||||
while (std::getline(*Files, FileName)) // next line
|
while (std::getline(*Files, FileName)) { // next line
|
||||||
{
|
if (!FileName.empty()) {
|
||||||
if (!FileName.empty())
|
|
||||||
{
|
|
||||||
PathNames.push_back(FileName);
|
PathNames.push_back(FileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,10 +79,8 @@ void CmdLineParser::PrintMessage(const std::string &message)
|
||||||
|
|
||||||
bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
{
|
{
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++) {
|
||||||
{
|
if (strcmp(argv[i], "--version") == 0) {
|
||||||
if (strcmp(argv[i], "--version") == 0)
|
|
||||||
{
|
|
||||||
_showVersion = true;
|
_showVersion = true;
|
||||||
_exitAfterPrint = true;
|
_exitAfterPrint = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -107,8 +99,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
_settings->debugFalsePositive = true;
|
_settings->debugFalsePositive = true;
|
||||||
|
|
||||||
// Enable all checks - will be removed in future
|
// Enable all checks - will be removed in future
|
||||||
else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--all") == 0)
|
else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--all") == 0) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: -a/--all option is deprecated and will be removed in 1.55 release.");
|
PrintMessage("cppcheck: -a/--all option is deprecated and will be removed in 1.55 release.");
|
||||||
PrintMessage("cppcheck: please use --enable=all instead.");
|
PrintMessage("cppcheck: please use --enable=all instead.");
|
||||||
}
|
}
|
||||||
|
@ -118,66 +109,56 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
_settings->inconclusive = true;
|
_settings->inconclusive = true;
|
||||||
|
|
||||||
// Checking coding style - will be removed in the future
|
// Checking coding style - will be removed in the future
|
||||||
else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--style") == 0)
|
else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--style") == 0) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: -s/--style option is deprecated and will be removed in 1.55 release.");
|
PrintMessage("cppcheck: -s/--style option is deprecated and will be removed in 1.55 release.");
|
||||||
PrintMessage("cppcheck: please use --enable=style instead.");
|
PrintMessage("cppcheck: please use --enable=style instead.");
|
||||||
|
|
||||||
const std::string errmsg = _settings->addEnabled("style");
|
const std::string errmsg = _settings->addEnabled("style");
|
||||||
if (!errmsg.empty())
|
if (!errmsg.empty()) {
|
||||||
{
|
|
||||||
PrintMessage(errmsg);
|
PrintMessage(errmsg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter errors
|
// Filter errors
|
||||||
else if (strncmp(argv[i], "--exitcode-suppressions", 23) == 0)
|
else if (strncmp(argv[i], "--exitcode-suppressions", 23) == 0) {
|
||||||
{
|
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
|
||||||
// exitcode-suppressions filename.txt
|
// exitcode-suppressions filename.txt
|
||||||
// Deprecated
|
// Deprecated
|
||||||
if (strcmp(argv[i], "--exitcode-suppressions") == 0)
|
if (strcmp(argv[i], "--exitcode-suppressions") == 0) {
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (i >= argc || strncmp(argv[i], "-", 1) == 0 ||
|
if (i >= argc || strncmp(argv[i], "-", 1) == 0 ||
|
||||||
strncmp(argv[i], "--", 2) == 0)
|
strncmp(argv[i], "--", 2) == 0) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: No filename specified for the --exitcode-suppressions option");
|
PrintMessage("cppcheck: No filename specified for the --exitcode-suppressions option");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
filename = argv[i];
|
filename = argv[i];
|
||||||
}
|
}
|
||||||
// exitcode-suppressions=filename.txt
|
// exitcode-suppressions=filename.txt
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
filename = 24 + argv[i];
|
filename = 24 + argv[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream f(filename.c_str());
|
std::ifstream f(filename.c_str());
|
||||||
if (!f.is_open())
|
if (!f.is_open()) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: Couldn't open the file \"" + std::string(filename) + "\"");
|
PrintMessage("cppcheck: Couldn't open the file \"" + std::string(filename) + "\"");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const std::string errmsg(_settings->nofail.parseFile(f));
|
const std::string errmsg(_settings->nofail.parseFile(f));
|
||||||
if (!errmsg.empty())
|
if (!errmsg.empty()) {
|
||||||
{
|
|
||||||
PrintMessage(errmsg);
|
PrintMessage(errmsg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter errors
|
// Filter errors
|
||||||
else if (strncmp(argv[i], "--suppressions-list=", 20) == 0)
|
else if (strncmp(argv[i], "--suppressions-list=", 20) == 0) {
|
||||||
{
|
|
||||||
std::string filename = argv[i];
|
std::string filename = argv[i];
|
||||||
filename = filename.substr(20);
|
filename = filename.substr(20);
|
||||||
std::ifstream f(filename.c_str());
|
std::ifstream f(filename.c_str());
|
||||||
if (!f.is_open())
|
if (!f.is_open()) {
|
||||||
{
|
|
||||||
std::string message("cppcheck: Couldn't open the file \"");
|
std::string message("cppcheck: Couldn't open the file \"");
|
||||||
message += std::string(filename);
|
message += std::string(filename);
|
||||||
message += "\"";
|
message += "\"";
|
||||||
|
@ -185,8 +166,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const std::string errmsg(_settings->nomsg.parseFile(f));
|
const std::string errmsg(_settings->nomsg.parseFile(f));
|
||||||
if (!errmsg.empty())
|
if (!errmsg.empty()) {
|
||||||
{
|
|
||||||
PrintMessage(errmsg);
|
PrintMessage(errmsg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -195,19 +175,16 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
// Filter errors
|
// Filter errors
|
||||||
// This is deprecated, see --supressions-list above
|
// This is deprecated, see --supressions-list above
|
||||||
else if (strcmp(argv[i], "--suppressions") == 0 &&
|
else if (strcmp(argv[i], "--suppressions") == 0 &&
|
||||||
strlen(argv[i]) == 14)
|
strlen(argv[i]) == 14) {
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (i >= argc)
|
if (i >= argc) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: No file specified for the --suppressions option");
|
PrintMessage("cppcheck: No file specified for the --suppressions option");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream f(argv[i]);
|
std::ifstream f(argv[i]);
|
||||||
if (!f.is_open())
|
if (!f.is_open()) {
|
||||||
{
|
|
||||||
std::string message("cppcheck: Couldn't open the file \"");
|
std::string message("cppcheck: Couldn't open the file \"");
|
||||||
message += std::string(argv[i]);
|
message += std::string(argv[i]);
|
||||||
message += "\"";
|
message += "\"";
|
||||||
|
@ -215,20 +192,17 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const std::string errmsg(_settings->nomsg.parseFile(f));
|
const std::string errmsg(_settings->nomsg.parseFile(f));
|
||||||
if (!errmsg.empty())
|
if (!errmsg.empty()) {
|
||||||
{
|
|
||||||
PrintMessage(errmsg);
|
PrintMessage(errmsg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strncmp(argv[i], "--suppress=", 11) == 0)
|
else if (strncmp(argv[i], "--suppress=", 11) == 0) {
|
||||||
{
|
|
||||||
std::string suppression = argv[i];
|
std::string suppression = argv[i];
|
||||||
suppression = suppression.substr(11);
|
suppression = suppression.substr(11);
|
||||||
const std::string errmsg(_settings->nomsg.addSuppressionLine(suppression));
|
const std::string errmsg(_settings->nomsg.addSuppressionLine(suppression));
|
||||||
if (!errmsg.empty())
|
if (!errmsg.empty()) {
|
||||||
{
|
|
||||||
PrintMessage(errmsg);
|
PrintMessage(errmsg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -251,20 +225,17 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
_settings->_xml = true;
|
_settings->_xml = true;
|
||||||
|
|
||||||
// Define the XML file version (and enable XML output)
|
// Define the XML file version (and enable XML output)
|
||||||
else if (strncmp(argv[i], "--xml-version=", 14) == 0)
|
else if (strncmp(argv[i], "--xml-version=", 14) == 0) {
|
||||||
{
|
|
||||||
std::string numberString(argv[i]);
|
std::string numberString(argv[i]);
|
||||||
numberString = numberString.substr(14);
|
numberString = numberString.substr(14);
|
||||||
|
|
||||||
std::istringstream iss(numberString);
|
std::istringstream iss(numberString);
|
||||||
if (!(iss >> _settings->_xml_version))
|
if (!(iss >> _settings->_xml_version)) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: argument to '--xml-version' is not a number");
|
PrintMessage("cppcheck: argument to '--xml-version' is not a number");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_settings->_xml_version < 0 || _settings->_xml_version > 2)
|
if (_settings->_xml_version < 0 || _settings->_xml_version > 2) {
|
||||||
{
|
|
||||||
// We only have xml versions 1 and 2
|
// We only have xml versions 1 and 2
|
||||||
PrintMessage("cppcheck: --xml-version can only be 1 or 2.");
|
PrintMessage("cppcheck: --xml-version can only be 1 or 2.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -282,30 +253,25 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
else if (strncmp(argv[i], "--append=", 9) == 0)
|
else if (strncmp(argv[i], "--append=", 9) == 0)
|
||||||
_settings->append(9 + argv[i]);
|
_settings->append(9 + argv[i]);
|
||||||
|
|
||||||
else if (strncmp(argv[i], "--enable=", 9) == 0)
|
else if (strncmp(argv[i], "--enable=", 9) == 0) {
|
||||||
{
|
|
||||||
const std::string errmsg = _settings->addEnabled(argv[i] + 9);
|
const std::string errmsg = _settings->addEnabled(argv[i] + 9);
|
||||||
if (!errmsg.empty())
|
if (!errmsg.empty()) {
|
||||||
{
|
|
||||||
PrintMessage(errmsg);
|
PrintMessage(errmsg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// when "style" is enabled, also enable "performance" and "portability"
|
// when "style" is enabled, also enable "performance" and "portability"
|
||||||
else if (strstr(argv[i]+9, "style"))
|
else if (strstr(argv[i]+9, "style")) {
|
||||||
{
|
|
||||||
_settings->addEnabled("performance");
|
_settings->addEnabled("performance");
|
||||||
_settings->addEnabled("portability");
|
_settings->addEnabled("portability");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --error-exitcode=1
|
// --error-exitcode=1
|
||||||
else if (strncmp(argv[i], "--error-exitcode=", 17) == 0)
|
else if (strncmp(argv[i], "--error-exitcode=", 17) == 0) {
|
||||||
{
|
|
||||||
std::string temp = argv[i];
|
std::string temp = argv[i];
|
||||||
temp = temp.substr(17);
|
temp = temp.substr(17);
|
||||||
std::istringstream iss(temp);
|
std::istringstream iss(temp);
|
||||||
if (!(iss >> _settings->_exitCode))
|
if (!(iss >> _settings->_exitCode)) {
|
||||||
{
|
|
||||||
_settings->_exitCode = 0;
|
_settings->_exitCode = 0;
|
||||||
PrintMessage("cppcheck: Argument must be an integer. Try something like '--error-exitcode=1'");
|
PrintMessage("cppcheck: Argument must be an integer. Try something like '--error-exitcode=1'");
|
||||||
return false;
|
return false;
|
||||||
|
@ -313,17 +279,14 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// User define
|
// User define
|
||||||
else if (strncmp(argv[i], "-D", 2) == 0)
|
else if (strncmp(argv[i], "-D", 2) == 0) {
|
||||||
{
|
|
||||||
std::string define;
|
std::string define;
|
||||||
|
|
||||||
// "-D define"
|
// "-D define"
|
||||||
if (strcmp(argv[i], "-D") == 0)
|
if (strcmp(argv[i], "-D") == 0) {
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
if (i >= argc || strncmp(argv[i], "-", 1) == 0 ||
|
if (i >= argc || strncmp(argv[i], "-", 1) == 0 ||
|
||||||
strncmp(argv[i], "--", 2) == 0)
|
strncmp(argv[i], "--", 2) == 0) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: argument to '-D' is missing");
|
PrintMessage("cppcheck: argument to '-D' is missing");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -331,8 +294,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
define = argv[i];
|
define = argv[i];
|
||||||
}
|
}
|
||||||
// "-Ddefine"
|
// "-Ddefine"
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
define = 2 + argv[i];
|
define = 2 + argv[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,16 +304,13 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include paths
|
// Include paths
|
||||||
else if (strncmp(argv[i], "-I", 2) == 0)
|
else if (strncmp(argv[i], "-I", 2) == 0) {
|
||||||
{
|
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
// "-I path/"
|
// "-I path/"
|
||||||
if (strcmp(argv[i], "-I") == 0)
|
if (strcmp(argv[i], "-I") == 0) {
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
if (i >= argc)
|
if (i >= argc) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: argument to '-I' is missing");
|
PrintMessage("cppcheck: argument to '-I' is missing");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -359,8 +318,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// "-Ipath/"
|
// "-Ipath/"
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
path = 2 + argv[i];
|
path = 2 + argv[i];
|
||||||
}
|
}
|
||||||
path = Path::fromNativeSeparators(path);
|
path = Path::fromNativeSeparators(path);
|
||||||
|
@ -374,23 +332,19 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// file list specified
|
// file list specified
|
||||||
else if (strncmp(argv[i], "--file-list=", 12) == 0)
|
else if (strncmp(argv[i], "--file-list=", 12) == 0) {
|
||||||
{
|
|
||||||
// open this file and read every input file (1 file name per line)
|
// open this file and read every input file (1 file name per line)
|
||||||
AddFilesToList(12 + argv[i], _pathnames);
|
AddFilesToList(12 + argv[i], _pathnames);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignored paths
|
// Ignored paths
|
||||||
else if (strncmp(argv[i], "-i", 2) == 0)
|
else if (strncmp(argv[i], "-i", 2) == 0) {
|
||||||
{
|
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
// "-i path/"
|
// "-i path/"
|
||||||
if (strcmp(argv[i], "-i") == 0)
|
if (strcmp(argv[i], "-i") == 0) {
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
if (i >= argc)
|
if (i >= argc) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: argument to '-i' is missing");
|
PrintMessage("cppcheck: argument to '-i' is missing");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -398,19 +352,16 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// "-ipath/"
|
// "-ipath/"
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
path = 2 + argv[i];
|
path = 2 + argv[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path.empty())
|
if (!path.empty()) {
|
||||||
{
|
|
||||||
path = Path::fromNativeSeparators(path);
|
path = Path::fromNativeSeparators(path);
|
||||||
path = Path::simplifyPath(path.c_str());
|
path = Path::simplifyPath(path.c_str());
|
||||||
path = Path::removeQuotationMarks(path);
|
path = Path::removeQuotationMarks(path);
|
||||||
|
|
||||||
if (!FileLister::fileExists(path) && FileLister::isDirectory(path))
|
if (!FileLister::fileExists(path) && FileLister::isDirectory(path)) {
|
||||||
{
|
|
||||||
// If directory name doesn't end with / or \, add it
|
// If directory name doesn't end with / or \, add it
|
||||||
if (path[path.length()-1] != '/')
|
if (path[path.length()-1] != '/')
|
||||||
path += '/';
|
path += '/';
|
||||||
|
@ -420,30 +371,25 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report progress
|
// Report progress
|
||||||
else if (strcmp(argv[i], "--report-progress") == 0)
|
else if (strcmp(argv[i], "--report-progress") == 0) {
|
||||||
{
|
|
||||||
_settings->reportProgress = true;
|
_settings->reportProgress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --std
|
// --std
|
||||||
else if (strcmp(argv[i], "--std=posix") == 0)
|
else if (strcmp(argv[i], "--std=posix") == 0) {
|
||||||
{
|
|
||||||
_settings->posix = true;
|
_settings->posix = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --C99
|
// --C99
|
||||||
else if (strcmp(argv[i], "--std=c99") == 0)
|
else if (strcmp(argv[i], "--std=c99") == 0) {
|
||||||
{
|
|
||||||
_settings->c99 = true;
|
_settings->c99 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output formatter
|
// Output formatter
|
||||||
else if (strcmp(argv[i], "--template") == 0)
|
else if (strcmp(argv[i], "--template") == 0) {
|
||||||
{
|
|
||||||
// "--template path/"
|
// "--template path/"
|
||||||
++i;
|
++i;
|
||||||
if (i >= argc)
|
if (i >= argc) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: argument to '--template' is missing");
|
PrintMessage("cppcheck: argument to '--template' is missing");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -457,16 +403,13 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
|
|
||||||
// Checking threads
|
// Checking threads
|
||||||
else if (strcmp(argv[i], "-j") == 0 ||
|
else if (strcmp(argv[i], "-j") == 0 ||
|
||||||
strncmp(argv[i], "-j", 2) == 0)
|
strncmp(argv[i], "-j", 2) == 0) {
|
||||||
{
|
|
||||||
std::string numberString;
|
std::string numberString;
|
||||||
|
|
||||||
// "-j 3"
|
// "-j 3"
|
||||||
if (strcmp(argv[i], "-j") == 0)
|
if (strcmp(argv[i], "-j") == 0) {
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
if (i >= argc)
|
if (i >= argc) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: argument to '-j' is missing");
|
PrintMessage("cppcheck: argument to '-j' is missing");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -475,21 +418,18 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// "-j3"
|
// "-j3"
|
||||||
else if (strncmp(argv[i], "-j", 2) == 0)
|
else if (strncmp(argv[i], "-j", 2) == 0) {
|
||||||
{
|
|
||||||
numberString = argv[i];
|
numberString = argv[i];
|
||||||
numberString = numberString.substr(2);
|
numberString = numberString.substr(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istringstream iss(numberString);
|
std::istringstream iss(numberString);
|
||||||
if (!(iss >> _settings->_jobs))
|
if (!(iss >> _settings->_jobs)) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: argument to '-j' is not a number");
|
PrintMessage("cppcheck: argument to '-j' is not a number");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_settings->_jobs > 10000)
|
if (_settings->_jobs > 10000) {
|
||||||
{
|
|
||||||
// This limit is here just to catch typos. If someone has
|
// This limit is here just to catch typos. If someone has
|
||||||
// need for more jobs, this value should be increased.
|
// need for more jobs, this value should be increased.
|
||||||
PrintMessage("cppcheck: argument for '-j' is allowed to be 10000 at max");
|
PrintMessage("cppcheck: argument for '-j' is allowed to be 10000 at max");
|
||||||
|
@ -498,27 +438,23 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// deprecated: auto deallocated classes..
|
// deprecated: auto deallocated classes..
|
||||||
else if (strcmp(argv[i], "--auto-dealloc") == 0)
|
else if (strcmp(argv[i], "--auto-dealloc") == 0) {
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
PrintMessage("cppcheck: --auto-dealloc option is deprecated and will be removed in 1.55 release.");
|
PrintMessage("cppcheck: --auto-dealloc option is deprecated and will be removed in 1.55 release.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// print all possible error messages..
|
// print all possible error messages..
|
||||||
else if (strcmp(argv[i], "--errorlist") == 0)
|
else if (strcmp(argv[i], "--errorlist") == 0) {
|
||||||
{
|
|
||||||
_showErrorMessages = true;
|
_showErrorMessages = true;
|
||||||
_settings->_xml = true;
|
_settings->_xml = true;
|
||||||
_exitAfterPrint = true;
|
_exitAfterPrint = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation..
|
// documentation..
|
||||||
else if (strcmp(argv[i], "--doc") == 0)
|
else if (strcmp(argv[i], "--doc") == 0) {
|
||||||
{
|
|
||||||
std::ostringstream doc;
|
std::ostringstream doc;
|
||||||
// Get documentation..
|
// Get documentation..
|
||||||
for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it)
|
for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
|
||||||
{
|
|
||||||
doc << "===" << (*it)->name() << "===\n"
|
doc << "===" << (*it)->name() << "===\n"
|
||||||
<< (*it)->classInfo() << "\n\n";
|
<< (*it)->classInfo() << "\n\n";
|
||||||
}
|
}
|
||||||
|
@ -533,14 +469,12 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
|
|
||||||
// --test-2-pass Experimental 2-pass checking of files
|
// --test-2-pass Experimental 2-pass checking of files
|
||||||
// This command line flag will be removed
|
// This command line flag will be removed
|
||||||
else if (strcmp(argv[i], "--test-2-pass") == 0)
|
else if (strcmp(argv[i], "--test-2-pass") == 0) {
|
||||||
{
|
|
||||||
_settings->test_2_pass = true;
|
_settings->test_2_pass = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// show timing information..
|
// show timing information..
|
||||||
else if (strncmp(argv[i], "--showtime=", 11) == 0)
|
else if (strncmp(argv[i], "--showtime=", 11) == 0) {
|
||||||
{
|
|
||||||
const std::string showtimeMode = argv[i] + 11;
|
const std::string showtimeMode = argv[i] + 11;
|
||||||
if (showtimeMode == "file")
|
if (showtimeMode == "file")
|
||||||
_settings->_showtime = SHOWTIME_FILE;
|
_settings->_showtime = SHOWTIME_FILE;
|
||||||
|
@ -554,33 +488,27 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
|
|
||||||
#ifdef HAVE_RULES
|
#ifdef HAVE_RULES
|
||||||
// Rule given at command line
|
// Rule given at command line
|
||||||
else if (strncmp(argv[i], "--rule=", 7) == 0)
|
else if (strncmp(argv[i], "--rule=", 7) == 0) {
|
||||||
{
|
|
||||||
Settings::Rule rule;
|
Settings::Rule rule;
|
||||||
rule.pattern = 7 + argv[i];
|
rule.pattern = 7 + argv[i];
|
||||||
_settings->rules.push_back(rule);
|
_settings->rules.push_back(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rule file
|
// Rule file
|
||||||
else if (strncmp(argv[i], "--rule-file=", 12) == 0)
|
else if (strncmp(argv[i], "--rule-file=", 12) == 0) {
|
||||||
{
|
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
if (doc.LoadFile(12+argv[i]))
|
if (doc.LoadFile(12+argv[i])) {
|
||||||
{
|
|
||||||
TiXmlElement *node = doc.FirstChildElement();
|
TiXmlElement *node = doc.FirstChildElement();
|
||||||
for (; node && node->ValueStr() == "rule"; node = node->NextSiblingElement())
|
for (; node && node->ValueStr() == "rule"; node = node->NextSiblingElement()) {
|
||||||
{
|
|
||||||
Settings::Rule rule;
|
Settings::Rule rule;
|
||||||
|
|
||||||
TiXmlElement *pattern = node->FirstChildElement("pattern");
|
TiXmlElement *pattern = node->FirstChildElement("pattern");
|
||||||
if (pattern)
|
if (pattern) {
|
||||||
{
|
|
||||||
rule.pattern = pattern->GetText();
|
rule.pattern = pattern->GetText();
|
||||||
}
|
}
|
||||||
|
|
||||||
TiXmlElement *message = node->FirstChildElement("message");
|
TiXmlElement *message = node->FirstChildElement("message");
|
||||||
if (message)
|
if (message) {
|
||||||
{
|
|
||||||
TiXmlElement *severity = message->FirstChildElement("severity");
|
TiXmlElement *severity = message->FirstChildElement("severity");
|
||||||
if (severity)
|
if (severity)
|
||||||
rule.severity = severity->GetText();
|
rule.severity = severity->GetText();
|
||||||
|
@ -602,14 +530,12 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check configuration
|
// Check configuration
|
||||||
else if (strcmp(argv[i], "--check-config") == 0)
|
else if (strcmp(argv[i], "--check-config") == 0) {
|
||||||
{
|
|
||||||
_settings->checkConfiguration = true;
|
_settings->checkConfiguration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify platform
|
// Specify platform
|
||||||
else if (strncmp(argv[i], "--platform=", 11) == 0)
|
else if (strncmp(argv[i], "--platform=", 11) == 0) {
|
||||||
{
|
|
||||||
std::string platform(11+argv[i]);
|
std::string platform(11+argv[i]);
|
||||||
|
|
||||||
if (platform == "win32A")
|
if (platform == "win32A")
|
||||||
|
@ -622,8 +548,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
_settings->platform(Settings::Unix32);
|
_settings->platform(Settings::Unix32);
|
||||||
else if (platform == "unix64")
|
else if (platform == "unix64")
|
||||||
_settings->platform(Settings::Unix64);
|
_settings->platform(Settings::Unix64);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
std::string message("cppcheck: error: unrecognized platform\"");
|
std::string message("cppcheck: error: unrecognized platform\"");
|
||||||
message += argv[i];
|
message += argv[i];
|
||||||
message += "\"";
|
message += "\"";
|
||||||
|
@ -633,16 +558,14 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print help
|
// Print help
|
||||||
else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
|
else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
||||||
{
|
|
||||||
_pathnames.clear();
|
_pathnames.clear();
|
||||||
_showHelp = true;
|
_showHelp = true;
|
||||||
_exitAfterPrint = true;
|
_exitAfterPrint = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0)
|
else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0) {
|
||||||
{
|
|
||||||
std::string message("cppcheck: error: unrecognized command line option \"");
|
std::string message("cppcheck: error: unrecognized command line option \"");
|
||||||
message += argv[i];
|
message += argv[i];
|
||||||
message += "\"";
|
message += "\"";
|
||||||
|
@ -650,37 +573,32 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
std::string path = Path::fromNativeSeparators(argv[i]);
|
std::string path = Path::fromNativeSeparators(argv[i]);
|
||||||
path = Path::removeQuotationMarks(path);
|
path = Path::removeQuotationMarks(path);
|
||||||
_pathnames.push_back(path);
|
_pathnames.push_back(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_settings->isEnabled("unusedFunction") && _settings->_jobs > 1)
|
if (_settings->isEnabled("unusedFunction") && _settings->_jobs > 1) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: unusedFunction check can't be used with -j option, so it was disabled.");
|
PrintMessage("cppcheck: unusedFunction check can't be used with -j option, so it was disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Make the _settings.test_2_pass thread safe
|
// FIXME: Make the _settings.test_2_pass thread safe
|
||||||
if (_settings->test_2_pass && _settings->_jobs > 1)
|
if (_settings->test_2_pass && _settings->_jobs > 1) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: --test-2-pass doesn't work with -j option yet.");
|
PrintMessage("cppcheck: --test-2-pass doesn't work with -j option yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc <= 1)
|
if (argc <= 1)
|
||||||
_showHelp = true;
|
_showHelp = true;
|
||||||
|
|
||||||
if (_showHelp)
|
if (_showHelp) {
|
||||||
{
|
|
||||||
PrintHelp();
|
PrintHelp();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print error only if we have "real" command and expect files
|
// Print error only if we have "real" command and expect files
|
||||||
if (!_exitAfterPrint && _pathnames.empty())
|
if (!_exitAfterPrint && _pathnames.empty()) {
|
||||||
{
|
|
||||||
PrintMessage("cppcheck: No C or C++ source files found.");
|
PrintMessage("cppcheck: No C or C++ source files found.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,7 @@ class Settings;
|
||||||
* based on options user has given. Couple of options are handled as
|
* based on options user has given. Couple of options are handled as
|
||||||
* class internal options.
|
* class internal options.
|
||||||
*/
|
*/
|
||||||
class CmdLineParser
|
class CmdLineParser {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* The constructor.
|
* The constructor.
|
||||||
|
@ -55,48 +54,42 @@ public:
|
||||||
/**
|
/**
|
||||||
* Return if user wanted to see program version.
|
* Return if user wanted to see program version.
|
||||||
*/
|
*/
|
||||||
bool GetShowVersion() const
|
bool GetShowVersion() const {
|
||||||
{
|
|
||||||
return _showVersion;
|
return _showVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if user wanted to see list of error messages.
|
* Return if user wanted to see list of error messages.
|
||||||
*/
|
*/
|
||||||
bool GetShowErrorMessages() const
|
bool GetShowErrorMessages() const {
|
||||||
{
|
|
||||||
return _showErrorMessages;
|
return _showErrorMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the path names user gave to command line.
|
* Return the path names user gave to command line.
|
||||||
*/
|
*/
|
||||||
std::vector<std::string> GetPathNames() const
|
std::vector<std::string> GetPathNames() const {
|
||||||
{
|
|
||||||
return _pathnames;
|
return _pathnames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if help is shown to user.
|
* Return if help is shown to user.
|
||||||
*/
|
*/
|
||||||
bool GetShowHelp() const
|
bool GetShowHelp() const {
|
||||||
{
|
|
||||||
return _showHelp;
|
return _showHelp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if we should exit after printing version, help etc.
|
* Return if we should exit after printing version, help etc.
|
||||||
*/
|
*/
|
||||||
bool ExitAfterPrinting() const
|
bool ExitAfterPrinting() const {
|
||||||
{
|
|
||||||
return _exitAfterPrint;
|
return _exitAfterPrint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of paths user wants to ignore.
|
* Return a list of paths user wants to ignore.
|
||||||
*/
|
*/
|
||||||
std::vector<std::string> GetIgnoredPaths() const
|
std::vector<std::string> GetIgnoredPaths() const {
|
||||||
{
|
|
||||||
return _ignoredPaths;
|
return _ignoredPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,8 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
||||||
bool success = parser.ParseFromArgs(argc, argv);
|
bool success = parser.ParseFromArgs(argc, argv);
|
||||||
cppcheck->settings(_settings); // copy the settings
|
cppcheck->settings(_settings); // copy the settings
|
||||||
|
|
||||||
if (success)
|
if (success) {
|
||||||
{
|
if (parser.GetShowVersion() && !parser.GetShowErrorMessages()) {
|
||||||
if (parser.GetShowVersion() && !parser.GetShowErrorMessages())
|
|
||||||
{
|
|
||||||
const char * extraVersion = cppcheck->extraVersion();
|
const char * extraVersion = cppcheck->extraVersion();
|
||||||
if (strlen(extraVersion) > 0)
|
if (strlen(extraVersion) > 0)
|
||||||
std::cout << "Cppcheck " << cppcheck->version() << " ("
|
std::cout << "Cppcheck " << cppcheck->version() << " ("
|
||||||
|
@ -61,8 +59,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
||||||
std::cout << "Cppcheck " << cppcheck->version() << std::endl;
|
std::cout << "Cppcheck " << cppcheck->version() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parser.GetShowErrorMessages())
|
if (parser.GetShowErrorMessages()) {
|
||||||
{
|
|
||||||
errorlist = true;
|
errorlist = true;
|
||||||
std::cout << ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version);
|
std::cout << ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version);
|
||||||
cppcheck->getErrorMessages();
|
cppcheck->getErrorMessages();
|
||||||
|
@ -78,13 +75,11 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
||||||
std::list<std::string>::iterator iter;
|
std::list<std::string>::iterator iter;
|
||||||
for (iter = _settings._includePaths.begin();
|
for (iter = _settings._includePaths.begin();
|
||||||
iter != _settings._includePaths.end();
|
iter != _settings._includePaths.end();
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
const std::string path(Path::toNativeSeparators(*iter));
|
const std::string path(Path::toNativeSeparators(*iter));
|
||||||
if (FileLister::isDirectory(path))
|
if (FileLister::isDirectory(path))
|
||||||
++iter;
|
++iter;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// If the include path is not found, warn user and remove the
|
// If the include path is not found, warn user and remove the
|
||||||
// non-existing path from the list.
|
// non-existing path from the list.
|
||||||
std::cout << "cppcheck: warning: Couldn't find path given by -I '" + path + "'" << std::endl;
|
std::cout << "cppcheck: warning: Couldn't find path given by -I '" + path + "'" << std::endl;
|
||||||
|
@ -97,30 +92,25 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
||||||
std::vector<std::string> filenames;
|
std::vector<std::string> filenames;
|
||||||
std::map<std::string, long> filesizes;
|
std::map<std::string, long> filesizes;
|
||||||
|
|
||||||
if (!pathnames.empty())
|
if (!pathnames.empty()) {
|
||||||
{
|
|
||||||
// Execute recursiveAddFiles() to each given file parameter
|
// Execute recursiveAddFiles() to each given file parameter
|
||||||
std::vector<std::string>::const_iterator iter;
|
std::vector<std::string>::const_iterator iter;
|
||||||
for (iter = pathnames.begin(); iter != pathnames.end(); ++iter)
|
for (iter = pathnames.begin(); iter != pathnames.end(); ++iter)
|
||||||
FileLister::recursiveAddFiles(filenames, filesizes, Path::toNativeSeparators(*iter));
|
FileLister::recursiveAddFiles(filenames, filesizes, Path::toNativeSeparators(*iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filenames.empty())
|
if (!filenames.empty()) {
|
||||||
{
|
|
||||||
// Remove header files from the list of ignored files.
|
// Remove header files from the list of ignored files.
|
||||||
// Also output a warning for the user.
|
// Also output a warning for the user.
|
||||||
// TODO: Remove all unknown files? (use FileLister::acceptFile())
|
// TODO: Remove all unknown files? (use FileLister::acceptFile())
|
||||||
bool warned = false;
|
bool warned = false;
|
||||||
std::vector<std::string> ignored = parser.GetIgnoredPaths();
|
std::vector<std::string> ignored = parser.GetIgnoredPaths();
|
||||||
std::vector<std::string>::iterator iterIgnored = ignored.begin();
|
std::vector<std::string>::iterator iterIgnored = ignored.begin();
|
||||||
for (int i = (int)ignored.size() - 1; i >= 0; i--)
|
for (int i = (int)ignored.size() - 1; i >= 0; i--) {
|
||||||
{
|
|
||||||
const std::string extension = Path::getFilenameExtension(ignored[i]);
|
const std::string extension = Path::getFilenameExtension(ignored[i]);
|
||||||
if (extension == ".h" || extension == ".hpp")
|
if (extension == ".h" || extension == ".hpp") {
|
||||||
{
|
|
||||||
ignored.erase(iterIgnored + i);
|
ignored.erase(iterIgnored + i);
|
||||||
if (!warned)
|
if (!warned) {
|
||||||
{
|
|
||||||
std::cout << "cppcheck: filename exclusion does not apply to header (.h and .hpp) files." << std::endl;
|
std::cout << "cppcheck: filename exclusion does not apply to header (.h and .hpp) files." << std::endl;
|
||||||
std::cout << "cppcheck: Please use --suppress for ignoring results from the header files." << std::endl;
|
std::cout << "cppcheck: Please use --suppress for ignoring results from the header files." << std::endl;
|
||||||
warned = true; // Warn only once
|
warned = true; // Warn only once
|
||||||
|
@ -130,8 +120,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
||||||
|
|
||||||
PathMatch matcher(parser.GetIgnoredPaths());
|
PathMatch matcher(parser.GetIgnoredPaths());
|
||||||
std::vector<std::string>::iterator iterBegin = filenames.begin();
|
std::vector<std::string>::iterator iterBegin = filenames.begin();
|
||||||
for (int i = (int)filenames.size() - 1; i >= 0; i--)
|
for (int i = (int)filenames.size() - 1; i >= 0; i--) {
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// For Windows we want case-insensitive path matching
|
// For Windows we want case-insensitive path matching
|
||||||
const bool caseSensitive = false;
|
const bool caseSensitive = false;
|
||||||
|
@ -141,26 +130,20 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
|
||||||
if (matcher.Match(filenames[(unsigned int)i], caseSensitive))
|
if (matcher.Match(filenames[(unsigned int)i], caseSensitive))
|
||||||
filenames.erase(iterBegin + i);
|
filenames.erase(iterBegin + i);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "cppcheck: error: could not find or open any of the paths given." << std::endl;
|
std::cout << "cppcheck: error: could not find or open any of the paths given." << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filenames.empty())
|
if (!filenames.empty()) {
|
||||||
{
|
|
||||||
std::vector<std::string>::iterator iter;
|
std::vector<std::string>::iterator iter;
|
||||||
for (iter = filenames.begin(); iter != filenames.end(); ++iter)
|
for (iter = filenames.begin(); iter != filenames.end(); ++iter) {
|
||||||
{
|
|
||||||
_filenames.push_back(*iter);
|
_filenames.push_back(*iter);
|
||||||
_filesizes[*iter] = filesizes[*iter];
|
_filesizes[*iter] = filesizes[*iter];
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "cppcheck: error: no files to check - all paths ignored." << std::endl;
|
std::cout << "cppcheck: error: no files to check - all paths ignored." << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -171,8 +154,7 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
|
||||||
Preprocessor::missingIncludeFlag = false;
|
Preprocessor::missingIncludeFlag = false;
|
||||||
|
|
||||||
CppCheck cppCheck(*this, true);
|
CppCheck cppCheck(*this, true);
|
||||||
if (!parseFromArgs(&cppCheck, argc, argv))
|
if (!parseFromArgs(&cppCheck, argc, argv)) {
|
||||||
{
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,28 +162,23 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
|
||||||
time1 = std::time(0);
|
time1 = std::time(0);
|
||||||
|
|
||||||
_settings = cppCheck.settings();
|
_settings = cppCheck.settings();
|
||||||
if (_settings._xml)
|
if (_settings._xml) {
|
||||||
{
|
|
||||||
reportErr(ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version));
|
reportErr(ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int returnValue = 0;
|
unsigned int returnValue = 0;
|
||||||
if (_settings._jobs == 1)
|
if (_settings._jobs == 1) {
|
||||||
{
|
|
||||||
// Single process
|
// Single process
|
||||||
|
|
||||||
long totalfilesize = 0;
|
long totalfilesize = 0;
|
||||||
for (std::map<std::string, long>::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i)
|
for (std::map<std::string, long>::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i) {
|
||||||
{
|
|
||||||
totalfilesize += i->second;
|
totalfilesize += i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
long processedsize = 0;
|
long processedsize = 0;
|
||||||
for (unsigned int c = 0; c < _filenames.size(); c++)
|
for (unsigned int c = 0; c < _filenames.size(); c++) {
|
||||||
{
|
|
||||||
returnValue += cppCheck.check(_filenames[c]);
|
returnValue += cppCheck.check(_filenames[c]);
|
||||||
if (_filesizes.find(_filenames[c]) != _filesizes.end())
|
if (_filesizes.find(_filenames[c]) != _filesizes.end()) {
|
||||||
{
|
|
||||||
processedsize += _filesizes[_filenames[c]];
|
processedsize += _filesizes[_filenames[c]];
|
||||||
}
|
}
|
||||||
if (!_settings._errorsOnly)
|
if (!_settings._errorsOnly)
|
||||||
|
@ -209,26 +186,20 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
cppCheck.checkFunctionUsage();
|
cppCheck.checkFunctionUsage();
|
||||||
}
|
} else if (!ThreadExecutor::isEnabled()) {
|
||||||
else if (!ThreadExecutor::isEnabled())
|
|
||||||
{
|
|
||||||
std::cout << "No thread support yet implemented for this platform." << std::endl;
|
std::cout << "No thread support yet implemented for this platform." << std::endl;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Multiple processes
|
// Multiple processes
|
||||||
Settings &settings = cppCheck.settings();
|
Settings &settings = cppCheck.settings();
|
||||||
ThreadExecutor executor(_filenames, _filesizes, settings, *this);
|
ThreadExecutor executor(_filenames, _filesizes, settings, *this);
|
||||||
returnValue = executor.check();
|
returnValue = executor.check();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cppCheck.settings().checkConfiguration)
|
if (!cppCheck.settings().checkConfiguration) {
|
||||||
{
|
|
||||||
if (!_settings._errorsOnly)
|
if (!_settings._errorsOnly)
|
||||||
reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions());
|
reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions());
|
||||||
|
|
||||||
if (Preprocessor::missingIncludeFlag)
|
if (Preprocessor::missingIncludeFlag) {
|
||||||
{
|
|
||||||
const std::list<ErrorLogger::ErrorMessage::FileLocation> callStack;
|
const std::list<ErrorLogger::ErrorMessage::FileLocation> callStack;
|
||||||
ErrorLogger::ErrorMessage msg(callStack,
|
ErrorLogger::ErrorMessage msg(callStack,
|
||||||
Severity::information,
|
Severity::information,
|
||||||
|
@ -244,8 +215,7 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_settings._xml)
|
if (_settings._xml) {
|
||||||
{
|
|
||||||
reportErr(ErrorLogger::ErrorMessage::getXMLFooter(_settings._xml_version));
|
reportErr(ErrorLogger::ErrorMessage::getXMLFooter(_settings._xml_version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,8 +249,7 @@ void CppCheckExecutor::reportProgress(const std::string &filename, const char st
|
||||||
|
|
||||||
// Report progress messages every 10 seconds
|
// Report progress messages every 10 seconds
|
||||||
const std::time_t time2 = std::time(NULL);
|
const std::time_t time2 = std::time(NULL);
|
||||||
if (time2 >= (time1 + 10))
|
if (time2 >= (time1 + 10)) {
|
||||||
{
|
|
||||||
time1 = time2;
|
time1 = time2;
|
||||||
|
|
||||||
// current time in the format "Www Mmm dd hh:mm:ss yyyy"
|
// current time in the format "Www Mmm dd hh:mm:ss yyyy"
|
||||||
|
@ -301,8 +270,7 @@ void CppCheckExecutor::reportProgress(const std::string &filename, const char st
|
||||||
|
|
||||||
void CppCheckExecutor::reportStatus(unsigned int fileindex, unsigned int filecount, long sizedone, long sizetotal)
|
void CppCheckExecutor::reportStatus(unsigned int fileindex, unsigned int filecount, long sizedone, long sizetotal)
|
||||||
{
|
{
|
||||||
if (filecount > 1)
|
if (filecount > 1) {
|
||||||
{
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << fileindex << "/" << filecount
|
oss << fileindex << "/" << filecount
|
||||||
<< " files checked " <<
|
<< " files checked " <<
|
||||||
|
@ -314,16 +282,11 @@ void CppCheckExecutor::reportStatus(unsigned int fileindex, unsigned int filecou
|
||||||
|
|
||||||
void CppCheckExecutor::reportErr(const ErrorLogger::ErrorMessage &msg)
|
void CppCheckExecutor::reportErr(const ErrorLogger::ErrorMessage &msg)
|
||||||
{
|
{
|
||||||
if (errorlist)
|
if (errorlist) {
|
||||||
{
|
|
||||||
reportOut(msg.toXML(false, _settings._xml_version));
|
reportOut(msg.toXML(false, _settings._xml_version));
|
||||||
}
|
} else if (_settings._xml) {
|
||||||
else if (_settings._xml)
|
|
||||||
{
|
|
||||||
reportErr(msg.toXML(_settings._verbose, _settings._xml_version));
|
reportErr(msg.toXML(_settings._verbose, _settings._xml_version));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
reportErr(msg.toString(_settings._verbose, _settings._outputFormat));
|
reportErr(msg.toString(_settings._verbose, _settings._outputFormat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,7 @@ class CppCheck;
|
||||||
* just rewrite this class for your needs and possibly use other methods
|
* just rewrite this class for your needs and possibly use other methods
|
||||||
* from CppCheck class instead the ones used here.
|
* from CppCheck class instead the ones used here.
|
||||||
*/
|
*/
|
||||||
class CppCheckExecutor : public ErrorLogger
|
class CppCheckExecutor : public ErrorLogger {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
|
|
@ -44,8 +44,7 @@ bool FileLister::acceptFile(const std::string &filename)
|
||||||
extension == ".c" ||
|
extension == ".c" ||
|
||||||
extension == ".c++" ||
|
extension == ".c++" ||
|
||||||
extension == ".tpp" ||
|
extension == ".tpp" ||
|
||||||
extension == ".txx")
|
extension == ".txx") {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +152,9 @@ void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map
|
||||||
|
|
||||||
oss << cleanedPath;
|
oss << cleanedPath;
|
||||||
|
|
||||||
if (MyIsDirectory(cleanedPath.c_str()))
|
if (MyIsDirectory(cleanedPath.c_str())) {
|
||||||
{
|
|
||||||
char c = cleanedPath[ cleanedPath.size()-1 ];
|
char c = cleanedPath[ cleanedPath.size()-1 ];
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case '\\':
|
case '\\':
|
||||||
oss << '*';
|
oss << '*';
|
||||||
bdir << cleanedPath;
|
bdir << cleanedPath;
|
||||||
|
@ -170,13 +167,10 @@ void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map
|
||||||
if (cleanedPath != ".")
|
if (cleanedPath != ".")
|
||||||
bdir << cleanedPath << '\\';
|
bdir << cleanedPath << '\\';
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string::size_type pos;
|
std::string::size_type pos;
|
||||||
pos = cleanedPath.find_last_of('\\');
|
pos = cleanedPath.find_last_of('\\');
|
||||||
if (std::string::npos != pos)
|
if (std::string::npos != pos) {
|
||||||
{
|
|
||||||
bdir << cleanedPath.substr(0, pos + 1);
|
bdir << cleanedPath.substr(0, pos + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,8 +180,7 @@ void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map
|
||||||
if (INVALID_HANDLE_VALUE == hFind)
|
if (INVALID_HANDLE_VALUE == hFind)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
if (ffd.cFileName[0] == '.' || ffd.cFileName[0] == '\0')
|
if (ffd.cFileName[0] == '.' || ffd.cFileName[0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -196,8 +189,7 @@ void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map
|
||||||
TransformUcs2ToAnsi(ffd.cFileName, ansiFfd, wcslen(ffd.cFileName) + 1);
|
TransformUcs2ToAnsi(ffd.cFileName, ansiFfd, wcslen(ffd.cFileName) + 1);
|
||||||
#else // defined(UNICODE)
|
#else // defined(UNICODE)
|
||||||
const char * ansiFfd = &ffd.cFileName[0];
|
const char * ansiFfd = &ffd.cFileName[0];
|
||||||
if (strchr(ansiFfd,'?'))
|
if (strchr(ansiFfd,'?')) {
|
||||||
{
|
|
||||||
ansiFfd = &ffd.cAlternateFileName[0];
|
ansiFfd = &ffd.cAlternateFileName[0];
|
||||||
}
|
}
|
||||||
#endif // defined(UNICODE)
|
#endif // defined(UNICODE)
|
||||||
|
@ -205,32 +197,26 @@ void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map
|
||||||
std::ostringstream fname;
|
std::ostringstream fname;
|
||||||
fname << bdir.str().c_str() << ansiFfd;
|
fname << bdir.str().c_str() << ansiFfd;
|
||||||
|
|
||||||
if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||||
{
|
|
||||||
// File
|
// File
|
||||||
|
|
||||||
// If recursive is not used, accept all files given by user
|
// If recursive is not used, accept all files given by user
|
||||||
if (Path::sameFileName(path,ansiFfd) || FileLister::acceptFile(ansiFfd))
|
if (Path::sameFileName(path,ansiFfd) || FileLister::acceptFile(ansiFfd)) {
|
||||||
{
|
|
||||||
const std::string nativename = Path::fromNativeSeparators(fname.str());
|
const std::string nativename = Path::fromNativeSeparators(fname.str());
|
||||||
filenames.push_back(nativename);
|
filenames.push_back(nativename);
|
||||||
// Limitation: file sizes are assumed to fit in a 'long'
|
// Limitation: file sizes are assumed to fit in a 'long'
|
||||||
filesizes[nativename] = ffd.nFileSizeLow;
|
filesizes[nativename] = ffd.nFileSizeLow;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Directory
|
// Directory
|
||||||
FileLister::recursiveAddFiles(filenames, filesizes, fname.str());
|
FileLister::recursiveAddFiles(filenames, filesizes, fname.str());
|
||||||
}
|
}
|
||||||
#if defined(UNICODE)
|
#if defined(UNICODE)
|
||||||
delete [] ansiFfd;
|
delete [] ansiFfd;
|
||||||
#endif // defined(UNICODE)
|
#endif // defined(UNICODE)
|
||||||
}
|
} while (FindNextFile(hFind, &ffd) != FALSE);
|
||||||
while (FindNextFile(hFind, &ffd) != FALSE);
|
|
||||||
|
|
||||||
if (INVALID_HANDLE_VALUE != hFind)
|
if (INVALID_HANDLE_VALUE != hFind) {
|
||||||
{
|
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
hFind = INVALID_HANDLE_VALUE;
|
hFind = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
@ -274,14 +260,12 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
|
||||||
|
|
||||||
glob_t glob_results;
|
glob_t glob_results;
|
||||||
glob(oss.str().c_str(), GLOB_MARK, 0, &glob_results);
|
glob(oss.str().c_str(), GLOB_MARK, 0, &glob_results);
|
||||||
for (unsigned int i = 0; i < glob_results.gl_pathc; i++)
|
for (unsigned int i = 0; i < glob_results.gl_pathc; i++) {
|
||||||
{
|
|
||||||
const std::string filename = glob_results.gl_pathv[i];
|
const std::string filename = glob_results.gl_pathv[i];
|
||||||
if (filename == "." || filename == ".." || filename.length() == 0)
|
if (filename == "." || filename == ".." || filename.length() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (filename[filename.length()-1] != '/')
|
if (filename[filename.length()-1] != '/') {
|
||||||
{
|
|
||||||
// File
|
// File
|
||||||
#ifdef PATH_MAX
|
#ifdef PATH_MAX
|
||||||
char fname[PATH_MAX];
|
char fname[PATH_MAX];
|
||||||
|
@ -295,21 +279,18 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does absolute path exist? then bail out
|
// Does absolute path exist? then bail out
|
||||||
if (std::find(absolute.begin(), absolute.end(), std::string(fname)) != absolute.end())
|
if (std::find(absolute.begin(), absolute.end(), std::string(fname)) != absolute.end()) {
|
||||||
{
|
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
free(fname);
|
free(fname);
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Path::sameFileName(path,filename) || FileLister::acceptFile(filename))
|
if (Path::sameFileName(path,filename) || FileLister::acceptFile(filename)) {
|
||||||
{
|
|
||||||
relative.push_back(filename);
|
relative.push_back(filename);
|
||||||
absolute.push_back(fname);
|
absolute.push_back(fname);
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
if (stat(fname, &sb) == 0)
|
if (stat(fname, &sb) == 0) {
|
||||||
{
|
|
||||||
// Limitation: file sizes are assumed to fit in a 'long'
|
// Limitation: file sizes are assumed to fit in a 'long'
|
||||||
filesizes[filename] = static_cast<long>(sb.st_size);
|
filesizes[filename] = static_cast<long>(sb.st_size);
|
||||||
}
|
}
|
||||||
|
@ -318,9 +299,7 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
free(fname);
|
free(fname);
|
||||||
#endif
|
#endif
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Directory
|
// Directory
|
||||||
recursiveAddFiles2(relative, absolute, filesizes, filename);
|
recursiveAddFiles2(relative, absolute, filesizes, filename);
|
||||||
}
|
}
|
||||||
|
@ -341,11 +320,9 @@ bool FileLister::isDirectory(const std::string &path)
|
||||||
|
|
||||||
glob_t glob_results;
|
glob_t glob_results;
|
||||||
glob(path.c_str(), GLOB_MARK, 0, &glob_results);
|
glob(path.c_str(), GLOB_MARK, 0, &glob_results);
|
||||||
if (glob_results.gl_pathc == 1)
|
if (glob_results.gl_pathc == 1) {
|
||||||
{
|
|
||||||
const std::string glob_path = glob_results.gl_pathv[0];
|
const std::string glob_path = glob_results.gl_pathv[0];
|
||||||
if (!glob_path.empty() && glob_path[glob_path.size() - 1] == '/')
|
if (!glob_path.empty() && glob_path[glob_path.size() - 1] == '/') {
|
||||||
{
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,8 +336,7 @@ bool FileLister::fileExists(const std::string &path)
|
||||||
struct stat statinfo;
|
struct stat statinfo;
|
||||||
int result = stat(path.c_str(), &statinfo);
|
int result = stat(path.c_str(), &statinfo);
|
||||||
|
|
||||||
if (result < 0) // Todo: should check errno == ENOENT?
|
if (result < 0) { // Todo: should check errno == ENOENT?
|
||||||
{
|
|
||||||
// File not found
|
// File not found
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,7 @@
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/** @brief Cross-platform FileLister */
|
/** @brief Cross-platform FileLister */
|
||||||
class FileLister
|
class FileLister {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Recursively add source files to a vector.
|
* @brief Recursively add source files to a vector.
|
||||||
|
|
|
@ -30,8 +30,7 @@ bool PathMatch::Match(const std::string &path, bool caseSensitive)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::vector<std::string>::const_iterator iterMask;
|
std::vector<std::string>::const_iterator iterMask;
|
||||||
for (iterMask = _masks.begin(); iterMask != _masks.end(); ++iterMask)
|
for (iterMask = _masks.begin(); iterMask != _masks.end(); ++iterMask) {
|
||||||
{
|
|
||||||
std::string mask(*iterMask);
|
std::string mask(*iterMask);
|
||||||
if (!caseSensitive)
|
if (!caseSensitive)
|
||||||
std::transform(mask.begin(), mask.end(), mask.begin(), ::tolower);
|
std::transform(mask.begin(), mask.end(), mask.begin(), ::tolower);
|
||||||
|
@ -41,8 +40,7 @@ bool PathMatch::Match(const std::string &path, bool caseSensitive)
|
||||||
std::transform(findpath.begin(), findpath.end(), findpath.begin(), ::tolower);
|
std::transform(findpath.begin(), findpath.end(), findpath.begin(), ::tolower);
|
||||||
|
|
||||||
// Filtering directory name
|
// Filtering directory name
|
||||||
if (mask[mask.length() - 1] == '/')
|
if (mask[mask.length() - 1] == '/') {
|
||||||
{
|
|
||||||
if (findpath[findpath.length() - 1] != '/')
|
if (findpath[findpath.length() - 1] != '/')
|
||||||
findpath = RemoveFilename(findpath);
|
findpath = RemoveFilename(findpath);
|
||||||
|
|
||||||
|
@ -59,8 +57,7 @@ bool PathMatch::Match(const std::string &path, bool caseSensitive)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Filtering filename
|
// Filtering filename
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (mask.length() > findpath.length())
|
if (mask.length() > findpath.length())
|
||||||
continue;
|
continue;
|
||||||
// Check if path ends with mask
|
// Check if path ends with mask
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
/**
|
/**
|
||||||
* @brief Simple path matching for ignoring paths in CLI.
|
* @brief Simple path matching for ignoring paths in CLI.
|
||||||
*/
|
*/
|
||||||
class PathMatch
|
class PathMatch {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -59,64 +59,52 @@ void ThreadExecutor::addFileContent(const std::string &path, const std::string &
|
||||||
int ThreadExecutor::handleRead(int rpipe, unsigned int &result)
|
int ThreadExecutor::handleRead(int rpipe, unsigned int &result)
|
||||||
{
|
{
|
||||||
char type = 0;
|
char type = 0;
|
||||||
if (read(rpipe, &type, 1) <= 0)
|
if (read(rpipe, &type, 1) <= 0) {
|
||||||
{
|
|
||||||
if (errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != '1' && type != '2' && type != '3')
|
if (type != '1' && type != '2' && type != '3') {
|
||||||
{
|
|
||||||
std::cerr << "#### You found a bug from cppcheck.\nThreadExecutor::handleRead error, type was:" << type << std::endl;
|
std::cerr << "#### You found a bug from cppcheck.\nThreadExecutor::handleRead error, type was:" << type << std::endl;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int len = 0;
|
unsigned int len = 0;
|
||||||
if (read(rpipe, &len, sizeof(len)) <= 0)
|
if (read(rpipe, &len, sizeof(len)) <= 0) {
|
||||||
{
|
|
||||||
std::cerr << "#### You found a bug from cppcheck.\nThreadExecutor::handleRead error, type was:" << type << std::endl;
|
std::cerr << "#### You found a bug from cppcheck.\nThreadExecutor::handleRead error, type was:" << type << std::endl;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *buf = new char[len];
|
char *buf = new char[len];
|
||||||
if (read(rpipe, buf, len) <= 0)
|
if (read(rpipe, buf, len) <= 0) {
|
||||||
{
|
|
||||||
std::cerr << "#### You found a bug from cppcheck.\nThreadExecutor::handleRead error, type was:" << type << std::endl;
|
std::cerr << "#### You found a bug from cppcheck.\nThreadExecutor::handleRead error, type was:" << type << std::endl;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == '1')
|
if (type == '1') {
|
||||||
{
|
|
||||||
_errorLogger.reportOut(buf);
|
_errorLogger.reportOut(buf);
|
||||||
}
|
} else if (type == '2') {
|
||||||
else if (type == '2')
|
|
||||||
{
|
|
||||||
ErrorLogger::ErrorMessage msg;
|
ErrorLogger::ErrorMessage msg;
|
||||||
msg.deserialize(buf);
|
msg.deserialize(buf);
|
||||||
|
|
||||||
std::string file;
|
std::string file;
|
||||||
unsigned int line(0);
|
unsigned int line(0);
|
||||||
if (!msg._callStack.empty())
|
if (!msg._callStack.empty()) {
|
||||||
{
|
|
||||||
file = msg._callStack.back().getfile(false);
|
file = msg._callStack.back().getfile(false);
|
||||||
line = msg._callStack.back().line;
|
line = msg._callStack.back().line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_settings.nomsg.isSuppressed(msg._id, file, line))
|
if (!_settings.nomsg.isSuppressed(msg._id, file, line)) {
|
||||||
{
|
|
||||||
// Alert only about unique errors
|
// Alert only about unique errors
|
||||||
std::string errmsg = msg.toString(_settings._verbose);
|
std::string errmsg = msg.toString(_settings._verbose);
|
||||||
if (std::find(_errorList.begin(), _errorList.end(), errmsg) == _errorList.end())
|
if (std::find(_errorList.begin(), _errorList.end(), errmsg) == _errorList.end()) {
|
||||||
{
|
|
||||||
_errorList.push_back(errmsg);
|
_errorList.push_back(errmsg);
|
||||||
_errorLogger.reportErr(msg);
|
_errorLogger.reportErr(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (type == '3') {
|
||||||
else if (type == '3')
|
|
||||||
{
|
|
||||||
std::istringstream iss(buf);
|
std::istringstream iss(buf);
|
||||||
unsigned int fileResult = 0;
|
unsigned int fileResult = 0;
|
||||||
iss >> fileResult;
|
iss >> fileResult;
|
||||||
|
@ -135,8 +123,7 @@ unsigned int ThreadExecutor::check()
|
||||||
unsigned int result = 0;
|
unsigned int result = 0;
|
||||||
|
|
||||||
long totalfilesize = 0;
|
long totalfilesize = 0;
|
||||||
for (std::map<std::string, long>::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i)
|
for (std::map<std::string, long>::const_iterator i = _filesizes.begin(); i != _filesizes.end(); ++i) {
|
||||||
{
|
|
||||||
totalfilesize += i->second;
|
totalfilesize += i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,40 +132,32 @@ unsigned int ThreadExecutor::check()
|
||||||
std::map<int, std::string> pipeFile;
|
std::map<int, std::string> pipeFile;
|
||||||
long processedsize = 0;
|
long processedsize = 0;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
|
||||||
// Start a new child
|
// Start a new child
|
||||||
if (i < _filenames.size() && rpipes.size() < _settings._jobs)
|
if (i < _filenames.size() && rpipes.size() < _settings._jobs) {
|
||||||
{
|
|
||||||
int pipes[2];
|
int pipes[2];
|
||||||
if (pipe(pipes) == -1)
|
if (pipe(pipes) == -1) {
|
||||||
{
|
|
||||||
perror("pipe");
|
perror("pipe");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if ((flags = fcntl(pipes[0], F_GETFL, 0)) < 0)
|
if ((flags = fcntl(pipes[0], F_GETFL, 0)) < 0) {
|
||||||
{
|
|
||||||
perror("fcntl");
|
perror("fcntl");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcntl(pipes[0], F_SETFL, flags | O_NONBLOCK) < 0)
|
if (fcntl(pipes[0], F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||||
{
|
|
||||||
perror("fcntl");
|
perror("fcntl");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid < 0)
|
if (pid < 0) {
|
||||||
{
|
|
||||||
// Error
|
// Error
|
||||||
std::cerr << "Failed to create child process" << std::endl;
|
std::cerr << "Failed to create child process" << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
} else if (pid == 0) {
|
||||||
else if (pid == 0)
|
|
||||||
{
|
|
||||||
close(pipes[0]);
|
close(pipes[0]);
|
||||||
_wpipe = pipes[1];
|
_wpipe = pipes[1];
|
||||||
|
|
||||||
|
@ -186,13 +165,10 @@ unsigned int ThreadExecutor::check()
|
||||||
fileChecker.settings(_settings);
|
fileChecker.settings(_settings);
|
||||||
unsigned int resultOfCheck = 0;
|
unsigned int resultOfCheck = 0;
|
||||||
|
|
||||||
if (_fileContents.size() > 0 && _fileContents.find(_filenames[i]) != _fileContents.end())
|
if (_fileContents.size() > 0 && _fileContents.find(_filenames[i]) != _fileContents.end()) {
|
||||||
{
|
|
||||||
// File content was given as a string
|
// File content was given as a string
|
||||||
resultOfCheck = fileChecker.check(_filenames[i], _fileContents[ _filenames[i] ]);
|
resultOfCheck = fileChecker.check(_filenames[i], _fileContents[ _filenames[i] ]);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Read file from a file
|
// Read file from a file
|
||||||
resultOfCheck = fileChecker.check(_filenames[i]);
|
resultOfCheck = fileChecker.check(_filenames[i]);
|
||||||
}
|
}
|
||||||
|
@ -209,9 +185,7 @@ unsigned int ThreadExecutor::check()
|
||||||
pipeFile[pipes[0]] = _filenames[i];
|
pipeFile[pipes[0]] = _filenames[i];
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
} else if (!rpipes.empty()) {
|
||||||
else if (!rpipes.empty())
|
|
||||||
{
|
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
for (std::list<int>::const_iterator rp = rpipes.begin(); rp != rpipes.end(); ++rp)
|
for (std::list<int>::const_iterator rp = rpipes.begin(); rp != rpipes.end(); ++rp)
|
||||||
|
@ -219,25 +193,19 @@ unsigned int ThreadExecutor::check()
|
||||||
|
|
||||||
int r = select(*std::max_element(rpipes.begin(), rpipes.end()) + 1, &rfds, NULL, NULL, NULL);
|
int r = select(*std::max_element(rpipes.begin(), rpipes.end()) + 1, &rfds, NULL, NULL, NULL);
|
||||||
|
|
||||||
if (r > 0)
|
if (r > 0) {
|
||||||
{
|
|
||||||
std::list<int>::iterator rp = rpipes.begin();
|
std::list<int>::iterator rp = rpipes.begin();
|
||||||
while (rp != rpipes.end())
|
while (rp != rpipes.end()) {
|
||||||
{
|
if (FD_ISSET(*rp, &rfds)) {
|
||||||
if (FD_ISSET(*rp, &rfds))
|
|
||||||
{
|
|
||||||
int readRes = handleRead(*rp, result);
|
int readRes = handleRead(*rp, result);
|
||||||
if (readRes == -1)
|
if (readRes == -1) {
|
||||||
{
|
|
||||||
long size = 0;
|
long size = 0;
|
||||||
std::map<int, std::string>::iterator p = pipeFile.find(*rp);
|
std::map<int, std::string>::iterator p = pipeFile.find(*rp);
|
||||||
if (p != pipeFile.end())
|
if (p != pipeFile.end()) {
|
||||||
{
|
|
||||||
std::string name = p->second;
|
std::string name = p->second;
|
||||||
pipeFile.erase(p);
|
pipeFile.erase(p);
|
||||||
std::map<std::string, long>::const_iterator fs = _filesizes.find(name);
|
std::map<std::string, long>::const_iterator fs = _filesizes.find(name);
|
||||||
if (fs != _filesizes.end())
|
if (fs != _filesizes.end()) {
|
||||||
{
|
|
||||||
size = fs->second;
|
size = fs->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,29 +217,24 @@ unsigned int ThreadExecutor::check()
|
||||||
|
|
||||||
close(*rp);
|
close(*rp);
|
||||||
rp = rpipes.erase(rp);
|
rp = rpipes.erase(rp);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
++rp;
|
++rp;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
++rp;
|
++rp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int stat = 0;
|
int stat = 0;
|
||||||
pid_t child = waitpid(0, &stat, WNOHANG);
|
pid_t child = waitpid(0, &stat, WNOHANG);
|
||||||
if (child > 0)
|
if (child > 0) {
|
||||||
{
|
|
||||||
std::string childname;
|
std::string childname;
|
||||||
std::map<pid_t, std::string>::iterator c = childFile.find(child);
|
std::map<pid_t, std::string>::iterator c = childFile.find(child);
|
||||||
if (c != childFile.end())
|
if (c != childFile.end()) {
|
||||||
{
|
|
||||||
childname = c->second;
|
childname = c->second;
|
||||||
childFile.erase(c);
|
childFile.erase(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WIFSIGNALED(stat))
|
if (WIFSIGNALED(stat)) {
|
||||||
{
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Internal error: Child process crashed with signal " << WTERMSIG(stat);
|
oss << "Internal error: Child process crashed with signal " << WTERMSIG(stat);
|
||||||
|
|
||||||
|
@ -287,9 +250,7 @@ unsigned int ThreadExecutor::check()
|
||||||
_errorLogger.reportErr(errmsg);
|
_errorLogger.reportErr(errmsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// All done
|
// All done
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -306,8 +267,7 @@ void ThreadExecutor::writeToPipe(char type, const std::string &data)
|
||||||
out[0] = type;
|
out[0] = type;
|
||||||
std::memcpy(&(out[1]), &len, sizeof(len));
|
std::memcpy(&(out[1]), &len, sizeof(len));
|
||||||
std::memcpy(&(out[1+sizeof(len)]), data.c_str(), len);
|
std::memcpy(&(out[1+sizeof(len)]), data.c_str(), len);
|
||||||
if (write(_wpipe, out, len + 1 + sizeof(len)) <= 0)
|
if (write(_wpipe, out, len + 1 + sizeof(len)) <= 0) {
|
||||||
{
|
|
||||||
delete [] out;
|
delete [] out;
|
||||||
out = 0;
|
out = 0;
|
||||||
std::cerr << "#### ThreadExecutor::writeToPipe, Failed to write to pipe" << std::endl;
|
std::cerr << "#### ThreadExecutor::writeToPipe, Failed to write to pipe" << std::endl;
|
||||||
|
|
|
@ -36,8 +36,7 @@
|
||||||
* This class will take a list of filenames and settings and check then
|
* This class will take a list of filenames and settings and check then
|
||||||
* all files using threads.
|
* all files using threads.
|
||||||
*/
|
*/
|
||||||
class ThreadExecutor : public ErrorLogger
|
class ThreadExecutor : public ErrorLogger {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ThreadExecutor(const std::vector<std::string> &filenames, const std::map<std::string, long> &filesizes, Settings &settings, ErrorLogger &_errorLogger);
|
ThreadExecutor(const std::vector<std::string> &filenames, const std::map<std::string, long> &filesizes, Settings &settings, ErrorLogger &_errorLogger);
|
||||||
virtual ~ThreadExecutor();
|
virtual ~ThreadExecutor();
|
||||||
|
@ -84,8 +83,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return true if support for threads exist.
|
* @return true if support for threads exist.
|
||||||
*/
|
*/
|
||||||
static bool isEnabled()
|
static bool isEnabled() {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -93,8 +91,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return true if support for threads exist.
|
* @return true if support for threads exist.
|
||||||
*/
|
*/
|
||||||
static bool isEnabled()
|
static bool isEnabled() {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,8 +27,7 @@ AboutDialog::AboutDialog(const QString &version, const QString &extraVersion, QW
|
||||||
mUI.setupUi(this);
|
mUI.setupUi(this);
|
||||||
|
|
||||||
QString fmtVersion(version);
|
QString fmtVersion(version);
|
||||||
if (!extraVersion.isEmpty())
|
if (!extraVersion.isEmpty()) {
|
||||||
{
|
|
||||||
fmtVersion += " (" + extraVersion + ")";
|
fmtVersion += " (" + extraVersion + ")";
|
||||||
}
|
}
|
||||||
mUI.mVersion->setText(mUI.mVersion->text().arg(fmtVersion));
|
mUI.mVersion->setText(mUI.mVersion->text().arg(fmtVersion));
|
||||||
|
|
|
@ -32,8 +32,7 @@ class QWidget;
|
||||||
* @brief About dialog
|
* @brief About dialog
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class AboutDialog : public QDialog
|
class AboutDialog : public QDialog {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AboutDialog(const QString &version, const QString &extraVersion,
|
AboutDialog(const QString &version, const QString &extraVersion,
|
||||||
|
|
|
@ -40,8 +40,7 @@
|
||||||
* Executable: kate
|
* Executable: kate
|
||||||
* Parameters: -l(line) (file)
|
* Parameters: -l(line) (file)
|
||||||
*/
|
*/
|
||||||
class Application
|
class Application {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Application() { }
|
Application() { }
|
||||||
Application(const QString &name, const QString &path, const QString ¶ms);
|
Application(const QString &name, const QString &path, const QString ¶ms);
|
||||||
|
@ -50,8 +49,7 @@ public:
|
||||||
* @brief Get application name.
|
* @brief Get application name.
|
||||||
* @return Application name.
|
* @return Application name.
|
||||||
*/
|
*/
|
||||||
QString getName() const
|
QString getName() const {
|
||||||
{
|
|
||||||
return mName;
|
return mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,8 +57,7 @@ public:
|
||||||
* @brief Get application path.
|
* @brief Get application path.
|
||||||
* @return Application path.
|
* @return Application path.
|
||||||
*/
|
*/
|
||||||
QString getPath() const
|
QString getPath() const {
|
||||||
{
|
|
||||||
return mPath;
|
return mPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +65,7 @@ public:
|
||||||
* @brief Get application command line parameters.
|
* @brief Get application command line parameters.
|
||||||
* @return Application command line parameters.
|
* @return Application command line parameters.
|
||||||
*/
|
*/
|
||||||
QString getParameters() const
|
QString getParameters() const {
|
||||||
{
|
|
||||||
return mParameters;
|
return mParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +73,7 @@ public:
|
||||||
* @brief Set application name.
|
* @brief Set application name.
|
||||||
* @param name Application name.
|
* @param name Application name.
|
||||||
*/
|
*/
|
||||||
void setName(const QString &name)
|
void setName(const QString &name) {
|
||||||
{
|
|
||||||
mName = name;
|
mName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +81,7 @@ public:
|
||||||
* @brief Set application path.
|
* @brief Set application path.
|
||||||
* @param path Application path.
|
* @param path Application path.
|
||||||
*/
|
*/
|
||||||
void setPath(const QString &path)
|
void setPath(const QString &path) {
|
||||||
{
|
|
||||||
mPath = path;
|
mPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +89,7 @@ public:
|
||||||
* @brief Set application command line parameters.
|
* @brief Set application command line parameters.
|
||||||
* @param parameters Application command line parameters.
|
* @param parameters Application command line parameters.
|
||||||
*/
|
*/
|
||||||
void setParameters(const QString ¶meters)
|
void setParameters(const QString ¶meters) {
|
||||||
{
|
|
||||||
mParameters = parameters;
|
mParameters = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,8 +62,7 @@ void ApplicationDialog::Browse()
|
||||||
QString(),
|
QString(),
|
||||||
filter);
|
filter);
|
||||||
|
|
||||||
if (!selectedFile.isEmpty())
|
if (!selectedFile.isEmpty()) {
|
||||||
{
|
|
||||||
QString path(QDir::toNativeSeparators(selectedFile));
|
QString path(QDir::toNativeSeparators(selectedFile));
|
||||||
mUI.mPath->setText(path);
|
mUI.mPath->setText(path);
|
||||||
}
|
}
|
||||||
|
@ -81,8 +80,7 @@ Application ApplicationDialog::GetApplication() const
|
||||||
void ApplicationDialog::Ok()
|
void ApplicationDialog::Ok()
|
||||||
{
|
{
|
||||||
if (mUI.mName->text().isEmpty() || mUI.mPath->text().isEmpty() ||
|
if (mUI.mName->text().isEmpty() || mUI.mPath->text().isEmpty() ||
|
||||||
mUI.mParameters->text().isEmpty())
|
mUI.mParameters->text().isEmpty()) {
|
||||||
{
|
|
||||||
QMessageBox msg(QMessageBox::Warning,
|
QMessageBox msg(QMessageBox::Warning,
|
||||||
tr("Cppcheck"),
|
tr("Cppcheck"),
|
||||||
tr("You must specify a name, a path and parameters for the application!"),
|
tr("You must specify a name, a path and parameters for the application!"),
|
||||||
|
@ -91,9 +89,7 @@ void ApplicationDialog::Ok()
|
||||||
|
|
||||||
msg.exec();
|
msg.exec();
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Convert possible native (Windows) path to internal presentation format
|
// Convert possible native (Windows) path to internal presentation format
|
||||||
mUI.mPath->setText(QDir::fromNativeSeparators(mUI.mPath->text()));
|
mUI.mPath->setText(QDir::fromNativeSeparators(mUI.mPath->text()));
|
||||||
accept();
|
accept();
|
||||||
|
|
|
@ -36,8 +36,7 @@ class QWidget;
|
||||||
* to modify/add an application to open errors with.
|
* to modify/add an application to open errors with.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ApplicationDialog : public QDialog
|
class ApplicationDialog : public QDialog {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -50,20 +50,16 @@ bool ApplicationList::LoadSettings()
|
||||||
// Params will be empty first time starting with the new setting.
|
// Params will be empty first time starting with the new setting.
|
||||||
// Return false and inform user about problem with application settings.
|
// Return false and inform user about problem with application settings.
|
||||||
bool succeeded = true;
|
bool succeeded = true;
|
||||||
if (!names.empty() && !paths.empty() && params.empty())
|
if (!names.empty() && !paths.empty() && params.empty()) {
|
||||||
{
|
|
||||||
for (int i = 0; i < paths.length(); i++)
|
for (int i = 0; i < paths.length(); i++)
|
||||||
params << "";
|
params << "";
|
||||||
succeeded = false;
|
succeeded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (names.empty() && paths.empty() && params.empty())
|
if (names.empty() && paths.empty() && params.empty()) {
|
||||||
{
|
do {
|
||||||
do
|
|
||||||
{
|
|
||||||
// use as default for gnome environments
|
// use as default for gnome environments
|
||||||
if (QFileInfo("/usr/bin/gedit").isExecutable())
|
if (QFileInfo("/usr/bin/gedit").isExecutable()) {
|
||||||
{
|
|
||||||
Application app;
|
Application app;
|
||||||
app.setName("gedit");
|
app.setName("gedit");
|
||||||
app.setPath("/usr/bin/gedit");
|
app.setPath("/usr/bin/gedit");
|
||||||
|
@ -73,8 +69,7 @@ bool ApplicationList::LoadSettings()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// use as default for kde environments
|
// use as default for kde environments
|
||||||
if (QFileInfo("/usr/bin/kate").isExecutable())
|
if (QFileInfo("/usr/bin/kate").isExecutable()) {
|
||||||
{
|
|
||||||
Application app;
|
Application app;
|
||||||
app.setName("kate");
|
app.setName("kate");
|
||||||
app.setPath("/usr/bin/kate");
|
app.setPath("/usr/bin/kate");
|
||||||
|
@ -83,19 +78,15 @@ bool ApplicationList::LoadSettings()
|
||||||
defapp = 0;
|
defapp = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (FindDefaultWindowsEditor())
|
if (FindDefaultWindowsEditor()) {
|
||||||
{
|
|
||||||
defapp = 0;
|
defapp = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (0);
|
||||||
while (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (names.size() > 0 && (names.size() == paths.size()))
|
if (names.size() > 0 && (names.size() == paths.size())) {
|
||||||
{
|
for (int i = 0; i < names.size(); i++) {
|
||||||
for (int i = 0; i < names.size(); i++)
|
|
||||||
{
|
|
||||||
const Application app(names[i], paths[i], params[i]);
|
const Application app(names[i], paths[i], params[i]);
|
||||||
AddApplication(app);
|
AddApplication(app);
|
||||||
}
|
}
|
||||||
|
@ -117,8 +108,7 @@ void ApplicationList::SaveSettings()
|
||||||
QStringList paths;
|
QStringList paths;
|
||||||
QStringList params;
|
QStringList params;
|
||||||
|
|
||||||
for (int i = 0; i < GetApplicationCount(); i++)
|
for (int i = 0; i < GetApplicationCount(); i++) {
|
||||||
{
|
|
||||||
Application app = GetApplication(i);
|
Application app = GetApplication(i);
|
||||||
names << app.getName();
|
names << app.getName();
|
||||||
paths << app.getPath();
|
paths << app.getPath();
|
||||||
|
@ -139,8 +129,7 @@ int ApplicationList::GetApplicationCount() const
|
||||||
|
|
||||||
Application ApplicationList::GetApplication(const int index) const
|
Application ApplicationList::GetApplication(const int index) const
|
||||||
{
|
{
|
||||||
if (index >= 0 && index < mApplications.size())
|
if (index >= 0 && index < mApplications.size()) {
|
||||||
{
|
|
||||||
return mApplications[index];
|
return mApplications[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,16 +138,14 @@ Application ApplicationList::GetApplication(const int index) const
|
||||||
|
|
||||||
void ApplicationList::SetApplication(int index, const Application &app)
|
void ApplicationList::SetApplication(int index, const Application &app)
|
||||||
{
|
{
|
||||||
if (index >= 0 && index < mApplications.size())
|
if (index >= 0 && index < mApplications.size()) {
|
||||||
{
|
|
||||||
mApplications.replace(index, app);
|
mApplications.replace(index, app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationList::AddApplication(const Application &app)
|
void ApplicationList::AddApplication(const Application &app)
|
||||||
{
|
{
|
||||||
if (app.getName().isEmpty() || app.getPath().isEmpty())
|
if (app.getName().isEmpty() || app.getPath().isEmpty()) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mApplications << app;
|
mApplications << app;
|
||||||
|
@ -171,22 +158,19 @@ void ApplicationList::RemoveApplication(const int index)
|
||||||
|
|
||||||
void ApplicationList::SetDefault(const int index)
|
void ApplicationList::SetDefault(const int index)
|
||||||
{
|
{
|
||||||
if (index < mApplications.size() && index >= 0)
|
if (index < mApplications.size() && index >= 0) {
|
||||||
{
|
|
||||||
mDefaultApplicationIndex = index;
|
mDefaultApplicationIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationList::Copy(const ApplicationList *list)
|
void ApplicationList::Copy(const ApplicationList *list)
|
||||||
{
|
{
|
||||||
if (!list)
|
if (!list) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
for (int i = 0; i < list->GetApplicationCount(); i++)
|
for (int i = 0; i < list->GetApplicationCount(); i++) {
|
||||||
{
|
|
||||||
const Application app = list->GetApplication(i);
|
const Application app = list->GetApplication(i);
|
||||||
AddApplication(app);
|
AddApplication(app);
|
||||||
}
|
}
|
||||||
|
@ -203,8 +187,7 @@ bool ApplicationList::FindDefaultWindowsEditor()
|
||||||
{
|
{
|
||||||
const QString appPath(getenv("ProgramFiles"));
|
const QString appPath(getenv("ProgramFiles"));
|
||||||
const QString notepadppPath = appPath + "\\Notepad++\\notepad++.exe";
|
const QString notepadppPath = appPath + "\\Notepad++\\notepad++.exe";
|
||||||
if (QFileInfo(notepadppPath).isExecutable())
|
if (QFileInfo(notepadppPath).isExecutable()) {
|
||||||
{
|
|
||||||
Application app;
|
Application app;
|
||||||
app.setName("Notepad++");
|
app.setName("Notepad++");
|
||||||
app.setPath("\"" + notepadppPath + "\"");
|
app.setPath("\"" + notepadppPath + "\"");
|
||||||
|
@ -215,8 +198,7 @@ bool ApplicationList::FindDefaultWindowsEditor()
|
||||||
|
|
||||||
const QString windowsPath(getenv("windir"));
|
const QString windowsPath(getenv("windir"));
|
||||||
const QString notepadPath = windowsPath + "\\system32\\notepad.exe";
|
const QString notepadPath = windowsPath + "\\system32\\notepad.exe";
|
||||||
if (QFileInfo(notepadPath).isExecutable())
|
if (QFileInfo(notepadPath).isExecutable()) {
|
||||||
{
|
|
||||||
Application app;
|
Application app;
|
||||||
app.setName("Notepad");
|
app.setName("Notepad");
|
||||||
app.setPath(notepadPath);
|
app.setPath(notepadPath);
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
/**
|
/**
|
||||||
* @brief List of applications user has specified to open errors with.
|
* @brief List of applications user has specified to open errors with.
|
||||||
*/
|
*/
|
||||||
class ApplicationList : public QObject
|
class ApplicationList : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -70,8 +69,7 @@ public:
|
||||||
* @brief Return the default application.
|
* @brief Return the default application.
|
||||||
* @return Index of the default application.
|
* @return Index of the default application.
|
||||||
*/
|
*/
|
||||||
int GetDefaultApplication() const
|
int GetDefaultApplication() const {
|
||||||
{
|
|
||||||
return mDefaultApplicationIndex;
|
return mDefaultApplicationIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,7 @@ CheckStatistics::CheckStatistics(QObject *parent)
|
||||||
|
|
||||||
void CheckStatistics::AddItem(ShowTypes::ShowType type)
|
void CheckStatistics::AddItem(ShowTypes::ShowType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case ShowTypes::ShowStyle:
|
case ShowTypes::ShowStyle:
|
||||||
mStyle++;
|
mStyle++;
|
||||||
break;
|
break;
|
||||||
|
@ -68,8 +67,7 @@ void CheckStatistics::Clear()
|
||||||
unsigned CheckStatistics::GetCount(ShowTypes::ShowType type) const
|
unsigned CheckStatistics::GetCount(ShowTypes::ShowType type) const
|
||||||
{
|
{
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case ShowTypes::ShowStyle:
|
case ShowTypes::ShowStyle:
|
||||||
count = mStyle;
|
count = mStyle;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -29,8 +29,7 @@
|
||||||
/**
|
/**
|
||||||
* A class for check statistics.
|
* A class for check statistics.
|
||||||
*/
|
*/
|
||||||
class CheckStatistics : public QObject
|
class CheckStatistics : public QObject {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
CheckStatistics(QObject *parent = NULL);
|
CheckStatistics(QObject *parent = NULL);
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,7 @@ void CheckThread::run()
|
||||||
QString file;
|
QString file;
|
||||||
file = mResult.GetNextFile();
|
file = mResult.GetNextFile();
|
||||||
|
|
||||||
while (!file.isEmpty() && mState == Running)
|
while (!file.isEmpty() && mState == Running) {
|
||||||
{
|
|
||||||
qDebug() << "Checking file" << file;
|
qDebug() << "Checking file" << file;
|
||||||
mCppcheck.check(file.toStdString());
|
mCppcheck.check(file.toStdString());
|
||||||
emit FileChecked(file);
|
emit FileChecked(file);
|
||||||
|
|
|
@ -32,8 +32,7 @@
|
||||||
* @brief Thread to run cppcheck
|
* @brief Thread to run cppcheck
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CheckThread : public QThread
|
class CheckThread : public QThread {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CheckThread(ThreadResult &result);
|
CheckThread(ThreadResult &result);
|
||||||
|
@ -73,8 +72,7 @@ protected:
|
||||||
* has been completed. Thread must be stopped cleanly, just terminating thread
|
* has been completed. Thread must be stopped cleanly, just terminating thread
|
||||||
* likely causes unpredictable side-effects.
|
* likely causes unpredictable side-effects.
|
||||||
*/
|
*/
|
||||||
enum State
|
enum State {
|
||||||
{
|
|
||||||
Running, /**< The thread is checking. */
|
Running, /**< The thread is checking. */
|
||||||
Stopping, /**< The thread will stop after current work. */
|
Stopping, /**< The thread will stop after current work. */
|
||||||
Stopped, /**< The thread has been stopped. */
|
Stopped, /**< The thread has been stopped. */
|
||||||
|
|
|
@ -37,8 +37,7 @@ CsvReport::~CsvReport()
|
||||||
bool CsvReport::Create()
|
bool CsvReport::Create()
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (Report::Create())
|
if (Report::Create()) {
|
||||||
{
|
|
||||||
mTxtWriter.setDevice(Report::GetFile());
|
mTxtWriter.setDevice(Report::GetFile());
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,7 @@
|
||||||
* easy to import to many other programs.
|
* easy to import to many other programs.
|
||||||
* @todo This class should be inherited from TxtReport?
|
* @todo This class should be inherited from TxtReport?
|
||||||
*/
|
*/
|
||||||
class CsvReport : public Report
|
class CsvReport : public Report {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
CsvReport(const QString &filename, QObject * parent = 0);
|
CsvReport(const QString &filename, QObject * parent = 0);
|
||||||
virtual ~CsvReport();
|
virtual ~CsvReport();
|
||||||
|
|
|
@ -56,8 +56,7 @@ QString ErrorItem::ToString() const
|
||||||
str += GuiSeverity::toString(severity) +"\n";
|
str += GuiSeverity::toString(severity) +"\n";
|
||||||
str += summary + "\n";
|
str += summary + "\n";
|
||||||
str += message + "\n";
|
str += message + "\n";
|
||||||
for (int i = 0; i < files.size(); i++)
|
for (int i = 0; i < files.size(); i++) {
|
||||||
{
|
|
||||||
str += " " + files[i] + ": " + QString::number(lines[i]) + "\n";
|
str += " " + files[i] + ": " + QString::number(lines[i]) + "\n";
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
|
|
|
@ -35,13 +35,10 @@ class ErrorLine;
|
||||||
* GUI needs its own versions of conversions since GUI uses Qt's QString
|
* GUI needs its own versions of conversions since GUI uses Qt's QString
|
||||||
* instead of the std::string used by lib/cli.
|
* instead of the std::string used by lib/cli.
|
||||||
*/
|
*/
|
||||||
class GuiSeverity : Severity
|
class GuiSeverity : Severity {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static QString toString(SeverityType severity)
|
static QString toString(SeverityType severity) {
|
||||||
{
|
switch (severity) {
|
||||||
switch (severity)
|
|
||||||
{
|
|
||||||
case none:
|
case none:
|
||||||
return "";
|
return "";
|
||||||
case error:
|
case error:
|
||||||
|
@ -62,8 +59,7 @@ public:
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
|
|
||||||
static SeverityType fromString(const QString &severity)
|
static SeverityType fromString(const QString &severity) {
|
||||||
{
|
|
||||||
if (severity.isEmpty())
|
if (severity.isEmpty())
|
||||||
return none;
|
return none;
|
||||||
if (severity == "none")
|
if (severity == "none")
|
||||||
|
@ -94,8 +90,7 @@ public:
|
||||||
* Full path is stored instead of relative path for flexibility. It is easy
|
* Full path is stored instead of relative path for flexibility. It is easy
|
||||||
* to get the relative path from full path when needed.
|
* to get the relative path from full path when needed.
|
||||||
*/
|
*/
|
||||||
class ErrorItem
|
class ErrorItem {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ErrorItem();
|
ErrorItem();
|
||||||
ErrorItem(const ErrorItem &item);
|
ErrorItem(const ErrorItem &item);
|
||||||
|
@ -123,8 +118,7 @@ Q_DECLARE_METATYPE(ErrorItem);
|
||||||
/**
|
/**
|
||||||
* @brief A class containing error data for one shown error line.
|
* @brief A class containing error data for one shown error line.
|
||||||
*/
|
*/
|
||||||
class ErrorLine
|
class ErrorLine {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
QString file;
|
QString file;
|
||||||
unsigned int line;
|
unsigned int line;
|
||||||
|
|
|
@ -32,8 +32,7 @@ QStringList FileList::GetDefaultFilters()
|
||||||
|
|
||||||
bool FileList::FilterMatches(const QFileInfo &inf)
|
bool FileList::FilterMatches(const QFileInfo &inf)
|
||||||
{
|
{
|
||||||
if (inf.isFile())
|
if (inf.isFile()) {
|
||||||
{
|
|
||||||
const QStringList filters = FileList::GetDefaultFilters();
|
const QStringList filters = FileList::GetDefaultFilters();
|
||||||
QString ext("*.");
|
QString ext("*.");
|
||||||
ext += inf.suffix();
|
ext += inf.suffix();
|
||||||
|
@ -57,14 +56,11 @@ void FileList::AddDirectory(const QString &directory, bool recursive)
|
||||||
const QStringList filters = FileList::GetDefaultFilters();
|
const QStringList filters = FileList::GetDefaultFilters();
|
||||||
const QStringList origNameFilters = dir.nameFilters();
|
const QStringList origNameFilters = dir.nameFilters();
|
||||||
dir.setNameFilters(filters);
|
dir.setNameFilters(filters);
|
||||||
if (!recursive)
|
if (!recursive) {
|
||||||
{
|
|
||||||
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
||||||
QFileInfoList items = dir.entryInfoList();
|
QFileInfoList items = dir.entryInfoList();
|
||||||
mFileList += items;
|
mFileList += items;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
||||||
QFileInfoList items = dir.entryInfoList();
|
QFileInfoList items = dir.entryInfoList();
|
||||||
mFileList += items;
|
mFileList += items;
|
||||||
|
@ -73,8 +69,7 @@ void FileList::AddDirectory(const QString &directory, bool recursive)
|
||||||
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
|
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
QFileInfoList list = dir.entryInfoList();
|
QFileInfoList list = dir.entryInfoList();
|
||||||
QFileInfo item;
|
QFileInfo item;
|
||||||
foreach(item, list)
|
foreach(item, list) {
|
||||||
{
|
|
||||||
const QString path = item.canonicalFilePath();
|
const QString path = item.canonicalFilePath();
|
||||||
AddDirectory(path, recursive);
|
AddDirectory(path, recursive);
|
||||||
}
|
}
|
||||||
|
@ -84,8 +79,7 @@ void FileList::AddDirectory(const QString &directory, bool recursive)
|
||||||
void FileList::AddPathList(const QStringList &paths)
|
void FileList::AddPathList(const QStringList &paths)
|
||||||
{
|
{
|
||||||
QString path;
|
QString path;
|
||||||
foreach(path, paths)
|
foreach(path, paths) {
|
||||||
{
|
|
||||||
QFileInfo inf(path);
|
QFileInfo inf(path);
|
||||||
if (inf.isFile())
|
if (inf.isFile())
|
||||||
AddFile(path);
|
AddFile(path);
|
||||||
|
@ -96,18 +90,14 @@ void FileList::AddPathList(const QStringList &paths)
|
||||||
|
|
||||||
QStringList FileList::GetFileList() const
|
QStringList FileList::GetFileList() const
|
||||||
{
|
{
|
||||||
if (mExcludedPaths.empty())
|
if (mExcludedPaths.empty()) {
|
||||||
{
|
|
||||||
QStringList names;
|
QStringList names;
|
||||||
foreach(QFileInfo item, mFileList)
|
foreach(QFileInfo item, mFileList) {
|
||||||
{
|
|
||||||
QString name = QDir::fromNativeSeparators(item.canonicalFilePath());
|
QString name = QDir::fromNativeSeparators(item.canonicalFilePath());
|
||||||
names << name;
|
names << name;
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return ApplyExcludeList();
|
return ApplyExcludeList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,8 +110,7 @@ void FileList::AddExcludeList(const QStringList &paths)
|
||||||
QStringList FileList::ApplyExcludeList() const
|
QStringList FileList::ApplyExcludeList() const
|
||||||
{
|
{
|
||||||
QStringList paths;
|
QStringList paths;
|
||||||
foreach(QFileInfo item, mFileList)
|
foreach(QFileInfo item, mFileList) {
|
||||||
{
|
|
||||||
QString name = QDir::fromNativeSeparators(item.canonicalFilePath());
|
QString name = QDir::fromNativeSeparators(item.canonicalFilePath());
|
||||||
if (!Match(name))
|
if (!Match(name))
|
||||||
paths << name;
|
paths << name;
|
||||||
|
@ -131,16 +120,12 @@ QStringList FileList::ApplyExcludeList() const
|
||||||
|
|
||||||
bool FileList::Match(const QString &path) const
|
bool FileList::Match(const QString &path) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mExcludedPaths.size(); i++)
|
for (int i = 0; i < mExcludedPaths.size(); i++) {
|
||||||
{
|
if (mExcludedPaths[i].endsWith('/')) {
|
||||||
if (mExcludedPaths[i].endsWith('/'))
|
|
||||||
{
|
|
||||||
const QString pathexclude("/" + mExcludedPaths[i]);
|
const QString pathexclude("/" + mExcludedPaths[i]);
|
||||||
if (path.indexOf(pathexclude) != -1)
|
if (path.indexOf(pathexclude) != -1)
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (path.endsWith(mExcludedPaths[i]))
|
if (path.endsWith(mExcludedPaths[i]))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,7 @@
|
||||||
* there is ignore filters then only paths not matching those filters are
|
* there is ignore filters then only paths not matching those filters are
|
||||||
* returned.
|
* returned.
|
||||||
*/
|
*/
|
||||||
class FileList
|
class FileList {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -38,8 +38,7 @@ FileViewDialog::FileViewDialog(const QString &file,
|
||||||
void FileViewDialog::LoadTextFile(const QString &filename, QTextEdit *edit)
|
void FileViewDialog::LoadTextFile(const QString &filename, QTextEdit *edit)
|
||||||
{
|
{
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
if (!file.exists())
|
if (!file.exists()) {
|
||||||
{
|
|
||||||
QString msg(tr("Could not find the file: %1"));
|
QString msg(tr("Could not find the file: %1"));
|
||||||
msg = msg.arg(filename);
|
msg = msg.arg(filename);
|
||||||
|
|
||||||
|
@ -53,8 +52,7 @@ void FileViewDialog::LoadTextFile(const QString &filename, QTextEdit *edit)
|
||||||
}
|
}
|
||||||
|
|
||||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
if (!file.isReadable())
|
if (!file.isReadable()) {
|
||||||
{
|
|
||||||
QString msg(tr("Could not read the file: %1"));
|
QString msg(tr("Could not read the file: %1"));
|
||||||
msg = msg.arg(filename);
|
msg = msg.arg(filename);
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,7 @@ class QTextEdit;
|
||||||
* the authors list.
|
* the authors list.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class FileViewDialog : public QDialog
|
class FileViewDialog : public QDialog {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
FileViewDialog(const QString &file,
|
FileViewDialog(const QString &file,
|
||||||
|
|
|
@ -65,11 +65,9 @@ void LogView::SaveButtonClicked()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Log"),
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Log"),
|
||||||
"", tr("Text files (*.txt *.log);;All files (*.*)"));
|
"", tr("Text files (*.txt *.log);;All files (*.*)"));
|
||||||
if (!fileName.isEmpty())
|
if (!fileName.isEmpty()) {
|
||||||
{
|
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
{
|
|
||||||
QMessageBox::warning(this, tr("Cppcheck"),
|
QMessageBox::warning(this, tr("Cppcheck"),
|
||||||
tr("Could not open file for writing: \"%1\"").arg(fileName));
|
tr("Could not open file for writing: \"%1\"").arg(fileName));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -29,8 +29,7 @@
|
||||||
* @brief A tool window that shows checking log.
|
* @brief A tool window that shows checking log.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class LogView : public QWidget
|
class LogView : public QWidget {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
LogView(QWidget *parent = 0);
|
LogView(QWidget *parent = 0);
|
||||||
|
|
|
@ -58,8 +58,7 @@ int main(int argc, char *argv[])
|
||||||
// Rest of the arguments are handled in MainWindow::HandleCLIParams()
|
// Rest of the arguments are handled in MainWindow::HandleCLIParams()
|
||||||
bool CheckArgs(const QStringList &args)
|
bool CheckArgs(const QStringList &args)
|
||||||
{
|
{
|
||||||
if (args.contains("-h") || args.contains("--help"))
|
if (args.contains("-h") || args.contains("--help")) {
|
||||||
{
|
|
||||||
ShowUsage();
|
ShowUsage();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,13 +134,11 @@ MainWindow::MainWindow() :
|
||||||
QStringList args = QCoreApplication::arguments();
|
QStringList args = QCoreApplication::arguments();
|
||||||
//Remove the application itself
|
//Remove the application itself
|
||||||
args.removeFirst();
|
args.removeFirst();
|
||||||
if (!args.isEmpty())
|
if (!args.isEmpty()) {
|
||||||
{
|
|
||||||
HandleCLIParams(args);
|
HandleCLIParams(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MaxRecentProjects; ++i)
|
for (int i = 0; i < MaxRecentProjects; ++i) {
|
||||||
{
|
|
||||||
mRecentProjectActs[i] = new QAction(this);
|
mRecentProjectActs[i] = new QAction(this);
|
||||||
mRecentProjectActs[i]->setVisible(false);
|
mRecentProjectActs[i]->setVisible(false);
|
||||||
connect(mRecentProjectActs[i], SIGNAL(triggered()),
|
connect(mRecentProjectActs[i], SIGNAL(triggered()),
|
||||||
|
@ -151,8 +149,7 @@ MainWindow::MainWindow() :
|
||||||
UpdateMRUMenuItems();
|
UpdateMRUMenuItems();
|
||||||
|
|
||||||
QActionGroup* platformGroup = new QActionGroup(this);
|
QActionGroup* platformGroup = new QActionGroup(this);
|
||||||
for (int i = 0; i < mPlatforms.getCount(); i++)
|
for (int i = 0; i < mPlatforms.getCount(); i++) {
|
||||||
{
|
|
||||||
Platform plat = mPlatforms.mPlatforms[i];
|
Platform plat = mPlatforms.mPlatforms[i];
|
||||||
QAction *act = new QAction(this);
|
QAction *act = new QAction(this);
|
||||||
plat.mActMainWindow = act;
|
plat.mActMainWindow = act;
|
||||||
|
@ -185,28 +182,23 @@ MainWindow::~MainWindow()
|
||||||
|
|
||||||
void MainWindow::HandleCLIParams(const QStringList ¶ms)
|
void MainWindow::HandleCLIParams(const QStringList ¶ms)
|
||||||
{
|
{
|
||||||
if (params.contains("-p"))
|
if (params.contains("-p")) {
|
||||||
{
|
|
||||||
QString projFile;
|
QString projFile;
|
||||||
const int ind = params.indexOf("-p");
|
const int ind = params.indexOf("-p");
|
||||||
if ((ind + 1) < params.length())
|
if ((ind + 1) < params.length())
|
||||||
projFile = params[ind + 1];
|
projFile = params[ind + 1];
|
||||||
|
|
||||||
LoadProjectFile(projFile);
|
LoadProjectFile(projFile);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
DoCheckFiles(params);
|
DoCheckFiles(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::LoadSettings()
|
void MainWindow::LoadSettings()
|
||||||
{
|
{
|
||||||
// Window/dialog sizes
|
// Window/dialog sizes
|
||||||
if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool())
|
if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool()) {
|
||||||
{
|
|
||||||
showMaximized();
|
showMaximized();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
resize(mSettings->value(SETTINGS_WINDOW_WIDTH, 800).toInt(),
|
resize(mSettings->value(SETTINGS_WINDOW_WIDTH, 800).toInt(),
|
||||||
mSettings->value(SETTINGS_WINDOW_HEIGHT, 600).toInt());
|
mSettings->value(SETTINGS_WINDOW_HEIGHT, 600).toInt());
|
||||||
}
|
}
|
||||||
|
@ -235,8 +227,7 @@ void MainWindow::LoadSettings()
|
||||||
SetLanguage(mSettings->value(SETTINGS_LANGUAGE, mTranslation->SuggestLanguage()).toString());
|
SetLanguage(mSettings->value(SETTINGS_LANGUAGE, mTranslation->SuggestLanguage()).toString());
|
||||||
|
|
||||||
bool succeeded = mApplications->LoadSettings();
|
bool succeeded = mApplications->LoadSettings();
|
||||||
if (!succeeded)
|
if (!succeeded) {
|
||||||
{
|
|
||||||
const QString msg = tr("There was a problem with loading the editor application settings.\n\n"
|
const QString msg = tr("There was a problem with loading the editor application settings.\n\n"
|
||||||
"This is probably because the settings were changed between the Cppcheck versions. "
|
"This is probably because the settings were changed between the Cppcheck versions. "
|
||||||
"Please check (and fix) the editor application settings, otherwise the editor "
|
"Please check (and fix) the editor application settings, otherwise the editor "
|
||||||
|
@ -283,8 +274,7 @@ void MainWindow::SaveSettings()
|
||||||
|
|
||||||
void MainWindow::DoCheckFiles(const QStringList &files)
|
void MainWindow::DoCheckFiles(const QStringList &files)
|
||||||
{
|
{
|
||||||
if (files.isEmpty())
|
if (files.isEmpty()) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ClearResults();
|
ClearResults();
|
||||||
|
@ -298,8 +288,7 @@ void MainWindow::DoCheckFiles(const QStringList &files)
|
||||||
mUI.mResults->Clear();
|
mUI.mResults->Clear();
|
||||||
mThread->ClearFiles();
|
mThread->ClearFiles();
|
||||||
|
|
||||||
if (fileNames.isEmpty())
|
if (fileNames.isEmpty()) {
|
||||||
{
|
|
||||||
QMessageBox msg(QMessageBox::Warning,
|
QMessageBox msg(QMessageBox::Warning,
|
||||||
tr("Cppcheck"),
|
tr("Cppcheck"),
|
||||||
tr("No suitable files found to check!"),
|
tr("No suitable files found to check!"),
|
||||||
|
@ -329,8 +318,7 @@ void MainWindow::DoCheckFiles(const QStringList &files)
|
||||||
|
|
||||||
QStringList MainWindow::SelectFilesToCheck(QFileDialog::FileMode mode)
|
QStringList MainWindow::SelectFilesToCheck(QFileDialog::FileMode mode)
|
||||||
{
|
{
|
||||||
if (mProject)
|
if (mProject) {
|
||||||
{
|
|
||||||
QMessageBox msgBox(this);
|
QMessageBox msgBox(this);
|
||||||
msgBox.setWindowTitle(tr("Cppcheck"));
|
msgBox.setWindowTitle(tr("Cppcheck"));
|
||||||
const QString msg(tr("You must close the project file before selecting new files or directories!"));
|
const QString msg(tr("You must close the project file before selecting new files or directories!"));
|
||||||
|
@ -345,27 +333,22 @@ QStringList MainWindow::SelectFilesToCheck(QFileDialog::FileMode mode)
|
||||||
// NOTE: we use QFileDialog::getOpenFileNames() and
|
// NOTE: we use QFileDialog::getOpenFileNames() and
|
||||||
// QFileDialog::getExistingDirectory() because they show native Windows
|
// QFileDialog::getExistingDirectory() because they show native Windows
|
||||||
// selection dialog which is a lot more usable than QT:s own dialog.
|
// selection dialog which is a lot more usable than QT:s own dialog.
|
||||||
if (mode == QFileDialog::ExistingFiles)
|
if (mode == QFileDialog::ExistingFiles) {
|
||||||
{
|
|
||||||
selected = QFileDialog::getOpenFileNames(this,
|
selected = QFileDialog::getOpenFileNames(this,
|
||||||
tr("Select files to check"),
|
tr("Select files to check"),
|
||||||
mSettings->value(SETTINGS_CHECK_PATH, "").toString());
|
mSettings->value(SETTINGS_CHECK_PATH, "").toString());
|
||||||
if (selected.isEmpty())
|
if (selected.isEmpty())
|
||||||
mCurrentDirectory.clear();
|
mCurrentDirectory.clear();
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
QFileInfo inf(selected[0]);
|
QFileInfo inf(selected[0]);
|
||||||
mCurrentDirectory = inf.absolutePath();
|
mCurrentDirectory = inf.absolutePath();
|
||||||
}
|
}
|
||||||
FormatAndSetTitle();
|
FormatAndSetTitle();
|
||||||
}
|
} else if (mode == QFileDialog::DirectoryOnly) {
|
||||||
else if (mode == QFileDialog::DirectoryOnly)
|
|
||||||
{
|
|
||||||
QString dir = QFileDialog::getExistingDirectory(this,
|
QString dir = QFileDialog::getExistingDirectory(this,
|
||||||
tr("Select directory to check"),
|
tr("Select directory to check"),
|
||||||
mSettings->value(SETTINGS_CHECK_PATH, "").toString());
|
mSettings->value(SETTINGS_CHECK_PATH, "").toString());
|
||||||
if (!dir.isEmpty())
|
if (!dir.isEmpty()) {
|
||||||
{
|
|
||||||
qDebug() << "Setting current directory to: " << dir;
|
qDebug() << "Setting current directory to: " << dir;
|
||||||
mCurrentDirectory = dir;
|
mCurrentDirectory = dir;
|
||||||
selected.append(dir);
|
selected.append(dir);
|
||||||
|
@ -394,10 +377,8 @@ void MainWindow::CheckDirectory()
|
||||||
checkDir.setFilter(QDir::Files | QDir::Readable);
|
checkDir.setFilter(QDir::Files | QDir::Readable);
|
||||||
checkDir.setNameFilters(filters);
|
checkDir.setNameFilters(filters);
|
||||||
QStringList projFiles = checkDir.entryList();
|
QStringList projFiles = checkDir.entryList();
|
||||||
if (!projFiles.empty())
|
if (!projFiles.empty()) {
|
||||||
{
|
if (projFiles.size() == 1) {
|
||||||
if (projFiles.size() == 1)
|
|
||||||
{
|
|
||||||
// If one project file found, suggest loading it
|
// If one project file found, suggest loading it
|
||||||
QMessageBox msgBox(this);
|
QMessageBox msgBox(this);
|
||||||
msgBox.setWindowTitle(tr("Cppcheck"));
|
msgBox.setWindowTitle(tr("Cppcheck"));
|
||||||
|
@ -409,21 +390,16 @@ void MainWindow::CheckDirectory()
|
||||||
msgBox.addButton(QMessageBox::No);
|
msgBox.addButton(QMessageBox::No);
|
||||||
msgBox.setDefaultButton(QMessageBox::Yes);
|
msgBox.setDefaultButton(QMessageBox::Yes);
|
||||||
int dlgResult = msgBox.exec();
|
int dlgResult = msgBox.exec();
|
||||||
if (dlgResult == QMessageBox::Yes)
|
if (dlgResult == QMessageBox::Yes) {
|
||||||
{
|
|
||||||
QString path = checkDir.canonicalPath();
|
QString path = checkDir.canonicalPath();
|
||||||
if (!path.endsWith("/"))
|
if (!path.endsWith("/"))
|
||||||
path += "/";
|
path += "/";
|
||||||
path += projFiles[0];
|
path += projFiles[0];
|
||||||
LoadProjectFile(path);
|
LoadProjectFile(path);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
DoCheckFiles(dir);
|
DoCheckFiles(dir);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// If multiple project files found inform that there are project
|
// If multiple project files found inform that there are project
|
||||||
// files also available.
|
// files also available.
|
||||||
QMessageBox msgBox(this);
|
QMessageBox msgBox(this);
|
||||||
|
@ -437,14 +413,11 @@ void MainWindow::CheckDirectory()
|
||||||
msgBox.addButton(QMessageBox::No);
|
msgBox.addButton(QMessageBox::No);
|
||||||
msgBox.setDefaultButton(QMessageBox::Yes);
|
msgBox.setDefaultButton(QMessageBox::Yes);
|
||||||
int dlgResult = msgBox.exec();
|
int dlgResult = msgBox.exec();
|
||||||
if (dlgResult == QMessageBox::Yes)
|
if (dlgResult == QMessageBox::Yes) {
|
||||||
{
|
|
||||||
DoCheckFiles(dir);
|
DoCheckFiles(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
DoCheckFiles(dir);
|
DoCheckFiles(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,8 +425,7 @@ void MainWindow::CheckDirectory()
|
||||||
void MainWindow::AddIncludeDirs(const QStringList &includeDirs, Settings &result)
|
void MainWindow::AddIncludeDirs(const QStringList &includeDirs, Settings &result)
|
||||||
{
|
{
|
||||||
QString dir;
|
QString dir;
|
||||||
foreach(dir, includeDirs)
|
foreach(dir, includeDirs) {
|
||||||
{
|
|
||||||
QString incdir;
|
QString incdir;
|
||||||
if (!QDir::isAbsolutePath(dir))
|
if (!QDir::isAbsolutePath(dir))
|
||||||
incdir = mCurrentDirectory + "/";
|
incdir = mCurrentDirectory + "/";
|
||||||
|
@ -472,16 +444,14 @@ Settings MainWindow::GetCppcheckSettings()
|
||||||
Settings result;
|
Settings result;
|
||||||
|
|
||||||
// If project file loaded, read settings from it
|
// If project file loaded, read settings from it
|
||||||
if (mProject)
|
if (mProject) {
|
||||||
{
|
|
||||||
ProjectFile *pfile = mProject->GetProjectFile();
|
ProjectFile *pfile = mProject->GetProjectFile();
|
||||||
QStringList dirs = pfile->GetIncludeDirs();
|
QStringList dirs = pfile->GetIncludeDirs();
|
||||||
AddIncludeDirs(dirs, result);
|
AddIncludeDirs(dirs, result);
|
||||||
|
|
||||||
QStringList defines = pfile->GetDefines();
|
QStringList defines = pfile->GetDefines();
|
||||||
QString define;
|
QString define;
|
||||||
foreach(define, defines)
|
foreach(define, defines) {
|
||||||
{
|
|
||||||
if (!result.userDefines.empty())
|
if (!result.userDefines.empty())
|
||||||
result.userDefines += ";";
|
result.userDefines += ";";
|
||||||
result.userDefines += define.toStdString();
|
result.userDefines += define.toStdString();
|
||||||
|
@ -492,8 +462,7 @@ Settings MainWindow::GetCppcheckSettings()
|
||||||
// Global include directories must be added AFTER the per project include
|
// Global include directories must be added AFTER the per project include
|
||||||
// directories so per project include directories can override global ones.
|
// directories so per project include directories can override global ones.
|
||||||
const QString globalIncludes = mSettings->value(SETTINGS_GLOBAL_INCLUDE_PATHS).toString();
|
const QString globalIncludes = mSettings->value(SETTINGS_GLOBAL_INCLUDE_PATHS).toString();
|
||||||
if (!globalIncludes.isEmpty())
|
if (!globalIncludes.isEmpty()) {
|
||||||
{
|
|
||||||
QStringList includes = globalIncludes.split(";");
|
QStringList includes = globalIncludes.split(";");
|
||||||
AddIncludeDirs(includes, result);
|
AddIncludeDirs(includes, result);
|
||||||
}
|
}
|
||||||
|
@ -514,8 +483,7 @@ Settings MainWindow::GetCppcheckSettings()
|
||||||
result.inconclusive = mSettings->value(SETTINGS_INCONCLUSIVE_ERRORS, false).toBool();
|
result.inconclusive = mSettings->value(SETTINGS_INCONCLUSIVE_ERRORS, false).toBool();
|
||||||
result.platformType = (Settings::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt();
|
result.platformType = (Settings::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt();
|
||||||
|
|
||||||
if (result._jobs <= 0)
|
if (result._jobs <= 0) {
|
||||||
{
|
|
||||||
result._jobs = 1;
|
result._jobs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,8 +492,7 @@ Settings MainWindow::GetCppcheckSettings()
|
||||||
|
|
||||||
void MainWindow::CheckDone()
|
void MainWindow::CheckDone()
|
||||||
{
|
{
|
||||||
if (mExiting)
|
if (mExiting) {
|
||||||
{
|
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -537,8 +504,7 @@ void MainWindow::CheckDone()
|
||||||
EnableProjectActions(true);
|
EnableProjectActions(true);
|
||||||
EnableProjectOpenActions(true);
|
EnableProjectOpenActions(true);
|
||||||
|
|
||||||
if (mUI.mResults->HasResults())
|
if (mUI.mResults->HasResults()) {
|
||||||
{
|
|
||||||
mUI.mActionClearResults->setEnabled(true);
|
mUI.mActionClearResults->setEnabled(true);
|
||||||
mUI.mActionSave->setEnabled(true);
|
mUI.mActionSave->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -559,8 +525,7 @@ void MainWindow::CheckLockDownUI()
|
||||||
void MainWindow::ProgramSettings()
|
void MainWindow::ProgramSettings()
|
||||||
{
|
{
|
||||||
SettingsDialog dialog(mApplications, mTranslation, this);
|
SettingsDialog dialog(mApplications, mTranslation, this);
|
||||||
if (dialog.exec() == QDialog::Accepted)
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
{
|
|
||||||
dialog.SaveSettingValues();
|
dialog.SaveSettingValues();
|
||||||
mUI.mResults->UpdateSettings(dialog.ShowFullPath(),
|
mUI.mResults->UpdateSettings(dialog.ShowFullPath(),
|
||||||
dialog.SaveFullPath(),
|
dialog.SaveFullPath(),
|
||||||
|
@ -603,8 +568,7 @@ void MainWindow::OpenXML()
|
||||||
filter,
|
filter,
|
||||||
&selectedFilter);
|
&selectedFilter);
|
||||||
|
|
||||||
if (!selectedFile.isEmpty())
|
if (!selectedFile.isEmpty()) {
|
||||||
{
|
|
||||||
mUI.mResults->ReadErrorsXml(selectedFile);
|
mUI.mResults->ReadErrorsXml(selectedFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -663,13 +627,10 @@ void MainWindow::UncheckAll()
|
||||||
void MainWindow::closeEvent(QCloseEvent *event)
|
void MainWindow::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
// Check that we aren't checking files
|
// Check that we aren't checking files
|
||||||
if (!mThread->IsChecking())
|
if (!mThread->IsChecking()) {
|
||||||
{
|
|
||||||
SaveSettings();
|
SaveSettings();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
const QString text(tr("Checking is running.\n\n" \
|
const QString text(tr("Checking is running.\n\n" \
|
||||||
"Do you want to stop the checking and exit Cppcheck?."));
|
"Do you want to stop the checking and exit Cppcheck?."));
|
||||||
|
|
||||||
|
@ -681,8 +642,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||||
|
|
||||||
msg.setDefaultButton(QMessageBox::No);
|
msg.setDefaultButton(QMessageBox::No);
|
||||||
int rv = msg.exec();
|
int rv = msg.exec();
|
||||||
if (rv == QMessageBox::Yes)
|
if (rv == QMessageBox::Yes) {
|
||||||
{
|
|
||||||
// This isn't really very clean way to close threads but since the app is
|
// This isn't really very clean way to close threads but since the app is
|
||||||
// exiting it doesn't matter.
|
// exiting it doesn't matter.
|
||||||
mThread->Stop();
|
mThread->Stop();
|
||||||
|
@ -739,35 +699,25 @@ void MainWindow::Save()
|
||||||
filter,
|
filter,
|
||||||
&selectedFilter);
|
&selectedFilter);
|
||||||
|
|
||||||
if (!selectedFile.isEmpty())
|
if (!selectedFile.isEmpty()) {
|
||||||
{
|
|
||||||
Report::Type type = Report::TXT;
|
Report::Type type = Report::TXT;
|
||||||
if (selectedFilter == tr("XML files version 1 (*.xml)"))
|
if (selectedFilter == tr("XML files version 1 (*.xml)")) {
|
||||||
{
|
|
||||||
type = Report::XML;
|
type = Report::XML;
|
||||||
if (!selectedFile.endsWith(".xml", Qt::CaseInsensitive))
|
if (!selectedFile.endsWith(".xml", Qt::CaseInsensitive))
|
||||||
selectedFile += ".xml";
|
selectedFile += ".xml";
|
||||||
}
|
} else if (selectedFilter == tr("XML files version 2 (*.xml)")) {
|
||||||
else if (selectedFilter == tr("XML files version 2 (*.xml)"))
|
|
||||||
{
|
|
||||||
type = Report::XMLV2;
|
type = Report::XMLV2;
|
||||||
if (!selectedFile.endsWith(".xml", Qt::CaseInsensitive))
|
if (!selectedFile.endsWith(".xml", Qt::CaseInsensitive))
|
||||||
selectedFile += ".xml";
|
selectedFile += ".xml";
|
||||||
}
|
} else if (selectedFilter == tr("Text files (*.txt)")) {
|
||||||
else if (selectedFilter == tr("Text files (*.txt)"))
|
|
||||||
{
|
|
||||||
type = Report::TXT;
|
type = Report::TXT;
|
||||||
if (!selectedFile.endsWith(".txt", Qt::CaseInsensitive))
|
if (!selectedFile.endsWith(".txt", Qt::CaseInsensitive))
|
||||||
selectedFile += ".txt";
|
selectedFile += ".txt";
|
||||||
}
|
} else if (selectedFilter == tr("CSV files (*.csv)")) {
|
||||||
else if (selectedFilter == tr("CSV files (*.csv)"))
|
|
||||||
{
|
|
||||||
type = Report::CSV;
|
type = Report::CSV;
|
||||||
if (!selectedFile.endsWith(".csv", Qt::CaseInsensitive))
|
if (!selectedFile.endsWith(".csv", Qt::CaseInsensitive))
|
||||||
selectedFile += ".csv";
|
selectedFile += ".csv";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (selectedFile.endsWith(".xml", Qt::CaseInsensitive))
|
if (selectedFile.endsWith(".xml", Qt::CaseInsensitive))
|
||||||
type = Report::XML;
|
type = Report::XML;
|
||||||
else if (selectedFile.endsWith(".txt", Qt::CaseInsensitive))
|
else if (selectedFile.endsWith(".txt", Qt::CaseInsensitive))
|
||||||
|
@ -817,8 +767,7 @@ void MainWindow::SetLanguage(const QString &code)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
if (!mTranslation->SetLanguage(code, error))
|
if (!mTranslation->SetLanguage(code, error)) {
|
||||||
{
|
|
||||||
const QString msg(tr("Failed to change the user interface language:"
|
const QString msg(tr("Failed to change the user interface language:"
|
||||||
"\n\n%1\n\n"
|
"\n\n%1\n\n"
|
||||||
"The user interface language has been reset to English. Open "
|
"The user interface language has been reset to English. Open "
|
||||||
|
@ -830,9 +779,7 @@ void MainWindow::SetLanguage(const QString &code)
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
this);
|
this);
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//Translate everything that is visible here
|
//Translate everything that is visible here
|
||||||
mUI.retranslateUi(this);
|
mUI.retranslateUi(this);
|
||||||
mUI.mResults->Translate();
|
mUI.mResults->Translate();
|
||||||
|
@ -870,8 +817,7 @@ void MainWindow::OpenProjectFile()
|
||||||
QString(),
|
QString(),
|
||||||
filter);
|
filter);
|
||||||
|
|
||||||
if (!filepath.isEmpty())
|
if (!filepath.isEmpty()) {
|
||||||
{
|
|
||||||
LoadProjectFile(filepath);
|
LoadProjectFile(filepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -911,16 +857,13 @@ void MainWindow::CheckProject(Project *project)
|
||||||
// file's location, see above). This is to keep the compatibility with
|
// file's location, see above). This is to keep the compatibility with
|
||||||
// old "silent" project file loading when we checked the director where the
|
// old "silent" project file loading when we checked the director where the
|
||||||
// project file was located.
|
// project file was located.
|
||||||
if (paths.isEmpty())
|
if (paths.isEmpty()) {
|
||||||
{
|
|
||||||
paths << mCurrentDirectory;
|
paths << mCurrentDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert relative paths to absolute paths
|
// Convert relative paths to absolute paths
|
||||||
for (int i = 0; i < paths.size(); i++)
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
{
|
if (!QDir::isAbsolutePath(paths[i])) {
|
||||||
if (!QDir::isAbsolutePath(paths[i]))
|
|
||||||
{
|
|
||||||
QString path = mCurrentDirectory + "/";
|
QString path = mCurrentDirectory + "/";
|
||||||
path += paths[i];
|
path += paths[i];
|
||||||
paths[i] = QDir::cleanPath(path);
|
paths[i] = QDir::cleanPath(path);
|
||||||
|
@ -937,8 +880,7 @@ void MainWindow::NewProjectFile()
|
||||||
QString(),
|
QString(),
|
||||||
filter);
|
filter);
|
||||||
|
|
||||||
if (!filepath.isEmpty())
|
if (!filepath.isEmpty()) {
|
||||||
{
|
|
||||||
EnableProjectActions(true);
|
EnableProjectActions(true);
|
||||||
QFileInfo inf(filepath);
|
QFileInfo inf(filepath);
|
||||||
const QString filename = inf.fileName();
|
const QString filename = inf.fileName();
|
||||||
|
@ -964,8 +906,7 @@ void MainWindow::CloseProjectFile()
|
||||||
|
|
||||||
void MainWindow::EditProjectFile()
|
void MainWindow::EditProjectFile()
|
||||||
{
|
{
|
||||||
if (!mProject)
|
if (!mProject) {
|
||||||
{
|
|
||||||
QMessageBox msg(QMessageBox::Critical,
|
QMessageBox msg(QMessageBox::Critical,
|
||||||
tr("Cppcheck"),
|
tr("Cppcheck"),
|
||||||
QString(tr("No project file loaded")),
|
QString(tr("No project file loaded")),
|
||||||
|
@ -992,8 +933,7 @@ void MainWindow::ShowStatistics()
|
||||||
StatsDialog statsDialog(this);
|
StatsDialog statsDialog(this);
|
||||||
|
|
||||||
// Show a dialog with the previous scan statistics and project information
|
// Show a dialog with the previous scan statistics and project information
|
||||||
if (mProject)
|
if (mProject) {
|
||||||
{
|
|
||||||
statsDialog.setProject(*mProject);
|
statsDialog.setProject(*mProject);
|
||||||
}
|
}
|
||||||
statsDialog.setPathSelected(mCurrentDirectory);
|
statsDialog.setPathSelected(mCurrentDirectory);
|
||||||
|
@ -1006,16 +946,14 @@ void MainWindow::ShowStatistics()
|
||||||
|
|
||||||
void MainWindow::Log(const QString &logline)
|
void MainWindow::Log(const QString &logline)
|
||||||
{
|
{
|
||||||
if (mLogView)
|
if (mLogView) {
|
||||||
{
|
|
||||||
mLogView->AppendLine(logline);
|
mLogView->AppendLine(logline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::DebugError(const ErrorItem &item)
|
void MainWindow::DebugError(const ErrorItem &item)
|
||||||
{
|
{
|
||||||
if (mLogView)
|
if (mLogView) {
|
||||||
{
|
|
||||||
mLogView->AppendLine(item.ToString());
|
mLogView->AppendLine(item.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1040,16 +978,12 @@ void MainWindow::EnableProjectOpenActions(bool enable)
|
||||||
void MainWindow::OpenRecentProject()
|
void MainWindow::OpenRecentProject()
|
||||||
{
|
{
|
||||||
QAction *action = qobject_cast<QAction *>(sender());
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
if (action)
|
if (action) {
|
||||||
{
|
|
||||||
const QString project = action->data().toString();
|
const QString project = action->data().toString();
|
||||||
QFileInfo inf(project);
|
QFileInfo inf(project);
|
||||||
if (inf.exists())
|
if (inf.exists()) {
|
||||||
{
|
|
||||||
LoadProjectFile(project);
|
LoadProjectFile(project);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
const QString text(tr("The project file\n\n%1\n\n could not be found!\n\n"
|
const QString text(tr("The project file\n\n%1\n\n could not be found!\n\n"
|
||||||
"Do you want to remove the file from the recently "
|
"Do you want to remove the file from the recently "
|
||||||
"used projects -list?").arg(project));
|
"used projects -list?").arg(project));
|
||||||
|
@ -1062,8 +996,7 @@ void MainWindow::OpenRecentProject()
|
||||||
|
|
||||||
msg.setDefaultButton(QMessageBox::No);
|
msg.setDefaultButton(QMessageBox::No);
|
||||||
int rv = msg.exec();
|
int rv = msg.exec();
|
||||||
if (rv == QMessageBox::Yes)
|
if (rv == QMessageBox::Yes) {
|
||||||
{
|
|
||||||
RemoveProjectMRU(project);
|
RemoveProjectMRU(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1073,16 +1006,14 @@ void MainWindow::OpenRecentProject()
|
||||||
|
|
||||||
void MainWindow::UpdateMRUMenuItems()
|
void MainWindow::UpdateMRUMenuItems()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MaxRecentProjects + 1; i++)
|
for (int i = 0; i < MaxRecentProjects + 1; i++) {
|
||||||
{
|
|
||||||
if (mRecentProjectActs[i] != NULL)
|
if (mRecentProjectActs[i] != NULL)
|
||||||
mUI.mMenuFile->removeAction(mRecentProjectActs[i]);
|
mUI.mMenuFile->removeAction(mRecentProjectActs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList projects = mSettings->value(SETTINGS_MRU_PROJECTS).toStringList();
|
QStringList projects = mSettings->value(SETTINGS_MRU_PROJECTS).toStringList();
|
||||||
const int numRecentProjects = qMin(projects.size(), (int)MaxRecentProjects);
|
const int numRecentProjects = qMin(projects.size(), (int)MaxRecentProjects);
|
||||||
for (int i = 0; i < numRecentProjects; i++)
|
for (int i = 0; i < numRecentProjects; i++) {
|
||||||
{
|
|
||||||
const QString filename = QFileInfo(projects[i]).fileName();
|
const QString filename = QFileInfo(projects[i]).fileName();
|
||||||
const QString text = QString("&%1 %2").arg(i + 1).arg(filename);
|
const QString text = QString("&%1 %2").arg(i + 1).arg(filename);
|
||||||
mRecentProjectActs[i]->setText(text);
|
mRecentProjectActs[i]->setText(text);
|
||||||
|
@ -1119,8 +1050,7 @@ void MainWindow::RemoveProjectMRU(const QString &project)
|
||||||
void MainWindow::SelectPlatform()
|
void MainWindow::SelectPlatform()
|
||||||
{
|
{
|
||||||
QAction *action = qobject_cast<QAction *>(sender());
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
if (action)
|
if (action) {
|
||||||
{
|
|
||||||
const Settings::PlatformType platform = (Settings::PlatformType) action->data().toInt();
|
const Settings::PlatformType platform = (Settings::PlatformType) action->data().toInt();
|
||||||
mSettings->setValue(SETTINGS_CHECKED_PLATFORM, platform);
|
mSettings->setValue(SETTINGS_CHECKED_PLATFORM, platform);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,7 @@ class QAction;
|
||||||
* @brief Main window for cppcheck-gui
|
* @brief Main window for cppcheck-gui
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -50,10 +50,8 @@ int Platforms::getCount() const
|
||||||
Platform& Platforms::get(Settings::PlatformType platform)
|
Platform& Platforms::get(Settings::PlatformType platform)
|
||||||
{
|
{
|
||||||
QList<Platform>::iterator iter = mPlatforms.begin();
|
QList<Platform>::iterator iter = mPlatforms.begin();
|
||||||
while (iter != mPlatforms.end())
|
while (iter != mPlatforms.end()) {
|
||||||
{
|
if ((*iter).mType == platform) {
|
||||||
if ((*iter).mType == platform)
|
|
||||||
{
|
|
||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
++iter;
|
++iter;
|
||||||
|
|
|
@ -31,8 +31,7 @@
|
||||||
/**
|
/**
|
||||||
* @brief Checked platform GUI-data.
|
* @brief Checked platform GUI-data.
|
||||||
*/
|
*/
|
||||||
struct Platform
|
struct Platform {
|
||||||
{
|
|
||||||
QString mTitle; /**< Text visible in the GUI. */
|
QString mTitle; /**< Text visible in the GUI. */
|
||||||
Settings::PlatformType mType; /**< Type in the core. */
|
Settings::PlatformType mType; /**< Type in the core. */
|
||||||
QAction *mActMainWindow; /**< Pointer to main window action item. */
|
QAction *mActMainWindow; /**< Pointer to main window action item. */
|
||||||
|
@ -41,8 +40,7 @@ struct Platform
|
||||||
/**
|
/**
|
||||||
* @brief List of checked platforms.
|
* @brief List of checked platforms.
|
||||||
*/
|
*/
|
||||||
class Platforms : public QObject
|
class Platforms : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -65,10 +65,8 @@ bool Project::IsOpen() const
|
||||||
bool Project::Open()
|
bool Project::Open()
|
||||||
{
|
{
|
||||||
mPFile = new ProjectFile(mFilename, this);
|
mPFile = new ProjectFile(mFilename, this);
|
||||||
if (QFile::exists(mFilename))
|
if (QFile::exists(mFilename)) {
|
||||||
{
|
if (!mPFile->Read()) {
|
||||||
if (!mPFile->Read())
|
|
||||||
{
|
|
||||||
QMessageBox msg(QMessageBox::Critical,
|
QMessageBox msg(QMessageBox::Critical,
|
||||||
tr("Cppcheck"),
|
tr("Cppcheck"),
|
||||||
tr("Could not read the project file."),
|
tr("Could not read the project file."),
|
||||||
|
@ -99,8 +97,7 @@ void Project::Edit()
|
||||||
dlg.SetExcludedPaths(ignorepaths);
|
dlg.SetExcludedPaths(ignorepaths);
|
||||||
|
|
||||||
int rv = dlg.exec();
|
int rv = dlg.exec();
|
||||||
if (rv == QDialog::Accepted)
|
if (rv == QDialog::Accepted) {
|
||||||
{
|
|
||||||
QString root = dlg.GetRootPath();
|
QString root = dlg.GetRootPath();
|
||||||
mPFile->SetRootPath(root);
|
mPFile->SetRootPath(root);
|
||||||
QStringList includes = dlg.GetIncludePaths();
|
QStringList includes = dlg.GetIncludePaths();
|
||||||
|
@ -113,8 +110,7 @@ void Project::Edit()
|
||||||
mPFile->SetExcludedPaths(excludedpaths);
|
mPFile->SetExcludedPaths(excludedpaths);
|
||||||
|
|
||||||
bool writeSuccess = mPFile->Write();
|
bool writeSuccess = mPFile->Write();
|
||||||
if (!writeSuccess)
|
if (!writeSuccess) {
|
||||||
{
|
|
||||||
QMessageBox msg(QMessageBox::Critical,
|
QMessageBox msg(QMessageBox::Critical,
|
||||||
tr("Cppcheck"),
|
tr("Cppcheck"),
|
||||||
tr("Could not write the project file."),
|
tr("Could not write the project file."),
|
||||||
|
|
|
@ -32,8 +32,7 @@ class ProjectFile;
|
||||||
* @brief A class that contains project data and manages projects.
|
* @brief A class that contains project data and manages projects.
|
||||||
* Currently only project file creation and editing is implemented.
|
* Currently only project file creation and editing is implemented.
|
||||||
*/
|
*/
|
||||||
class Project : public QObject
|
class Project : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -79,8 +78,7 @@ public:
|
||||||
* @brief Return current project file.
|
* @brief Return current project file.
|
||||||
* @return project file.
|
* @return project file.
|
||||||
*/
|
*/
|
||||||
ProjectFile * GetProjectFile() const
|
ProjectFile * GetProjectFile() const {
|
||||||
{
|
|
||||||
return mPFile;
|
return mPFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,13 +68,10 @@ bool ProjectFile::Read(const QString &filename)
|
||||||
QXmlStreamReader xmlReader(&file);
|
QXmlStreamReader xmlReader(&file);
|
||||||
bool insideProject = false;
|
bool insideProject = false;
|
||||||
bool projectTagFound = false;
|
bool projectTagFound = false;
|
||||||
while (!xmlReader.atEnd())
|
while (!xmlReader.atEnd()) {
|
||||||
{
|
switch (xmlReader.readNext()) {
|
||||||
switch (xmlReader.readNext())
|
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
if (xmlReader.name() == ProjectElementName)
|
if (xmlReader.name() == ProjectElementName) {
|
||||||
{
|
|
||||||
insideProject = true;
|
insideProject = true;
|
||||||
projectTagFound = true;
|
projectTagFound = true;
|
||||||
}
|
}
|
||||||
|
@ -134,8 +131,7 @@ bool ProjectFile::Read(const QString &filename)
|
||||||
QStringList ProjectFile::GetIncludeDirs() const
|
QStringList ProjectFile::GetIncludeDirs() const
|
||||||
{
|
{
|
||||||
QStringList dirs;
|
QStringList dirs;
|
||||||
foreach(QString path, mIncludeDirs)
|
foreach(QString path, mIncludeDirs) {
|
||||||
{
|
|
||||||
dirs << QDir::fromNativeSeparators(path);
|
dirs << QDir::fromNativeSeparators(path);
|
||||||
}
|
}
|
||||||
return dirs;
|
return dirs;
|
||||||
|
@ -149,8 +145,7 @@ QStringList ProjectFile::GetDefines() const
|
||||||
QStringList ProjectFile::GetCheckPaths() const
|
QStringList ProjectFile::GetCheckPaths() const
|
||||||
{
|
{
|
||||||
QStringList paths;
|
QStringList paths;
|
||||||
foreach(QString path, mPaths)
|
foreach(QString path, mPaths) {
|
||||||
{
|
|
||||||
paths << QDir::fromNativeSeparators(path);
|
paths << QDir::fromNativeSeparators(path);
|
||||||
}
|
}
|
||||||
return paths;
|
return paths;
|
||||||
|
@ -159,8 +154,7 @@ QStringList ProjectFile::GetCheckPaths() const
|
||||||
QStringList ProjectFile::GetExcludedPaths() const
|
QStringList ProjectFile::GetExcludedPaths() const
|
||||||
{
|
{
|
||||||
QStringList paths;
|
QStringList paths;
|
||||||
foreach(QString path, mExcludedPaths)
|
foreach(QString path, mExcludedPaths) {
|
||||||
{
|
|
||||||
paths << QDir::fromNativeSeparators(path);
|
paths << QDir::fromNativeSeparators(path);
|
||||||
}
|
}
|
||||||
return paths;
|
return paths;
|
||||||
|
@ -178,16 +172,13 @@ void ProjectFile::ReadIncludeDirs(QXmlStreamReader &reader)
|
||||||
{
|
{
|
||||||
QXmlStreamReader::TokenType type;
|
QXmlStreamReader::TokenType type;
|
||||||
bool allRead = false;
|
bool allRead = false;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
type = reader.readNext();
|
type = reader.readNext();
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
|
|
||||||
// Read dir-elements
|
// Read dir-elements
|
||||||
if (reader.name().toString() == DirElementName)
|
if (reader.name().toString() == DirElementName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = reader.attributes();
|
QXmlStreamAttributes attribs = reader.attributes();
|
||||||
QString name = attribs.value("", DirNameAttrib).toString();
|
QString name = attribs.value("", DirNameAttrib).toString();
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
|
@ -212,23 +203,19 @@ void ProjectFile::ReadIncludeDirs(QXmlStreamReader &reader)
|
||||||
case QXmlStreamReader::ProcessingInstruction:
|
case QXmlStreamReader::ProcessingInstruction:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (!allRead);
|
||||||
while (!allRead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFile::ReadDefines(QXmlStreamReader &reader)
|
void ProjectFile::ReadDefines(QXmlStreamReader &reader)
|
||||||
{
|
{
|
||||||
QXmlStreamReader::TokenType type;
|
QXmlStreamReader::TokenType type;
|
||||||
bool allRead = false;
|
bool allRead = false;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
type = reader.readNext();
|
type = reader.readNext();
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
// Read define-elements
|
// Read define-elements
|
||||||
if (reader.name().toString() == DefineName)
|
if (reader.name().toString() == DefineName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = reader.attributes();
|
QXmlStreamAttributes attribs = reader.attributes();
|
||||||
QString name = attribs.value("", DefineNameAttrib).toString();
|
QString name = attribs.value("", DefineNameAttrib).toString();
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
|
@ -253,24 +240,20 @@ void ProjectFile::ReadDefines(QXmlStreamReader &reader)
|
||||||
case QXmlStreamReader::ProcessingInstruction:
|
case QXmlStreamReader::ProcessingInstruction:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (!allRead);
|
||||||
while (!allRead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFile::ReadCheckPaths(QXmlStreamReader &reader)
|
void ProjectFile::ReadCheckPaths(QXmlStreamReader &reader)
|
||||||
{
|
{
|
||||||
QXmlStreamReader::TokenType type;
|
QXmlStreamReader::TokenType type;
|
||||||
bool allRead = false;
|
bool allRead = false;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
type = reader.readNext();
|
type = reader.readNext();
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
|
|
||||||
// Read dir-elements
|
// Read dir-elements
|
||||||
if (reader.name().toString() == PathName)
|
if (reader.name().toString() == PathName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = reader.attributes();
|
QXmlStreamAttributes attribs = reader.attributes();
|
||||||
QString name = attribs.value("", PathNameAttrib).toString();
|
QString name = attribs.value("", PathNameAttrib).toString();
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
|
@ -295,31 +278,26 @@ void ProjectFile::ReadCheckPaths(QXmlStreamReader &reader)
|
||||||
case QXmlStreamReader::ProcessingInstruction:
|
case QXmlStreamReader::ProcessingInstruction:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (!allRead);
|
||||||
while (!allRead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFile::ReadExcludes(QXmlStreamReader &reader)
|
void ProjectFile::ReadExcludes(QXmlStreamReader &reader)
|
||||||
{
|
{
|
||||||
QXmlStreamReader::TokenType type;
|
QXmlStreamReader::TokenType type;
|
||||||
bool allRead = false;
|
bool allRead = false;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
type = reader.readNext();
|
type = reader.readNext();
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
// Read exclude-elements
|
// Read exclude-elements
|
||||||
if (reader.name().toString() == ExcludePathName)
|
if (reader.name().toString() == ExcludePathName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = reader.attributes();
|
QXmlStreamAttributes attribs = reader.attributes();
|
||||||
QString name = attribs.value("", ExcludePathNameAttrib).toString();
|
QString name = attribs.value("", ExcludePathNameAttrib).toString();
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
mExcludedPaths << name;
|
mExcludedPaths << name;
|
||||||
}
|
}
|
||||||
// Read ignore-elements - deprecated but support reading them
|
// Read ignore-elements - deprecated but support reading them
|
||||||
else if (reader.name().toString() == IgnorePathName)
|
else if (reader.name().toString() == IgnorePathName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = reader.attributes();
|
QXmlStreamAttributes attribs = reader.attributes();
|
||||||
QString name = attribs.value("", IgnorePathNameAttrib).toString();
|
QString name = attribs.value("", IgnorePathNameAttrib).toString();
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
|
@ -346,8 +324,7 @@ void ProjectFile::ReadExcludes(QXmlStreamReader &reader)
|
||||||
case QXmlStreamReader::ProcessingInstruction:
|
case QXmlStreamReader::ProcessingInstruction:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (!allRead);
|
||||||
while (!allRead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFile::SetIncludes(const QStringList &includes)
|
void ProjectFile::SetIncludes(const QStringList &includes)
|
||||||
|
@ -385,18 +362,15 @@ bool ProjectFile::Write(const QString &filename)
|
||||||
xmlWriter.writeStartElement(ProjectElementName);
|
xmlWriter.writeStartElement(ProjectElementName);
|
||||||
xmlWriter.writeAttribute(ProjectVersionAttrib, ProjectFileVersion);
|
xmlWriter.writeAttribute(ProjectVersionAttrib, ProjectFileVersion);
|
||||||
|
|
||||||
if (!mRootPath.isEmpty())
|
if (!mRootPath.isEmpty()) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(RootPathName);
|
xmlWriter.writeStartElement(RootPathName);
|
||||||
xmlWriter.writeAttribute(RootPathNameAttrib, mRootPath);
|
xmlWriter.writeAttribute(RootPathNameAttrib, mRootPath);
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mIncludeDirs.isEmpty())
|
if (!mIncludeDirs.isEmpty()) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(IncludDirElementName);
|
xmlWriter.writeStartElement(IncludDirElementName);
|
||||||
foreach(QString incdir, mIncludeDirs)
|
foreach(QString incdir, mIncludeDirs) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(DirElementName);
|
xmlWriter.writeStartElement(DirElementName);
|
||||||
xmlWriter.writeAttribute(DirNameAttrib, incdir);
|
xmlWriter.writeAttribute(DirNameAttrib, incdir);
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
|
@ -404,11 +378,9 @@ bool ProjectFile::Write(const QString &filename)
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mDefines.isEmpty())
|
if (!mDefines.isEmpty()) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(DefinesElementName);
|
xmlWriter.writeStartElement(DefinesElementName);
|
||||||
foreach(QString define, mDefines)
|
foreach(QString define, mDefines) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(DefineName);
|
xmlWriter.writeStartElement(DefineName);
|
||||||
xmlWriter.writeAttribute(DefineNameAttrib, define);
|
xmlWriter.writeAttribute(DefineNameAttrib, define);
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
|
@ -416,11 +388,9 @@ bool ProjectFile::Write(const QString &filename)
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mPaths.isEmpty())
|
if (!mPaths.isEmpty()) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(PathsElementName);
|
xmlWriter.writeStartElement(PathsElementName);
|
||||||
foreach(QString path, mPaths)
|
foreach(QString path, mPaths) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(PathName);
|
xmlWriter.writeStartElement(PathName);
|
||||||
xmlWriter.writeAttribute(PathNameAttrib, path);
|
xmlWriter.writeAttribute(PathNameAttrib, path);
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
|
@ -428,11 +398,9 @@ bool ProjectFile::Write(const QString &filename)
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mExcludedPaths.isEmpty())
|
if (!mExcludedPaths.isEmpty()) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(ExcludeElementName);
|
xmlWriter.writeStartElement(ExcludeElementName);
|
||||||
foreach(QString path, mExcludedPaths)
|
foreach(QString path, mExcludedPaths) {
|
||||||
{
|
|
||||||
xmlWriter.writeStartElement(ExcludePathName);
|
xmlWriter.writeStartElement(ExcludePathName);
|
||||||
xmlWriter.writeAttribute(ExcludePathNameAttrib, path);
|
xmlWriter.writeAttribute(ExcludePathNameAttrib, path);
|
||||||
xmlWriter.writeEndElement();
|
xmlWriter.writeEndElement();
|
||||||
|
|
|
@ -33,8 +33,7 @@
|
||||||
* The project files contain project-specific settings for checking. For
|
* The project files contain project-specific settings for checking. For
|
||||||
* example a list of include paths.
|
* example a list of include paths.
|
||||||
*/
|
*/
|
||||||
class ProjectFile : public QObject
|
class ProjectFile : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -51,8 +50,7 @@ public:
|
||||||
* @brief Get project root path.
|
* @brief Get project root path.
|
||||||
* @return project root path.
|
* @return project root path.
|
||||||
*/
|
*/
|
||||||
QString GetRootPath() const
|
QString GetRootPath() const {
|
||||||
{
|
|
||||||
return mRootPath;
|
return mRootPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +82,7 @@ public:
|
||||||
* @brief Get filename for the project file.
|
* @brief Get filename for the project file.
|
||||||
* @return file name.
|
* @return file name.
|
||||||
*/
|
*/
|
||||||
QString GetFilename()
|
QString GetFilename() {
|
||||||
{
|
|
||||||
return mFilename;
|
return mFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +90,7 @@ public:
|
||||||
* @brief Set project root path.
|
* @brief Set project root path.
|
||||||
* @param rootpath new project root path.
|
* @param rootpath new project root path.
|
||||||
*/
|
*/
|
||||||
void SetRootPath(const QString &rootpath)
|
void SetRootPath(const QString &rootpath) {
|
||||||
{
|
|
||||||
mRootPath = rootpath;
|
mRootPath = rootpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +128,7 @@ public:
|
||||||
* @brief Set filename for the project file.
|
* @brief Set filename for the project file.
|
||||||
* @param filename Filename to use.
|
* @param filename Filename to use.
|
||||||
*/
|
*/
|
||||||
void SetFilename(const QString &filename)
|
void SetFilename(const QString &filename) {
|
||||||
{
|
|
||||||
mFilename = filename;
|
mFilename = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,7 @@ QStringList ProjectFileDialog::GetIncludePaths() const
|
||||||
{
|
{
|
||||||
const int count = mUI.mListIncludeDirs->count();
|
const int count = mUI.mListIncludeDirs->count();
|
||||||
QStringList includePaths;
|
QStringList includePaths;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
QListWidgetItem *item = mUI.mListIncludeDirs->item(i);
|
QListWidgetItem *item = mUI.mListIncludeDirs->item(i);
|
||||||
includePaths << QDir::fromNativeSeparators(item->text());
|
includePaths << QDir::fromNativeSeparators(item->text());
|
||||||
}
|
}
|
||||||
|
@ -130,8 +129,7 @@ QStringList ProjectFileDialog::GetDefines() const
|
||||||
{
|
{
|
||||||
QString define = mUI.mEditDefines->text();
|
QString define = mUI.mEditDefines->text();
|
||||||
QStringList defines;
|
QStringList defines;
|
||||||
if (!define.isEmpty())
|
if (!define.isEmpty()) {
|
||||||
{
|
|
||||||
define = define.trimmed();
|
define = define.trimmed();
|
||||||
if (define.indexOf(';') != -1)
|
if (define.indexOf(';') != -1)
|
||||||
defines = define.split(";");
|
defines = define.split(";");
|
||||||
|
@ -145,8 +143,7 @@ QStringList ProjectFileDialog::GetPaths() const
|
||||||
{
|
{
|
||||||
const int count = mUI.mListPaths->count();
|
const int count = mUI.mListPaths->count();
|
||||||
QStringList paths;
|
QStringList paths;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
QListWidgetItem *item = mUI.mListPaths->item(i);
|
QListWidgetItem *item = mUI.mListPaths->item(i);
|
||||||
paths << QDir::fromNativeSeparators(item->text());
|
paths << QDir::fromNativeSeparators(item->text());
|
||||||
}
|
}
|
||||||
|
@ -157,8 +154,7 @@ QStringList ProjectFileDialog::GetExcludedPaths() const
|
||||||
{
|
{
|
||||||
const int count = mUI.mListExcludedPaths->count();
|
const int count = mUI.mListExcludedPaths->count();
|
||||||
QStringList paths;
|
QStringList paths;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
QListWidgetItem *item = mUI.mListExcludedPaths->item(i);
|
QListWidgetItem *item = mUI.mListExcludedPaths->item(i);
|
||||||
paths << QDir::fromNativeSeparators(item->text());
|
paths << QDir::fromNativeSeparators(item->text());
|
||||||
}
|
}
|
||||||
|
@ -173,8 +169,7 @@ void ProjectFileDialog::SetRootPath(const QString &root)
|
||||||
|
|
||||||
void ProjectFileDialog::SetIncludepaths(const QStringList &includes)
|
void ProjectFileDialog::SetIncludepaths(const QStringList &includes)
|
||||||
{
|
{
|
||||||
foreach(QString dir, includes)
|
foreach(QString dir, includes) {
|
||||||
{
|
|
||||||
AddIncludeDir(dir);
|
AddIncludeDir(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,8 +178,7 @@ void ProjectFileDialog::SetDefines(const QStringList &defines)
|
||||||
{
|
{
|
||||||
QString definestr;
|
QString definestr;
|
||||||
QString define;
|
QString define;
|
||||||
foreach(define, defines)
|
foreach(define, defines) {
|
||||||
{
|
|
||||||
definestr += define;
|
definestr += define;
|
||||||
definestr += ";";
|
definestr += ";";
|
||||||
}
|
}
|
||||||
|
@ -196,16 +190,14 @@ void ProjectFileDialog::SetDefines(const QStringList &defines)
|
||||||
|
|
||||||
void ProjectFileDialog::SetPaths(const QStringList &paths)
|
void ProjectFileDialog::SetPaths(const QStringList &paths)
|
||||||
{
|
{
|
||||||
foreach(QString path, paths)
|
foreach(QString path, paths) {
|
||||||
{
|
|
||||||
AddPath(path);
|
AddPath(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFileDialog::SetExcludedPaths(const QStringList &paths)
|
void ProjectFileDialog::SetExcludedPaths(const QStringList &paths)
|
||||||
{
|
{
|
||||||
foreach(QString path, paths)
|
foreach(QString path, paths) {
|
||||||
{
|
|
||||||
AddExcludePath(path);
|
AddExcludePath(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,8 +210,7 @@ void ProjectFileDialog::AddIncludeDir()
|
||||||
tr("Select include directory"),
|
tr("Select include directory"),
|
||||||
rootpath);
|
rootpath);
|
||||||
|
|
||||||
if (!selectedDir.isEmpty())
|
if (!selectedDir.isEmpty()) {
|
||||||
{
|
|
||||||
AddIncludeDir(selectedDir);
|
AddIncludeDir(selectedDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,8 +223,7 @@ void ProjectFileDialog::AddPath()
|
||||||
tr("Select a directory to check"),
|
tr("Select a directory to check"),
|
||||||
rootpath);
|
rootpath);
|
||||||
|
|
||||||
if (!selectedDir.isEmpty())
|
if (!selectedDir.isEmpty()) {
|
||||||
{
|
|
||||||
AddPath(selectedDir);
|
AddPath(selectedDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,8 +263,7 @@ void ProjectFileDialog::AddExcludePath()
|
||||||
tr("Select directory to ignore"),
|
tr("Select directory to ignore"),
|
||||||
rootpath);
|
rootpath);
|
||||||
|
|
||||||
if (!selectedDir.isEmpty())
|
if (!selectedDir.isEmpty()) {
|
||||||
{
|
|
||||||
if (!selectedDir.endsWith('/'))
|
if (!selectedDir.endsWith('/'))
|
||||||
selectedDir += '/';
|
selectedDir += '/';
|
||||||
AddExcludePath(selectedDir);
|
AddExcludePath(selectedDir);
|
||||||
|
|
|
@ -36,8 +36,7 @@ class QLineEdit;
|
||||||
/**
|
/**
|
||||||
* @brief A dialog for editing project file data.
|
* @brief A dialog for editing project file data.
|
||||||
*/
|
*/
|
||||||
class ProjectFileDialog : public QDialog
|
class ProjectFileDialog : public QDialog {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ProjectFileDialog(const QString &path, QWidget *parent = 0);
|
ProjectFileDialog(const QString &path, QWidget *parent = 0);
|
||||||
|
|
|
@ -36,8 +36,7 @@ Report::~Report()
|
||||||
bool Report::Create()
|
bool Report::Create()
|
||||||
{
|
{
|
||||||
bool succeed = false;
|
bool succeed = false;
|
||||||
if (!mFile.isOpen())
|
if (!mFile.isOpen()) {
|
||||||
{
|
|
||||||
mFile.setFileName(mFilename);
|
mFile.setFileName(mFilename);
|
||||||
succeed = mFile.open(QIODevice::WriteOnly | QIODevice::Text);
|
succeed = mFile.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
}
|
}
|
||||||
|
@ -47,8 +46,7 @@ bool Report::Create()
|
||||||
bool Report::Open()
|
bool Report::Open()
|
||||||
{
|
{
|
||||||
bool succeed = false;
|
bool succeed = false;
|
||||||
if (!mFile.isOpen())
|
if (!mFile.isOpen()) {
|
||||||
{
|
|
||||||
mFile.setFileName(mFilename);
|
mFile.setFileName(mFilename);
|
||||||
succeed = mFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
succeed = mFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,10 @@
|
||||||
/**
|
/**
|
||||||
* @brief A base class for reports.
|
* @brief A base class for reports.
|
||||||
*/
|
*/
|
||||||
class Report : public QObject
|
class Report : public QObject {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Type
|
enum Type {
|
||||||
{
|
|
||||||
TXT,
|
TXT,
|
||||||
XML,
|
XML,
|
||||||
XMLV2,
|
XMLV2,
|
||||||
|
|
|
@ -96,15 +96,13 @@ QStandardItem *ResultsTree::CreateLineNumberItem(const QString &linenumber)
|
||||||
|
|
||||||
void ResultsTree::AddErrorItem(const ErrorItem &item)
|
void ResultsTree::AddErrorItem(const ErrorItem &item)
|
||||||
{
|
{
|
||||||
if (item.files.isEmpty())
|
if (item.files.isEmpty()) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString realfile = StripPath(item.files[0], false);
|
QString realfile = StripPath(item.files[0], false);
|
||||||
|
|
||||||
if (realfile.isEmpty())
|
if (realfile.isEmpty()) {
|
||||||
{
|
|
||||||
realfile = tr("Undefined file");
|
realfile = tr("Undefined file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,20 +110,17 @@ void ResultsTree::AddErrorItem(const ErrorItem &item)
|
||||||
//bool hide = !mShowTypes[SeverityToShowType(item.severity)];
|
//bool hide = !mShowTypes[SeverityToShowType(item.severity)];
|
||||||
|
|
||||||
//If specified, filter on summary, message, filename, and id
|
//If specified, filter on summary, message, filename, and id
|
||||||
if (!hide && !mFilter.isEmpty())
|
if (!hide && !mFilter.isEmpty()) {
|
||||||
{
|
|
||||||
if (!item.summary.contains(mFilter, Qt::CaseInsensitive) &&
|
if (!item.summary.contains(mFilter, Qt::CaseInsensitive) &&
|
||||||
!item.message.contains(mFilter, Qt::CaseInsensitive) &&
|
!item.message.contains(mFilter, Qt::CaseInsensitive) &&
|
||||||
!item.file.contains(mFilter, Qt::CaseInsensitive) &&
|
!item.file.contains(mFilter, Qt::CaseInsensitive) &&
|
||||||
!item.errorId.contains(mFilter, Qt::CaseInsensitive))
|
!item.errorId.contains(mFilter, Qt::CaseInsensitive)) {
|
||||||
{
|
|
||||||
hide = true;
|
hide = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if there is at least one error that is not hidden, we have a visible error
|
//if there is at least one error that is not hidden, we have a visible error
|
||||||
if (!hide)
|
if (!hide) {
|
||||||
{
|
|
||||||
mVisibleErrors = true;
|
mVisibleErrors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,8 +155,7 @@ void ResultsTree::AddErrorItem(const ErrorItem &item)
|
||||||
stditem->setData(QVariant(data));
|
stditem->setData(QVariant(data));
|
||||||
|
|
||||||
//Add backtrace files as children
|
//Add backtrace files as children
|
||||||
for (int i = 1; i < item.files.size(); i++)
|
for (int i = 1; i < item.files.size(); i++) {
|
||||||
{
|
|
||||||
line.file = StripPath(item.files[i], false);
|
line.file = StripPath(item.files[i], false);
|
||||||
line.line = item.lines[i];
|
line.line = item.lines[i];
|
||||||
QStandardItem *child_item;
|
QStandardItem *child_item;
|
||||||
|
@ -184,8 +178,7 @@ void ResultsTree::AddErrorItem(const ErrorItem &item)
|
||||||
|
|
||||||
//TODO just hide/show current error and it's file
|
//TODO just hide/show current error and it's file
|
||||||
//since this does a lot of unnecessary work
|
//since this does a lot of unnecessary work
|
||||||
if (!hide)
|
if (!hide) {
|
||||||
{
|
|
||||||
ShowFileItem(realfile);
|
ShowFileItem(realfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,8 +189,7 @@ QStandardItem *ResultsTree::AddBacktraceFiles(QStandardItem *parent,
|
||||||
const QString &icon)
|
const QString &icon)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!parent)
|
if (!parent) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,8 +203,7 @@ QStandardItem *ResultsTree::AddBacktraceFiles(QStandardItem *parent,
|
||||||
//TODO message has parameter names so we'll need changes to the core
|
//TODO message has parameter names so we'll need changes to the core
|
||||||
//cppcheck so we can get proper translations
|
//cppcheck so we can get proper translations
|
||||||
QString summary;
|
QString summary;
|
||||||
if (item.inconclusive)
|
if (item.inconclusive) {
|
||||||
{
|
|
||||||
summary = tr("[Inconclusive]");
|
summary = tr("[Inconclusive]");
|
||||||
summary += " ";
|
summary += " ";
|
||||||
}
|
}
|
||||||
|
@ -220,22 +211,18 @@ QStandardItem *ResultsTree::AddBacktraceFiles(QStandardItem *parent,
|
||||||
list << CreateNormalItem(summary);
|
list << CreateNormalItem(summary);
|
||||||
|
|
||||||
// Check for duplicate rows and don't add them if found
|
// Check for duplicate rows and don't add them if found
|
||||||
for (int i = 0; i < parent->rowCount(); i++)
|
for (int i = 0; i < parent->rowCount(); i++) {
|
||||||
{
|
|
||||||
// The first column is the file name and is always the same so
|
// The first column is the file name and is always the same so
|
||||||
// we skip it in other platforms than Windows, where filename case
|
// we skip it in other platforms than Windows, where filename case
|
||||||
// is ignored. So in Windows we can get filenames "header.h" and
|
// is ignored. So in Windows we can get filenames "header.h" and
|
||||||
// "Header.h" and must compare them as identical filenames.
|
// "Header.h" and must compare them as identical filenames.
|
||||||
|
|
||||||
// the third column is the line number so check it first
|
// the third column is the line number so check it first
|
||||||
if (parent->child(i, 2)->text() == list[2]->text())
|
if (parent->child(i, 2)->text() == list[2]->text()) {
|
||||||
{
|
|
||||||
// the second column is the severity so check it next
|
// the second column is the severity so check it next
|
||||||
if (parent->child(i, 1)->text() == list[1]->text())
|
if (parent->child(i, 1)->text() == list[1]->text()) {
|
||||||
{
|
|
||||||
// the fourth column is the summary so check it last
|
// the fourth column is the summary so check it last
|
||||||
if (parent->child(i, 3)->text() == list[3]->text())
|
if (parent->child(i, 3)->text() == list[3]->text()) {
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
const QString first = parent->child(i, 0)->text().toLower();
|
const QString first = parent->child(i, 0)->text().toLower();
|
||||||
const QString second = list[0]->text().toLower();
|
const QString second = list[0]->text().toLower();
|
||||||
|
@ -254,8 +241,7 @@ QStandardItem *ResultsTree::AddBacktraceFiles(QStandardItem *parent,
|
||||||
|
|
||||||
setRowHidden(parent->rowCount() - 1, parent->index(), hide);
|
setRowHidden(parent->rowCount() - 1, parent->index(), hide);
|
||||||
|
|
||||||
if (!icon.isEmpty())
|
if (!icon.isEmpty()) {
|
||||||
{
|
|
||||||
list[0]->setIcon(QIcon(icon));
|
list[0]->setIcon(QIcon(icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,8 +252,7 @@ QStandardItem *ResultsTree::AddBacktraceFiles(QStandardItem *parent,
|
||||||
|
|
||||||
QString ResultsTree::SeverityToTranslatedString(Severity::SeverityType severity)
|
QString ResultsTree::SeverityToTranslatedString(Severity::SeverityType severity)
|
||||||
{
|
{
|
||||||
switch (severity)
|
switch (severity) {
|
||||||
{
|
|
||||||
case Severity::style:
|
case Severity::style:
|
||||||
return tr("style");
|
return tr("style");
|
||||||
break;
|
break;
|
||||||
|
@ -307,8 +292,7 @@ QString ResultsTree::SeverityToTranslatedString(Severity::SeverityType severity)
|
||||||
QStandardItem *ResultsTree::FindFileItem(const QString &name)
|
QStandardItem *ResultsTree::FindFileItem(const QString &name)
|
||||||
{
|
{
|
||||||
QList<QStandardItem *> list = mModel.findItems(name);
|
QList<QStandardItem *> list = mModel.findItems(name);
|
||||||
if (list.size() > 0)
|
if (list.size() > 0) {
|
||||||
{
|
|
||||||
return list[0];
|
return list[0];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -321,8 +305,7 @@ void ResultsTree::Clear()
|
||||||
|
|
||||||
void ResultsTree::LoadSettings()
|
void ResultsTree::LoadSettings()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mModel.columnCount(); i++)
|
for (int i = 0; i < mModel.columnCount(); i++) {
|
||||||
{
|
|
||||||
//mFileTree.columnWidth(i);
|
//mFileTree.columnWidth(i);
|
||||||
QString temp = QString(SETTINGS_RESULT_COLUMN_WIDTH).arg(i);
|
QString temp = QString(SETTINGS_RESULT_COLUMN_WIDTH).arg(i);
|
||||||
setColumnWidth(i, mSettings->value(temp, 800 / mModel.columnCount()).toInt());
|
setColumnWidth(i, mSettings->value(temp, 800 / mModel.columnCount()).toInt());
|
||||||
|
@ -335,8 +318,7 @@ void ResultsTree::LoadSettings()
|
||||||
|
|
||||||
void ResultsTree::SaveSettings()
|
void ResultsTree::SaveSettings()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mModel.columnCount(); i++)
|
for (int i = 0; i < mModel.columnCount(); i++) {
|
||||||
{
|
|
||||||
QString temp = QString(SETTINGS_RESULT_COLUMN_WIDTH).arg(i);
|
QString temp = QString(SETTINGS_RESULT_COLUMN_WIDTH).arg(i);
|
||||||
mSettings->setValue(temp, columnWidth(i));
|
mSettings->setValue(temp, columnWidth(i));
|
||||||
}
|
}
|
||||||
|
@ -344,8 +326,7 @@ void ResultsTree::SaveSettings()
|
||||||
|
|
||||||
void ResultsTree::ShowResults(ShowTypes::ShowType type, bool show)
|
void ResultsTree::ShowResults(ShowTypes::ShowType type, bool show)
|
||||||
{
|
{
|
||||||
if (type != ShowTypes::ShowNone && mShowSeverities.isShown(type) != show)
|
if (type != ShowTypes::ShowNone && mShowSeverities.isShown(type) != show) {
|
||||||
{
|
|
||||||
mShowSeverities.show(type, show);
|
mShowSeverities.show(type, show);
|
||||||
RefreshTree();
|
RefreshTree();
|
||||||
}
|
}
|
||||||
|
@ -361,8 +342,7 @@ void ResultsTree::ShowHiddenResults()
|
||||||
{
|
{
|
||||||
//Clear the "hide" flag for each item
|
//Clear the "hide" flag for each item
|
||||||
int filecount = mModel.rowCount();
|
int filecount = mModel.rowCount();
|
||||||
for (int i = 0; i < filecount; i++)
|
for (int i = 0; i < filecount; i++) {
|
||||||
{
|
|
||||||
QStandardItem *file = mModel.item(i, 0);
|
QStandardItem *file = mModel.item(i, 0);
|
||||||
if (!file)
|
if (!file)
|
||||||
continue;
|
continue;
|
||||||
|
@ -372,11 +352,9 @@ void ResultsTree::ShowHiddenResults()
|
||||||
file->setData(QVariant(data));
|
file->setData(QVariant(data));
|
||||||
|
|
||||||
int errorcount = file->rowCount();
|
int errorcount = file->rowCount();
|
||||||
for (int j = 0; j < errorcount; j++)
|
for (int j = 0; j < errorcount; j++) {
|
||||||
{
|
|
||||||
QStandardItem *child = file->child(j, 0);
|
QStandardItem *child = file->child(j, 0);
|
||||||
if (child)
|
if (child) {
|
||||||
{
|
|
||||||
data = child->data().toMap();
|
data = child->data().toMap();
|
||||||
data["hide"] = false;
|
data["hide"] = false;
|
||||||
child->setData(QVariant(data));
|
child->setData(QVariant(data));
|
||||||
|
@ -394,12 +372,10 @@ void ResultsTree::RefreshTree()
|
||||||
//Get the amount of files in the tree
|
//Get the amount of files in the tree
|
||||||
int filecount = mModel.rowCount();
|
int filecount = mModel.rowCount();
|
||||||
|
|
||||||
for (int i = 0; i < filecount; i++)
|
for (int i = 0; i < filecount; i++) {
|
||||||
{
|
|
||||||
//Get file i
|
//Get file i
|
||||||
QStandardItem *file = mModel.item(i, 0);
|
QStandardItem *file = mModel.item(i, 0);
|
||||||
if (!file)
|
if (!file) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,12 +385,10 @@ void ResultsTree::RefreshTree()
|
||||||
//By default it shouldn't be visible
|
//By default it shouldn't be visible
|
||||||
bool show = false;
|
bool show = false;
|
||||||
|
|
||||||
for (int j = 0; j < errorcount; j++)
|
for (int j = 0; j < errorcount; j++) {
|
||||||
{
|
|
||||||
//Get the error itself
|
//Get the error itself
|
||||||
QStandardItem *child = file->child(j, 0);
|
QStandardItem *child = file->child(j, 0);
|
||||||
if (!child)
|
if (!child) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,19 +401,16 @@ void ResultsTree::RefreshTree()
|
||||||
bool hide = (data["hide"].toBool() || !mShowSeverities.isShown(ShowTypes::VariantToShowType(data["severity"])));
|
bool hide = (data["hide"].toBool() || !mShowSeverities.isShown(ShowTypes::VariantToShowType(data["severity"])));
|
||||||
|
|
||||||
//If specified, filter on summary, message, filename, and id
|
//If specified, filter on summary, message, filename, and id
|
||||||
if (!hide && !mFilter.isEmpty())
|
if (!hide && !mFilter.isEmpty()) {
|
||||||
{
|
|
||||||
if (!data["summary"].toString().contains(mFilter, Qt::CaseInsensitive) &&
|
if (!data["summary"].toString().contains(mFilter, Qt::CaseInsensitive) &&
|
||||||
!data["message"].toString().contains(mFilter, Qt::CaseInsensitive) &&
|
!data["message"].toString().contains(mFilter, Qt::CaseInsensitive) &&
|
||||||
!data["file"].toString().contains(mFilter, Qt::CaseInsensitive) &&
|
!data["file"].toString().contains(mFilter, Qt::CaseInsensitive) &&
|
||||||
!data["id"].toString().contains(mFilter, Qt::CaseInsensitive))
|
!data["id"].toString().contains(mFilter, Qt::CaseInsensitive)) {
|
||||||
{
|
|
||||||
hide = true;
|
hide = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hide)
|
if (!hide) {
|
||||||
{
|
|
||||||
mVisibleErrors = true;
|
mVisibleErrors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,15 +418,13 @@ void ResultsTree::RefreshTree()
|
||||||
setRowHidden(j, file->index(), hide);
|
setRowHidden(j, file->index(), hide);
|
||||||
|
|
||||||
//If it was shown then the file itself has to be shown as well
|
//If it was shown then the file itself has to be shown as well
|
||||||
if (!hide)
|
if (!hide) {
|
||||||
{
|
|
||||||
show = true;
|
show = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Hide the file if its "hide" attribute is set
|
//Hide the file if its "hide" attribute is set
|
||||||
if (file->data().toMap()["hide"].toBool())
|
if (file->data().toMap()["hide"].toBool()) {
|
||||||
{
|
|
||||||
show = false;
|
show = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,8 +440,7 @@ QStandardItem *ResultsTree::EnsureFileItem(const QString &fullpath, bool hide)
|
||||||
// native separators to find it.
|
// native separators to find it.
|
||||||
QStandardItem *item = FindFileItem(QDir::toNativeSeparators(name));
|
QStandardItem *item = FindFileItem(QDir::toNativeSeparators(name));
|
||||||
|
|
||||||
if (item)
|
if (item) {
|
||||||
{
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,8 +463,7 @@ QStandardItem *ResultsTree::EnsureFileItem(const QString &fullpath, bool hide)
|
||||||
void ResultsTree::ShowFileItem(const QString &name)
|
void ResultsTree::ShowFileItem(const QString &name)
|
||||||
{
|
{
|
||||||
QStandardItem *item = FindFileItem(name);
|
QStandardItem *item = FindFileItem(name);
|
||||||
if (item)
|
if (item) {
|
||||||
{
|
|
||||||
setRowHidden(0, mModel.indexFromItem(item), false);
|
setRowHidden(0, mModel.indexFromItem(item), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -504,8 +471,7 @@ void ResultsTree::ShowFileItem(const QString &name)
|
||||||
void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
{
|
{
|
||||||
QModelIndex index = indexAt(e->pos());
|
QModelIndex index = indexAt(e->pos());
|
||||||
if (index.isValid())
|
if (index.isValid()) {
|
||||||
{
|
|
||||||
bool multipleSelection = false;
|
bool multipleSelection = false;
|
||||||
mSelectionModel = selectionModel();
|
mSelectionModel = selectionModel();
|
||||||
if (mSelectionModel->selectedRows().count() > 1)
|
if (mSelectionModel->selectedRows().count() > 1)
|
||||||
|
@ -523,11 +489,9 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
//member variables
|
//member variables
|
||||||
QSignalMapper *signalMapper = new QSignalMapper(this);
|
QSignalMapper *signalMapper = new QSignalMapper(this);
|
||||||
|
|
||||||
if (mContextItem && mApplications->GetApplicationCount() > 0 && mContextItem->parent())
|
if (mContextItem && mApplications->GetApplicationCount() > 0 && mContextItem->parent()) {
|
||||||
{
|
|
||||||
//Go through all applications and add them to the context menu
|
//Go through all applications and add them to the context menu
|
||||||
for (int i = 0; i < mApplications->GetApplicationCount(); i++)
|
for (int i = 0; i < mApplications->GetApplicationCount(); i++) {
|
||||||
{
|
|
||||||
//Create an action for the application
|
//Create an action for the application
|
||||||
const Application app = mApplications->GetApplication(i);
|
const Application app = mApplications->GetApplication(i);
|
||||||
QAction *start = new QAction(app.getName(), &menu);
|
QAction *start = new QAction(app.getName(), &menu);
|
||||||
|
@ -552,10 +516,8 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add menuitems to copy full path/filename to clipboard
|
// Add menuitems to copy full path/filename to clipboard
|
||||||
if (mContextItem)
|
if (mContextItem) {
|
||||||
{
|
if (mApplications->GetApplicationCount() > 0) {
|
||||||
if (mApplications->GetApplicationCount() > 0)
|
|
||||||
{
|
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,8 +527,7 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
QAction *copymessage = new QAction(tr("Copy message"), &menu);
|
QAction *copymessage = new QAction(tr("Copy message"), &menu);
|
||||||
QAction *hide = new QAction(tr("Hide"), &menu);
|
QAction *hide = new QAction(tr("Hide"), &menu);
|
||||||
|
|
||||||
if (multipleSelection)
|
if (multipleSelection) {
|
||||||
{
|
|
||||||
copyfilename->setDisabled(true);
|
copyfilename->setDisabled(true);
|
||||||
copypath->setDisabled(true);
|
copypath->setDisabled(true);
|
||||||
copymessage->setDisabled(true);
|
copymessage->setDisabled(true);
|
||||||
|
@ -586,11 +547,9 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
//Start the menu
|
//Start the menu
|
||||||
menu.exec(e->globalPos());
|
menu.exec(e->globalPos());
|
||||||
|
|
||||||
if (mContextItem && mApplications->GetApplicationCount() > 0 && mContextItem->parent())
|
if (mContextItem && mApplications->GetApplicationCount() > 0 && mContextItem->parent()) {
|
||||||
{
|
|
||||||
//Disconnect all signals
|
//Disconnect all signals
|
||||||
for (int i = 0; i < actions.size(); i++)
|
for (int i = 0; i < actions.size(); i++) {
|
||||||
{
|
|
||||||
|
|
||||||
disconnect(actions[i], SIGNAL(triggered()), signalMapper, SLOT(map()));
|
disconnect(actions[i], SIGNAL(triggered()), signalMapper, SLOT(map()));
|
||||||
}
|
}
|
||||||
|
@ -607,8 +566,7 @@ void ResultsTree::contextMenuEvent(QContextMenuEvent * e)
|
||||||
void ResultsTree::StartApplication(QStandardItem *target, int application)
|
void ResultsTree::StartApplication(QStandardItem *target, int application)
|
||||||
{
|
{
|
||||||
//If there are no applications specified, tell the user about it
|
//If there are no applications specified, tell the user about it
|
||||||
if (mApplications->GetApplicationCount() == 0)
|
if (mApplications->GetApplicationCount() == 0) {
|
||||||
{
|
|
||||||
QMessageBox msg(QMessageBox::Critical,
|
QMessageBox msg(QMessageBox::Critical,
|
||||||
tr("Cppcheck"),
|
tr("Cppcheck"),
|
||||||
tr("No editor application configured.\n\n"
|
tr("No editor application configured.\n\n"
|
||||||
|
@ -622,8 +580,7 @@ void ResultsTree::StartApplication(QStandardItem *target, int application)
|
||||||
if (application == -1)
|
if (application == -1)
|
||||||
application = mApplications->GetDefaultApplication();
|
application = mApplications->GetDefaultApplication();
|
||||||
|
|
||||||
if (application == -1)
|
if (application == -1) {
|
||||||
{
|
|
||||||
QMessageBox msg(QMessageBox::Critical,
|
QMessageBox msg(QMessageBox::Critical,
|
||||||
tr("Cppcheck"),
|
tr("Cppcheck"),
|
||||||
tr("No default editor application selected.\n\n"
|
tr("No default editor application selected.\n\n"
|
||||||
|
@ -635,8 +592,7 @@ void ResultsTree::StartApplication(QStandardItem *target, int application)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target && application >= 0 && application < mApplications->GetApplicationCount() && target->parent())
|
if (target && application >= 0 && application < mApplications->GetApplicationCount() && target->parent()) {
|
||||||
{
|
|
||||||
// Make sure we are working with the first column
|
// Make sure we are working with the first column
|
||||||
if (target->column() != 0)
|
if (target->column() != 0)
|
||||||
target = target->parent()->child(target->row(), 0);
|
target = target->parent()->child(target->row(), 0);
|
||||||
|
@ -649,25 +605,18 @@ void ResultsTree::StartApplication(QStandardItem *target, int application)
|
||||||
qDebug() << "Opening file: " << file;
|
qDebug() << "Opening file: " << file;
|
||||||
|
|
||||||
QFileInfo info(file);
|
QFileInfo info(file);
|
||||||
if (!info.exists())
|
if (!info.exists()) {
|
||||||
{
|
if (info.isAbsolute()) {
|
||||||
if (info.isAbsolute())
|
|
||||||
{
|
|
||||||
QMessageBox msgbox(this);
|
QMessageBox msgbox(this);
|
||||||
msgbox.setWindowTitle("Cppcheck");
|
msgbox.setWindowTitle("Cppcheck");
|
||||||
msgbox.setText(tr("Could not find the file!"));
|
msgbox.setText(tr("Could not find the file!"));
|
||||||
msgbox.setIcon(QMessageBox::Critical);
|
msgbox.setIcon(QMessageBox::Critical);
|
||||||
msgbox.exec();
|
msgbox.exec();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
QDir checkdir(mCheckPath);
|
QDir checkdir(mCheckPath);
|
||||||
if (checkdir.isAbsolute() && checkdir.exists())
|
if (checkdir.isAbsolute() && checkdir.exists()) {
|
||||||
{
|
|
||||||
file = mCheckPath + "/" + file;
|
file = mCheckPath + "/" + file;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
QString dir = AskFileDir(file);
|
QString dir = AskFileDir(file);
|
||||||
dir += '/';
|
dir += '/';
|
||||||
file = dir + file;
|
file = dir + file;
|
||||||
|
@ -675,8 +624,7 @@ void ResultsTree::StartApplication(QStandardItem *target, int application)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.indexOf(" ") > -1)
|
if (file.indexOf(" ") > -1) {
|
||||||
{
|
|
||||||
file.insert(0, "\"");
|
file.insert(0, "\"");
|
||||||
file.append("\"");
|
file.append("\"");
|
||||||
}
|
}
|
||||||
|
@ -695,10 +643,8 @@ void ResultsTree::StartApplication(QStandardItem *target, int application)
|
||||||
|
|
||||||
// In Windows we must surround paths including spaces with quotation marks.
|
// In Windows we must surround paths including spaces with quotation marks.
|
||||||
#ifdef Q_WS_WIN
|
#ifdef Q_WS_WIN
|
||||||
if (program.indexOf(" ") > -1)
|
if (program.indexOf(" ") > -1) {
|
||||||
{
|
if (!program.startsWith('"') && !program.endsWith('"')) {
|
||||||
if (!program.startsWith('"') && !program.endsWith('"'))
|
|
||||||
{
|
|
||||||
program.insert(0, "\"");
|
program.insert(0, "\"");
|
||||||
program.append("\"");
|
program.append("\"");
|
||||||
}
|
}
|
||||||
|
@ -708,8 +654,7 @@ void ResultsTree::StartApplication(QStandardItem *target, int application)
|
||||||
const QString cmdLine = QString("%1 %2").arg(program).arg(params);
|
const QString cmdLine = QString("%1 %2").arg(program).arg(params);
|
||||||
|
|
||||||
bool success = QProcess::startDetached(cmdLine);
|
bool success = QProcess::startDetached(cmdLine);
|
||||||
if (!success)
|
if (!success) {
|
||||||
{
|
|
||||||
QString text = tr("Could not start %1\n\nPlease check the application path and parameters are correct.").arg(program);
|
QString text = tr("Could not start %1\n\nPlease check the application path and parameters are correct.").arg(program);
|
||||||
|
|
||||||
QMessageBox msgbox(this);
|
QMessageBox msgbox(this);
|
||||||
|
@ -750,8 +695,7 @@ void ResultsTree::CopyFullPath()
|
||||||
|
|
||||||
void ResultsTree::CopyMessage()
|
void ResultsTree::CopyMessage()
|
||||||
{
|
{
|
||||||
if (mContextItem)
|
if (mContextItem) {
|
||||||
{
|
|
||||||
// Make sure we are working with the first column
|
// Make sure we are working with the first column
|
||||||
if (mContextItem->column() != 0)
|
if (mContextItem->column() != 0)
|
||||||
mContextItem = mContextItem->parent()->child(mContextItem->row(), 0);
|
mContextItem = mContextItem->parent()->child(mContextItem->row(), 0);
|
||||||
|
@ -759,8 +703,7 @@ void ResultsTree::CopyMessage()
|
||||||
QVariantMap data = mContextItem->data().toMap();
|
QVariantMap data = mContextItem->data().toMap();
|
||||||
|
|
||||||
QString message;
|
QString message;
|
||||||
if (data["inconclusive"].toBool())
|
if (data["inconclusive"].toBool()) {
|
||||||
{
|
|
||||||
message = tr("[Inconclusive]");
|
message = tr("[Inconclusive]");
|
||||||
message += " ";
|
message += " ";
|
||||||
}
|
}
|
||||||
|
@ -778,8 +721,7 @@ void ResultsTree::HideResult()
|
||||||
|
|
||||||
QModelIndexList selectedRows = mSelectionModel->selectedRows();
|
QModelIndexList selectedRows = mSelectionModel->selectedRows();
|
||||||
QModelIndex index;
|
QModelIndex index;
|
||||||
foreach(index, selectedRows)
|
foreach(index, selectedRows) {
|
||||||
{
|
|
||||||
QStandardItem *item = mModel.itemFromIndex(index);
|
QStandardItem *item = mModel.itemFromIndex(index);
|
||||||
//Set the "hide" flag for this item
|
//Set the "hide" flag for this item
|
||||||
QVariantMap data = item->data().toMap();
|
QVariantMap data = item->data().toMap();
|
||||||
|
@ -803,8 +745,7 @@ void ResultsTree::QuickStartApplication(const QModelIndex &index)
|
||||||
|
|
||||||
void ResultsTree::CopyPath(QStandardItem *target, bool fullPath)
|
void ResultsTree::CopyPath(QStandardItem *target, bool fullPath)
|
||||||
{
|
{
|
||||||
if (target)
|
if (target) {
|
||||||
{
|
|
||||||
// Make sure we are working with the first column
|
// Make sure we are working with the first column
|
||||||
if (target->column() != 0)
|
if (target->column() != 0)
|
||||||
target = target->parent()->child(target->row(), 0);
|
target = target->parent()->child(target->row(), 0);
|
||||||
|
@ -815,8 +756,7 @@ void ResultsTree::CopyPath(QStandardItem *target, bool fullPath)
|
||||||
//Replace (file) with filename
|
//Replace (file) with filename
|
||||||
QString file = data["file"].toString();
|
QString file = data["file"].toString();
|
||||||
pathStr = QDir::toNativeSeparators(file);
|
pathStr = QDir::toNativeSeparators(file);
|
||||||
if (!fullPath)
|
if (!fullPath) {
|
||||||
{
|
|
||||||
QFileInfo fi(pathStr);
|
QFileInfo fi(pathStr);
|
||||||
pathStr = fi.fileName();
|
pathStr = fi.fileName();
|
||||||
}
|
}
|
||||||
|
@ -828,8 +768,7 @@ void ResultsTree::CopyPath(QStandardItem *target, bool fullPath)
|
||||||
|
|
||||||
QString ResultsTree::SeverityToIcon(Severity::SeverityType severity) const
|
QString ResultsTree::SeverityToIcon(Severity::SeverityType severity) const
|
||||||
{
|
{
|
||||||
switch (severity)
|
switch (severity) {
|
||||||
{
|
|
||||||
case Severity::error:
|
case Severity::error:
|
||||||
return ":images/dialog-error.png";
|
return ":images/dialog-error.png";
|
||||||
case Severity::style:
|
case Severity::style:
|
||||||
|
@ -852,8 +791,7 @@ void ResultsTree::SaveResults(Report *report)
|
||||||
{
|
{
|
||||||
report->WriteHeader();
|
report->WriteHeader();
|
||||||
|
|
||||||
for (int i = 0; i < mModel.rowCount(); i++)
|
for (int i = 0; i < mModel.rowCount(); i++) {
|
||||||
{
|
|
||||||
QStandardItem *item = mModel.item(i, 0);
|
QStandardItem *item = mModel.item(i, 0);
|
||||||
if (!isRowHidden(i, item->index()))
|
if (!isRowHidden(i, item->index()))
|
||||||
SaveErrors(report, item);
|
SaveErrors(report, item);
|
||||||
|
@ -864,22 +802,18 @@ void ResultsTree::SaveResults(Report *report)
|
||||||
|
|
||||||
void ResultsTree::SaveErrors(Report *report, QStandardItem *item)
|
void ResultsTree::SaveErrors(Report *report, QStandardItem *item)
|
||||||
{
|
{
|
||||||
if (!item)
|
if (!item) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < item->rowCount(); i++)
|
for (int i = 0; i < item->rowCount(); i++) {
|
||||||
{
|
|
||||||
QStandardItem *error = item->child(i, 0);
|
QStandardItem *error = item->child(i, 0);
|
||||||
|
|
||||||
if (!error)
|
if (!error) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRowHidden(i, item->index()) && !mSaveAllErrors)
|
if (isRowHidden(i, item->index()) && !mSaveAllErrors) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,8 +834,7 @@ void ResultsTree::SaveErrors(Report *report, QStandardItem *item)
|
||||||
item.files << file;
|
item.files << file;
|
||||||
item.lines << line;
|
item.lines << line;
|
||||||
|
|
||||||
for (int j = 0; j < error->rowCount(); j++)
|
for (int j = 0; j < error->rowCount(); j++) {
|
||||||
{
|
|
||||||
QStandardItem *child_error = error->child(j, 0);
|
QStandardItem *child_error = error->child(j, 0);
|
||||||
//Get error's user data
|
//Get error's user data
|
||||||
QVariant child_userdata = child_error->data();
|
QVariant child_userdata = child_error->data();
|
||||||
|
@ -923,8 +856,7 @@ void ResultsTree::UpdateSettings(bool showFullPath,
|
||||||
bool saveFullPath,
|
bool saveFullPath,
|
||||||
bool saveAllErrors)
|
bool saveAllErrors)
|
||||||
{
|
{
|
||||||
if (mShowFullPath != showFullPath)
|
if (mShowFullPath != showFullPath) {
|
||||||
{
|
|
||||||
mShowFullPath = showFullPath;
|
mShowFullPath = showFullPath;
|
||||||
RefreshFilePaths();
|
RefreshFilePaths();
|
||||||
}
|
}
|
||||||
|
@ -940,8 +872,7 @@ void ResultsTree::SetCheckDirectory(const QString &dir)
|
||||||
|
|
||||||
QString ResultsTree::StripPath(const QString &path, bool saving)
|
QString ResultsTree::StripPath(const QString &path, bool saving)
|
||||||
{
|
{
|
||||||
if ((!saving && mShowFullPath) || (saving && mSaveFullPath))
|
if ((!saving && mShowFullPath) || (saving && mSaveFullPath)) {
|
||||||
{
|
|
||||||
return QString(path);
|
return QString(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,8 +882,7 @@ QString ResultsTree::StripPath(const QString &path, bool saving)
|
||||||
|
|
||||||
void ResultsTree::RefreshFilePaths(QStandardItem *item)
|
void ResultsTree::RefreshFilePaths(QStandardItem *item)
|
||||||
{
|
{
|
||||||
if (!item)
|
if (!item) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,13 +890,11 @@ void ResultsTree::RefreshFilePaths(QStandardItem *item)
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
|
|
||||||
//Loop through all errors within this file
|
//Loop through all errors within this file
|
||||||
for (int i = 0; i < item->rowCount(); i++)
|
for (int i = 0; i < item->rowCount(); i++) {
|
||||||
{
|
|
||||||
//Get error i
|
//Get error i
|
||||||
QStandardItem *error = item->child(i, 0);
|
QStandardItem *error = item->child(i, 0);
|
||||||
|
|
||||||
if (!error)
|
if (!error) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,15 +910,12 @@ void ResultsTree::RefreshFilePaths(QStandardItem *item)
|
||||||
error->setText(StripPath(file, false));
|
error->setText(StripPath(file, false));
|
||||||
|
|
||||||
//If this error has backtraces make sure the files list has enough filenames
|
//If this error has backtraces make sure the files list has enough filenames
|
||||||
if (error->hasChildren())
|
if (error->hasChildren()) {
|
||||||
{
|
|
||||||
//Loop through all files within the error
|
//Loop through all files within the error
|
||||||
for (int j = 0; j < error->rowCount(); j++)
|
for (int j = 0; j < error->rowCount(); j++) {
|
||||||
{
|
|
||||||
//Get file
|
//Get file
|
||||||
QStandardItem *child = error->child(j, 0);
|
QStandardItem *child = error->child(j, 0);
|
||||||
if (!child)
|
if (!child) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//Get childs's user data
|
//Get childs's user data
|
||||||
|
@ -1006,8 +931,7 @@ void ResultsTree::RefreshFilePaths(QStandardItem *item)
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the main file hasn't been updated yet, update it now
|
//if the main file hasn't been updated yet, update it now
|
||||||
if (!updated)
|
if (!updated) {
|
||||||
{
|
|
||||||
updated = true;
|
updated = true;
|
||||||
item->setText(error->text());
|
item->setText(error->text());
|
||||||
}
|
}
|
||||||
|
@ -1020,8 +944,7 @@ void ResultsTree::RefreshFilePaths()
|
||||||
qDebug("Refreshing file paths");
|
qDebug("Refreshing file paths");
|
||||||
|
|
||||||
//Go through all file items (these are parent items that contain the errors)
|
//Go through all file items (these are parent items that contain the errors)
|
||||||
for (int i = 0; i < mModel.rowCount(); i++)
|
for (int i = 0; i < mModel.rowCount(); i++) {
|
||||||
{
|
|
||||||
RefreshFilePaths(mModel.item(i, 0));
|
RefreshFilePaths(mModel.item(i, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,7 @@ class QItemSelectionModel;
|
||||||
* @brief Cppcheck's results are shown in this tree
|
* @brief Cppcheck's results are shown in this tree
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ResultsTree : public QTreeView
|
class ResultsTree : public QTreeView {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ResultsTree(QWidget * parent = 0);
|
ResultsTree(QWidget * parent = 0);
|
||||||
|
|
|
@ -121,8 +121,7 @@ void ResultsView::FilterResults(const QString& filter)
|
||||||
|
|
||||||
void ResultsView::Save(const QString &filename, Report::Type type)
|
void ResultsView::Save(const QString &filename, Report::Type type)
|
||||||
{
|
{
|
||||||
if (!mErrorsFound)
|
if (!mErrorsFound) {
|
||||||
{
|
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setText(tr("No errors found, nothing to save."));
|
msgBox.setText(tr("No errors found, nothing to save."));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
@ -131,8 +130,7 @@ void ResultsView::Save(const QString &filename, Report::Type type)
|
||||||
|
|
||||||
Report *report = NULL;
|
Report *report = NULL;
|
||||||
|
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case Report::CSV:
|
case Report::CSV:
|
||||||
report = new CsvReport(filename, this);
|
report = new CsvReport(filename, this);
|
||||||
break;
|
break;
|
||||||
|
@ -147,12 +145,10 @@ void ResultsView::Save(const QString &filename, Report::Type type)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report)
|
if (report) {
|
||||||
{
|
|
||||||
if (report->Create())
|
if (report->Create())
|
||||||
mUI.mTree->SaveResults(report);
|
mUI.mTree->SaveResults(report);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setText(tr("Failed to save the report."));
|
msgBox.setText(tr("Failed to save the report."));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
@ -160,9 +156,7 @@ void ResultsView::Save(const QString &filename, Report::Type type)
|
||||||
}
|
}
|
||||||
delete report;
|
delete report;
|
||||||
report = NULL;
|
report = NULL;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setText(tr("Failed to save the report."));
|
msgBox.setText(tr("Failed to save the report."));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
@ -198,11 +192,9 @@ void ResultsView::CheckingFinished()
|
||||||
mUI.mProgress->setFormat("%p%");
|
mUI.mProgress->setFormat("%p%");
|
||||||
|
|
||||||
//Should we inform user of non visible/not found errors?
|
//Should we inform user of non visible/not found errors?
|
||||||
if (mShowNoErrorsMessage)
|
if (mShowNoErrorsMessage) {
|
||||||
{
|
|
||||||
//Tell user that we found no errors
|
//Tell user that we found no errors
|
||||||
if (!mErrorsFound)
|
if (!mErrorsFound) {
|
||||||
{
|
|
||||||
QMessageBox msg(QMessageBox::Information,
|
QMessageBox msg(QMessageBox::Information,
|
||||||
tr("Cppcheck"),
|
tr("Cppcheck"),
|
||||||
tr("No errors found."),
|
tr("No errors found."),
|
||||||
|
@ -211,8 +203,7 @@ void ResultsView::CheckingFinished()
|
||||||
|
|
||||||
msg.exec();
|
msg.exec();
|
||||||
} //If we have errors but they aren't visible, tell user about it
|
} //If we have errors but they aren't visible, tell user about it
|
||||||
else if (!mUI.mTree->HasVisibleResults())
|
else if (!mUI.mTree->HasVisibleResults()) {
|
||||||
{
|
|
||||||
QString text = tr("Errors were found, but they are configured to be hidden.\n"\
|
QString text = tr("Errors were found, but they are configured to be hidden.\n"\
|
||||||
"To toggle what kind of errors are shown, open view menu.");
|
"To toggle what kind of errors are shown, open view menu.");
|
||||||
QMessageBox msg(QMessageBox::Information,
|
QMessageBox msg(QMessageBox::Information,
|
||||||
|
@ -257,8 +248,7 @@ void ResultsView::DisableProgressbar()
|
||||||
void ResultsView::ReadErrorsXml(const QString &filename)
|
void ResultsView::ReadErrorsXml(const QString &filename)
|
||||||
{
|
{
|
||||||
const int version = XmlReport::determineVersion(filename);
|
const int version = XmlReport::determineVersion(filename);
|
||||||
if (version == 0)
|
if (version == 0) {
|
||||||
{
|
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setText(tr("Failed to read the report."));
|
msgBox.setText(tr("Failed to read the report."));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
@ -273,12 +263,10 @@ void ResultsView::ReadErrorsXml(const QString &filename)
|
||||||
report = new XmlReportV2(filename, this);
|
report = new XmlReportV2(filename, this);
|
||||||
|
|
||||||
QList<ErrorItem> errors;
|
QList<ErrorItem> errors;
|
||||||
if (report)
|
if (report) {
|
||||||
{
|
|
||||||
if (report->Open())
|
if (report->Open())
|
||||||
errors = report->Read();
|
errors = report->Read();
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setText(tr("Failed to read the report."));
|
msgBox.setText(tr("Failed to read the report."));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
@ -286,9 +274,7 @@ void ResultsView::ReadErrorsXml(const QString &filename)
|
||||||
}
|
}
|
||||||
delete report;
|
delete report;
|
||||||
report = NULL;
|
report = NULL;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setText(tr("Failed to read the report."));
|
msgBox.setText(tr("Failed to read the report."));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
@ -296,8 +282,7 @@ void ResultsView::ReadErrorsXml(const QString &filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorItem item;
|
ErrorItem item;
|
||||||
foreach(item, errors)
|
foreach(item, errors) {
|
||||||
{
|
|
||||||
mUI.mTree->AddErrorItem(item);
|
mUI.mTree->AddErrorItem(item);
|
||||||
}
|
}
|
||||||
mUI.mTree->SetCheckDirectory("");
|
mUI.mTree->SetCheckDirectory("");
|
||||||
|
@ -308,8 +293,7 @@ void ResultsView::UpdateDetails(const QModelIndex &index)
|
||||||
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(mUI.mTree->model());
|
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(mUI.mTree->model());
|
||||||
QStandardItem *item = model->itemFromIndex(index);
|
QStandardItem *item = model->itemFromIndex(index);
|
||||||
|
|
||||||
if (!item)
|
if (!item) {
|
||||||
{
|
|
||||||
mUI.mDetails->setText("");
|
mUI.mDetails->setText("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -321,8 +305,7 @@ void ResultsView::UpdateDetails(const QModelIndex &index)
|
||||||
QVariantMap data = item->data().toMap();
|
QVariantMap data = item->data().toMap();
|
||||||
|
|
||||||
// If there is no severity data then it is a parent item without summary and message
|
// If there is no severity data then it is a parent item without summary and message
|
||||||
if (!data.contains("severity"))
|
if (!data.contains("severity")) {
|
||||||
{
|
|
||||||
mUI.mDetails->setText("");
|
mUI.mDetails->setText("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,7 @@ class CheckStatistics;
|
||||||
* @brief Widget to show cppcheck progressbar and result
|
* @brief Widget to show cppcheck progressbar and result
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ResultsView : public QWidget
|
class ResultsView : public QWidget {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -147,8 +146,7 @@ public:
|
||||||
* @brief Return checking statistics.
|
* @brief Return checking statistics.
|
||||||
* @return Pointer to checking statistics.
|
* @return Pointer to checking statistics.
|
||||||
*/
|
*/
|
||||||
CheckStatistics *GetStatistics() const
|
CheckStatistics *GetStatistics() const {
|
||||||
{
|
|
||||||
return mStatistics;
|
return mStatistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,8 +154,7 @@ public:
|
||||||
* @brief Return Showtypes.
|
* @brief Return Showtypes.
|
||||||
* @return Pointer to Showtypes.
|
* @return Pointer to Showtypes.
|
||||||
*/
|
*/
|
||||||
ShowTypes * GetShowTypes() const
|
ShowTypes * GetShowTypes() const {
|
||||||
{
|
|
||||||
return &mUI.mTree->mShowSeverities;
|
return &mUI.mTree->mShowSeverities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,8 +108,7 @@ void SettingsDialog::InitIncludepathsList()
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
const QString allPaths = settings.value(SETTINGS_GLOBAL_INCLUDE_PATHS).toString();
|
const QString allPaths = settings.value(SETTINGS_GLOBAL_INCLUDE_PATHS).toString();
|
||||||
const QStringList paths = allPaths.split(";", QString::SkipEmptyParts);
|
const QStringList paths = allPaths.split(";", QString::SkipEmptyParts);
|
||||||
foreach(QString path, paths)
|
foreach(QString path, paths) {
|
||||||
{
|
|
||||||
AddIncludePath(path);
|
AddIncludePath(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,8 +117,7 @@ void SettingsDialog::InitTranslationsList()
|
||||||
{
|
{
|
||||||
const QString current = mTranslator->GetCurrentLanguage();
|
const QString current = mTranslator->GetCurrentLanguage();
|
||||||
QList<TranslationInfo> translations = mTranslator->GetTranslations();
|
QList<TranslationInfo> translations = mTranslator->GetTranslations();
|
||||||
foreach(TranslationInfo translation, translations)
|
foreach(TranslationInfo translation, translations) {
|
||||||
{
|
|
||||||
QListWidgetItem *item = new QListWidgetItem;
|
QListWidgetItem *item = new QListWidgetItem;
|
||||||
item->setText(translation.mName);
|
item->setText(translation.mName);
|
||||||
item->setData(LangCodeRole, QVariant(translation.mCode));
|
item->setData(LangCodeRole, QVariant(translation.mCode));
|
||||||
|
@ -131,8 +129,7 @@ void SettingsDialog::InitTranslationsList()
|
||||||
|
|
||||||
Qt::CheckState SettingsDialog::BoolToCheckState(bool yes) const
|
Qt::CheckState SettingsDialog::BoolToCheckState(bool yes) const
|
||||||
{
|
{
|
||||||
if (yes)
|
if (yes) {
|
||||||
{
|
|
||||||
return Qt::Checked;
|
return Qt::Checked;
|
||||||
}
|
}
|
||||||
return Qt::Unchecked;
|
return Qt::Unchecked;
|
||||||
|
@ -140,8 +137,7 @@ Qt::CheckState SettingsDialog::BoolToCheckState(bool yes) const
|
||||||
|
|
||||||
bool SettingsDialog::CheckStateToBool(Qt::CheckState state) const
|
bool SettingsDialog::CheckStateToBool(Qt::CheckState state) const
|
||||||
{
|
{
|
||||||
if (state == Qt::Checked)
|
if (state == Qt::Checked) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -165,8 +161,7 @@ void SettingsDialog::SaveSettings()
|
||||||
void SettingsDialog::SaveSettingValues()
|
void SettingsDialog::SaveSettingValues()
|
||||||
{
|
{
|
||||||
int jobs = mUI.mJobs->text().toInt();
|
int jobs = mUI.mJobs->text().toInt();
|
||||||
if (jobs <= 0)
|
if (jobs <= 0) {
|
||||||
{
|
|
||||||
jobs = 1;
|
jobs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,8 +182,7 @@ void SettingsDialog::SaveSettingValues()
|
||||||
|
|
||||||
const int count = mUI.mListIncludePaths->count();
|
const int count = mUI.mListIncludePaths->count();
|
||||||
QString includePaths;
|
QString includePaths;
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
QListWidgetItem *item = mUI.mListIncludePaths->item(i);
|
QListWidgetItem *item = mUI.mListIncludePaths->item(i);
|
||||||
includePaths += item->text();
|
includePaths += item->text();
|
||||||
includePaths += ";";
|
includePaths += ";";
|
||||||
|
@ -207,8 +201,7 @@ void SettingsDialog::AddApplication()
|
||||||
Application app;
|
Application app;
|
||||||
ApplicationDialog dialog(tr("Add a new application"), app, this);
|
ApplicationDialog dialog(tr("Add a new application"), app, this);
|
||||||
|
|
||||||
if (dialog.exec() == QDialog::Accepted)
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
{
|
|
||||||
const Application app = dialog.GetApplication();
|
const Application app = dialog.GetApplication();
|
||||||
mTempApplications->AddApplication(app);
|
mTempApplications->AddApplication(app);
|
||||||
mUI.mListWidget->addItem(app.getName());
|
mUI.mListWidget->addItem(app.getName());
|
||||||
|
@ -218,8 +211,7 @@ void SettingsDialog::AddApplication()
|
||||||
void SettingsDialog::RemoveApplication()
|
void SettingsDialog::RemoveApplication()
|
||||||
{
|
{
|
||||||
QList<QListWidgetItem *> selected = mUI.mListWidget->selectedItems();
|
QList<QListWidgetItem *> selected = mUI.mListWidget->selectedItems();
|
||||||
foreach(QListWidgetItem *item, selected)
|
foreach(QListWidgetItem *item, selected) {
|
||||||
{
|
|
||||||
const int removeIndex = mUI.mListWidget->row(item);
|
const int removeIndex = mUI.mListWidget->row(item);
|
||||||
const int currentDefault = mTempApplications->GetDefaultApplication();
|
const int currentDefault = mTempApplications->GetDefaultApplication();
|
||||||
mTempApplications->RemoveApplication(removeIndex);
|
mTempApplications->RemoveApplication(removeIndex);
|
||||||
|
@ -238,14 +230,12 @@ void SettingsDialog::EditApplication()
|
||||||
{
|
{
|
||||||
QList<QListWidgetItem *> selected = mUI.mListWidget->selectedItems();
|
QList<QListWidgetItem *> selected = mUI.mListWidget->selectedItems();
|
||||||
QListWidgetItem *item = 0;
|
QListWidgetItem *item = 0;
|
||||||
foreach(item, selected)
|
foreach(item, selected) {
|
||||||
{
|
|
||||||
int row = mUI.mListWidget->row(item);
|
int row = mUI.mListWidget->row(item);
|
||||||
const Application app = mTempApplications->GetApplication(row);
|
const Application app = mTempApplications->GetApplication(row);
|
||||||
ApplicationDialog dialog(tr("Modify an application"), app, this);
|
ApplicationDialog dialog(tr("Modify an application"), app, this);
|
||||||
|
|
||||||
if (dialog.exec() == QDialog::Accepted)
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
{
|
|
||||||
const Application app2 = dialog.GetApplication();
|
const Application app2 = dialog.GetApplication();
|
||||||
mTempApplications->SetApplication(row, app2);
|
mTempApplications->SetApplication(row, app2);
|
||||||
item->setText(app2.getName());
|
item->setText(app2.getName());
|
||||||
|
@ -256,8 +246,7 @@ void SettingsDialog::EditApplication()
|
||||||
void SettingsDialog::DefaultApplication()
|
void SettingsDialog::DefaultApplication()
|
||||||
{
|
{
|
||||||
QList<QListWidgetItem *> selected = mUI.mListWidget->selectedItems();
|
QList<QListWidgetItem *> selected = mUI.mListWidget->selectedItems();
|
||||||
if (selected.size() > 0)
|
if (selected.size() > 0) {
|
||||||
{
|
|
||||||
int index = mUI.mListWidget->row(selected[0]);
|
int index = mUI.mListWidget->row(selected[0]);
|
||||||
mTempApplications->SetDefault(index);
|
mTempApplications->SetDefault(index);
|
||||||
mUI.mListWidget->clear();
|
mUI.mListWidget->clear();
|
||||||
|
@ -268,12 +257,10 @@ void SettingsDialog::DefaultApplication()
|
||||||
void SettingsDialog::PopulateApplicationList()
|
void SettingsDialog::PopulateApplicationList()
|
||||||
{
|
{
|
||||||
const int defapp = mTempApplications->GetDefaultApplication();
|
const int defapp = mTempApplications->GetDefaultApplication();
|
||||||
for (int i = 0; i < mTempApplications->GetApplicationCount(); i++)
|
for (int i = 0; i < mTempApplications->GetApplicationCount(); i++) {
|
||||||
{
|
|
||||||
Application app = mTempApplications->GetApplication(i);
|
Application app = mTempApplications->GetApplication(i);
|
||||||
QString name = app.getName();
|
QString name = app.getName();
|
||||||
if (i == defapp)
|
if (i == defapp) {
|
||||||
{
|
|
||||||
name += " ";
|
name += " ";
|
||||||
name += tr("[Default]");
|
name += tr("[Default]");
|
||||||
}
|
}
|
||||||
|
@ -284,8 +271,7 @@ void SettingsDialog::PopulateApplicationList()
|
||||||
// first item.
|
// first item.
|
||||||
if (defapp == -1)
|
if (defapp == -1)
|
||||||
mUI.mListWidget->setCurrentRow(0);
|
mUI.mListWidget->setCurrentRow(0);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (mTempApplications->GetApplicationCount() > defapp)
|
if (mTempApplications->GetApplicationCount() > defapp)
|
||||||
mUI.mListWidget->setCurrentRow(defapp);
|
mUI.mListWidget->setCurrentRow(defapp);
|
||||||
else
|
else
|
||||||
|
@ -325,8 +311,7 @@ void SettingsDialog::AddIncludePath()
|
||||||
tr("Select include directory"),
|
tr("Select include directory"),
|
||||||
QString());
|
QString());
|
||||||
|
|
||||||
if (!selectedDir.isEmpty())
|
if (!selectedDir.isEmpty()) {
|
||||||
{
|
|
||||||
AddIncludePath(selectedDir);
|
AddIncludePath(selectedDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,7 @@ class TranslationHandler;
|
||||||
* @brief Settings dialog
|
* @brief Settings dialog
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class SettingsDialog : public QDialog
|
class SettingsDialog : public QDialog {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SettingsDialog(ApplicationList *list,
|
SettingsDialog(ApplicationList *list,
|
||||||
|
|
|
@ -33,8 +33,7 @@ ShowTypes::~ShowTypes()
|
||||||
|
|
||||||
ShowTypes::ShowType ShowTypes::SeverityToShowType(Severity::SeverityType severity)
|
ShowTypes::ShowType ShowTypes::SeverityToShowType(Severity::SeverityType severity)
|
||||||
{
|
{
|
||||||
switch (severity)
|
switch (severity) {
|
||||||
{
|
|
||||||
case Severity::none:
|
case Severity::none:
|
||||||
return ShowTypes::ShowNone;
|
return ShowTypes::ShowNone;
|
||||||
case Severity::error:
|
case Severity::error:
|
||||||
|
@ -58,8 +57,7 @@ ShowTypes::ShowType ShowTypes::SeverityToShowType(Severity::SeverityType severit
|
||||||
|
|
||||||
Severity::SeverityType ShowTypes::ShowTypeToSeverity(ShowTypes::ShowType type)
|
Severity::SeverityType ShowTypes::ShowTypeToSeverity(ShowTypes::ShowType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case ShowTypes::ShowStyle:
|
case ShowTypes::ShowStyle:
|
||||||
return Severity::style;
|
return Severity::style;
|
||||||
break;
|
break;
|
||||||
|
@ -95,8 +93,7 @@ Severity::SeverityType ShowTypes::ShowTypeToSeverity(ShowTypes::ShowType type)
|
||||||
ShowTypes::ShowType ShowTypes::VariantToShowType(const QVariant &data)
|
ShowTypes::ShowType ShowTypes::VariantToShowType(const QVariant &data)
|
||||||
{
|
{
|
||||||
const int value = data.toInt();
|
const int value = data.toInt();
|
||||||
if (value < ShowTypes::ShowStyle || value > ShowTypes::ShowErrors)
|
if (value < ShowTypes::ShowStyle || value > ShowTypes::ShowErrors) {
|
||||||
{
|
|
||||||
return ShowTypes::ShowNone;
|
return ShowTypes::ShowNone;
|
||||||
}
|
}
|
||||||
return (ShowTypes::ShowType)value;
|
return (ShowTypes::ShowType)value;
|
||||||
|
|
|
@ -34,15 +34,13 @@
|
||||||
* Notice that the "visibility" settings are automatically loaded when the
|
* Notice that the "visibility" settings are automatically loaded when the
|
||||||
* class is constructed and saved when the class is destroyed.
|
* class is constructed and saved when the class is destroyed.
|
||||||
*/
|
*/
|
||||||
class ShowTypes
|
class ShowTypes {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Show types we have (i.e. severities in the GUI).
|
* @brief Show types we have (i.e. severities in the GUI).
|
||||||
*/
|
*/
|
||||||
enum ShowType
|
enum ShowType {
|
||||||
{
|
|
||||||
ShowStyle = 0,
|
ShowStyle = 0,
|
||||||
ShowWarnings,
|
ShowWarnings,
|
||||||
ShowPerformance,
|
ShowPerformance,
|
||||||
|
|
|
@ -38,15 +38,12 @@ StatsDialog::StatsDialog(QWidget *parent)
|
||||||
void StatsDialog::setProject(const Project& project)
|
void StatsDialog::setProject(const Project& project)
|
||||||
{
|
{
|
||||||
ProjectFile *projectFile = project.GetProjectFile();
|
ProjectFile *projectFile = project.GetProjectFile();
|
||||||
if (projectFile)
|
if (projectFile) {
|
||||||
{
|
|
||||||
mUI.mProject->setText(projectFile->GetRootPath());
|
mUI.mProject->setText(projectFile->GetRootPath());
|
||||||
mUI.mPaths->setText(projectFile->GetCheckPaths().join(";"));
|
mUI.mPaths->setText(projectFile->GetCheckPaths().join(";"));
|
||||||
mUI.mIncludePaths->setText(projectFile->GetIncludeDirs().join(";"));
|
mUI.mIncludePaths->setText(projectFile->GetIncludeDirs().join(";"));
|
||||||
mUI.mDefines->setText(projectFile->GetDefines().join(";"));
|
mUI.mDefines->setText(projectFile->GetDefines().join(";"));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
mUI.mProject->setText("");
|
mUI.mProject->setText("");
|
||||||
mUI.mPaths->setText("");
|
mUI.mPaths->setText("");
|
||||||
mUI.mIncludePaths->setText("");
|
mUI.mIncludePaths->setText("");
|
||||||
|
@ -96,8 +93,7 @@ void StatsDialog::setScanDuration(double seconds)
|
||||||
void StatsDialog::copyToClipboard()
|
void StatsDialog::copyToClipboard()
|
||||||
{
|
{
|
||||||
QClipboard *clipboard = QApplication::clipboard();
|
QClipboard *clipboard = QApplication::clipboard();
|
||||||
if (clipboard)
|
if (clipboard) {
|
||||||
{
|
|
||||||
const QString projSettings(tr("Project Settings"));
|
const QString projSettings(tr("Project Settings"));
|
||||||
const QString project(tr("Project"));
|
const QString project(tr("Project"));
|
||||||
const QString paths(tr("Paths"));
|
const QString paths(tr("Paths"));
|
||||||
|
|
|
@ -32,8 +32,7 @@ class CheckStatistics;
|
||||||
* @brief A dialog that shows project and scan statistics.
|
* @brief A dialog that shows project and scan statistics.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class StatsDialog : public QDialog
|
class StatsDialog : public QDialog {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
StatsDialog(QWidget *parent = 0);
|
StatsDialog(QWidget *parent = 0);
|
||||||
|
|
|
@ -39,8 +39,7 @@ void BenchmarkSimple::tokenize()
|
||||||
// tokenize..
|
// tokenize..
|
||||||
Tokenizer tokenizer(&settings, this);
|
Tokenizer tokenizer(&settings, this);
|
||||||
std::istringstream istr(data.constData());
|
std::istringstream istr(data.constData());
|
||||||
QBENCHMARK
|
QBENCHMARK {
|
||||||
{
|
|
||||||
tokenizer.tokenize(istr, "test.cpp");
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,8 +56,7 @@ void BenchmarkSimple::simplify()
|
||||||
Tokenizer tokenizer(&settings, this);
|
Tokenizer tokenizer(&settings, this);
|
||||||
std::istringstream istr(data.constData());
|
std::istringstream istr(data.constData());
|
||||||
tokenizer.tokenize(istr, "test.cpp");
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
QBENCHMARK
|
QBENCHMARK {
|
||||||
{
|
|
||||||
tokenizer.simplifyTokenList();
|
tokenizer.simplifyTokenList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,8 +72,7 @@ void BenchmarkSimple::tokenizeAndSimplify()
|
||||||
// tokenize..
|
// tokenize..
|
||||||
Tokenizer tokenizer(&settings, this);
|
Tokenizer tokenizer(&settings, this);
|
||||||
std::istringstream istr(data.constData());
|
std::istringstream istr(data.constData());
|
||||||
QBENCHMARK
|
QBENCHMARK {
|
||||||
{
|
|
||||||
tokenizer.tokenize(istr, "test.cpp");
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
tokenizer.simplifyTokenList();
|
tokenizer.simplifyTokenList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "errorlogger.h"
|
#include "errorlogger.h"
|
||||||
|
|
||||||
class BenchmarkSimple: public QObject, public ErrorLogger
|
class BenchmarkSimple: public QObject, public ErrorLogger {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -32,10 +31,8 @@ private slots:
|
||||||
private:
|
private:
|
||||||
// Empty implementations of ErrorLogger methods.
|
// Empty implementations of ErrorLogger methods.
|
||||||
// We don't care about the output in the benchmark tests.
|
// We don't care about the output in the benchmark tests.
|
||||||
void reportOut(const std::string & outmsg)
|
void reportOut(const std::string & outmsg) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
void reportErr(const ErrorLogger::ErrorMessage &msg)
|
void reportErr(const ErrorLogger::ErrorMessage &msg) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,8 +19,7 @@
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class TestFileList: public QObject
|
class TestFileList: public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class TestProjectFile: public QObject
|
class TestProjectFile: public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class TestTranslationHandler: public QObject
|
class TestTranslationHandler: public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class TestXmlReport: public QObject
|
class TestXmlReport: public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class TestXmlReportV1: public QObject
|
class TestXmlReportV1: public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class TestXmlReportV2: public QObject
|
class TestXmlReportV2: public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -50,13 +50,11 @@ void ThreadHandler::SetFiles(const QStringList &files)
|
||||||
|
|
||||||
void ThreadHandler::Check(const Settings &settings, bool recheck)
|
void ThreadHandler::Check(const Settings &settings, bool recheck)
|
||||||
{
|
{
|
||||||
if (recheck && mRunningThreadCount == 0)
|
if (recheck && mRunningThreadCount == 0) {
|
||||||
{
|
|
||||||
mResults.SetFiles(mLastFiles);
|
mResults.SetFiles(mLastFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mResults.GetFileCount() == 0 || mRunningThreadCount > 0 || settings._jobs <= 0)
|
if (mResults.GetFileCount() == 0 || mRunningThreadCount > 0 || settings._jobs <= 0) {
|
||||||
{
|
|
||||||
qDebug() << "Can't start checking if there's no files to check or if check is in progress.";
|
qDebug() << "Can't start checking if there's no files to check or if check is in progress.";
|
||||||
emit Done();
|
emit Done();
|
||||||
return;
|
return;
|
||||||
|
@ -66,13 +64,11 @@ void ThreadHandler::Check(const Settings &settings, bool recheck)
|
||||||
|
|
||||||
mRunningThreadCount = mThreads.size();
|
mRunningThreadCount = mThreads.size();
|
||||||
|
|
||||||
if (mResults.GetFileCount() < mRunningThreadCount)
|
if (mResults.GetFileCount() < mRunningThreadCount) {
|
||||||
{
|
|
||||||
mRunningThreadCount = mResults.GetFileCount();
|
mRunningThreadCount = mResults.GetFileCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mRunningThreadCount; i++)
|
for (int i = 0; i < mRunningThreadCount; i++) {
|
||||||
{
|
|
||||||
mThreads[i]->Check(settings);
|
mThreads[i]->Check(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,16 +84,14 @@ void ThreadHandler::SetThreadCount(const int count)
|
||||||
{
|
{
|
||||||
if (mRunningThreadCount > 0 ||
|
if (mRunningThreadCount > 0 ||
|
||||||
count == mThreads.size() ||
|
count == mThreads.size() ||
|
||||||
count <= 0)
|
count <= 0) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove unused old threads
|
//Remove unused old threads
|
||||||
RemoveThreads();
|
RemoveThreads();
|
||||||
//Create new threads
|
//Create new threads
|
||||||
for (int i = mThreads.size(); i < count; i++)
|
for (int i = mThreads.size(); i < count; i++) {
|
||||||
{
|
|
||||||
mThreads << new CheckThread(mResults);
|
mThreads << new CheckThread(mResults);
|
||||||
connect(mThreads.last(), SIGNAL(Done()),
|
connect(mThreads.last(), SIGNAL(Done()),
|
||||||
this, SLOT(ThreadDone()));
|
this, SLOT(ThreadDone()));
|
||||||
|
@ -110,8 +104,7 @@ void ThreadHandler::SetThreadCount(const int count)
|
||||||
|
|
||||||
void ThreadHandler::RemoveThreads()
|
void ThreadHandler::RemoveThreads()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mThreads.size(); i++)
|
for (int i = 0; i < mThreads.size(); i++) {
|
||||||
{
|
|
||||||
mThreads[i]->terminate();
|
mThreads[i]->terminate();
|
||||||
disconnect(mThreads.last(), SIGNAL(Done()),
|
disconnect(mThreads.last(), SIGNAL(Done()),
|
||||||
this, SLOT(ThreadDone()));
|
this, SLOT(ThreadDone()));
|
||||||
|
@ -127,8 +120,7 @@ void ThreadHandler::RemoveThreads()
|
||||||
void ThreadHandler::ThreadDone()
|
void ThreadHandler::ThreadDone()
|
||||||
{
|
{
|
||||||
mRunningThreadCount--;
|
mRunningThreadCount--;
|
||||||
if (mRunningThreadCount == 0)
|
if (mRunningThreadCount == 0) {
|
||||||
{
|
|
||||||
emit Done();
|
emit Done();
|
||||||
|
|
||||||
mScanDuration = mTime.elapsed();
|
mScanDuration = mTime.elapsed();
|
||||||
|
@ -137,8 +129,7 @@ void ThreadHandler::ThreadDone()
|
||||||
|
|
||||||
void ThreadHandler::Stop()
|
void ThreadHandler::Stop()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mThreads.size(); i++)
|
for (int i = 0; i < mThreads.size(); i++) {
|
||||||
{
|
|
||||||
mThreads[i]->stop();
|
mThreads[i]->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,7 @@
|
||||||
* @brief This class handles creating threadresult and starting threads
|
* @brief This class handles creating threadresult and starting threads
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ThreadHandler : public QObject
|
class ThreadHandler : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ThreadHandler(QObject *parent = 0);
|
ThreadHandler(QObject *parent = 0);
|
||||||
|
|
|
@ -49,8 +49,7 @@ void ThreadResult::FileChecked(const QString &file)
|
||||||
mProgress += QFile(file).size();
|
mProgress += QFile(file).size();
|
||||||
mFilesChecked ++;
|
mFilesChecked ++;
|
||||||
|
|
||||||
if (mMaxProgress > 0)
|
if (mMaxProgress > 0) {
|
||||||
{
|
|
||||||
const int value = static_cast<int>(PROGRESS_MAX * mProgress / mMaxProgress);
|
const int value = static_cast<int>(PROGRESS_MAX * mProgress / mMaxProgress);
|
||||||
const QString description = tr("%1 of %2 files checked").arg(mFilesChecked).arg(mTotalFiles);
|
const QString description = tr("%1 of %2 files checked").arg(mFilesChecked).arg(mTotalFiles);
|
||||||
|
|
||||||
|
@ -67,8 +66,7 @@ void ThreadResult::reportErr(const ErrorLogger::ErrorMessage &msg)
|
||||||
|
|
||||||
for (std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator tok = msg._callStack.begin();
|
for (std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator tok = msg._callStack.begin();
|
||||||
tok != msg._callStack.end();
|
tok != msg._callStack.end();
|
||||||
++tok)
|
++tok) {
|
||||||
{
|
|
||||||
files << QString((*tok).getfile(false).c_str());
|
files << QString((*tok).getfile(false).c_str());
|
||||||
lines << (*tok).line;
|
lines << (*tok).line;
|
||||||
}
|
}
|
||||||
|
@ -92,8 +90,7 @@ void ThreadResult::reportErr(const ErrorLogger::ErrorMessage &msg)
|
||||||
QString ThreadResult::GetNextFile()
|
QString ThreadResult::GetNextFile()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
if (mFiles.size() == 0)
|
if (mFiles.size() == 0) {
|
||||||
{
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,8 +108,7 @@ void ThreadResult::SetFiles(const QStringList &files)
|
||||||
// Determine the total size of all of the files to check, so that we can
|
// Determine the total size of all of the files to check, so that we can
|
||||||
// show an accurate progress estimate
|
// show an accurate progress estimate
|
||||||
quint64 sizeOfFiles = 0;
|
quint64 sizeOfFiles = 0;
|
||||||
foreach(const QString& file, files)
|
foreach(const QString& file, files) {
|
||||||
{
|
|
||||||
sizeOfFiles += QFile(file).size();
|
sizeOfFiles += QFile(file).size();
|
||||||
}
|
}
|
||||||
mMaxProgress = sizeOfFiles;
|
mMaxProgress = sizeOfFiles;
|
||||||
|
|
|
@ -35,8 +35,7 @@ class ErrorItem;
|
||||||
* @brief Threads use this class to obtain new files to process and to publish results
|
* @brief Threads use this class to obtain new files to process and to publish results
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ThreadResult : public QObject, public ErrorLogger
|
class ThreadResult : public QObject, public ErrorLogger {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ThreadResult();
|
ThreadResult();
|
||||||
|
|
|
@ -43,12 +43,9 @@ TranslationHandler::TranslationHandler(QObject *parent) :
|
||||||
|
|
||||||
//Load English as a fallback language
|
//Load English as a fallback language
|
||||||
QTranslator *english = new QTranslator();
|
QTranslator *english = new QTranslator();
|
||||||
if (english->load("cppcheck_en"))
|
if (english->load("cppcheck_en")) {
|
||||||
{
|
|
||||||
qApp->installTranslator(english);
|
qApp->installTranslator(english);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << "Failed to load English translation!";
|
qDebug() << "Failed to load English translation!";
|
||||||
delete english;
|
delete english;
|
||||||
}
|
}
|
||||||
|
@ -61,8 +58,7 @@ TranslationHandler::~TranslationHandler()
|
||||||
const QStringList TranslationHandler::GetNames() const
|
const QStringList TranslationHandler::GetNames() const
|
||||||
{
|
{
|
||||||
QStringList names;
|
QStringList names;
|
||||||
foreach(TranslationInfo translation, mTranslations)
|
foreach(TranslationInfo translation, mTranslations) {
|
||||||
{
|
|
||||||
names.append(translation.mName);
|
names.append(translation.mName);
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
|
@ -71,11 +67,9 @@ const QStringList TranslationHandler::GetNames() const
|
||||||
bool TranslationHandler::SetLanguage(const QString &code, QString &error)
|
bool TranslationHandler::SetLanguage(const QString &code, QString &error)
|
||||||
{
|
{
|
||||||
//If English is the language
|
//If English is the language
|
||||||
if (code == "en")
|
if (code == "en") {
|
||||||
{
|
|
||||||
//Just remove all extra translators
|
//Just remove all extra translators
|
||||||
if (mTranslator)
|
if (mTranslator) {
|
||||||
{
|
|
||||||
qApp->removeTranslator(mTranslator);
|
qApp->removeTranslator(mTranslator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,18 +79,15 @@ bool TranslationHandler::SetLanguage(const QString &code, QString &error)
|
||||||
|
|
||||||
//Make sure the translator is otherwise valid
|
//Make sure the translator is otherwise valid
|
||||||
int index = GetLanguageIndexByCode(code);
|
int index = GetLanguageIndexByCode(code);
|
||||||
if (index == -1)
|
if (index == -1) {
|
||||||
{
|
|
||||||
error = QObject::tr("Unknown language specified!");
|
error = QObject::tr("Unknown language specified!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Load the new language
|
//Load the new language
|
||||||
if (!mTranslator->load(mTranslations[index].mFilename))
|
if (!mTranslator->load(mTranslations[index].mFilename)) {
|
||||||
{
|
|
||||||
//If it failed, lets check if the default file exists
|
//If it failed, lets check if the default file exists
|
||||||
if (!QFile::exists(mTranslations[index].mFilename + ".qm"))
|
if (!QFile::exists(mTranslations[index].mFilename + ".qm")) {
|
||||||
{
|
|
||||||
error = QObject::tr("Language file %1 not found!");
|
error = QObject::tr("Language file %1 not found!");
|
||||||
error = error.arg(mTranslations[index].mFilename + ".qm");
|
error = error.arg(mTranslations[index].mFilename + ".qm");
|
||||||
return false;
|
return false;
|
||||||
|
@ -136,8 +127,7 @@ QString TranslationHandler::SuggestLanguage() const
|
||||||
int index = GetLanguageIndexByCode(language);
|
int index = GetLanguageIndexByCode(language);
|
||||||
|
|
||||||
//If nothing found, return English
|
//If nothing found, return English
|
||||||
if (index < 0)
|
if (index < 0) {
|
||||||
{
|
|
||||||
return "en";
|
return "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,10 +146,8 @@ void TranslationHandler::AddTranslation(const char *name, const char *filename)
|
||||||
int TranslationHandler::GetLanguageIndexByCode(const QString &code) const
|
int TranslationHandler::GetLanguageIndexByCode(const QString &code) const
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int i = 0; i < mTranslations.size(); i++)
|
for (int i = 0; i < mTranslations.size(); i++) {
|
||||||
{
|
if (mTranslations[i].mCode == code) {
|
||||||
if (mTranslations[i].mCode == code)
|
|
||||||
{
|
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,7 @@
|
||||||
* @brief Information for one translation.
|
* @brief Information for one translation.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct TranslationInfo
|
struct TranslationInfo {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* @brief Readable name for the translation (e.g. "English").
|
* @brief Readable name for the translation (e.g. "English").
|
||||||
*
|
*
|
||||||
|
@ -59,8 +58,7 @@ struct TranslationInfo
|
||||||
* track which translation is the currently active translation.
|
* track which translation is the currently active translation.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class TranslationHandler : QObject
|
class TranslationHandler : QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
TranslationHandler(QObject *parent = 0);
|
TranslationHandler(QObject *parent = 0);
|
||||||
|
@ -78,8 +76,7 @@ public:
|
||||||
* @return List of available translations.
|
* @return List of available translations.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
QList<TranslationInfo> GetTranslations() const
|
QList<TranslationInfo> GetTranslations() const {
|
||||||
{
|
|
||||||
return mTranslations;
|
return mTranslations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,7 @@ TxtReport::~TxtReport()
|
||||||
bool TxtReport::Create()
|
bool TxtReport::Create()
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (Report::Create())
|
if (Report::Create()) {
|
||||||
{
|
|
||||||
mTxtWriter.setDevice(Report::GetFile());
|
mTxtWriter.setDevice(Report::GetFile());
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
@ -61,23 +60,19 @@ void TxtReport::WriteError(const ErrorItem &error)
|
||||||
|
|
||||||
QString line;
|
QString line;
|
||||||
|
|
||||||
for (int i = 0; i < error.lines.size(); i++)
|
for (int i = 0; i < error.lines.size(); i++) {
|
||||||
{
|
|
||||||
const QString file = QDir::toNativeSeparators(error.files[i]);
|
const QString file = QDir::toNativeSeparators(error.files[i]);
|
||||||
line += QString("[%1:%2]").arg(file).arg(error.lines[i]);
|
line += QString("[%1:%2]").arg(file).arg(error.lines[i]);
|
||||||
if (i < error.lines.size() - 1 && error.lines.size() > 0)
|
if (i < error.lines.size() - 1 && error.lines.size() > 0) {
|
||||||
{
|
|
||||||
line += " -> ";
|
line += " -> ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == error.lines.size() - 1)
|
if (i == error.lines.size() - 1) {
|
||||||
{
|
|
||||||
line += ": ";
|
line += ": ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line += QString("(%1) ").arg(GuiSeverity::toString(error.severity));
|
line += QString("(%1) ").arg(GuiSeverity::toString(error.severity));
|
||||||
if (error.inconclusive)
|
if (error.inconclusive) {
|
||||||
{
|
|
||||||
line += tr("inconclusive");
|
line += tr("inconclusive");
|
||||||
line += " ";
|
line += " ";
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,7 @@
|
||||||
* @brief Text file report.
|
* @brief Text file report.
|
||||||
* This report mimics the output of the command line cppcheck.
|
* This report mimics the output of the command line cppcheck.
|
||||||
*/
|
*/
|
||||||
class TxtReport : public Report
|
class TxtReport : public Report {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -62,20 +62,15 @@ int XmlReport::determineVersion(const QString &filename)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
QXmlStreamReader reader(&file);
|
QXmlStreamReader reader(&file);
|
||||||
while (!reader.atEnd())
|
while (!reader.atEnd()) {
|
||||||
{
|
switch (reader.readNext()) {
|
||||||
switch (reader.readNext())
|
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
if (reader.name() == ResultElementName)
|
if (reader.name() == ResultElementName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = reader.attributes();
|
QXmlStreamAttributes attribs = reader.attributes();
|
||||||
if (attribs.hasAttribute(QString(VersionAttribute)))
|
if (attribs.hasAttribute(QString(VersionAttribute))) {
|
||||||
{
|
|
||||||
int ver = attribs.value("", VersionAttribute).toString().toInt();
|
int ver = attribs.value("", VersionAttribute).toString().toInt();
|
||||||
return ver;
|
return ver;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -33,8 +33,7 @@ class QObject;
|
||||||
/**
|
/**
|
||||||
* @brief Base class for XML report classes.
|
* @brief Base class for XML report classes.
|
||||||
*/
|
*/
|
||||||
class XmlReport : public Report
|
class XmlReport : public Report {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
XmlReport(const QString &filename, QObject * parent = 0);
|
XmlReport(const QString &filename, QObject * parent = 0);
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,7 @@ XmlReportV1::~XmlReportV1()
|
||||||
bool XmlReportV1::Create()
|
bool XmlReportV1::Create()
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (Report::Create())
|
if (Report::Create()) {
|
||||||
{
|
|
||||||
mXmlWriter = new QXmlStreamWriter(Report::GetFile());
|
mXmlWriter = new QXmlStreamWriter(Report::GetFile());
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
@ -64,8 +63,7 @@ bool XmlReportV1::Create()
|
||||||
bool XmlReportV1::Open()
|
bool XmlReportV1::Open()
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (Report::Open())
|
if (Report::Open()) {
|
||||||
{
|
|
||||||
mXmlReader = new QXmlStreamReader(Report::GetFile());
|
mXmlReader = new QXmlStreamReader(Report::GetFile());
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
@ -116,22 +114,18 @@ QList<ErrorItem> XmlReportV1::Read()
|
||||||
{
|
{
|
||||||
QList<ErrorItem> errors;
|
QList<ErrorItem> errors;
|
||||||
bool insideResults = false;
|
bool insideResults = false;
|
||||||
if (!mXmlReader)
|
if (!mXmlReader) {
|
||||||
{
|
|
||||||
qDebug() << "You must Open() the file before reading it!";
|
qDebug() << "You must Open() the file before reading it!";
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
while (!mXmlReader->atEnd())
|
while (!mXmlReader->atEnd()) {
|
||||||
{
|
switch (mXmlReader->readNext()) {
|
||||||
switch (mXmlReader->readNext())
|
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
if (mXmlReader->name() == ResultElementName)
|
if (mXmlReader->name() == ResultElementName)
|
||||||
insideResults = true;
|
insideResults = true;
|
||||||
|
|
||||||
// Read error element from inside result element
|
// Read error element from inside result element
|
||||||
if (insideResults && mXmlReader->name() == ErrorElementName)
|
if (insideResults && mXmlReader->name() == ErrorElementName) {
|
||||||
{
|
|
||||||
ErrorItem item = ReadError(mXmlReader);
|
ErrorItem item = ReadError(mXmlReader);
|
||||||
errors.append(item);
|
errors.append(item);
|
||||||
}
|
}
|
||||||
|
@ -161,8 +155,7 @@ QList<ErrorItem> XmlReportV1::Read()
|
||||||
ErrorItem XmlReportV1::ReadError(QXmlStreamReader *reader)
|
ErrorItem XmlReportV1::ReadError(QXmlStreamReader *reader)
|
||||||
{
|
{
|
||||||
ErrorItem item;
|
ErrorItem item;
|
||||||
if (reader->name().toString() == ErrorElementName)
|
if (reader->name().toString() == ErrorElementName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = reader->attributes();
|
QXmlStreamAttributes attribs = reader->attributes();
|
||||||
QString file = attribs.value("", FilenameAttribute).toString();
|
QString file = attribs.value("", FilenameAttribute).toString();
|
||||||
file = XmlReport::unquoteMessage(file);
|
file = XmlReport::unquoteMessage(file);
|
||||||
|
|
|
@ -36,8 +36,7 @@
|
||||||
* This report outputs XML-formatted report, version 1. The XML format must match command
|
* This report outputs XML-formatted report, version 1. The XML format must match command
|
||||||
* line version's XML output.
|
* line version's XML output.
|
||||||
*/
|
*/
|
||||||
class XmlReportV1 : public XmlReport
|
class XmlReportV1 : public XmlReport {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
XmlReportV1(const QString &filename, QObject * parent = 0);
|
XmlReportV1(const QString &filename, QObject * parent = 0);
|
||||||
virtual ~XmlReportV1();
|
virtual ~XmlReportV1();
|
||||||
|
|
|
@ -59,8 +59,7 @@ XmlReportV2::~XmlReportV2()
|
||||||
bool XmlReportV2::Create()
|
bool XmlReportV2::Create()
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (Report::Create())
|
if (Report::Create()) {
|
||||||
{
|
|
||||||
mXmlWriter = new QXmlStreamWriter(Report::GetFile());
|
mXmlWriter = new QXmlStreamWriter(Report::GetFile());
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
@ -70,8 +69,7 @@ bool XmlReportV2::Create()
|
||||||
bool XmlReportV2::Open()
|
bool XmlReportV2::Open()
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (Report::Open())
|
if (Report::Open()) {
|
||||||
{
|
|
||||||
mXmlReader = new QXmlStreamReader(Report::GetFile());
|
mXmlReader = new QXmlStreamReader(Report::GetFile());
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
@ -122,8 +120,7 @@ void XmlReportV2::WriteError(const ErrorItem &error)
|
||||||
const QString message = XmlReport::quoteMessage(error.message);
|
const QString message = XmlReport::quoteMessage(error.message);
|
||||||
mXmlWriter->writeAttribute(VerboseAttribute, message);
|
mXmlWriter->writeAttribute(VerboseAttribute, message);
|
||||||
|
|
||||||
for (int i = 0; i < error.files.count(); i++)
|
for (int i = 0; i < error.files.count(); i++) {
|
||||||
{
|
|
||||||
mXmlWriter->writeStartElement(LocationElementName);
|
mXmlWriter->writeStartElement(LocationElementName);
|
||||||
|
|
||||||
QString file = QDir::toNativeSeparators(error.files[i]);
|
QString file = QDir::toNativeSeparators(error.files[i]);
|
||||||
|
@ -142,22 +139,18 @@ QList<ErrorItem> XmlReportV2::Read()
|
||||||
{
|
{
|
||||||
QList<ErrorItem> errors;
|
QList<ErrorItem> errors;
|
||||||
bool insideResults = false;
|
bool insideResults = false;
|
||||||
if (!mXmlReader)
|
if (!mXmlReader) {
|
||||||
{
|
|
||||||
qDebug() << "You must Open() the file before reading it!";
|
qDebug() << "You must Open() the file before reading it!";
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
while (!mXmlReader->atEnd())
|
while (!mXmlReader->atEnd()) {
|
||||||
{
|
switch (mXmlReader->readNext()) {
|
||||||
switch (mXmlReader->readNext())
|
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
if (mXmlReader->name() == ResultElementName)
|
if (mXmlReader->name() == ResultElementName)
|
||||||
insideResults = true;
|
insideResults = true;
|
||||||
|
|
||||||
// Read error element from inside result element
|
// Read error element from inside result element
|
||||||
if (insideResults && mXmlReader->name() == ErrorElementName)
|
if (insideResults && mXmlReader->name() == ErrorElementName) {
|
||||||
{
|
|
||||||
ErrorItem item = ReadError(mXmlReader);
|
ErrorItem item = ReadError(mXmlReader);
|
||||||
errors.append(item);
|
errors.append(item);
|
||||||
}
|
}
|
||||||
|
@ -198,8 +191,7 @@ ErrorItem XmlReportV2::ReadError(QXmlStreamReader *reader)
|
||||||
ErrorItem item;
|
ErrorItem item;
|
||||||
|
|
||||||
// Read error element from inside errors element
|
// Read error element from inside errors element
|
||||||
if (mXmlReader->name() == ErrorElementName)
|
if (mXmlReader->name() == ErrorElementName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = reader->attributes();
|
QXmlStreamAttributes attribs = reader->attributes();
|
||||||
item.errorId = attribs.value("", IdAttribute).toString();
|
item.errorId = attribs.value("", IdAttribute).toString();
|
||||||
item.severity = GuiSeverity::fromString(attribs.value("", SeverityAttribute).toString());
|
item.severity = GuiSeverity::fromString(attribs.value("", SeverityAttribute).toString());
|
||||||
|
@ -210,15 +202,12 @@ ErrorItem XmlReportV2::ReadError(QXmlStreamReader *reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool errorRead = false;
|
bool errorRead = false;
|
||||||
while (!errorRead && !mXmlReader->atEnd())
|
while (!errorRead && !mXmlReader->atEnd()) {
|
||||||
{
|
switch (mXmlReader->readNext()) {
|
||||||
switch (mXmlReader->readNext())
|
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
case QXmlStreamReader::StartElement:
|
||||||
|
|
||||||
// Read location element from inside error element
|
// Read location element from inside error element
|
||||||
if (mXmlReader->name() == LocationElementName)
|
if (mXmlReader->name() == LocationElementName) {
|
||||||
{
|
|
||||||
QXmlStreamAttributes attribs = mXmlReader->attributes();
|
QXmlStreamAttributes attribs = mXmlReader->attributes();
|
||||||
QString file = attribs.value("", FilenameAttribute).toString();
|
QString file = attribs.value("", FilenameAttribute).toString();
|
||||||
file = XmlReport::unquoteMessage(file);
|
file = XmlReport::unquoteMessage(file);
|
||||||
|
|
|
@ -37,8 +37,7 @@
|
||||||
* This report outputs XML-formatted report. The XML format must match command
|
* This report outputs XML-formatted report. The XML format must match command
|
||||||
* line version's XML output.
|
* line version's XML output.
|
||||||
*/
|
*/
|
||||||
class XmlReportV2 : public XmlReport
|
class XmlReportV2 : public XmlReport {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
XmlReportV2(const QString &filename, QObject * parent = 0);
|
XmlReportV2(const QString &filename, QObject * parent = 0);
|
||||||
virtual ~XmlReportV2();
|
virtual ~XmlReportV2();
|
||||||
|
|
52
lib/check.h
52
lib/check.h
|
@ -35,8 +35,7 @@
|
||||||
* @brief Interface class that cppcheck uses to communicate with the checks.
|
* @brief Interface class that cppcheck uses to communicate with the checks.
|
||||||
* All checking classes must inherit from this class
|
* All checking classes must inherit from this class
|
||||||
*/
|
*/
|
||||||
class Check
|
class Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** This constructor is used when registering the CheckClass */
|
/** This constructor is used when registering the CheckClass */
|
||||||
Check(const std::string &aname);
|
Check(const std::string &aname);
|
||||||
|
@ -46,16 +45,14 @@ public:
|
||||||
: _name(aname), _tokenizer(tokenizer), _settings(settings), _errorLogger(errorLogger)
|
: _name(aname), _tokenizer(tokenizer), _settings(settings), _errorLogger(errorLogger)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual ~Check()
|
virtual ~Check() {
|
||||||
{
|
|
||||||
#ifndef DJGPP
|
#ifndef DJGPP
|
||||||
instances().remove(this);
|
instances().remove(this);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** List of registered check classes. This is used by Cppcheck to run checks and generate documentation */
|
/** List of registered check classes. This is used by Cppcheck to run checks and generate documentation */
|
||||||
static std::list<Check *> &instances()
|
static std::list<Check *> &instances() {
|
||||||
{
|
|
||||||
static std::list<Check *> _instances;
|
static std::list<Check *> _instances;
|
||||||
return _instances;
|
return _instances;
|
||||||
}
|
}
|
||||||
|
@ -65,8 +62,7 @@ public:
|
||||||
* @param tokens The tokens to analyse
|
* @param tokens The tokens to analyse
|
||||||
* @param result container where results are stored
|
* @param result container where results are stored
|
||||||
*/
|
*/
|
||||||
virtual void analyse(const Token *tokens, std::set<std::string> &result) const
|
virtual void analyse(const Token *tokens, std::set<std::string> &result) const {
|
||||||
{
|
|
||||||
// suppress compiler warnings
|
// suppress compiler warnings
|
||||||
(void)tokens;
|
(void)tokens;
|
||||||
(void)result;
|
(void)result;
|
||||||
|
@ -76,8 +72,7 @@ public:
|
||||||
* Save analysis data - the caller ensures thread safety
|
* Save analysis data - the caller ensures thread safety
|
||||||
* @param data The data where the results are saved
|
* @param data The data where the results are saved
|
||||||
*/
|
*/
|
||||||
virtual void saveAnalysisData(const std::set<std::string> &data) const
|
virtual void saveAnalysisData(const std::set<std::string> &data) const {
|
||||||
{
|
|
||||||
// suppress compiler warnings
|
// suppress compiler warnings
|
||||||
(void)data;
|
(void)data;
|
||||||
}
|
}
|
||||||
|
@ -93,8 +88,7 @@ public:
|
||||||
virtual void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) = 0;
|
virtual void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) = 0;
|
||||||
|
|
||||||
/** class name, used to generate documentation */
|
/** class name, used to generate documentation */
|
||||||
std::string name() const
|
std::string name() const {
|
||||||
{
|
|
||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +100,7 @@ public:
|
||||||
* This is for for printout out the error list with --errorlist
|
* This is for for printout out the error list with --errorlist
|
||||||
* @param errmsg Error message to write
|
* @param errmsg Error message to write
|
||||||
*/
|
*/
|
||||||
static void reportError(const ErrorLogger::ErrorMessage &errmsg)
|
static void reportError(const ErrorLogger::ErrorMessage &errmsg) {
|
||||||
{
|
|
||||||
std::cout << errmsg.toXML(true, 1) << std::endl;
|
std::cout << errmsg.toXML(true, 1) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,8 +111,7 @@ protected:
|
||||||
ErrorLogger * const _errorLogger;
|
ErrorLogger * const _errorLogger;
|
||||||
|
|
||||||
/** report an error */
|
/** report an error */
|
||||||
void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg)
|
void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg) {
|
||||||
{
|
|
||||||
std::list<const Token *> callstack;
|
std::list<const Token *> callstack;
|
||||||
if (tok)
|
if (tok)
|
||||||
callstack.push_back(tok);
|
callstack.push_back(tok);
|
||||||
|
@ -127,14 +119,12 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** report an error */
|
/** report an error */
|
||||||
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, std::string msg)
|
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, std::string msg) {
|
||||||
{
|
|
||||||
reportError(callstack, severity, id, msg, false);
|
reportError(callstack, severity, id, msg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** report an inconclusive error */
|
/** report an inconclusive error */
|
||||||
void reportInconclusiveError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg)
|
void reportInconclusiveError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg) {
|
||||||
{
|
|
||||||
std::list<const Token *> callstack;
|
std::list<const Token *> callstack;
|
||||||
if (tok)
|
if (tok)
|
||||||
callstack.push_back(tok);
|
callstack.push_back(tok);
|
||||||
|
@ -142,8 +132,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** report an inconclusive error */
|
/** report an inconclusive error */
|
||||||
void reportInconclusiveError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, std::string msg)
|
void reportInconclusiveError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, std::string msg) {
|
||||||
{
|
|
||||||
reportError(callstack, severity, id, msg, true);
|
reportError(callstack, severity, id, msg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +142,9 @@ private:
|
||||||
void operator=(const Check &);
|
void operator=(const Check &);
|
||||||
|
|
||||||
/** report an error */
|
/** report an error */
|
||||||
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, std::string msg, bool inconclusive)
|
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, std::string msg, bool inconclusive) {
|
||||||
{
|
|
||||||
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
||||||
for (std::list<const Token *>::const_iterator it = callstack.begin(); it != callstack.end(); ++it)
|
for (std::list<const Token *>::const_iterator it = callstack.begin(); it != callstack.end(); ++it) {
|
||||||
{
|
|
||||||
// --errorlist can provide null values here
|
// --errorlist can provide null values here
|
||||||
if (!(*it))
|
if (!(*it))
|
||||||
continue;
|
continue;
|
||||||
|
@ -179,16 +166,13 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std
|
namespace std {
|
||||||
{
|
/** compare the names of Check classes, used when sorting the Check descendants */
|
||||||
/** compare the names of Check classes, used when sorting the Check descendants */
|
template <> struct less<Check *> {
|
||||||
template <> struct less<Check *>
|
bool operator()(const Check *p1, const Check *p2) const {
|
||||||
{
|
|
||||||
bool operator()(const Check *p1, const Check *p2) const
|
|
||||||
{
|
|
||||||
return (p1->name() < p2->name());
|
return (p1->name() < p2->name());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Check::Check(const std::string &aname)
|
inline Check::Check(const std::string &aname)
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Register this check class (by creating a static instance of it)
|
// Register this check class (by creating a static instance of it)
|
||||||
namespace
|
namespace {
|
||||||
{
|
Check64BitPortability instance;
|
||||||
Check64BitPortability instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Is given variable a pointer or array? */
|
/** Is given variable a pointer or array? */
|
||||||
|
@ -49,10 +48,8 @@ void Check64BitPortability::pointerassignment()
|
||||||
if (!_settings->isEnabled("portability"))
|
if (!_settings->isEnabled("portability"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
if (Token::Match(tok, "[;{}] %var% = %var% [;+]")) {
|
||||||
if (Token::Match(tok, "[;{}] %var% = %var% [;+]"))
|
|
||||||
{
|
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
const Variable *var1(symbolDatabase->getVariableFromVarId(tok->tokAt(1)->varId()));
|
const Variable *var1(symbolDatabase->getVariableFromVarId(tok->tokAt(1)->varId()));
|
||||||
|
@ -61,8 +58,7 @@ void Check64BitPortability::pointerassignment()
|
||||||
if (isaddr(var1) && isint(var2) && tok->strAt(4) != "+")
|
if (isaddr(var1) && isint(var2) && tok->strAt(4) != "+")
|
||||||
assignmentIntegerToAddressError(tok->next());
|
assignmentIntegerToAddressError(tok->next());
|
||||||
|
|
||||||
else if (isint(var1) && isaddr(var2) && !tok->tokAt(3)->isPointerCompare())
|
else if (isint(var1) && isaddr(var2) && !tok->tokAt(3)->isPointerCompare()) {
|
||||||
{
|
|
||||||
// assigning address => warning
|
// assigning address => warning
|
||||||
// some trivial addition => warning
|
// some trivial addition => warning
|
||||||
if (Token::Match(tok->tokAt(4), "+ %any% !!;"))
|
if (Token::Match(tok->tokAt(4), "+ %any% !!;"))
|
||||||
|
|
|
@ -32,30 +32,25 @@
|
||||||
* @brief Check for 64-bit portability issues
|
* @brief Check for 64-bit portability issues
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Check64BitPortability : public Check
|
class Check64BitPortability : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** This constructor is used when registering the Check64BitPortability */
|
/** This constructor is used when registering the Check64BitPortability */
|
||||||
Check64BitPortability() : Check(myName())
|
Check64BitPortability() : Check(myName()) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This constructor is used when running checks. */
|
/** This constructor is used when running checks. */
|
||||||
Check64BitPortability(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
Check64BitPortability(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
: Check(myName(), tokenizer, settings, errorLogger)
|
: Check(myName(), tokenizer, settings, errorLogger) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Run checks against the normal token list */
|
/** @brief Run checks against the normal token list */
|
||||||
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
Check64BitPortability check64BitPortability(tokenizer, settings, errorLogger);
|
Check64BitPortability check64BitPortability(tokenizer, settings, errorLogger);
|
||||||
check64BitPortability.pointerassignment();
|
check64BitPortability.pointerassignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Run checks against the simplified token list */
|
/** @brief Run checks against the simplified token list */
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
(void)tokenizer;
|
(void)tokenizer;
|
||||||
(void)settings;
|
(void)settings;
|
||||||
(void)errorLogger;
|
(void)errorLogger;
|
||||||
|
@ -69,20 +64,17 @@ private:
|
||||||
void assignmentAddressToIntegerError(const Token *tok);
|
void assignmentAddressToIntegerError(const Token *tok);
|
||||||
void assignmentIntegerToAddressError(const Token *tok);
|
void assignmentIntegerToAddressError(const Token *tok);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
Check64BitPortability c(0, settings, errorLogger);
|
Check64BitPortability c(0, settings, errorLogger);
|
||||||
c.assignmentAddressToIntegerError(0);
|
c.assignmentAddressToIntegerError(0);
|
||||||
c.assignmentIntegerToAddressError(0);
|
c.assignmentIntegerToAddressError(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "64-bit portability";
|
return "64-bit portability";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Check if there is 64-bit portability issues:\n"
|
return "Check if there is 64-bit portability issues:\n"
|
||||||
" * assign address to/from int/long";
|
" * assign address to/from int/long";
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Register this check class (by creating a static instance of it)
|
// Register this check class (by creating a static instance of it)
|
||||||
namespace
|
namespace {
|
||||||
{
|
CheckAssignIf instance;
|
||||||
CheckAssignIf instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,13 +36,11 @@ void CheckAssignIf::assignIf()
|
||||||
if (!_settings->isEnabled("style"))
|
if (!_settings->isEnabled("style"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
if (tok->str() != "=")
|
if (tok->str() != "=")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (Token::Match(tok->tokAt(-2), "[;{}] %var% = %var% [&|] %num% ;"))
|
if (Token::Match(tok->tokAt(-2), "[;{}] %var% = %var% [&|] %num% ;")) {
|
||||||
{
|
|
||||||
const unsigned int varid(tok->previous()->varId());
|
const unsigned int varid(tok->previous()->varId());
|
||||||
if (varid == 0)
|
if (varid == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -54,12 +51,10 @@ void CheckAssignIf::assignIf()
|
||||||
if (num < 0)
|
if (num < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const Token *tok2 = tok->tokAt(4); tok2; tok2 = tok2->next())
|
for (const Token *tok2 = tok->tokAt(4); tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
if (tok2->str() == "(" || tok2->str() == "}" || tok2->str() == "=")
|
if (tok2->str() == "(" || tok2->str() == "}" || tok2->str() == "=")
|
||||||
break;
|
break;
|
||||||
if (Token::Match(tok2,"if ( %varid% %any% %num% &&|%oror%|)", varid))
|
if (Token::Match(tok2,"if ( %varid% %any% %num% &&|%oror%|)", varid)) {
|
||||||
{
|
|
||||||
const std::string op(tok2->strAt(3));
|
const std::string op(tok2->strAt(3));
|
||||||
const MathLib::bigint num2 = MathLib::toLongNumber(tok2->strAt(4));
|
const MathLib::bigint num2 = MathLib::toLongNumber(tok2->strAt(4));
|
||||||
if (op == "==" && (num & num2) != ((bitop=='&') ? num2 : num))
|
if (op == "==" && (num & num2) != ((bitop=='&') ? num2 : num))
|
||||||
|
@ -89,20 +84,17 @@ void CheckAssignIf::comparison()
|
||||||
if (!_settings->isEnabled("style"))
|
if (!_settings->isEnabled("style"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
if (tok->str() != "&")
|
if (tok->str() != "&")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (Token::Match(tok, "& %num% )| ==|!= %num% &&|%oror%|)"))
|
if (Token::Match(tok, "& %num% )| ==|!= %num% &&|%oror%|)")) {
|
||||||
{
|
|
||||||
const MathLib::bigint num1 = MathLib::toLongNumber(tok->strAt(1));
|
const MathLib::bigint num1 = MathLib::toLongNumber(tok->strAt(1));
|
||||||
if (num1 < 0)
|
if (num1 < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Token *compareToken = tok->tokAt(2);
|
const Token *compareToken = tok->tokAt(2);
|
||||||
if (compareToken->str() == ")")
|
if (compareToken->str() == ")") {
|
||||||
{
|
|
||||||
if (!Token::Match(compareToken->link()->previous(), "(|%oror%|&&"))
|
if (!Token::Match(compareToken->link()->previous(), "(|%oror%|&&"))
|
||||||
continue;
|
continue;
|
||||||
compareToken = compareToken->next();
|
compareToken = compareToken->next();
|
||||||
|
@ -112,8 +104,7 @@ void CheckAssignIf::comparison()
|
||||||
if (num2 < 0)
|
if (num2 < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((num1 & num2) != num2)
|
if ((num1 & num2) != num2) {
|
||||||
{
|
|
||||||
const std::string op(compareToken->str());
|
const std::string op(compareToken->str());
|
||||||
comparisonError(tok, op=="==" ? false : true);
|
comparisonError(tok, op=="==" ? false : true);
|
||||||
}
|
}
|
||||||
|
@ -145,10 +136,8 @@ void CheckAssignIf::multiCondition()
|
||||||
if (!_settings->isEnabled("style"))
|
if (!_settings->isEnabled("style"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
if (Token::Match(tok, "if ( %var% & %num% ) {")) {
|
||||||
if (Token::Match(tok, "if ( %var% & %num% ) {"))
|
|
||||||
{
|
|
||||||
const unsigned int varid(tok->tokAt(2)->varId());
|
const unsigned int varid(tok->tokAt(2)->varId());
|
||||||
if (varid == 0)
|
if (varid == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -158,8 +147,7 @@ void CheckAssignIf::multiCondition()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Token *tok2 = tok->tokAt(6)->link();
|
const Token *tok2 = tok->tokAt(6)->link();
|
||||||
while (Token::simpleMatch(tok2, "} else { if ("))
|
while (Token::simpleMatch(tok2, "} else { if (")) {
|
||||||
{
|
|
||||||
// Goto '('
|
// Goto '('
|
||||||
const Token * const opar = tok2->tokAt(4);
|
const Token * const opar = tok2->tokAt(4);
|
||||||
|
|
||||||
|
@ -169,14 +157,12 @@ void CheckAssignIf::multiCondition()
|
||||||
tok2 = tok2->next()->link();
|
tok2 = tok2->next()->link();
|
||||||
|
|
||||||
// check condition..
|
// check condition..
|
||||||
if (Token::Match(opar, "( %varid% ==|& %num% &&|%oror%|)", varid))
|
if (Token::Match(opar, "( %varid% ==|& %num% &&|%oror%|)", varid)) {
|
||||||
{
|
|
||||||
const MathLib::bigint num2 = MathLib::toLongNumber(opar->strAt(3));
|
const MathLib::bigint num2 = MathLib::toLongNumber(opar->strAt(3));
|
||||||
if (num2 < 0)
|
if (num2 < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((num1 & num2) == num2)
|
if ((num1 & num2) == num2) {
|
||||||
{
|
|
||||||
multiConditionError(opar, tok->linenr());
|
multiConditionError(opar, tok->linenr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,23 +32,19 @@
|
||||||
* @brief Check for assignment / condition mismatches
|
* @brief Check for assignment / condition mismatches
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CheckAssignIf : public Check
|
class CheckAssignIf : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** This constructor is used when registering the CheckAssignIf */
|
/** This constructor is used when registering the CheckAssignIf */
|
||||||
CheckAssignIf() : Check(myName())
|
CheckAssignIf() : Check(myName()) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This constructor is used when running checks. */
|
/** This constructor is used when running checks. */
|
||||||
CheckAssignIf(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
CheckAssignIf(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
: Check(myName(), tokenizer, settings, errorLogger)
|
: Check(myName(), tokenizer, settings, errorLogger) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Run checks against the simplified token list */
|
/** @brief Run checks against the simplified token list */
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckAssignIf checkAssignIf(tokenizer, settings, errorLogger);
|
CheckAssignIf checkAssignIf(tokenizer, settings, errorLogger);
|
||||||
checkAssignIf.assignIf();
|
checkAssignIf.assignIf();
|
||||||
checkAssignIf.comparison();
|
checkAssignIf.comparison();
|
||||||
|
@ -70,21 +66,18 @@ private:
|
||||||
void comparisonError(const Token *tok, bool result);
|
void comparisonError(const Token *tok, bool result);
|
||||||
void multiConditionError(const Token *tok, unsigned int line1);
|
void multiConditionError(const Token *tok, unsigned int line1);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckAssignIf c(0, settings, errorLogger);
|
CheckAssignIf c(0, settings, errorLogger);
|
||||||
c.assignIfError(0, false);
|
c.assignIfError(0, false);
|
||||||
c.comparisonError(0, false);
|
c.comparisonError(0, false);
|
||||||
c.multiConditionError(0,1);
|
c.multiConditionError(0,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "match assignments and conditions";
|
return "match assignments and conditions";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Match assignments and conditions:\n"
|
return "Match assignments and conditions:\n"
|
||||||
" * Mismatching assignment and comparison => comparison is always true/false\n"
|
" * Mismatching assignment and comparison => comparison is always true/false\n"
|
||||||
" * Mismatching lhs and rhs in comparison => comparison is always true/false\n"
|
" * Mismatching lhs and rhs in comparison => comparison is always true/false\n"
|
||||||
|
|
|
@ -31,9 +31,8 @@
|
||||||
|
|
||||||
|
|
||||||
// Register this check class into cppcheck by creating a static instance of it..
|
// Register this check class into cppcheck by creating a static instance of it..
|
||||||
namespace
|
namespace {
|
||||||
{
|
static CheckAutoVariables instance;
|
||||||
static CheckAutoVariables instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,8 +55,7 @@ bool CheckAutoVariables::isAutoVar(unsigned int varId)
|
||||||
if (!var || !var->isLocal() || var->isStatic() || var->isArray() || var->typeEndToken()->str() == "*")
|
if (!var || !var->isLocal() || var->isStatic() || var->isArray() || var->typeEndToken()->str() == "*")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Token::simpleMatch(var->nameToken()->previous(), "&"))
|
if (Token::simpleMatch(var->nameToken()->previous(), "&")) {
|
||||||
{
|
|
||||||
// address of reference variable can be taken if the address
|
// address of reference variable can be taken if the address
|
||||||
// of the variable it points at is not a auto-var
|
// of the variable it points at is not a auto-var
|
||||||
// TODO: check what the reference variable references.
|
// TODO: check what the reference variable references.
|
||||||
|
@ -83,97 +81,74 @@ void CheckAutoVariables::autoVariables()
|
||||||
|
|
||||||
std::list<Scope>::const_iterator scope;
|
std::list<Scope>::const_iterator scope;
|
||||||
|
|
||||||
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
|
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
|
||||||
{
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (scope->type != Scope::eFunction)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
for (const Token *tok = scope->classDef->next()->link(); tok; tok = tok->next())
|
for (const Token *tok = scope->classDef->next()->link(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
// indentlevel..
|
// indentlevel..
|
||||||
if (tok->str() == "{")
|
if (tok->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
else if (tok->str() == "}")
|
else if (tok->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel <= 1)
|
if (indentlevel <= 1)
|
||||||
break;
|
break;
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Critical assignment
|
//Critical assignment
|
||||||
if (Token::Match(tok, "[;{}] * %var% = & %var%") && errorAv(tok->tokAt(2), tok->tokAt(5)))
|
if (Token::Match(tok, "[;{}] * %var% = & %var%") && errorAv(tok->tokAt(2), tok->tokAt(5))) {
|
||||||
{
|
|
||||||
const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(5)->varId());
|
const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(5)->varId());
|
||||||
if (var && (!var->isClass() || var->type()))
|
if (var && (!var->isClass() || var->type()))
|
||||||
errorAutoVariableAssignment(tok->next(), false);
|
errorAutoVariableAssignment(tok->next(), false);
|
||||||
}
|
} else if (Token::Match(tok, "[;{}] %var% . %var% = & %var%")) {
|
||||||
else if (Token::Match(tok, "[;{}] %var% . %var% = & %var%"))
|
|
||||||
{
|
|
||||||
// TODO: check if the parameter is only changed temporarily (#2969)
|
// TODO: check if the parameter is only changed temporarily (#2969)
|
||||||
if (_settings->inconclusive)
|
if (_settings->inconclusive) {
|
||||||
{
|
|
||||||
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(1)->varId());
|
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(1)->varId());
|
||||||
if (var1 && var1->isArgument() && Token::Match(var1->nameToken()->tokAt(-2), "%type% *"))
|
if (var1 && var1->isArgument() && Token::Match(var1->nameToken()->tokAt(-2), "%type% *")) {
|
||||||
{
|
|
||||||
const Variable * var2 = symbolDatabase->getVariableFromVarId(tok->tokAt(6)->varId());
|
const Variable * var2 = symbolDatabase->getVariableFromVarId(tok->tokAt(6)->varId());
|
||||||
if (var2 && var2->isLocal() && !var2->isStatic() && !Token::simpleMatch(var2->typeEndToken(), "*"))
|
if (var2 && var2->isLocal() && !var2->isStatic() && !Token::simpleMatch(var2->typeEndToken(), "*"))
|
||||||
errorAutoVariableAssignment(tok->next(), _settings->inconclusive);
|
errorAutoVariableAssignment(tok->next(), _settings->inconclusive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tok = tok->tokAt(6);
|
tok = tok->tokAt(6);
|
||||||
}
|
} else if (Token::Match(tok, "[;{}] %var% . %var% = %var% ;")) {
|
||||||
else if (Token::Match(tok, "[;{}] %var% . %var% = %var% ;"))
|
|
||||||
{
|
|
||||||
// TODO: check if the parameter is only changed temporarily (#2969)
|
// TODO: check if the parameter is only changed temporarily (#2969)
|
||||||
if (_settings->inconclusive)
|
if (_settings->inconclusive) {
|
||||||
{
|
|
||||||
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(1)->varId());
|
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(1)->varId());
|
||||||
if (var1 && var1->isArgument() && Token::Match(var1->nameToken()->tokAt(-2), "%type% *"))
|
if (var1 && var1->isArgument() && Token::Match(var1->nameToken()->tokAt(-2), "%type% *")) {
|
||||||
{
|
|
||||||
const Variable * var2 = symbolDatabase->getVariableFromVarId(tok->tokAt(5)->varId());
|
const Variable * var2 = symbolDatabase->getVariableFromVarId(tok->tokAt(5)->varId());
|
||||||
if (var2 && var2->isLocal() && var2->isArray() && !var2->isStatic())
|
if (var2 && var2->isLocal() && var2->isArray() && !var2->isStatic())
|
||||||
errorAutoVariableAssignment(tok->next(), _settings->inconclusive);
|
errorAutoVariableAssignment(tok->next(), _settings->inconclusive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tok = tok->tokAt(5);
|
tok = tok->tokAt(5);
|
||||||
}
|
} else if (Token::Match(tok, "[;{}] * %var% = %var% ;")) {
|
||||||
else if (Token::Match(tok, "[;{}] * %var% = %var% ;"))
|
|
||||||
{
|
|
||||||
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
|
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
|
||||||
if (var1 && var1->isArgument() && Token::Match(var1->nameToken()->tokAt(-3), "%type% * *"))
|
if (var1 && var1->isArgument() && Token::Match(var1->nameToken()->tokAt(-3), "%type% * *")) {
|
||||||
{
|
|
||||||
const Variable * var2 = symbolDatabase->getVariableFromVarId(tok->tokAt(4)->varId());
|
const Variable * var2 = symbolDatabase->getVariableFromVarId(tok->tokAt(4)->varId());
|
||||||
if (var2 && var2->isLocal() && var2->isArray() && !var2->isStatic())
|
if (var2 && var2->isLocal() && var2->isArray() && !var2->isStatic())
|
||||||
errorAutoVariableAssignment(tok->next(), false);
|
errorAutoVariableAssignment(tok->next(), false);
|
||||||
}
|
}
|
||||||
tok = tok->tokAt(4);
|
tok = tok->tokAt(4);
|
||||||
}
|
} else if (Token::Match(tok, "[;{}] %var% [ %any% ] = & %var%") && errorAv(tok->tokAt(1), tok->tokAt(7))) {
|
||||||
else if (Token::Match(tok, "[;{}] %var% [ %any% ] = & %var%") && errorAv(tok->tokAt(1), tok->tokAt(7)))
|
|
||||||
{
|
|
||||||
errorAutoVariableAssignment(tok->next(), false);
|
errorAutoVariableAssignment(tok->next(), false);
|
||||||
}
|
}
|
||||||
// Critical return
|
// Critical return
|
||||||
else if (Token::Match(tok, "return & %var% ;") && isAutoVar(tok->tokAt(2)->varId()))
|
else if (Token::Match(tok, "return & %var% ;") && isAutoVar(tok->tokAt(2)->varId())) {
|
||||||
{
|
|
||||||
errorReturnAddressToAutoVariable(tok);
|
errorReturnAddressToAutoVariable(tok);
|
||||||
}
|
} else if (Token::Match(tok, "return & %var% [") &&
|
||||||
else if (Token::Match(tok, "return & %var% [") &&
|
|
||||||
Token::Match(tok->tokAt(3)->link(), "] ;") &&
|
Token::Match(tok->tokAt(3)->link(), "] ;") &&
|
||||||
isAutoVarArray(tok->tokAt(2)->varId()))
|
isAutoVarArray(tok->tokAt(2)->varId())) {
|
||||||
{
|
|
||||||
errorReturnAddressToAutoVariable(tok);
|
errorReturnAddressToAutoVariable(tok);
|
||||||
}
|
} else if (Token::Match(tok, "return & %var% ;") && tok->tokAt(2)->varId()) {
|
||||||
else if (Token::Match(tok, "return & %var% ;") && tok->tokAt(2)->varId())
|
|
||||||
{
|
|
||||||
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
|
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
|
||||||
if (var1 && var1->isArgument() && var1->typeEndToken()->str() != "&")
|
if (var1 && var1->isArgument() && var1->typeEndToken()->str() != "&")
|
||||||
errorReturnAddressOfFunctionParameter(tok, tok->strAt(2));
|
errorReturnAddressOfFunctionParameter(tok, tok->strAt(2));
|
||||||
}
|
}
|
||||||
// Invalid pointer deallocation
|
// Invalid pointer deallocation
|
||||||
else if (Token::Match(tok, "free ( %var% ) ;") && isAutoVarArray(tok->tokAt(2)->varId()))
|
else if (Token::Match(tok, "free ( %var% ) ;") && isAutoVarArray(tok->tokAt(2)->varId())) {
|
||||||
{
|
|
||||||
errorInvalidDeallocation(tok);
|
errorInvalidDeallocation(tok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,8 +163,7 @@ void CheckAutoVariables::returnPointerToLocalArray()
|
||||||
|
|
||||||
std::list<Scope>::const_iterator scope;
|
std::list<Scope>::const_iterator scope;
|
||||||
|
|
||||||
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
|
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
|
||||||
{
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (scope->type != Scope::eFunction)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
@ -201,8 +175,7 @@ void CheckAutoVariables::returnPointerToLocalArray()
|
||||||
tok = tok->tokAt(-2);
|
tok = tok->tokAt(-2);
|
||||||
|
|
||||||
// have we reached a function that returns a pointer
|
// have we reached a function that returns a pointer
|
||||||
if (Token::Match(tok->tokAt(-2), "%type% *"))
|
if (Token::Match(tok->tokAt(-2), "%type% *")) {
|
||||||
{
|
|
||||||
// go to the '('
|
// go to the '('
|
||||||
const Token *tok2 = scope->classDef->next();
|
const Token *tok2 = scope->classDef->next();
|
||||||
|
|
||||||
|
@ -210,26 +183,22 @@ void CheckAutoVariables::returnPointerToLocalArray()
|
||||||
tok2 = tok2->next()->link();
|
tok2 = tok2->next()->link();
|
||||||
|
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
for (; tok2; tok2 = tok2->next())
|
for (; tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
// indentlevel..
|
// indentlevel..
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel <= 1)
|
if (indentlevel <= 1)
|
||||||
break;
|
break;
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return pointer to local array variable..
|
// Return pointer to local array variable..
|
||||||
if (Token::Match(tok2, "return %var% ;"))
|
if (Token::Match(tok2, "return %var% ;")) {
|
||||||
{
|
|
||||||
const unsigned int varid = tok2->next()->varId();
|
const unsigned int varid = tok2->next()->varId();
|
||||||
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
||||||
|
|
||||||
if (var && var->isLocal() && !var->isStatic() && var->isArray())
|
if (var && var->isLocal() && !var->isStatic() && var->isArray()) {
|
||||||
{
|
|
||||||
errorReturnPointerToLocalArray(tok2);
|
errorReturnPointerToLocalArray(tok2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,17 +219,14 @@ void CheckAutoVariables::errorReturnPointerToLocalArray(const Token *tok)
|
||||||
|
|
||||||
void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inconclusive)
|
void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inconclusive)
|
||||||
{
|
{
|
||||||
if (!inconclusive)
|
if (!inconclusive) {
|
||||||
{
|
|
||||||
reportError(tok, Severity::error, "autoVariables",
|
reportError(tok, Severity::error, "autoVariables",
|
||||||
"Assigning address of local auto-variable to a function parameter.\n"
|
"Assigning address of local auto-variable to a function parameter.\n"
|
||||||
"Dangerous assignment - function parameter takes the address of a local "
|
"Dangerous assignment - function parameter takes the address of a local "
|
||||||
"auto-variable. Local auto-variables are reserved from the stack. And the "
|
"auto-variable. Local auto-variables are reserved from the stack. And the "
|
||||||
"stack is freed when the function ends. So the pointer to a local variable "
|
"stack is freed when the function ends. So the pointer to a local variable "
|
||||||
"is invalid after the function ends.");
|
"is invalid after the function ends.");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
reportInconclusiveError(tok, Severity::error, "autoVariables",
|
reportInconclusiveError(tok, Severity::error, "autoVariables",
|
||||||
"Inconclusive: Assigning address of local auto-variable to a function parameter.\n"
|
"Inconclusive: Assigning address of local auto-variable to a function parameter.\n"
|
||||||
"Inconclusive: function parameter takes the address of a local auto-variable. "
|
"Inconclusive: function parameter takes the address of a local auto-variable. "
|
||||||
|
@ -296,8 +262,7 @@ void CheckAutoVariables::returnReference()
|
||||||
|
|
||||||
std::list<Scope>::const_iterator scope;
|
std::list<Scope>::const_iterator scope;
|
||||||
|
|
||||||
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
|
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
|
||||||
{
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (scope->type != Scope::eFunction)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
@ -310,8 +275,7 @@ void CheckAutoVariables::returnReference()
|
||||||
|
|
||||||
// have we reached a function that returns a reference?
|
// have we reached a function that returns a reference?
|
||||||
if (Token::Match(tok->tokAt(-2), "%type% &") ||
|
if (Token::Match(tok->tokAt(-2), "%type% &") ||
|
||||||
Token::Match(tok->tokAt(-2), "> &"))
|
Token::Match(tok->tokAt(-2), "> &")) {
|
||||||
{
|
|
||||||
// go to the '('
|
// go to the '('
|
||||||
const Token *tok2 = scope->classDef->next();
|
const Token *tok2 = scope->classDef->next();
|
||||||
|
|
||||||
|
@ -319,35 +283,30 @@ void CheckAutoVariables::returnReference()
|
||||||
tok2 = tok2->link();
|
tok2 = tok2->link();
|
||||||
|
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
for (; tok2; tok2 = tok2->next())
|
for (; tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
// indentlevel..
|
// indentlevel..
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel <= 1)
|
if (indentlevel <= 1)
|
||||||
break;
|
break;
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return..
|
// return..
|
||||||
if (Token::Match(tok2, "return %var% ;"))
|
if (Token::Match(tok2, "return %var% ;")) {
|
||||||
{
|
|
||||||
// is the returned variable a local variable?
|
// is the returned variable a local variable?
|
||||||
const unsigned int varid = tok2->next()->varId();
|
const unsigned int varid = tok2->next()->varId();
|
||||||
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
||||||
|
|
||||||
if (var && var->isLocal() && !var->isStatic())
|
if (var && var->isLocal() && !var->isStatic()) {
|
||||||
{
|
|
||||||
// report error..
|
// report error..
|
||||||
errorReturnReference(tok2);
|
errorReturnReference(tok2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return reference to temporary..
|
// return reference to temporary..
|
||||||
else if (returnTemporary(tok2))
|
else if (returnTemporary(tok2)) {
|
||||||
{
|
|
||||||
// report error..
|
// report error..
|
||||||
errorReturnTempReference(tok2);
|
errorReturnTempReference(tok2);
|
||||||
}
|
}
|
||||||
|
@ -382,8 +341,7 @@ void CheckAutoVariables::returncstr()
|
||||||
|
|
||||||
std::list<Scope>::const_iterator scope;
|
std::list<Scope>::const_iterator scope;
|
||||||
|
|
||||||
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
|
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
|
||||||
{
|
|
||||||
// only check functions
|
// only check functions
|
||||||
if (scope->type != Scope::eFunction)
|
if (scope->type != Scope::eFunction)
|
||||||
continue;
|
continue;
|
||||||
|
@ -395,8 +353,7 @@ void CheckAutoVariables::returncstr()
|
||||||
tok = tok->tokAt(-2);
|
tok = tok->tokAt(-2);
|
||||||
|
|
||||||
// have we reached a function that returns a const char *
|
// have we reached a function that returns a const char *
|
||||||
if (Token::simpleMatch(tok->tokAt(-3), "const char *"))
|
if (Token::simpleMatch(tok->tokAt(-3), "const char *")) {
|
||||||
{
|
|
||||||
// go to the '('
|
// go to the '('
|
||||||
const Token *tok2 = scope->classDef->next();
|
const Token *tok2 = scope->classDef->next();
|
||||||
|
|
||||||
|
@ -404,35 +361,30 @@ void CheckAutoVariables::returncstr()
|
||||||
tok2 = tok2->next()->link();
|
tok2 = tok2->next()->link();
|
||||||
|
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
for (; tok2; tok2 = tok2->next())
|
for (; tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
// indentlevel..
|
// indentlevel..
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel <= 1)
|
if (indentlevel <= 1)
|
||||||
break;
|
break;
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return..
|
// return..
|
||||||
if (Token::Match(tok2, "return %var% . c_str ( ) ;"))
|
if (Token::Match(tok2, "return %var% . c_str ( ) ;")) {
|
||||||
{
|
|
||||||
// is the returned variable a local variable?
|
// is the returned variable a local variable?
|
||||||
const unsigned int varid = tok2->next()->varId();
|
const unsigned int varid = tok2->next()->varId();
|
||||||
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
||||||
|
|
||||||
if (var && var->isLocal() && !var->isStatic())
|
if (var && var->isLocal() && !var->isStatic()) {
|
||||||
{
|
|
||||||
// report error..
|
// report error..
|
||||||
errorReturnAutocstr(tok2);
|
errorReturnAutocstr(tok2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return pointer to temporary..
|
// return pointer to temporary..
|
||||||
else if (returnTemporary(tok2))
|
else if (returnTemporary(tok2)) {
|
||||||
{
|
|
||||||
// report error..
|
// report error..
|
||||||
errorReturnTempPointer(tok2);
|
errorReturnTempPointer(tok2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
|
||||||
class CheckAutoVariables : public Check
|
class CheckAutoVariables : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** This constructor is used when registering the CheckClass */
|
/** This constructor is used when registering the CheckClass */
|
||||||
CheckAutoVariables() : Check(myName())
|
CheckAutoVariables() : Check(myName())
|
||||||
|
@ -43,14 +42,12 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/** @brief Run checks against the normal token list */
|
/** @brief Run checks against the normal token list */
|
||||||
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckAutoVariables checkAutoVariables(tokenizer, settings, errorLogger);
|
CheckAutoVariables checkAutoVariables(tokenizer, settings, errorLogger);
|
||||||
checkAutoVariables.returnReference();
|
checkAutoVariables.returnReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckAutoVariables checkAutoVariables(tokenizer, settings, errorLogger);
|
CheckAutoVariables checkAutoVariables(tokenizer, settings, errorLogger);
|
||||||
checkAutoVariables.autoVariables();
|
checkAutoVariables.autoVariables();
|
||||||
checkAutoVariables.returnPointerToLocalArray();
|
checkAutoVariables.returnPointerToLocalArray();
|
||||||
|
@ -91,8 +88,7 @@ private:
|
||||||
void errorInvalidDeallocation(const Token *tok);
|
void errorInvalidDeallocation(const Token *tok);
|
||||||
void errorReturnAddressOfFunctionParameter(const Token *tok, const std::string &varname);
|
void errorReturnAddressOfFunctionParameter(const Token *tok, const std::string &varname);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckAutoVariables c(0,settings,errorLogger);
|
CheckAutoVariables c(0,settings,errorLogger);
|
||||||
c.errorAutoVariableAssignment(0, false);
|
c.errorAutoVariableAssignment(0, false);
|
||||||
c.errorReturnAddressToAutoVariable(0);
|
c.errorReturnAddressToAutoVariable(0);
|
||||||
|
@ -105,13 +101,11 @@ private:
|
||||||
c.errorReturnAddressOfFunctionParameter(0, "parameter");
|
c.errorReturnAddressOfFunctionParameter(0, "parameter");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Auto Variables";
|
return "Auto Variables";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "A pointer to a variable is only valid as long as the variable is in scope.\n"
|
return "A pointer to a variable is only valid as long as the variable is in scope.\n"
|
||||||
"Check:\n"
|
"Check:\n"
|
||||||
"* returning a pointer to auto or temporary variable\n"
|
"* returning a pointer to auto or temporary variable\n"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -46,8 +46,7 @@ class Variable;
|
||||||
* I generally use 'buffer overrun' if you for example call a strcpy or
|
* I generally use 'buffer overrun' if you for example call a strcpy or
|
||||||
* other function and pass a buffer and reads or writes too much data.
|
* other function and pass a buffer and reads or writes too much data.
|
||||||
*/
|
*/
|
||||||
class CheckBufferOverrun : public Check
|
class CheckBufferOverrun : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** This constructor is used when registering the CheckClass */
|
/** This constructor is used when registering the CheckClass */
|
||||||
|
@ -59,8 +58,7 @@ public:
|
||||||
: Check(myName(), tokenizer, settings, errorLogger)
|
: Check(myName(), tokenizer, settings, errorLogger)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckBufferOverrun checkBufferOverrun(tokenizer, settings, errorLogger);
|
CheckBufferOverrun checkBufferOverrun(tokenizer, settings, errorLogger);
|
||||||
checkBufferOverrun.bufferOverrun();
|
checkBufferOverrun.bufferOverrun();
|
||||||
checkBufferOverrun.negativeIndex();
|
checkBufferOverrun.negativeIndex();
|
||||||
|
@ -111,8 +109,7 @@ public:
|
||||||
void negativeIndex();
|
void negativeIndex();
|
||||||
|
|
||||||
/** Information about N-dimensional array */
|
/** Information about N-dimensional array */
|
||||||
class ArrayInfo
|
class ArrayInfo {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
/** number of elements of array */
|
/** number of elements of array */
|
||||||
std::vector<MathLib::bigint> _num;
|
std::vector<MathLib::bigint> _num;
|
||||||
|
@ -152,44 +149,36 @@ public:
|
||||||
bool declare(const Token *tok, const Tokenizer &tokenizer);
|
bool declare(const Token *tok, const Tokenizer &tokenizer);
|
||||||
|
|
||||||
/** array sizes */
|
/** array sizes */
|
||||||
const std::vector<MathLib::bigint> &num() const
|
const std::vector<MathLib::bigint> &num() const {
|
||||||
{
|
|
||||||
return _num;
|
return _num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** array size */
|
/** array size */
|
||||||
MathLib::bigint num(size_t index) const
|
MathLib::bigint num(size_t index) const {
|
||||||
{
|
|
||||||
return _num[index];
|
return _num[index];
|
||||||
}
|
}
|
||||||
void num(size_t index, MathLib::bigint number)
|
void num(size_t index, MathLib::bigint number) {
|
||||||
{
|
|
||||||
_num[index] = number;
|
_num[index] = number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** size of each element */
|
/** size of each element */
|
||||||
MathLib::bigint element_size() const
|
MathLib::bigint element_size() const {
|
||||||
{
|
|
||||||
return _element_size;
|
return _element_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Variable name */
|
/** Variable name */
|
||||||
unsigned int varid() const
|
unsigned int varid() const {
|
||||||
{
|
|
||||||
return _varid;
|
return _varid;
|
||||||
}
|
}
|
||||||
void varid(unsigned int id)
|
void varid(unsigned int id) {
|
||||||
{
|
|
||||||
_varid = id;
|
_varid = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Variable name */
|
/** Variable name */
|
||||||
const std::string &varname() const
|
const std::string &varname() const {
|
||||||
{
|
|
||||||
return _varname;
|
return _varname;
|
||||||
}
|
}
|
||||||
void varname(const std::string &name)
|
void varname(const std::string &name) {
|
||||||
{
|
|
||||||
_varname = name;
|
_varname = name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -235,8 +224,7 @@ public:
|
||||||
void arrayIndexThenCheckError(const Token *tok, const std::string &indexName);
|
void arrayIndexThenCheckError(const Token *tok, const std::string &indexName);
|
||||||
void possibleBufferOverrunError(const Token *tok, const std::string &src, const std::string &dst, bool cat);
|
void possibleBufferOverrunError(const Token *tok, const std::string &src, const std::string &dst, bool cat);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckBufferOverrun c(0, settings, errorLogger);
|
CheckBufferOverrun c(0, settings, errorLogger);
|
||||||
std::vector<MathLib::bigint> indexes;
|
std::vector<MathLib::bigint> indexes;
|
||||||
indexes.push_back(2);
|
indexes.push_back(2);
|
||||||
|
@ -254,13 +242,11 @@ public:
|
||||||
c.possibleBufferOverrunError(0, "source", "destination", false);
|
c.possibleBufferOverrunError(0, "source", "destination", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Bounds checking";
|
return "Bounds checking";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "out of bounds checking";
|
return "out of bounds checking";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,8 +32,7 @@ class Token;
|
||||||
|
|
||||||
|
|
||||||
/** @brief %Check classes. Uninitialized member variables, non-conforming operators, missing virtual destructor, etc */
|
/** @brief %Check classes. Uninitialized member variables, non-conforming operators, missing virtual destructor, etc */
|
||||||
class CheckClass : public Check
|
class CheckClass : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** @brief This constructor is used when registering the CheckClass */
|
/** @brief This constructor is used when registering the CheckClass */
|
||||||
CheckClass() : Check(myName()), symbolDatabase(NULL)
|
CheckClass() : Check(myName()), symbolDatabase(NULL)
|
||||||
|
@ -43,8 +42,7 @@ public:
|
||||||
CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger);
|
CheckClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger);
|
||||||
|
|
||||||
/** @brief Run checks on the normal token list */
|
/** @brief Run checks on the normal token list */
|
||||||
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckClass checkClass(tokenizer, settings, errorLogger);
|
CheckClass checkClass(tokenizer, settings, errorLogger);
|
||||||
|
|
||||||
// can't be a simplified check .. the 'sizeof' is used.
|
// can't be a simplified check .. the 'sizeof' is used.
|
||||||
|
@ -52,8 +50,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Run checks on the simplified token list */
|
/** @brief Run checks on the simplified token list */
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckClass checkClass(tokenizer, settings, errorLogger);
|
CheckClass checkClass(tokenizer, settings, errorLogger);
|
||||||
|
|
||||||
// Coding style checks
|
// Coding style checks
|
||||||
|
@ -132,8 +129,7 @@ private:
|
||||||
void checkConstError2(const Token *tok1, const Token *tok2, const std::string &classname, const std::string &funcname);
|
void checkConstError2(const Token *tok1, const Token *tok2, const std::string &classname, const std::string &funcname);
|
||||||
void initializerListError(const Token *tok1,const Token *tok2, const std::string & classname, const std::string &varname);
|
void initializerListError(const Token *tok1,const Token *tok2, const std::string & classname, const std::string &varname);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckClass c(0, settings, errorLogger);
|
CheckClass c(0, settings, errorLogger);
|
||||||
c.noConstructorError(0, "classname", false);
|
c.noConstructorError(0, "classname", false);
|
||||||
c.uninitVarError(0, "classname", "varname");
|
c.uninitVarError(0, "classname", "varname");
|
||||||
|
@ -149,13 +145,11 @@ private:
|
||||||
c.initializerListError(0, 0, "class", "variable");
|
c.initializerListError(0, 0, "class", "variable");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Class";
|
return "Class";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Check the code for each class.\n"
|
return "Check the code for each class.\n"
|
||||||
"* Missing constructors\n"
|
"* Missing constructors\n"
|
||||||
"* Are all variables initialized by the constructors?\n"
|
"* Are all variables initialized by the constructors?\n"
|
||||||
|
@ -183,8 +177,7 @@ private:
|
||||||
|
|
||||||
// constructors helper function
|
// constructors helper function
|
||||||
/** @brief Information about a member variable. Used when checking for uninitialized variables */
|
/** @brief Information about a member variable. Used when checking for uninitialized variables */
|
||||||
struct Usage
|
struct Usage {
|
||||||
{
|
|
||||||
Usage() : assign(false), init(false) { }
|
Usage() : assign(false), init(false) { }
|
||||||
|
|
||||||
/** @brief has this variable been assigned? */
|
/** @brief has this variable been assigned? */
|
||||||
|
|
|
@ -24,9 +24,8 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Register CheckExceptionSafety..
|
// Register CheckExceptionSafety..
|
||||||
namespace
|
namespace {
|
||||||
{
|
CheckExceptionSafety instance;
|
||||||
CheckExceptionSafety instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,8 +38,7 @@ void CheckExceptionSafety::destructors()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Perform check..
|
// Perform check..
|
||||||
for (const Token * tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token * tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
// Skip executable scopes
|
// Skip executable scopes
|
||||||
if (Token::simpleMatch(tok, ") {"))
|
if (Token::simpleMatch(tok, ") {"))
|
||||||
tok = tok->next()->link();
|
tok = tok->next()->link();
|
||||||
|
@ -51,23 +49,19 @@ void CheckExceptionSafety::destructors()
|
||||||
|
|
||||||
// Inspect this destructor..
|
// Inspect this destructor..
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
for (const Token *tok2 = tok->tokAt(5); tok2; tok2 = tok2->next())
|
for (const Token *tok2 = tok->tokAt(5); tok2; tok2 = tok2->next()) {
|
||||||
{
|
if (tok2->str() == "{") {
|
||||||
if (tok2->str() == "{")
|
|
||||||
{
|
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel <= 1)
|
if (indentlevel <= 1)
|
||||||
break;
|
break;
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// throw found within a destructor
|
// throw found within a destructor
|
||||||
else if (tok2->str() == "throw")
|
else if (tok2->str() == "throw") {
|
||||||
{
|
|
||||||
destructorsError(tok2);
|
destructorsError(tok2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -82,8 +76,7 @@ void CheckExceptionSafety::deallocThrow()
|
||||||
{
|
{
|
||||||
// Deallocate a global/member pointer and then throw exception
|
// Deallocate a global/member pointer and then throw exception
|
||||||
// the pointer will be a dead pointer
|
// the pointer will be a dead pointer
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
// only looking for delete now
|
// only looking for delete now
|
||||||
if (tok->str() != "delete")
|
if (tok->str() != "delete")
|
||||||
continue;
|
continue;
|
||||||
|
@ -104,16 +97,13 @@ void CheckExceptionSafety::deallocThrow()
|
||||||
{
|
{
|
||||||
// TODO: Isn't it better to use symbol database instead?
|
// TODO: Isn't it better to use symbol database instead?
|
||||||
bool globalVar = false;
|
bool globalVar = false;
|
||||||
for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next())
|
for (const Token *tok2 = _tokenizer->tokens(); tok2; tok2 = tok2->next()) {
|
||||||
{
|
if (tok2->varId() == varid) {
|
||||||
if (tok2->varId() == varid)
|
|
||||||
{
|
|
||||||
globalVar = true;
|
globalVar = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok2->str() == "class")
|
if (tok2->str() == "class") {
|
||||||
{
|
|
||||||
while (tok2 && tok2->str() != ";" && tok2->str() != "{")
|
while (tok2 && tok2->str() != ";" && tok2->str() != "{")
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
tok2 = tok2 ? tok2->next() : 0;
|
tok2 = tok2 ? tok2->next() : 0;
|
||||||
|
@ -121,8 +111,7 @@ void CheckExceptionSafety::deallocThrow()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{") {
|
||||||
{
|
|
||||||
tok2 = tok2->link();
|
tok2 = tok2->link();
|
||||||
if (!tok2)
|
if (!tok2)
|
||||||
break;
|
break;
|
||||||
|
@ -141,12 +130,10 @@ void CheckExceptionSafety::deallocThrow()
|
||||||
const Token *ThrowToken = 0;
|
const Token *ThrowToken = 0;
|
||||||
|
|
||||||
// is there a throw after the deallocation?
|
// is there a throw after the deallocation?
|
||||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
|
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel == 0)
|
if (indentlevel == 0)
|
||||||
break;
|
break;
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
|
@ -157,8 +144,7 @@ void CheckExceptionSafety::deallocThrow()
|
||||||
|
|
||||||
// if the variable is not assigned after the throw then it
|
// if the variable is not assigned after the throw then it
|
||||||
// is assumed that it is not the intention that it is a dead pointer.
|
// is assumed that it is not the intention that it is a dead pointer.
|
||||||
else if (Token::Match(tok2, "%varid% =", varid))
|
else if (Token::Match(tok2, "%varid% =", varid)) {
|
||||||
{
|
|
||||||
if (ThrowToken)
|
if (ThrowToken)
|
||||||
deallocThrowError(ThrowToken, tok->str());
|
deallocThrowError(ThrowToken, tok->str());
|
||||||
break;
|
break;
|
||||||
|
@ -180,15 +166,13 @@ void CheckExceptionSafety::checkRethrowCopy()
|
||||||
const char catchPattern[] = "catch ( const| %type% &|*| %var% ) { %any%";
|
const char catchPattern[] = "catch ( const| %type% &|*| %var% ) { %any%";
|
||||||
|
|
||||||
const Token *tok = Token::findmatch(_tokenizer->tokens(), catchPattern);
|
const Token *tok = Token::findmatch(_tokenizer->tokens(), catchPattern);
|
||||||
while (tok)
|
while (tok) {
|
||||||
{
|
|
||||||
const Token *startBlockTok = tok->next()->link()->next();
|
const Token *startBlockTok = tok->next()->link()->next();
|
||||||
const Token *endBlockTok = startBlockTok->link();
|
const Token *endBlockTok = startBlockTok->link();
|
||||||
const unsigned int varid = startBlockTok->tokAt(-2)->varId();
|
const unsigned int varid = startBlockTok->tokAt(-2)->varId();
|
||||||
|
|
||||||
const Token* rethrowTok = Token::findmatch(startBlockTok, "throw %varid%", endBlockTok, varid);
|
const Token* rethrowTok = Token::findmatch(startBlockTok, "throw %varid%", endBlockTok, varid);
|
||||||
if (rethrowTok)
|
if (rethrowTok) {
|
||||||
{
|
|
||||||
rethrowCopyError(rethrowTok, startBlockTok->tokAt(-2)->str());
|
rethrowCopyError(rethrowTok, startBlockTok->tokAt(-2)->str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,7 @@ class Token;
|
||||||
* that certain variable values are corrupt.
|
* that certain variable values are corrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CheckExceptionSafety : public Check
|
class CheckExceptionSafety : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** This constructor is used when registering the CheckClass */
|
/** This constructor is used when registering the CheckClass */
|
||||||
CheckExceptionSafety() : Check(myName())
|
CheckExceptionSafety() : Check(myName())
|
||||||
|
@ -52,8 +51,7 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/** Checks that uses the simplified token list */
|
/** Checks that uses the simplified token list */
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckExceptionSafety checkExceptionSafety(tokenizer, settings, errorLogger);
|
CheckExceptionSafety checkExceptionSafety(tokenizer, settings, errorLogger);
|
||||||
checkExceptionSafety.destructors();
|
checkExceptionSafety.destructors();
|
||||||
checkExceptionSafety.deallocThrow();
|
checkExceptionSafety.deallocThrow();
|
||||||
|
@ -71,18 +69,15 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Don't throw exceptions in destructors */
|
/** Don't throw exceptions in destructors */
|
||||||
void destructorsError(const Token * const tok)
|
void destructorsError(const Token * const tok) {
|
||||||
{
|
|
||||||
reportError(tok, Severity::error, "exceptThrowInDestructor", "Throwing exception in destructor");
|
reportError(tok, Severity::error, "exceptThrowInDestructor", "Throwing exception in destructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocThrowError(const Token * const tok, const std::string &varname)
|
void deallocThrowError(const Token * const tok, const std::string &varname) {
|
||||||
{
|
|
||||||
reportError(tok, Severity::error, "exceptDeallocThrow", "Throwing exception in invalid state, " + varname + " points at deallocated memory");
|
reportError(tok, Severity::error, "exceptDeallocThrow", "Throwing exception in invalid state, " + varname + " points at deallocated memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
void rethrowCopyError(const Token * const tok, const std::string &varname)
|
void rethrowCopyError(const Token * const tok, const std::string &varname) {
|
||||||
{
|
|
||||||
reportError(tok, Severity::style, "exceptRethrowCopy",
|
reportError(tok, Severity::style, "exceptRethrowCopy",
|
||||||
"Throwing a copy of the caught exception instead of rethrowing the original exception\n"
|
"Throwing a copy of the caught exception instead of rethrowing the original exception\n"
|
||||||
"Rethrowing an exception with 'throw " + varname + ";' makes an unnecessary copy of '" + varname + "'.\n"
|
"Rethrowing an exception with 'throw " + varname + ";' makes an unnecessary copy of '" + varname + "'.\n"
|
||||||
|
@ -90,8 +85,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate all possible errors (for --errorlist) */
|
/** Generate all possible errors (for --errorlist) */
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckExceptionSafety c(0, settings, errorLogger);
|
CheckExceptionSafety c(0, settings, errorLogger);
|
||||||
c.destructorsError(0);
|
c.destructorsError(0);
|
||||||
c.deallocThrowError(0, "p");
|
c.deallocThrowError(0, "p");
|
||||||
|
@ -99,14 +93,12 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Short description of class (for --doc) */
|
/** Short description of class (for --doc) */
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Exception Safety";
|
return "Exception Safety";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** wiki formatted description of the class (for --doc) */
|
/** wiki formatted description of the class (for --doc) */
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Checking exception safety\n"
|
return "Checking exception safety\n"
|
||||||
"* Throwing exceptions in destructors\n"
|
"* Throwing exceptions in destructors\n"
|
||||||
"* Throwing exception during invalid state\n"
|
"* Throwing exception during invalid state\n"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -47,8 +47,7 @@ class Token;
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/** @brief Base class for memory leaks checking */
|
/** @brief Base class for memory leaks checking */
|
||||||
class CheckMemoryLeak
|
class CheckMemoryLeak {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
/** For access to the tokens */
|
/** For access to the tokens */
|
||||||
const Tokenizer * const tokenizer;
|
const Tokenizer * const tokenizer;
|
||||||
|
@ -85,8 +84,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e)
|
CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e)
|
||||||
: tokenizer(t), errorLogger(e)
|
: tokenizer(t), errorLogger(e) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,8 +178,7 @@ public:
|
||||||
* -# finally, check if the simplified token list contain any leaks.
|
* -# finally, check if the simplified token list contain any leaks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CheckMemoryLeakInFunction : private Check, public CheckMemoryLeak
|
class CheckMemoryLeakInFunction : private Check, public CheckMemoryLeak {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** @brief This constructor is used when registering this class */
|
/** @brief This constructor is used when registering this class */
|
||||||
CheckMemoryLeakInFunction() : Check(myName()), CheckMemoryLeak(0, 0), symbolDatabase(NULL)
|
CheckMemoryLeakInFunction() : Check(myName()), CheckMemoryLeak(0, 0), symbolDatabase(NULL)
|
||||||
|
@ -189,8 +186,7 @@ public:
|
||||||
|
|
||||||
/** @brief This constructor is used when running checks */
|
/** @brief This constructor is used when running checks */
|
||||||
CheckMemoryLeakInFunction(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
CheckMemoryLeakInFunction(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
||||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog)
|
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog) {
|
||||||
{
|
|
||||||
// get the symbol database
|
// get the symbol database
|
||||||
if (tokenizr)
|
if (tokenizr)
|
||||||
symbolDatabase = tokenizr->getSymbolDatabase();
|
symbolDatabase = tokenizr->getSymbolDatabase();
|
||||||
|
@ -199,12 +195,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief run all simplified checks */
|
/** @brief run all simplified checks */
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog) {
|
||||||
{
|
|
||||||
// Don't use these check for Java and C# programs..
|
// Don't use these check for Java and C# programs..
|
||||||
if (tokenizr->getFiles()->at(0).find(".java") != std::string::npos ||
|
if (tokenizr->getFiles()->at(0).find(".java") != std::string::npos ||
|
||||||
tokenizr->getFiles()->at(0).find(".cs") != std::string::npos)
|
tokenizr->getFiles()->at(0).find(".cs") != std::string::npos) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,8 +309,7 @@ public:
|
||||||
void checkScope(const Token *Tok1, const std::string &varname, unsigned int varid, bool classmember, unsigned int sz);
|
void checkScope(const Token *Tok1, const std::string &varname, unsigned int varid, bool classmember, unsigned int sz);
|
||||||
|
|
||||||
/** Report all possible errors (for the --errorlist) */
|
/** Report all possible errors (for the --errorlist) */
|
||||||
void getErrorMessages(ErrorLogger *e, const Settings *settings)
|
void getErrorMessages(ErrorLogger *e, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckMemoryLeakInFunction c(0, settings, e);
|
CheckMemoryLeakInFunction c(0, settings, e);
|
||||||
|
|
||||||
c.memleakError(0, "varname");
|
c.memleakError(0, "varname");
|
||||||
|
@ -334,8 +327,7 @@ public:
|
||||||
* Get name of class (--doc)
|
* Get name of class (--doc)
|
||||||
* @return name of class
|
* @return name of class
|
||||||
*/
|
*/
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Memory leaks (function variables)";
|
return "Memory leaks (function variables)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,8 +335,7 @@ public:
|
||||||
* Get class information (--doc)
|
* Get class information (--doc)
|
||||||
* @return Wiki formatted information about this class
|
* @return Wiki formatted information about this class
|
||||||
*/
|
*/
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Is there any allocated memory when a function goes out of scope";
|
return "Is there any allocated memory when a function goes out of scope";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,8 +357,7 @@ public:
|
||||||
* @brief %Check class variables, variables that are allocated in the constructor should be deallocated in the destructor
|
* @brief %Check class variables, variables that are allocated in the constructor should be deallocated in the destructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CheckMemoryLeakInClass : private Check, private CheckMemoryLeak
|
class CheckMemoryLeakInClass : private Check, private CheckMemoryLeak {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
CheckMemoryLeakInClass() : Check(myName()), CheckMemoryLeak(0, 0)
|
CheckMemoryLeakInClass() : Check(myName()), CheckMemoryLeak(0, 0)
|
||||||
{ }
|
{ }
|
||||||
|
@ -376,12 +366,10 @@ public:
|
||||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog)
|
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog) {
|
||||||
{
|
|
||||||
// Don't use these check for Java and C# programs..
|
// Don't use these check for Java and C# programs..
|
||||||
if (tokenizr->getFiles()->at(0).find(".java") != std::string::npos ||
|
if (tokenizr->getFiles()->at(0).find(".java") != std::string::npos ||
|
||||||
tokenizr->getFiles()->at(0).find(".cs") != std::string::npos)
|
tokenizr->getFiles()->at(0).find(".cs") != std::string::npos) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,13 +389,11 @@ private:
|
||||||
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/)
|
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Memory leaks (class variables)";
|
return "Memory leaks (class variables)";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "If the constructor allocate memory then the destructor must deallocate it.";
|
return "If the constructor allocate memory then the destructor must deallocate it.";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -416,8 +402,7 @@ private:
|
||||||
|
|
||||||
/** @brief detect simple memory leaks for struct members */
|
/** @brief detect simple memory leaks for struct members */
|
||||||
|
|
||||||
class CheckMemoryLeakStructMember : private Check, private CheckMemoryLeak
|
class CheckMemoryLeakStructMember : private Check, private CheckMemoryLeak {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
CheckMemoryLeakStructMember() : Check(myName()), CheckMemoryLeak(0, 0)
|
CheckMemoryLeakStructMember() : Check(myName()), CheckMemoryLeak(0, 0)
|
||||||
{ }
|
{ }
|
||||||
|
@ -426,8 +411,7 @@ public:
|
||||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog)
|
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog) {
|
||||||
{
|
|
||||||
CheckMemoryLeakStructMember checkMemoryLeak(tokenizr, settings, errLog);
|
CheckMemoryLeakStructMember checkMemoryLeak(tokenizr, settings, errLog);
|
||||||
checkMemoryLeak.check();
|
checkMemoryLeak.check();
|
||||||
}
|
}
|
||||||
|
@ -444,13 +428,11 @@ private:
|
||||||
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/)
|
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Memory leaks (struct members)";
|
return "Memory leaks (struct members)";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Don't forget to deallocate struct members";
|
return "Don't forget to deallocate struct members";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -459,8 +441,7 @@ private:
|
||||||
|
|
||||||
/** @brief detect simple memory leaks (address not taken) */
|
/** @brief detect simple memory leaks (address not taken) */
|
||||||
|
|
||||||
class CheckMemoryLeakNoVar : private Check, private CheckMemoryLeak
|
class CheckMemoryLeakNoVar : private Check, private CheckMemoryLeak {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
CheckMemoryLeakNoVar() : Check(myName()), CheckMemoryLeak(0, 0)
|
CheckMemoryLeakNoVar() : Check(myName()), CheckMemoryLeak(0, 0)
|
||||||
{ }
|
{ }
|
||||||
|
@ -469,8 +450,7 @@ public:
|
||||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog)
|
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog) {
|
||||||
{
|
|
||||||
CheckMemoryLeakNoVar checkMemoryLeak(tokenizr, settings, errLog);
|
CheckMemoryLeakNoVar checkMemoryLeak(tokenizr, settings, errLog);
|
||||||
checkMemoryLeak.check();
|
checkMemoryLeak.check();
|
||||||
}
|
}
|
||||||
|
@ -484,13 +464,11 @@ private:
|
||||||
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/)
|
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Memory leaks (address not taken)";
|
return "Memory leaks (address not taken)";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Not taking the address to allocated memory";
|
return "Not taking the address to allocated memory";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
|
|
||||||
|
|
||||||
// Register this check class (by creating a static instance of it)
|
// Register this check class (by creating a static instance of it)
|
||||||
namespace
|
namespace {
|
||||||
{
|
CheckNonReentrantFunctions instance;
|
||||||
CheckNonReentrantFunctions instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckNonReentrantFunctions::nonReentrantFunctions()
|
void CheckNonReentrantFunctions::nonReentrantFunctions()
|
||||||
|
@ -40,13 +39,10 @@ void CheckNonReentrantFunctions::nonReentrantFunctions()
|
||||||
if (_tokenizer->isJavaOrCSharp())
|
if (_tokenizer->isJavaOrCSharp())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
std::list< std::pair<const std::string, const std::string> >::const_iterator it(_nonReentrantFunctions.begin()), itend(_nonReentrantFunctions.end());
|
std::list< std::pair<const std::string, const std::string> >::const_iterator it(_nonReentrantFunctions.begin()), itend(_nonReentrantFunctions.end());
|
||||||
for (; it!=itend; ++it)
|
for (; it!=itend; ++it) {
|
||||||
{
|
if (tok->strAt(1) == it->first && tok->strAt(2) == "(" && tok->tokAt(1)->varId() == 0 && !tok->tokAt(0)->isName() && !Token::Match(tok, ".|::|:|,")) {
|
||||||
if (tok->strAt(1) == it->first && tok->strAt(2) == "(" && tok->tokAt(1)->varId() == 0 && !tok->tokAt(0)->isName() && !Token::Match(tok, ".|::|:|,"))
|
|
||||||
{
|
|
||||||
// If checking code that is single threaded, this might be not interesing for all.
|
// If checking code that is single threaded, this might be not interesing for all.
|
||||||
// Therefore this is "portabiblity"
|
// Therefore this is "portabiblity"
|
||||||
reportError(tok->tokAt(1), Severity::portability, "nonreentrantFunctions"+it->first, it->second);
|
reportError(tok->tokAt(1), Severity::portability, "nonreentrantFunctions"+it->first, it->second);
|
||||||
|
|
|
@ -34,24 +34,20 @@
|
||||||
* @brief Using non reentrant functions that can be replaced by their reentrant versions
|
* @brief Using non reentrant functions that can be replaced by their reentrant versions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CheckNonReentrantFunctions : public Check
|
class CheckNonReentrantFunctions : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** This constructor is used when registering the CheckNonReentrantFunctions */
|
/** This constructor is used when registering the CheckNonReentrantFunctions */
|
||||||
CheckNonReentrantFunctions() : Check(myName())
|
CheckNonReentrantFunctions() : Check(myName()) {
|
||||||
{
|
|
||||||
initNonReentrantFunctions();
|
initNonReentrantFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This constructor is used when running checks. */
|
/** This constructor is used when running checks. */
|
||||||
CheckNonReentrantFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
CheckNonReentrantFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
: Check(myName(), tokenizer, settings, errorLogger)
|
: Check(myName(), tokenizer, settings, errorLogger) {
|
||||||
{
|
|
||||||
initNonReentrantFunctions();
|
initNonReentrantFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckNonReentrantFunctions checkNonReentrantFunctions(tokenizer, settings, errorLogger);
|
CheckNonReentrantFunctions checkNonReentrantFunctions(tokenizer, settings, errorLogger);
|
||||||
checkNonReentrantFunctions.nonReentrantFunctions();
|
checkNonReentrantFunctions.nonReentrantFunctions();
|
||||||
}
|
}
|
||||||
|
@ -65,10 +61,8 @@ private:
|
||||||
std::list< std::pair< const std::string, const std::string> > _nonReentrantFunctions;
|
std::list< std::pair< const std::string, const std::string> > _nonReentrantFunctions;
|
||||||
|
|
||||||
/** init nonreentrant functions list ' */
|
/** init nonreentrant functions list ' */
|
||||||
void initNonReentrantFunctions()
|
void initNonReentrantFunctions() {
|
||||||
{
|
static const char * const non_reentrant_functions_list[] = {
|
||||||
static const char * const non_reentrant_functions_list[] =
|
|
||||||
{
|
|
||||||
"ctime", "localtime", "gmtime", "asctime", "strtok", "gethostbyname", "gethostbyaddr", "getservbyname"
|
"ctime", "localtime", "gmtime", "asctime", "strtok", "gethostbyname", "gethostbyaddr", "getservbyname"
|
||||||
, "getservbyport", "crypt", "ttyname", "rand", "gethostbyname2"
|
, "getservbyport", "crypt", "ttyname", "rand", "gethostbyname2"
|
||||||
, "getprotobyname", "getnetbyname", "getnetbyaddr", "getrpcbyname", "getrpcbynumber", "getrpcent"
|
, "getprotobyname", "getnetbyname", "getnetbyaddr", "getrpcbyname", "getrpcbynumber", "getrpcent"
|
||||||
|
@ -78,8 +72,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// generate messages
|
// generate messages
|
||||||
for (unsigned int i = 0; i < (sizeof(non_reentrant_functions_list) / sizeof(char *)); ++i)
|
for (unsigned int i = 0; i < (sizeof(non_reentrant_functions_list) / sizeof(char *)); ++i) {
|
||||||
{
|
|
||||||
std::string strMsg("Found non reentrant function \'");
|
std::string strMsg("Found non reentrant function \'");
|
||||||
strMsg+=non_reentrant_functions_list[i];
|
strMsg+=non_reentrant_functions_list[i];
|
||||||
strMsg+= "\'. For threadsafe applications it is recommended to use the reentrant replacement function \'";
|
strMsg+= "\'. For threadsafe applications it is recommended to use the reentrant replacement function \'";
|
||||||
|
@ -89,28 +82,23 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckNonReentrantFunctions c(0, settings, errorLogger);
|
CheckNonReentrantFunctions c(0, settings, errorLogger);
|
||||||
|
|
||||||
std::list< std::pair<const std::string, const std::string> >::const_iterator it(_nonReentrantFunctions.begin()), itend(_nonReentrantFunctions.end());
|
std::list< std::pair<const std::string, const std::string> >::const_iterator it(_nonReentrantFunctions.begin()), itend(_nonReentrantFunctions.end());
|
||||||
for (; it!=itend; ++it)
|
for (; it!=itend; ++it) {
|
||||||
{
|
|
||||||
c.reportError(0, Severity::portability, "nonreentrantFunctions"+it->first, it->second);
|
c.reportError(0, Severity::portability, "nonreentrantFunctions"+it->first, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Non reentrant functions";
|
return "Non reentrant functions";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
std::string info = "Warn if any of these non reentrant functions are used:\n";
|
std::string info = "Warn if any of these non reentrant functions are used:\n";
|
||||||
std::list< std::pair<const std::string, const std::string> >::const_iterator it(_nonReentrantFunctions.begin()), itend(_nonReentrantFunctions.end());
|
std::list< std::pair<const std::string, const std::string> >::const_iterator it(_nonReentrantFunctions.begin()), itend(_nonReentrantFunctions.end());
|
||||||
for (; it!=itend; ++it)
|
for (; it!=itend; ++it) {
|
||||||
{
|
|
||||||
info += "* " + it->first + "\n";
|
info += "* " + it->first + "\n";
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Register this check class (by creating a static instance of it)
|
// Register this check class (by creating a static instance of it)
|
||||||
namespace
|
namespace {
|
||||||
{
|
CheckNullPointer instance;
|
||||||
CheckNullPointer instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -37,8 +36,7 @@ CheckNullPointer instance;
|
||||||
/** Is string uppercase? */
|
/** Is string uppercase? */
|
||||||
bool CheckNullPointer::isUpper(const std::string &str)
|
bool CheckNullPointer::isUpper(const std::string &str)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < str.length(); ++i)
|
for (unsigned int i = 0; i < str.length(); ++i) {
|
||||||
{
|
|
||||||
if (str[i] >= 'a' && str[i] <= 'z')
|
if (str[i] >= 'a' && str[i] <= 'z')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -57,8 +55,7 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
||||||
// standard functions that dereference first parameter..
|
// standard functions that dereference first parameter..
|
||||||
// both uninitialized data and null pointers are invalid.
|
// both uninitialized data and null pointers are invalid.
|
||||||
static std::set<std::string> functionNames1;
|
static std::set<std::string> functionNames1;
|
||||||
if (functionNames1.empty())
|
if (functionNames1.empty()) {
|
||||||
{
|
|
||||||
functionNames1.insert("memchr");
|
functionNames1.insert("memchr");
|
||||||
functionNames1.insert("memcmp");
|
functionNames1.insert("memcmp");
|
||||||
functionNames1.insert("strcat");
|
functionNames1.insert("strcat");
|
||||||
|
@ -87,8 +84,7 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
||||||
// standard functions that dereference second parameter..
|
// standard functions that dereference second parameter..
|
||||||
// both uninitialized data and null pointers are invalid.
|
// both uninitialized data and null pointers are invalid.
|
||||||
static std::set<std::string> functionNames2;
|
static std::set<std::string> functionNames2;
|
||||||
if (functionNames2.empty())
|
if (functionNames2.empty()) {
|
||||||
{
|
|
||||||
functionNames2.insert("memcmp");
|
functionNames2.insert("memcmp");
|
||||||
functionNames2.insert("memcpy");
|
functionNames2.insert("memcpy");
|
||||||
functionNames2.insert("memmove");
|
functionNames2.insert("memmove");
|
||||||
|
@ -107,8 +103,7 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
||||||
|
|
||||||
// 1st parameter..
|
// 1st parameter..
|
||||||
if ((Token::Match(&tok, "%var% ( %var% ,|)") && tok.tokAt(2)->varId() > 0) ||
|
if ((Token::Match(&tok, "%var% ( %var% ,|)") && tok.tokAt(2)->varId() > 0) ||
|
||||||
(value == 0 && Token::Match(&tok, "%var% ( 0 ,|)")))
|
(value == 0 && Token::Match(&tok, "%var% ( 0 ,|)"))) {
|
||||||
{
|
|
||||||
if (functionNames1.find(tok.str()) != functionNames1.end())
|
if (functionNames1.find(tok.str()) != functionNames1.end())
|
||||||
var.push_back(tok.tokAt(2));
|
var.push_back(tok.tokAt(2));
|
||||||
else if (value == 0 && Token::Match(&tok, "memcpy|memmove|memset|strcpy|printf|sprintf|vsprintf|vprintf|fprintf|vfprintf"))
|
else if (value == 0 && Token::Match(&tok, "memcpy|memmove|memset|strcpy|printf|sprintf|vsprintf|vprintf|fprintf|vfprintf"))
|
||||||
|
@ -121,55 +116,39 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
||||||
|
|
||||||
// 2nd parameter..
|
// 2nd parameter..
|
||||||
if ((Token::Match(&tok, "%var% ( %any% , %var% ,|)") && tok.tokAt(4)->varId() > 0) ||
|
if ((Token::Match(&tok, "%var% ( %any% , %var% ,|)") && tok.tokAt(4)->varId() > 0) ||
|
||||||
(value == 0 && Token::Match(&tok, "%var% ( %any% , 0 ,|)")))
|
(value == 0 && Token::Match(&tok, "%var% ( %any% , 0 ,|)"))) {
|
||||||
{
|
|
||||||
if (functionNames2.find(tok.str()) != functionNames2.end())
|
if (functionNames2.find(tok.str()) != functionNames2.end())
|
||||||
var.push_back(tok.tokAt(4));
|
var.push_back(tok.tokAt(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(&tok, "printf|sprintf|snprintf|fprintf|fnprintf|scanf|sscanf|fscanf"))
|
if (Token::Match(&tok, "printf|sprintf|snprintf|fprintf|fnprintf|scanf|sscanf|fscanf")) {
|
||||||
{
|
|
||||||
const Token* argListTok = 0; // Points to first va_list argument
|
const Token* argListTok = 0; // Points to first va_list argument
|
||||||
std::string formatString;
|
std::string formatString;
|
||||||
bool scan = Token::Match(&tok, "scanf|sscanf|fscanf");
|
bool scan = Token::Match(&tok, "scanf|sscanf|fscanf");
|
||||||
if (Token::Match(&tok, "printf|scanf ( %str% , %any%"))
|
if (Token::Match(&tok, "printf|scanf ( %str% , %any%")) {
|
||||||
{
|
|
||||||
formatString = tok.strAt(2);
|
formatString = tok.strAt(2);
|
||||||
argListTok = tok.tokAt(4);
|
argListTok = tok.tokAt(4);
|
||||||
}
|
} else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf ( %var% , %str% , %any%")) {
|
||||||
else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf ( %var% , %str% , %any%"))
|
|
||||||
{
|
|
||||||
formatString = tok.strAt(4);
|
formatString = tok.strAt(4);
|
||||||
argListTok = tok.tokAt(6);
|
argListTok = tok.tokAt(6);
|
||||||
}
|
} else if (Token::Match(&tok, "snprintf|fnprintf ( %var% , %any% , %str% , %any%")) {
|
||||||
else if (Token::Match(&tok, "snprintf|fnprintf ( %var% , %any% , %str% , %any%"))
|
|
||||||
{
|
|
||||||
formatString = tok.strAt(6);
|
formatString = tok.strAt(6);
|
||||||
argListTok = tok.tokAt(8);
|
argListTok = tok.tokAt(8);
|
||||||
}
|
}
|
||||||
if (argListTok)
|
if (argListTok) {
|
||||||
{
|
|
||||||
bool percent = false;
|
bool percent = false;
|
||||||
for (std::string::iterator i = formatString.begin(); i != formatString.end(); ++i)
|
for (std::string::iterator i = formatString.begin(); i != formatString.end(); ++i) {
|
||||||
{
|
if (*i == '%') {
|
||||||
if (*i == '%')
|
|
||||||
{
|
|
||||||
percent = !percent;
|
percent = !percent;
|
||||||
}
|
} else if (percent && std::isalpha(*i)) {
|
||||||
else if (percent && std::isalpha(*i))
|
if (*i == 'n' || *i == 's' || scan) {
|
||||||
{
|
if ((value == 0 && argListTok->str() == "0") || (Token::Match(argListTok, "%var%") && argListTok->varId() > 0)) {
|
||||||
if (*i == 'n' || *i == 's' || scan)
|
|
||||||
{
|
|
||||||
if ((value == 0 && argListTok->str() == "0") || (Token::Match(argListTok, "%var%") && argListTok->varId() > 0))
|
|
||||||
{
|
|
||||||
var.push_back(argListTok);
|
var.push_back(argListTok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; argListTok; argListTok = argListTok->next()) // Find next argument
|
for (; argListTok; argListTok = argListTok->next()) { // Find next argument
|
||||||
{
|
if (argListTok->str() == ",") {
|
||||||
if (argListTok->str() == ",")
|
|
||||||
{
|
|
||||||
argListTok = argListTok->next();
|
argListTok = argListTok->next();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -244,8 +223,7 @@ bool CheckNullPointer::isPointer(const unsigned int varid)
|
||||||
// it is a pointer
|
// it is a pointer
|
||||||
if (!tok->previous() ||
|
if (!tok->previous() ||
|
||||||
Token::Match(tok->previous(), "[({};]") ||
|
Token::Match(tok->previous(), "[({};]") ||
|
||||||
tok->previous()->isName())
|
tok->previous()->isName()) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,8 +234,7 @@ bool CheckNullPointer::isPointer(const unsigned int varid)
|
||||||
void CheckNullPointer::nullPointerAfterLoop()
|
void CheckNullPointer::nullPointerAfterLoop()
|
||||||
{
|
{
|
||||||
// Locate insufficient null-pointer handling after loop
|
// Locate insufficient null-pointer handling after loop
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
// only interested in while ( %var% )
|
// only interested in while ( %var% )
|
||||||
// TODO: Aren't there false negatives. Shouldn't other loops be handled such as:
|
// TODO: Aren't there false negatives. Shouldn't other loops be handled such as:
|
||||||
// - while ( ! %var% )
|
// - while ( ! %var% )
|
||||||
|
@ -284,19 +261,16 @@ void CheckNullPointer::nullPointerAfterLoop()
|
||||||
bool inconclusive = false;
|
bool inconclusive = false;
|
||||||
|
|
||||||
// Check if the variable is dereferenced after the while loop
|
// Check if the variable is dereferenced after the while loop
|
||||||
while (0 != (tok2 = tok2 ? tok2->next() : 0))
|
while (0 != (tok2 = tok2 ? tok2->next() : 0)) {
|
||||||
{
|
|
||||||
// inner and outer scopes
|
// inner and outer scopes
|
||||||
if (tok2->str() == "{" || tok2->str() == "}")
|
if (tok2->str() == "{" || tok2->str() == "}") {
|
||||||
{
|
|
||||||
// Not inconclusive: bail out
|
// Not inconclusive: bail out
|
||||||
if (!_settings->inconclusive)
|
if (!_settings->inconclusive)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
inconclusive = true;
|
inconclusive = true;
|
||||||
|
|
||||||
if (tok2->str() == "}")
|
if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
// "}" => leaving function? then break.
|
// "}" => leaving function? then break.
|
||||||
const Token *tok3 = tok2->link()->previous();
|
const Token *tok3 = tok2->link()->previous();
|
||||||
if (!tok3 || !Token::Match(tok3, "[);]"))
|
if (!tok3 || !Token::Match(tok3, "[);]"))
|
||||||
|
@ -311,14 +285,12 @@ void CheckNullPointer::nullPointerAfterLoop()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// loop variable is found..
|
// loop variable is found..
|
||||||
else if (tok2->varId() == varid)
|
else if (tok2->varId() == varid) {
|
||||||
{
|
|
||||||
// dummy variable.. is it unknown if pointer is dereferenced or not?
|
// dummy variable.. is it unknown if pointer is dereferenced or not?
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
|
|
||||||
// Is the loop variable dereferenced?
|
// Is the loop variable dereferenced?
|
||||||
if (CheckNullPointer::isPointerDeRef(tok2, unknown))
|
if (CheckNullPointer::isPointerDeRef(tok2, unknown)) {
|
||||||
{
|
|
||||||
nullPointerError(tok2, varname, tok->linenr(), inconclusive);
|
nullPointerError(tok2, varname, tok->linenr(), inconclusive);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -335,8 +307,7 @@ void CheckNullPointer::nullPointerLinkedList()
|
||||||
// if (tok->str() == "hello")
|
// if (tok->str() == "hello")
|
||||||
// tok = tok->next; // <- tok might become a null pointer!
|
// tok = tok->next; // <- tok might become a null pointer!
|
||||||
// }
|
// }
|
||||||
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
|
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next()) {
|
||||||
{
|
|
||||||
// search for a "for" token..
|
// search for a "for" token..
|
||||||
if (!Token::simpleMatch(tok1, "for ("))
|
if (!Token::simpleMatch(tok1, "for ("))
|
||||||
continue;
|
continue;
|
||||||
|
@ -344,21 +315,18 @@ void CheckNullPointer::nullPointerLinkedList()
|
||||||
// is there any dereferencing occurring in the for statement
|
// is there any dereferencing occurring in the for statement
|
||||||
// parlevel2 counts the parentheses when using tok2.
|
// parlevel2 counts the parentheses when using tok2.
|
||||||
unsigned int parlevel2 = 1;
|
unsigned int parlevel2 = 1;
|
||||||
for (const Token *tok2 = tok1->tokAt(2); tok2; tok2 = tok2->next())
|
for (const Token *tok2 = tok1->tokAt(2); tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
// Parentheses..
|
// Parentheses..
|
||||||
if (tok2->str() == "(")
|
if (tok2->str() == "(")
|
||||||
++parlevel2;
|
++parlevel2;
|
||||||
else if (tok2->str() == ")")
|
else if (tok2->str() == ")") {
|
||||||
{
|
|
||||||
if (parlevel2 <= 1)
|
if (parlevel2 <= 1)
|
||||||
break;
|
break;
|
||||||
--parlevel2;
|
--parlevel2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dereferencing a variable inside the "for" parentheses..
|
// Dereferencing a variable inside the "for" parentheses..
|
||||||
else if (Token::Match(tok2, "%var% . %var%"))
|
else if (Token::Match(tok2, "%var% . %var%")) {
|
||||||
{
|
|
||||||
// Variable id for dereferenced variable
|
// Variable id for dereferenced variable
|
||||||
const unsigned int varid(tok2->varId());
|
const unsigned int varid(tok2->varId());
|
||||||
if (varid == 0)
|
if (varid == 0)
|
||||||
|
@ -372,33 +340,27 @@ void CheckNullPointer::nullPointerLinkedList()
|
||||||
|
|
||||||
// Check usage of dereferenced variable in the loop..
|
// Check usage of dereferenced variable in the loop..
|
||||||
unsigned int indentlevel3 = 0;
|
unsigned int indentlevel3 = 0;
|
||||||
for (const Token *tok3 = tok1->next()->link(); tok3; tok3 = tok3->next())
|
for (const Token *tok3 = tok1->next()->link(); tok3; tok3 = tok3->next()) {
|
||||||
{
|
|
||||||
if (tok3->str() == "{")
|
if (tok3->str() == "{")
|
||||||
++indentlevel3;
|
++indentlevel3;
|
||||||
else if (tok3->str() == "}")
|
else if (tok3->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel3 <= 1)
|
if (indentlevel3 <= 1)
|
||||||
break;
|
break;
|
||||||
--indentlevel3;
|
--indentlevel3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: are there false negatives for "while ( %varid% ||"
|
// TODO: are there false negatives for "while ( %varid% ||"
|
||||||
else if (Token::Match(tok3, "while ( %varid% &&|)", varid))
|
else if (Token::Match(tok3, "while ( %varid% &&|)", varid)) {
|
||||||
{
|
|
||||||
// Make sure there is a "break" or "return" inside the loop.
|
// Make sure there is a "break" or "return" inside the loop.
|
||||||
// Without the "break" a null pointer could be dereferenced in the
|
// Without the "break" a null pointer could be dereferenced in the
|
||||||
// for statement.
|
// for statement.
|
||||||
// indentlevel4 is a counter for { and }. When scanning the code with tok4
|
// indentlevel4 is a counter for { and }. When scanning the code with tok4
|
||||||
unsigned int indentlevel4 = indentlevel3;
|
unsigned int indentlevel4 = indentlevel3;
|
||||||
for (const Token *tok4 = tok3->next()->link(); tok4; tok4 = tok4->next())
|
for (const Token *tok4 = tok3->next()->link(); tok4; tok4 = tok4->next()) {
|
||||||
{
|
|
||||||
if (tok4->str() == "{")
|
if (tok4->str() == "{")
|
||||||
++indentlevel4;
|
++indentlevel4;
|
||||||
else if (tok4->str() == "}")
|
else if (tok4->str() == "}") {
|
||||||
{
|
if (indentlevel4 <= 1) {
|
||||||
if (indentlevel4 <= 1)
|
|
||||||
{
|
|
||||||
// Is this variable a pointer?
|
// Is this variable a pointer?
|
||||||
if (isPointer(varid))
|
if (isPointer(varid))
|
||||||
nullPointerError(tok1, varname, tok3->linenr());
|
nullPointerError(tok1, varname, tok3->linenr());
|
||||||
|
@ -430,21 +392,17 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
|
||||||
skipvar.insert(0);
|
skipvar.insert(0);
|
||||||
|
|
||||||
// Scan through all tokens
|
// Scan through all tokens
|
||||||
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
|
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next()) {
|
||||||
{
|
|
||||||
// Checking if some pointer is null.
|
// Checking if some pointer is null.
|
||||||
// then add the pointer to skipvar => is it known that it isn't NULL
|
// then add the pointer to skipvar => is it known that it isn't NULL
|
||||||
if (Token::Match(tok1, "if|while ( !| %var% )"))
|
if (Token::Match(tok1, "if|while ( !| %var% )")) {
|
||||||
{
|
|
||||||
tok1 = tok1->tokAt(2);
|
tok1 = tok1->tokAt(2);
|
||||||
if (tok1->str() == "!")
|
if (tok1->str() == "!")
|
||||||
tok1 = tok1->next();
|
tok1 = tok1->next();
|
||||||
skipvar.insert(tok1->varId());
|
skipvar.insert(tok1->varId());
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (Token::Match(tok1, "( ! %var% ||") ||
|
||||||
else if (Token::Match(tok1, "( ! %var% ||") ||
|
Token::Match(tok1, "( %var% &&")) {
|
||||||
Token::Match(tok1, "( %var% &&"))
|
|
||||||
{
|
|
||||||
// TODO: there are false negatives caused by this. The
|
// TODO: there are false negatives caused by this. The
|
||||||
// variable should be removed from skipvar after the
|
// variable should be removed from skipvar after the
|
||||||
// condition
|
// condition
|
||||||
|
@ -461,22 +419,19 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// dereference in assignment
|
// dereference in assignment
|
||||||
if (Token::Match(tok1, "[;{}] %var% . %var%"))
|
if (Token::Match(tok1, "[;{}] %var% . %var%")) {
|
||||||
{
|
|
||||||
tok1 = tok1->next();
|
tok1 = tok1->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
// dereference in assignment
|
// dereference in assignment
|
||||||
else if (Token::Match(tok1, "[{};] %var% = %var% . %var%"))
|
else if (Token::Match(tok1, "[{};] %var% = %var% . %var%")) {
|
||||||
{
|
|
||||||
if (std::string(tok1->strAt(1)) == tok1->strAt(3))
|
if (std::string(tok1->strAt(1)) == tok1->strAt(3))
|
||||||
continue;
|
continue;
|
||||||
tok1 = tok1->tokAt(3);
|
tok1 = tok1->tokAt(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dereference in condition
|
// dereference in condition
|
||||||
else if (Token::Match(tok1, "if ( !| %var% ."))
|
else if (Token::Match(tok1, "if ( !| %var% .")) {
|
||||||
{
|
|
||||||
tok1 = tok1->tokAt(2);
|
tok1 = tok1->tokAt(2);
|
||||||
if (tok1->str() == "!")
|
if (tok1->str() == "!")
|
||||||
tok1 = tok1->next();
|
tok1 = tok1->next();
|
||||||
|
@ -484,18 +439,15 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
|
||||||
|
|
||||||
// dereference in function call (but not sizeof|decltype)
|
// dereference in function call (but not sizeof|decltype)
|
||||||
else if ((Token::Match(tok1->tokAt(-2), "%var% ( %var% . %var%") && !Token::Match(tok1->tokAt(-2), "sizeof|decltype ( %var% . %var%")) ||
|
else if ((Token::Match(tok1->tokAt(-2), "%var% ( %var% . %var%") && !Token::Match(tok1->tokAt(-2), "sizeof|decltype ( %var% . %var%")) ||
|
||||||
Token::Match(tok1->previous(), ", %var% . %var%"))
|
Token::Match(tok1->previous(), ", %var% . %var%")) {
|
||||||
{
|
|
||||||
// Is the function return value taken by the pointer?
|
// Is the function return value taken by the pointer?
|
||||||
bool assignment = false;
|
bool assignment = false;
|
||||||
const unsigned int varid1(tok1->varId());
|
const unsigned int varid1(tok1->varId());
|
||||||
if (varid1 == 0)
|
if (varid1 == 0)
|
||||||
continue;
|
continue;
|
||||||
const Token *tok2 = tok1->previous();
|
const Token *tok2 = tok1->previous();
|
||||||
while (tok2 && !Token::Match(tok2, "[;{}]"))
|
while (tok2 && !Token::Match(tok2, "[;{}]")) {
|
||||||
{
|
if (Token::Match(tok2, "%varid% =", varid1)) {
|
||||||
if (Token::Match(tok2, "%varid% =", varid1))
|
|
||||||
{
|
|
||||||
assignment = true;
|
assignment = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -506,8 +458,7 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Goto next token
|
// Goto next token
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,8 +478,7 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
|
||||||
isLocal = true;
|
isLocal = true;
|
||||||
|
|
||||||
// member function may or may not nullify the pointer if it's global (#2647)
|
// member function may or may not nullify the pointer if it's global (#2647)
|
||||||
if (!isLocal)
|
if (!isLocal) {
|
||||||
{
|
|
||||||
const Token *tok2 = tok1;
|
const Token *tok2 = tok1;
|
||||||
while (Token::Match(tok2, "%var% ."))
|
while (Token::Match(tok2, "%var% ."))
|
||||||
tok2 = tok2->tokAt(2);
|
tok2 = tok2->tokAt(2);
|
||||||
|
@ -538,13 +488,11 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
|
||||||
|
|
||||||
// count { and } using tok2
|
// count { and } using tok2
|
||||||
unsigned int indentlevel2 = 0;
|
unsigned int indentlevel2 = 0;
|
||||||
for (const Token *tok2 = tok1->tokAt(3); tok2; tok2 = tok2->next())
|
for (const Token *tok2 = tok1->tokAt(3); tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel2;
|
++indentlevel2;
|
||||||
|
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel2 == 0)
|
if (indentlevel2 == 0)
|
||||||
break;
|
break;
|
||||||
--indentlevel2;
|
--indentlevel2;
|
||||||
|
@ -555,10 +503,8 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Reassignment of the struct
|
// Reassignment of the struct
|
||||||
else if (tok2->varId() == varid1)
|
else if (tok2->varId() == varid1) {
|
||||||
{
|
if (tok2->next()->str() == "=") {
|
||||||
if (tok2->next()->str() == "=")
|
|
||||||
{
|
|
||||||
// Avoid false positives when there is 'else if'
|
// Avoid false positives when there is 'else if'
|
||||||
// TODO: can this be handled better?
|
// TODO: can this be handled better?
|
||||||
if (tok1->strAt(-2) == "if")
|
if (tok1->strAt(-2) == "if")
|
||||||
|
@ -581,15 +527,13 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
|
||||||
// Function call: If the pointer is not a local variable it
|
// Function call: If the pointer is not a local variable it
|
||||||
// might be changed by the call.
|
// might be changed by the call.
|
||||||
else if (Token::Match(tok2, "[;{}] %var% (") &&
|
else if (Token::Match(tok2, "[;{}] %var% (") &&
|
||||||
Token::simpleMatch(tok2->tokAt(2)->link(), ") ;") && !isLocal)
|
Token::simpleMatch(tok2->tokAt(2)->link(), ") ;") && !isLocal) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if pointer is null.
|
// Check if pointer is null.
|
||||||
// TODO: false negatives for "if (!p || .."
|
// TODO: false negatives for "if (!p || .."
|
||||||
else if (Token::Match(tok2, "if ( !| %varid% )|&&", varid1))
|
else if (Token::Match(tok2, "if ( !| %varid% )|&&", varid1)) {
|
||||||
{
|
|
||||||
// Is this variable a pointer?
|
// Is this variable a pointer?
|
||||||
if (isPointer(varid1))
|
if (isPointer(varid1))
|
||||||
nullPointerError(tok1, varname, tok2->linenr());
|
nullPointerError(tok1, varname, tok2->linenr());
|
||||||
|
@ -606,13 +550,11 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
|
||||||
// Dereferencing a pointer and then checking if it's NULL..
|
// Dereferencing a pointer and then checking if it's NULL..
|
||||||
// This check will first scan for the check. And then scan backwards
|
// This check will first scan for the check. And then scan backwards
|
||||||
// from the check, searching for dereferencing.
|
// from the check, searching for dereferencing.
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
// TODO: false negatives.
|
// TODO: false negatives.
|
||||||
// - logical operators
|
// - logical operators
|
||||||
// - while
|
// - while
|
||||||
if (tok->str() == "if" && Token::Match(tok->previous(), "; if ( !| %var% )|%oror%|&&"))
|
if (tok->str() == "if" && Token::Match(tok->previous(), "; if ( !| %var% )|%oror%|&&")) {
|
||||||
{
|
|
||||||
const Token * vartok = tok->tokAt(2);
|
const Token * vartok = tok->tokAt(2);
|
||||||
if (vartok->str() == "!")
|
if (vartok->str() == "!")
|
||||||
vartok = vartok->next();
|
vartok = vartok->next();
|
||||||
|
@ -636,10 +578,8 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
|
||||||
|
|
||||||
const Token * const decltok = var->nameToken();
|
const Token * const decltok = var->nameToken();
|
||||||
|
|
||||||
for (const Token *tok1 = tok->previous(); tok1 && tok1 != decltok; tok1 = tok1->previous())
|
for (const Token *tok1 = tok->previous(); tok1 && tok1 != decltok; tok1 = tok1->previous()) {
|
||||||
{
|
if (tok1->str() == ")" && Token::Match(tok1->link()->previous(), "%var% (")) {
|
||||||
if (tok1->str() == ")" && Token::Match(tok1->link()->previous(), "%var% ("))
|
|
||||||
{
|
|
||||||
const Token *tok2 = tok1->link();
|
const Token *tok2 = tok1->link();
|
||||||
while (tok2 && !Token::Match(tok2, "[;{}?:]"))
|
while (tok2 && !Token::Match(tok2, "[;{}?:]"))
|
||||||
tok2 = tok2->previous();
|
tok2 = tok2->previous();
|
||||||
|
@ -652,24 +592,20 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (Token::Match(tok1->link(), "( ! %varid% ||", varid) ||
|
if (Token::Match(tok1->link(), "( ! %varid% ||", varid) ||
|
||||||
Token::Match(tok1->link(), "( %varid% &&", varid))
|
Token::Match(tok1->link(), "( %varid% &&", varid)) {
|
||||||
{
|
|
||||||
tok1 = tok1->link();
|
tok1 = tok1->link();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::simpleMatch(tok1->link()->previous(), "sizeof ("))
|
if (Token::simpleMatch(tok1->link()->previous(), "sizeof (")) {
|
||||||
{
|
|
||||||
tok1 = tok1->link()->previous();
|
tok1 = tok1->link()->previous();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok2, "[;{}] %var% ( %varid% ,", varid))
|
if (Token::Match(tok2, "[;{}] %var% ( %varid% ,", varid)) {
|
||||||
{
|
|
||||||
std::list<const Token *> varlist;
|
std::list<const Token *> varlist;
|
||||||
parseFunctionCall(*(tok2->next()), varlist, 0);
|
parseFunctionCall(*(tok2->next()), varlist, 0);
|
||||||
if (!varlist.empty() && varlist.front() == tok2->tokAt(3))
|
if (!varlist.empty() && varlist.front() == tok2->tokAt(3)) {
|
||||||
{
|
|
||||||
nullPointerError(tok2->tokAt(3), varname, tok->linenr());
|
nullPointerError(tok2->tokAt(3), varname, tok->linenr());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -683,15 +619,12 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
|
||||||
if (tok1->str() == "break")
|
if (tok1->str() == "break")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (tok1->varId() == varid)
|
if (tok1->varId() == varid) {
|
||||||
{
|
|
||||||
// Don't write warning if the dereferencing is
|
// Don't write warning if the dereferencing is
|
||||||
// guarded by ?:
|
// guarded by ?:
|
||||||
const Token *tok2 = tok1->previous();
|
const Token *tok2 = tok1->previous();
|
||||||
if (tok2 && (tok2->isArithmeticalOp() || tok2->str() == "("))
|
if (tok2 && (tok2->isArithmeticalOp() || tok2->str() == "(")) {
|
||||||
{
|
while (tok2 && !Token::Match(tok2, "[;{}?:]")) {
|
||||||
while (tok2 && !Token::Match(tok2, "[;{}?:]"))
|
|
||||||
{
|
|
||||||
if (tok2->str() == ")")
|
if (tok2->str() == ")")
|
||||||
tok2 = tok2->link();
|
tok2 = tok2->link();
|
||||||
tok2 = tok2->previous();
|
tok2 = tok2->previous();
|
||||||
|
@ -704,29 +637,18 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
|
||||||
// uncertain
|
// uncertain
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
|
|
||||||
if (Token::Match(tok1->tokAt(-2), "%varid% = %varid% .", varid))
|
if (Token::Match(tok1->tokAt(-2), "%varid% = %varid% .", varid)) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
} else if (Token::Match(tok1->previous(), "&&|%oror%")) {
|
||||||
else if (Token::Match(tok1->previous(), "&&|%oror%"))
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
} else if (Token::Match(tok1->tokAt(-2), "&&|%oror% !")) {
|
||||||
else if (Token::Match(tok1->tokAt(-2), "&&|%oror% !"))
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
} else if (CheckNullPointer::isPointerDeRef(tok1, unknown)) {
|
||||||
else if (CheckNullPointer::isPointerDeRef(tok1, unknown))
|
|
||||||
{
|
|
||||||
nullPointerError(tok1, varname, tok->linenr());
|
nullPointerError(tok1, varname, tok->linenr());
|
||||||
break;
|
break;
|
||||||
}
|
} else if (Token::simpleMatch(tok1->previous(), "&")) {
|
||||||
else if (Token::simpleMatch(tok1->previous(), "&"))
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
} else if (Token::simpleMatch(tok1->next(), "=")) {
|
||||||
else if (Token::simpleMatch(tok1->next(), "="))
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -751,13 +673,11 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
|
||||||
// TODO: Use isPointer?
|
// TODO: Use isPointer?
|
||||||
std::set<unsigned int> pointerVariables;
|
std::set<unsigned int> pointerVariables;
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
if (Token::Match(tok, "* %var% [;,)=]"))
|
if (Token::Match(tok, "* %var% [;,)=]"))
|
||||||
pointerVariables.insert(tok->next()->varId());
|
pointerVariables.insert(tok->next()->varId());
|
||||||
|
|
||||||
else if (Token::simpleMatch(tok, "if ("))
|
else if (Token::simpleMatch(tok, "if (")) {
|
||||||
{
|
|
||||||
// TODO: investigate false negatives:
|
// TODO: investigate false negatives:
|
||||||
// - handle "while"?
|
// - handle "while"?
|
||||||
// - if there are logical operators
|
// - if there are logical operators
|
||||||
|
@ -808,8 +728,7 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
|
||||||
// indentlevel inside the if-body is 1
|
// indentlevel inside the if-body is 1
|
||||||
unsigned int indentlevel = 1;
|
unsigned int indentlevel = 1;
|
||||||
|
|
||||||
if (Token::Match(tok, "if|while ( %var% )|&&"))
|
if (Token::Match(tok, "if|while ( %var% )|&&")) {
|
||||||
{
|
|
||||||
// pointer might be null
|
// pointer might be null
|
||||||
null = false;
|
null = false;
|
||||||
|
|
||||||
|
@ -827,18 +746,15 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
|
||||||
const std::string &pointerName = vartok->str();
|
const std::string &pointerName = vartok->str();
|
||||||
|
|
||||||
// Count { and } for tok2
|
// Count { and } for tok2
|
||||||
for (const Token *tok2 = tok1; tok2; tok2 = tok2->next())
|
for (const Token *tok2 = tok1; tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel == 0)
|
if (indentlevel == 0)
|
||||||
break;
|
break;
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
|
|
||||||
if (null && indentlevel == 0)
|
if (null && indentlevel == 0) {
|
||||||
{
|
|
||||||
// skip all "else" blocks because they are not executed in this execution path
|
// skip all "else" blocks because they are not executed in this execution path
|
||||||
while (Token::simpleMatch(tok2, "} else {"))
|
while (Token::simpleMatch(tok2, "} else {"))
|
||||||
tok2 = tok2->tokAt(2)->link();
|
tok2 = tok2->tokAt(2)->link();
|
||||||
|
@ -846,8 +762,7 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok2, "goto|return|continue|break|throw|if|switch"))
|
if (Token::Match(tok2, "goto|return|continue|break|throw|if|switch")) {
|
||||||
{
|
|
||||||
bool dummy = false;
|
bool dummy = false;
|
||||||
if (Token::Match(tok2, "return * %varid%", varid))
|
if (Token::Match(tok2, "return * %varid%", varid))
|
||||||
nullPointerError(tok2, pointerName, linenr);
|
nullPointerError(tok2, pointerName, linenr);
|
||||||
|
@ -858,21 +773,17 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
|
||||||
}
|
}
|
||||||
|
|
||||||
// parameters to sizeof are not dereferenced
|
// parameters to sizeof are not dereferenced
|
||||||
if (Token::Match(tok2, "decltype|sizeof ("))
|
if (Token::Match(tok2, "decltype|sizeof (")) {
|
||||||
{
|
|
||||||
tok2 = tok2->next()->link();
|
tok2 = tok2->next()->link();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function call, check if pointer is dereferenced
|
// function call, check if pointer is dereferenced
|
||||||
if (Token::Match(tok2, "%var% ("))
|
if (Token::Match(tok2, "%var% (")) {
|
||||||
{
|
|
||||||
std::list<const Token *> var;
|
std::list<const Token *> var;
|
||||||
parseFunctionCall(*tok2, var, 0);
|
parseFunctionCall(*tok2, var, 0);
|
||||||
for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
|
for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it) {
|
||||||
{
|
if ((*it)->varId() == varid) {
|
||||||
if ((*it)->varId() == varid)
|
|
||||||
{
|
|
||||||
nullPointerError(*it, pointerName, linenr);
|
nullPointerError(*it, pointerName, linenr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -882,8 +793,7 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
|
||||||
// calling unknown function (abort/init)..
|
// calling unknown function (abort/init)..
|
||||||
if (Token::simpleMatch(tok2, ") ;") &&
|
if (Token::simpleMatch(tok2, ") ;") &&
|
||||||
(Token::Match(tok2->link()->tokAt(-2), "[;{}.] %var% (") ||
|
(Token::Match(tok2->link()->tokAt(-2), "[;{}.] %var% (") ||
|
||||||
Token::Match(tok2->link()->tokAt(-5), "[;{}] ( * %var% ) (")))
|
Token::Match(tok2->link()->tokAt(-5), "[;{}] ( * %var% ) ("))) {
|
||||||
{
|
|
||||||
// noreturn function?
|
// noreturn function?
|
||||||
if (tok2->strAt(2) == "}")
|
if (tok2->strAt(2) == "}")
|
||||||
break;
|
break;
|
||||||
|
@ -895,8 +805,7 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok2->varId() == varid)
|
if (tok2->varId() == varid) {
|
||||||
{
|
|
||||||
// unknown: this is set to true by isPointerDeRef if
|
// unknown: this is set to true by isPointerDeRef if
|
||||||
// the function fails to determine if there
|
// the function fails to determine if there
|
||||||
// is a dereference or not
|
// is a dereference or not
|
||||||
|
@ -932,19 +841,16 @@ void CheckNullPointer::nullConstantDereference()
|
||||||
// this is kept at 0 for all scopes that are not executing
|
// this is kept at 0 for all scopes that are not executing
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
// start of executable scope..
|
// start of executable scope..
|
||||||
if (indentlevel == 0 && Token::Match(tok, ") const| {"))
|
if (indentlevel == 0 && Token::Match(tok, ") const| {"))
|
||||||
indentlevel = 1;
|
indentlevel = 1;
|
||||||
|
|
||||||
else if (indentlevel >= 1)
|
else if (indentlevel >= 1) {
|
||||||
{
|
|
||||||
if (tok->str() == "{")
|
if (tok->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
|
|
||||||
else if (tok->str() == "}")
|
else if (tok->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel <= 2)
|
if (indentlevel <= 2)
|
||||||
indentlevel = 0;
|
indentlevel = 0;
|
||||||
else
|
else
|
||||||
|
@ -954,11 +860,9 @@ void CheckNullPointer::nullConstantDereference()
|
||||||
if (tok->str() == "(" && Token::Match(tok->previous(), "sizeof|decltype"))
|
if (tok->str() == "(" && Token::Match(tok->previous(), "sizeof|decltype"))
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
|
|
||||||
else if (Token::simpleMatch(tok, "exit ( )"))
|
else if (Token::simpleMatch(tok, "exit ( )")) {
|
||||||
{
|
|
||||||
// Goto end of scope
|
// Goto end of scope
|
||||||
while (tok && tok->str() != "}")
|
while (tok && tok->str() != "}") {
|
||||||
{
|
|
||||||
if (tok->str() == "{")
|
if (tok->str() == "{")
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
@ -967,24 +871,19 @@ void CheckNullPointer::nullConstantDereference()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Token::simpleMatch(tok, "* 0"))
|
else if (Token::simpleMatch(tok, "* 0")) {
|
||||||
{
|
if (Token::Match(tok->previous(), "return|;|{|}|=|(|,|%op%")) {
|
||||||
if (Token::Match(tok->previous(), "return|;|{|}|=|(|,|%op%"))
|
|
||||||
{
|
|
||||||
nullPointerError(tok);
|
nullPointerError(tok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (indentlevel > 0 && Token::Match(tok->previous(), "[={};] %var% ("))
|
else if (indentlevel > 0 && Token::Match(tok->previous(), "[={};] %var% (")) {
|
||||||
{
|
|
||||||
std::list<const Token *> var;
|
std::list<const Token *> var;
|
||||||
parseFunctionCall(*tok, var, 0);
|
parseFunctionCall(*tok, var, 0);
|
||||||
|
|
||||||
// is one of the var items a NULL pointer?
|
// is one of the var items a NULL pointer?
|
||||||
for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
|
for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it) {
|
||||||
{
|
if ((*it)->str() == "0") {
|
||||||
if ((*it)->str() == "0")
|
|
||||||
{
|
|
||||||
nullPointerError(*it);
|
nullPointerError(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1002,12 +901,10 @@ void CheckNullPointer::nullConstantDereference()
|
||||||
* @brief %Check for null pointer usage (using ExecutionPath)
|
* @brief %Check for null pointer usage (using ExecutionPath)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Nullpointer : public ExecutionPath
|
class Nullpointer : public ExecutionPath {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** Startup constructor */
|
/** Startup constructor */
|
||||||
Nullpointer(Check *c) : ExecutionPath(c, 0), null(false)
|
Nullpointer(Check *c) : ExecutionPath(c, 0), null(false) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1015,13 +912,11 @@ private:
|
||||||
Nullpointer(Check *c, const unsigned int id, const std::string &name)
|
Nullpointer(Check *c, const unsigned int id, const std::string &name)
|
||||||
: ExecutionPath(c, id),
|
: ExecutionPath(c, id),
|
||||||
varname(name),
|
varname(name),
|
||||||
null(false)
|
null(false) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copy this check */
|
/** Copy this check */
|
||||||
ExecutionPath *copy()
|
ExecutionPath *copy() {
|
||||||
{
|
|
||||||
return new Nullpointer(*this);
|
return new Nullpointer(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1029,8 +924,7 @@ private:
|
||||||
void operator=(const Nullpointer &);
|
void operator=(const Nullpointer &);
|
||||||
|
|
||||||
/** is other execution path equal? */
|
/** is other execution path equal? */
|
||||||
bool is_equal(const ExecutionPath *e) const
|
bool is_equal(const ExecutionPath *e) const {
|
||||||
{
|
|
||||||
const Nullpointer *c = static_cast<const Nullpointer *>(e);
|
const Nullpointer *c = static_cast<const Nullpointer *>(e);
|
||||||
return (varname == c->varname && null == c->null);
|
return (varname == c->varname && null == c->null);
|
||||||
}
|
}
|
||||||
|
@ -1042,11 +936,9 @@ private:
|
||||||
bool null;
|
bool null;
|
||||||
|
|
||||||
/** variable is set to null */
|
/** variable is set to null */
|
||||||
static void setnull(std::list<ExecutionPath *> &checks, const unsigned int varid)
|
static void setnull(std::list<ExecutionPath *> &checks, const unsigned int varid) {
|
||||||
{
|
|
||||||
std::list<ExecutionPath *>::iterator it;
|
std::list<ExecutionPath *>::iterator it;
|
||||||
for (it = checks.begin(); it != checks.end(); ++it)
|
for (it = checks.begin(); it != checks.end(); ++it) {
|
||||||
{
|
|
||||||
Nullpointer *c = dynamic_cast<Nullpointer *>(*it);
|
Nullpointer *c = dynamic_cast<Nullpointer *>(*it);
|
||||||
if (c && c->varId == varid)
|
if (c && c->varId == varid)
|
||||||
c->null = true;
|
c->null = true;
|
||||||
|
@ -1058,19 +950,15 @@ private:
|
||||||
* @param checks Checks
|
* @param checks Checks
|
||||||
* @param tok token where dereferencing happens
|
* @param tok token where dereferencing happens
|
||||||
*/
|
*/
|
||||||
static void dereference(std::list<ExecutionPath *> &checks, const Token *tok)
|
static void dereference(std::list<ExecutionPath *> &checks, const Token *tok) {
|
||||||
{
|
|
||||||
const unsigned int varid(tok->varId());
|
const unsigned int varid(tok->varId());
|
||||||
|
|
||||||
std::list<ExecutionPath *>::iterator it;
|
std::list<ExecutionPath *>::iterator it;
|
||||||
for (it = checks.begin(); it != checks.end(); ++it)
|
for (it = checks.begin(); it != checks.end(); ++it) {
|
||||||
{
|
|
||||||
Nullpointer *c = dynamic_cast<Nullpointer *>(*it);
|
Nullpointer *c = dynamic_cast<Nullpointer *>(*it);
|
||||||
if (c && c->varId == varid && c->null)
|
if (c && c->varId == varid && c->null) {
|
||||||
{
|
|
||||||
CheckNullPointer *checkNullPointer = dynamic_cast<CheckNullPointer *>(c->owner);
|
CheckNullPointer *checkNullPointer = dynamic_cast<CheckNullPointer *>(c->owner);
|
||||||
if (checkNullPointer)
|
if (checkNullPointer) {
|
||||||
{
|
|
||||||
checkNullPointer->nullPointerError(tok, c->varname);
|
checkNullPointer->nullPointerError(tok, c->varname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1079,10 +967,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** parse tokens */
|
/** parse tokens */
|
||||||
const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const
|
const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const {
|
||||||
{
|
if (Token::Match(tok.previous(), "[;{}] const| struct| %type% * %var% ;")) {
|
||||||
if (Token::Match(tok.previous(), "[;{}] const| struct| %type% * %var% ;"))
|
|
||||||
{
|
|
||||||
const Token * vartok = tok.tokAt(2);
|
const Token * vartok = tok.tokAt(2);
|
||||||
|
|
||||||
if (tok.str() == "const")
|
if (tok.str() == "const")
|
||||||
|
@ -1097,21 +983,18 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Template pointer variable..
|
// Template pointer variable..
|
||||||
if (Token::Match(tok.previous(), "[;{}] %type% ::|<"))
|
if (Token::Match(tok.previous(), "[;{}] %type% ::|<")) {
|
||||||
{
|
|
||||||
const Token * vartok = &tok;
|
const Token * vartok = &tok;
|
||||||
while (Token::Match(vartok, "%type% ::"))
|
while (Token::Match(vartok, "%type% ::"))
|
||||||
vartok = vartok->tokAt(2);
|
vartok = vartok->tokAt(2);
|
||||||
if (Token::Match(vartok, "%type% < %type%"))
|
if (Token::Match(vartok, "%type% < %type%")) {
|
||||||
{
|
|
||||||
vartok = vartok->tokAt(3);
|
vartok = vartok->tokAt(3);
|
||||||
while (vartok && (vartok->str() == "*" || vartok->isName()))
|
while (vartok && (vartok->str() == "*" || vartok->isName()))
|
||||||
vartok = vartok->next();
|
vartok = vartok->next();
|
||||||
}
|
}
|
||||||
if (vartok
|
if (vartok
|
||||||
&& (vartok->str() == ">" || vartok->isName())
|
&& (vartok->str() == ">" || vartok->isName())
|
||||||
&& Token::Match(vartok->next(), "* %var% ;|="))
|
&& Token::Match(vartok->next(), "* %var% ;|=")) {
|
||||||
{
|
|
||||||
vartok = vartok->tokAt(2);
|
vartok = vartok->tokAt(2);
|
||||||
checks.push_back(new Nullpointer(owner, vartok->varId(), vartok->str()));
|
checks.push_back(new Nullpointer(owner, vartok->varId(), vartok->str()));
|
||||||
if (Token::simpleMatch(vartok->next(), "= 0 ;"))
|
if (Token::simpleMatch(vartok->next(), "= 0 ;"))
|
||||||
|
@ -1120,29 +1003,24 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::simpleMatch(&tok, "try {"))
|
if (Token::simpleMatch(&tok, "try {")) {
|
||||||
{
|
|
||||||
// Bail out all used variables
|
// Bail out all used variables
|
||||||
unsigned int indentlevel = 0;
|
unsigned int indentlevel = 0;
|
||||||
for (const Token *tok2 = &tok; tok2; tok2 = tok2->next())
|
for (const Token *tok2 = &tok; tok2; tok2 = tok2->next()) {
|
||||||
{
|
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}") {
|
||||||
{
|
|
||||||
if (indentlevel == 0)
|
if (indentlevel == 0)
|
||||||
break;
|
break;
|
||||||
if (indentlevel == 1 && !Token::simpleMatch(tok2,"} catch ("))
|
if (indentlevel == 1 && !Token::simpleMatch(tok2,"} catch ("))
|
||||||
return tok2;
|
return tok2;
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
}
|
} else if (tok2->varId())
|
||||||
else if (tok2->varId())
|
|
||||||
bailOutVar(checks,tok2->varId());
|
bailOutVar(checks,tok2->varId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(&tok, "%var% ("))
|
if (Token::Match(&tok, "%var% (")) {
|
||||||
{
|
|
||||||
if (tok.str() == "sizeof")
|
if (tok.str() == "sizeof")
|
||||||
return tok.next()->link();
|
return tok.next()->link();
|
||||||
|
|
||||||
|
@ -1156,8 +1034,7 @@ private:
|
||||||
else if (Token::simpleMatch(&tok, "( 0 &&"))
|
else if (Token::simpleMatch(&tok, "( 0 &&"))
|
||||||
return tok.link();
|
return tok.link();
|
||||||
|
|
||||||
if (tok.varId() != 0)
|
if (tok.varId() != 0) {
|
||||||
{
|
|
||||||
// unknown : not really used. it is passed to isPointerDeRef.
|
// unknown : not really used. it is passed to isPointerDeRef.
|
||||||
// if isPointerDeRef fails to determine if there
|
// if isPointerDeRef fails to determine if there
|
||||||
// is a dereference the this will be set to true.
|
// is a dereference the this will be set to true.
|
||||||
|
@ -1173,8 +1050,7 @@ private:
|
||||||
bailOutVar(checks, tok.varId());
|
bailOutVar(checks, tok.varId());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (tok.str() == "delete")
|
else if (tok.str() == "delete") {
|
||||||
{
|
|
||||||
const Token *ret = tok.next();
|
const Token *ret = tok.next();
|
||||||
if (Token::simpleMatch(ret, "[ ]"))
|
if (Token::simpleMatch(ret, "[ ]"))
|
||||||
ret = ret->tokAt(2);
|
ret = ret->tokAt(2);
|
||||||
|
@ -1182,14 +1058,12 @@ private:
|
||||||
return ret->next();
|
return ret->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (tok.str() == "return")
|
else if (tok.str() == "return") {
|
||||||
{
|
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
const Token *vartok = tok.next();
|
const Token *vartok = tok.next();
|
||||||
if (vartok->str() == "*")
|
if (vartok->str() == "*")
|
||||||
vartok = vartok->next();
|
vartok = vartok->next();
|
||||||
if (vartok->varId() && CheckNullPointer::isPointerDeRef(vartok, unknown))
|
if (vartok->varId() && CheckNullPointer::isPointerDeRef(vartok, unknown)) {
|
||||||
{
|
|
||||||
dereference(checks, vartok);
|
dereference(checks, vartok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1198,18 +1072,15 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** parse condition. @sa ExecutionPath::parseCondition */
|
/** parse condition. @sa ExecutionPath::parseCondition */
|
||||||
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks)
|
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks) {
|
||||||
{
|
for (const Token *tok2 = &tok; tok2; tok2 = tok2->next()) {
|
||||||
for (const Token *tok2 = &tok; tok2; tok2 = tok2->next())
|
|
||||||
{
|
|
||||||
if (tok2->str() == "(" || tok2->str() == ")")
|
if (tok2->str() == "(" || tok2->str() == ")")
|
||||||
break;
|
break;
|
||||||
if (Token::Match(tok2, "[<>=] * %var%"))
|
if (Token::Match(tok2, "[<>=] * %var%"))
|
||||||
dereference(checks, tok2->tokAt(2));
|
dereference(checks, tok2->tokAt(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(&tok, "!| %var% ("))
|
if (Token::Match(&tok, "!| %var% (")) {
|
||||||
{
|
|
||||||
std::list<const Token *> var;
|
std::list<const Token *> var;
|
||||||
CheckNullPointer::parseFunctionCall(tok.str() == "!" ? *tok.next() : tok, var, 0);
|
CheckNullPointer::parseFunctionCall(tok.str() == "!" ? *tok.next() : tok, var, 0);
|
||||||
for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
|
for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
|
||||||
|
@ -1220,10 +1091,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parseLoopBody(const Token *tok, std::list<ExecutionPath *> &checks) const
|
void parseLoopBody(const Token *tok, std::list<ExecutionPath *> &checks) const {
|
||||||
{
|
while (tok) {
|
||||||
while (tok)
|
|
||||||
{
|
|
||||||
if (Token::Match(tok, "{|}|return|goto|break|if"))
|
if (Token::Match(tok, "{|}|return|goto|break|if"))
|
||||||
return;
|
return;
|
||||||
const Token *next = parse(*tok, checks);
|
const Token *next = parse(*tok, checks);
|
||||||
|
|
|
@ -33,8 +33,7 @@ class Token;
|
||||||
|
|
||||||
/** @brief check for null pointer dereferencing */
|
/** @brief check for null pointer dereferencing */
|
||||||
|
|
||||||
class CheckNullPointer : public Check
|
class CheckNullPointer : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** @brief This constructor is used when registering the CheckNullPointer */
|
/** @brief This constructor is used when registering the CheckNullPointer */
|
||||||
CheckNullPointer() : Check(myName())
|
CheckNullPointer() : Check(myName())
|
||||||
|
@ -46,15 +45,13 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/** @brief Run checks against the normal token list */
|
/** @brief Run checks against the normal token list */
|
||||||
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckNullPointer checkNullPointer(tokenizer, settings, errorLogger);
|
CheckNullPointer checkNullPointer(tokenizer, settings, errorLogger);
|
||||||
checkNullPointer.nullPointer();
|
checkNullPointer.nullPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Run checks against the simplified token list */
|
/** @brief Run checks against the simplified token list */
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckNullPointer checkNullPointer(tokenizer, settings, errorLogger);
|
CheckNullPointer checkNullPointer(tokenizer, settings, errorLogger);
|
||||||
checkNullPointer.nullConstantDereference();
|
checkNullPointer.nullConstantDereference();
|
||||||
checkNullPointer.executionPaths();
|
checkNullPointer.executionPaths();
|
||||||
|
@ -105,21 +102,18 @@ public:
|
||||||
void nullPointerError(const Token *tok, const std::string &varname, const unsigned int line, bool inconclusive = false);
|
void nullPointerError(const Token *tok, const std::string &varname, const unsigned int line, bool inconclusive = false);
|
||||||
|
|
||||||
/** Get error messages. Used by --errorlist */
|
/** Get error messages. Used by --errorlist */
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckNullPointer c(0, settings, errorLogger);
|
CheckNullPointer c(0, settings, errorLogger);
|
||||||
c.nullPointerError(0, "pointer");
|
c.nullPointerError(0, "pointer");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Name of check */
|
/** Name of check */
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Null pointer";
|
return "Null pointer";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** class info in WIKI format. Used by --doc */
|
/** class info in WIKI format. Used by --doc */
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Null pointers\n"
|
return "Null pointers\n"
|
||||||
"* null pointer dereferencing\n";
|
"* null pointer dereferencing\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,8 @@
|
||||||
|
|
||||||
|
|
||||||
// Register this check class (by creating a static instance of it)
|
// Register this check class (by creating a static instance of it)
|
||||||
namespace
|
namespace {
|
||||||
{
|
CheckObsoleteFunctions instance;
|
||||||
CheckObsoleteFunctions instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckObsoleteFunctions::obsoleteFunctions()
|
void CheckObsoleteFunctions::obsoleteFunctions()
|
||||||
|
@ -43,45 +42,35 @@ void CheckObsoleteFunctions::obsoleteFunctions()
|
||||||
|
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
{
|
|
||||||
|
|
||||||
if (tok->isName() && tok->varId()==0 && tok->strAt(1) == "(" &&
|
if (tok->isName() && tok->varId()==0 && tok->strAt(1) == "(" &&
|
||||||
(!Token::Match(tok->previous(), ".|::|:|,") || Token::simpleMatch(tok->previous()->previous(), "std :: gets")))
|
(!Token::Match(tok->previous(), ".|::|:|,") || Token::simpleMatch(tok->previous()->previous(), "std :: gets"))) {
|
||||||
{
|
|
||||||
// function declaration?
|
// function declaration?
|
||||||
if ((tok->previous() && (tok->previous()->str() == "*" || tok->previous()->isName()))
|
if ((tok->previous() && (tok->previous()->str() == "*" || tok->previous()->isName()))
|
||||||
|| symbolDatabase->findFunctionByToken(tok))
|
|| symbolDatabase->findFunctionByToken(tok)) {
|
||||||
{
|
|
||||||
_obsoleteStandardFunctions.erase(tok->str());
|
_obsoleteStandardFunctions.erase(tok->str());
|
||||||
_obsoletePosixFunctions.erase(tok->str());
|
_obsoletePosixFunctions.erase(tok->str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string,std::string>::const_iterator it = _obsoleteStandardFunctions.find(tok->str());
|
std::map<std::string,std::string>::const_iterator it = _obsoleteStandardFunctions.find(tok->str());
|
||||||
if (it != _obsoleteStandardFunctions.end())
|
if (it != _obsoleteStandardFunctions.end()) {
|
||||||
{
|
|
||||||
// If checking an old code base it might be uninteresting to update obsolete functions.
|
// If checking an old code base it might be uninteresting to update obsolete functions.
|
||||||
// Therefore this is "information"
|
// Therefore this is "information"
|
||||||
reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
||||||
}
|
} else {
|
||||||
else
|
if (_settings->posix) {
|
||||||
{
|
|
||||||
if (_settings->posix)
|
|
||||||
{
|
|
||||||
it = _obsoletePosixFunctions.find(tok->str());
|
it = _obsoletePosixFunctions.find(tok->str());
|
||||||
if (it != _obsoletePosixFunctions.end())
|
if (it != _obsoletePosixFunctions.end()) {
|
||||||
{
|
|
||||||
// If checking an old code base it might be uninteresting to update obsolete functions.
|
// If checking an old code base it might be uninteresting to update obsolete functions.
|
||||||
// Therefore this is "information"
|
// Therefore this is "information"
|
||||||
reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_settings->c99)
|
if (_settings->c99) {
|
||||||
{
|
|
||||||
it = _obsoleteC99Functions.find(tok->str());
|
it = _obsoleteC99Functions.find(tok->str());
|
||||||
if (it != _obsoleteC99Functions.end())
|
if (it != _obsoleteC99Functions.end()) {
|
||||||
{
|
|
||||||
reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,24 +34,20 @@
|
||||||
* @brief Using obsolete functions that are always insecure to use.
|
* @brief Using obsolete functions that are always insecure to use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CheckObsoleteFunctions : public Check
|
class CheckObsoleteFunctions : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** This constructor is used when registering the CheckObsoleteFunctions */
|
/** This constructor is used when registering the CheckObsoleteFunctions */
|
||||||
CheckObsoleteFunctions() : Check(myName())
|
CheckObsoleteFunctions() : Check(myName()) {
|
||||||
{
|
|
||||||
initObsoleteFunctions();
|
initObsoleteFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This constructor is used when running checks. */
|
/** This constructor is used when running checks. */
|
||||||
CheckObsoleteFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
CheckObsoleteFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
: Check(myName(), tokenizer, settings, errorLogger)
|
: Check(myName(), tokenizer, settings, errorLogger) {
|
||||||
{
|
|
||||||
initObsoleteFunctions();
|
initObsoleteFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckObsoleteFunctions checkObsoleteFunctions(tokenizer, settings, errorLogger);
|
CheckObsoleteFunctions checkObsoleteFunctions(tokenizer, settings, errorLogger);
|
||||||
checkObsoleteFunctions.obsoleteFunctions();
|
checkObsoleteFunctions.obsoleteFunctions();
|
||||||
}
|
}
|
||||||
|
@ -66,8 +62,7 @@ private:
|
||||||
std::map<std::string, std::string> _obsoleteC99Functions;
|
std::map<std::string, std::string> _obsoleteC99Functions;
|
||||||
|
|
||||||
/** init obsolete functions list ' */
|
/** init obsolete functions list ' */
|
||||||
void initObsoleteFunctions()
|
void initObsoleteFunctions() {
|
||||||
{
|
|
||||||
_obsoletePosixFunctions["bsd_signal"] = "Found obsolete function 'bsd_signal'. It is recommended that new applications use the 'sigaction' function";
|
_obsoletePosixFunctions["bsd_signal"] = "Found obsolete function 'bsd_signal'. It is recommended that new applications use the 'sigaction' function";
|
||||||
|
|
||||||
_obsoletePosixFunctions["gethostbyaddr"] = "Found obsolete function 'gethostbyaddr'. It is recommended that new applications use the 'getnameinfo' function";
|
_obsoletePosixFunctions["gethostbyaddr"] = "Found obsolete function 'gethostbyaddr'. It is recommended that new applications use the 'getnameinfo' function";
|
||||||
|
@ -116,28 +111,23 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckObsoleteFunctions c(0, settings, errorLogger);
|
CheckObsoleteFunctions c(0, settings, errorLogger);
|
||||||
|
|
||||||
std::map<std::string,std::string>::const_iterator it(_obsoletePosixFunctions.begin()), itend(_obsoletePosixFunctions.end());
|
std::map<std::string,std::string>::const_iterator it(_obsoletePosixFunctions.begin()), itend(_obsoletePosixFunctions.end());
|
||||||
for (; it!=itend; ++it)
|
for (; it!=itend; ++it) {
|
||||||
{
|
|
||||||
c.reportError(0, Severity::style, "obsoleteFunctions"+it->first, it->second);
|
c.reportError(0, Severity::style, "obsoleteFunctions"+it->first, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Obsolete functions";
|
return "Obsolete functions";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
std::string info = "Warn if any of these obsolete functions are used:\n";
|
std::string info = "Warn if any of these obsolete functions are used:\n";
|
||||||
std::map<std::string,std::string>::const_iterator it(_obsoletePosixFunctions.begin()), itend(_obsoletePosixFunctions.end());
|
std::map<std::string,std::string>::const_iterator it(_obsoletePosixFunctions.begin()), itend(_obsoletePosixFunctions.end());
|
||||||
for (; it!=itend; ++it)
|
for (; it!=itend; ++it) {
|
||||||
{
|
|
||||||
info += "* " + it->first + "\n";
|
info += "* " + it->first + "\n";
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,8 +33,7 @@ class Token;
|
||||||
|
|
||||||
/** @brief Various small checks */
|
/** @brief Various small checks */
|
||||||
|
|
||||||
class CheckOther : public Check
|
class CheckOther : public Check {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
/** @brief This constructor is used when registering the CheckClass */
|
/** @brief This constructor is used when registering the CheckClass */
|
||||||
CheckOther() : Check(myName())
|
CheckOther() : Check(myName())
|
||||||
|
@ -46,8 +45,7 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/** @brief Run checks against the normal token list */
|
/** @brief Run checks against the normal token list */
|
||||||
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckOther checkOther(tokenizer, settings, errorLogger);
|
CheckOther checkOther(tokenizer, settings, errorLogger);
|
||||||
|
|
||||||
// Coding style checks
|
// Coding style checks
|
||||||
|
@ -76,8 +74,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Run checks against the simplified token list */
|
/** @brief Run checks against the simplified token list */
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
{
|
|
||||||
CheckOther checkOther(tokenizer, settings, errorLogger);
|
CheckOther checkOther(tokenizer, settings, errorLogger);
|
||||||
|
|
||||||
checkOther.clarifyCalculation();
|
checkOther.clarifyCalculation();
|
||||||
|
@ -278,8 +275,7 @@ public:
|
||||||
void comparisonOfBoolExpressionWithIntError(const Token *tok);
|
void comparisonOfBoolExpressionWithIntError(const Token *tok);
|
||||||
void SuspiciousSemicolonError(const Token *tok);
|
void SuspiciousSemicolonError(const Token *tok);
|
||||||
|
|
||||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) {
|
||||||
{
|
|
||||||
CheckOther c(0, settings, errorLogger);
|
CheckOther c(0, settings, errorLogger);
|
||||||
|
|
||||||
// error
|
// error
|
||||||
|
@ -330,13 +326,11 @@ public:
|
||||||
c.SuspiciousSemicolonError(0);
|
c.SuspiciousSemicolonError(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string myName() const
|
std::string myName() const {
|
||||||
{
|
|
||||||
return "Other";
|
return "Other";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string classInfo() const
|
std::string classInfo() const {
|
||||||
{
|
|
||||||
return "Other checks\n"
|
return "Other checks\n"
|
||||||
|
|
||||||
// error
|
// error
|
||||||
|
@ -391,11 +385,9 @@ private:
|
||||||
* @brief Used in warningRedundantCode()
|
* @brief Used in warningRedundantCode()
|
||||||
* Iterates through the %var% tokens in a fully qualified name and concatenates them.
|
* Iterates through the %var% tokens in a fully qualified name and concatenates them.
|
||||||
*/
|
*/
|
||||||
std::string concatNames(const Token **tok) const
|
std::string concatNames(const Token **tok) const {
|
||||||
{
|
|
||||||
std::string varname;
|
std::string varname;
|
||||||
while (Token::Match(*tok, "%var% ::|."))
|
while (Token::Match(*tok, "%var% ::|.")) {
|
||||||
{
|
|
||||||
varname.append((*tok)->str());
|
varname.append((*tok)->str());
|
||||||
varname.append((*tok)->next()->str());
|
varname.append((*tok)->next()->str());
|
||||||
*tok = (*tok)->tokAt(2);
|
*tok = (*tok)->tokAt(2);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue