This commit is contained in:
Tim Gerundt 2011-01-07 16:04:24 +01:00
commit 3ce8aaf1ce
13 changed files with 98 additions and 66 deletions

View File

@ -30,6 +30,11 @@ class ErrorLine;
/** /**
* @brief A class containing error data for one error. * @brief A class containing error data for one error.
*
* The paths are stored with internal ("/") separators. Only when we show the
* path or copy if for user (to clipboard) we convert to native separators.
* Full path is stored instead of relative path for flexibility. It is easy
* to get the relative path from full path when needed.
*/ */
class ErrorItem class ErrorItem
{ {

View File

@ -719,7 +719,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 = file; pathStr = QDir::toNativeSeparators(file);
if (!fullPath) if (!fullPath)
{ {
QFileInfo fi(pathStr); QFileInfo fi(pathStr);

View File

@ -2819,7 +2819,7 @@ void CheckOther::catchExceptionByValueError(const Token *tok)
void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varname) void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::warning, const std::string summary("memset() called to fill 0 bytes of \'" + varname + "\'");
"memsetZeroBytes", "memset() called to fill 0 bytes of \"" + varname + "\"" const std::string verbose(summary + ". Second and third arguments might be inverted.");
". Second and third arguments might be inverted."); reportError(tok, Severity::warning, "memsetZeroBytes", summary + "\n" + verbose);
} }

View File

@ -699,8 +699,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
processedFile = ostr.str(); processedFile = ostr.str();
} }
std::set<std::string> systemIncludes; handleIncludes(processedFile, filename, includePaths);
handleIncludes(processedFile, filename, includePaths, systemIncludes);
processedFile = replaceIfDefined(processedFile); processedFile = replaceIfDefined(processedFile);
@ -1490,13 +1489,17 @@ static int tolowerWrapper(int c)
} }
void Preprocessor::handleIncludes(std::string &code, void Preprocessor::handleIncludes(std::string &code, const std::string &filePath, const std::list<std::string> &includePaths)
const std::string &filePath,
const std::list<std::string> &includePaths,
std::set<std::string> &systemIncludes,
std::set<std::string> handledFiles)
{ {
std::list<std::string> paths;
std::string path;
path = filePath;
path.erase(1 + path.find_last_of("\\/"));
paths.push_back(path);
std::string::size_type pos = 0; std::string::size_type pos = 0;
std::string::size_type endfilePos = 0;
std::set<std::string> handledFiles;
endfilePos = pos;
while ((pos = code.find("#include", pos)) != std::string::npos) while ((pos = code.find("#include", pos)) != std::string::npos)
{ {
// Accept only includes that are at the start of a line // Accept only includes that are at the start of a line
@ -1506,6 +1509,15 @@ void Preprocessor::handleIncludes(std::string &code,
continue; continue;
} }
// If endfile is encountered, we have moved to a next file in our stack,
// so remove last path in our list.
while ((endfilePos = code.find("\n#endfile", endfilePos)) != std::string::npos && endfilePos < pos)
{
paths.pop_back();
endfilePos += 9; // size of #endfile
}
endfilePos = pos;
std::string::size_type end = code.find("\n", pos); std::string::size_type end = code.find("\n", pos);
std::string filename = code.substr(pos, end - pos); std::string filename = code.substr(pos, end - pos);
@ -1539,27 +1551,20 @@ void Preprocessor::handleIncludes(std::string &code,
if (headerType == UserHeader && !fileOpened) if (headerType == UserHeader && !fileOpened)
{ {
if (filePath.find_first_of("\\/") != std::string::npos) fin.open((paths.back() + filename).c_str());
{
std::string path(filePath);
path.erase(1 + path.find_last_of("\\/"));
fin.open((path + filename).c_str());
if (fin.is_open()) if (fin.is_open())
{ {
filename = path + filename; filename = paths.back() + filename;
fileOpened = true; fileOpened = true;
} }
} }
}
if (fileOpened) if (fileOpened)
{ {
filename = Path::simplifyPath(filename.c_str()); filename = Path::simplifyPath(filename.c_str());
std::string tempFile = filename; std::string tempFile = filename;
std::transform(tempFile.begin(), tempFile.end(), tempFile.begin(), tolowerWrapper); std::transform(tempFile.begin(), tempFile.end(), tempFile.begin(), tolowerWrapper);
if (handledFiles.find(tempFile) != handledFiles.end() || if (handledFiles.find(tempFile) != handledFiles.end())
(headerType == SystemHeader && systemIncludes.find(tempFile) != systemIncludes.end()))
{ {
// We have processed this file already once, skip // We have processed this file already once, skip
// it this time to avoid eternal loop. // it this time to avoid eternal loop.
@ -1567,9 +1572,6 @@ void Preprocessor::handleIncludes(std::string &code,
continue; continue;
} }
if (headerType == SystemHeader)
systemIncludes.insert(tempFile);
else
handledFiles.insert(tempFile); handledFiles.insert(tempFile);
processedFile = Preprocessor::read(fin, filename, _settings); processedFile = Preprocessor::read(fin, filename, _settings);
fin.close(); fin.close();
@ -1586,10 +1588,12 @@ void Preprocessor::handleIncludes(std::string &code,
// Remove space characters that are after or before new line character // Remove space characters that are after or before new line character
processedFile = removeSpaceNearNL(processedFile); processedFile = removeSpaceNearNL(processedFile);
handleIncludes(processedFile, filename, includePaths, systemIncludes, handledFiles);
processedFile = "#file \"" + filename + "\"\n" + processedFile + "\n#endfile"; processedFile = "#file \"" + filename + "\"\n" + processedFile + "\n#endfile";
code.insert(pos, processedFile); code.insert(pos, processedFile);
pos += processedFile.size();
path = filename;
path.erase(1 + path.find_last_of("\\/"));
paths.push_back(path);
} }
else if (!fileOpened) else if (!fileOpened)
{ {

View File

@ -25,7 +25,6 @@
#include <istream> #include <istream>
#include <string> #include <string>
#include <list> #include <list>
#include <set>
class ErrorLogger; class ErrorLogger;
class Settings; class Settings;
@ -213,16 +212,9 @@ private:
* There must be a path separator at the end. Default parameter is empty list. * There must be a path separator at the end. Default parameter is empty list.
* Note that if path from given filename is also extracted and that is used as * Note that if path from given filename is also extracted and that is used as
* a last include path if include file was not found from earlier paths. * a last include path if include file was not found from earlier paths.
* @param systemIncludes System includes
* @param handledFiles used in the recursive handling. Should be empty unless
* a recursive call is made.
* @return modified source code * @return modified source code
*/ */
void handleIncludes(std::string &code, void handleIncludes(std::string &code, const std::string &filePath, const std::list<std::string> &includePaths);
const std::string &filePath,
const std::list<std::string> &includePaths,
std::set<std::string> &systemIncludes,
std::set<std::string> handledFiles = std::set<std::string>());
Settings *_settings; Settings *_settings;
ErrorLogger *_errorLogger; ErrorLogger *_errorLogger;

View File

@ -1574,7 +1574,8 @@ void SymbolDatabase::SpaceInfo::initializeVarList(const Func &func, std::list<st
} }
// Calling member function? // Calling member function?
else if (Token::simpleMatch(ftok, "operator = (")) else if (Token::simpleMatch(ftok, "operator = (") &&
ftok->previous()->str() != "::")
{ {
// check if member function exists // check if member function exists
std::list<Func>::const_iterator it; std::list<Func>::const_iterator it;

View File

@ -665,8 +665,16 @@ void Tokenizer::unsupportedTypedef(const Token *tok) const
std::ostringstream str; std::ostringstream str;
const Token *tok1 = tok; const Token *tok1 = tok;
while (tok && tok->str() != ";") int level = 0;
while (tok)
{ {
if (level == 0 && tok->str() == ";")
break;
else if (tok->str() == "{")
level++;
else if (tok->str() == "}")
level--;
if (tok != tok1) if (tok != tok1)
str << " "; str << " ";
str << tok->str(); str << tok->str();
@ -694,10 +702,19 @@ void Tokenizer::unsupportedTypedef(const Token *tok) const
Token * Tokenizer::deleteInvalidTypedef(Token *typeDef) Token * Tokenizer::deleteInvalidTypedef(Token *typeDef)
{ {
Token *tok = NULL; Token *tok = NULL;
int level = 0;
// remove typedef but leave ; // remove typedef but leave ;
while (typeDef->next() && typeDef->next()->str() != ";") while (typeDef->next())
{
if (level == 0 && typeDef->next()->str() == ";")
break;
else if (typeDef->next()->str() == "{")
level++;
else if (typeDef->next()->str() == "}")
level--;
typeDef->deleteNext(); typeDef->deleteNext();
}
if (typeDef != _tokens) if (typeDef != _tokens)
{ {
@ -2029,6 +2046,22 @@ bool Tokenizer::tokenize(std::istream &code,
} }
} }
// Replace NULL with 0..
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (tok->str() == "NULL" || tok->str() == "'\\0'" || tok->str() == "'\\x0'")
{
tok->str("0");
}
else if (tok->isNumber() &&
MathLib::isInt(tok->str()) &&
MathLib::toLongNumber(tok->str()) == 0)
{
tok->str("0");
}
}
// remove inline SQL (Oracle PRO*C). Ticket: #1959 // remove inline SQL (Oracle PRO*C). Ticket: #1959
for (Token *tok = _tokens; tok; tok = tok->next()) for (Token *tok = _tokens; tok; tok = tok->next())
{ {
@ -2422,6 +2455,8 @@ bool Tokenizer::tokenize(std::istream &code,
// Change initialisation of variable to assignment // Change initialisation of variable to assignment
simplifyInitVar(); simplifyInitVar();
if (!preprocessorCondition) if (!preprocessorCondition)
{ {
setVarId(); setVarId();
@ -3987,22 +4022,6 @@ bool Tokenizer::simplifyTokenList()
tok->deleteNext(); tok->deleteNext();
} }
// Replace NULL with 0..
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (tok->str() == "NULL" || tok->str() == "'\\0'" || tok->str() == "'\\x0'")
{
tok->str("0");
}
else if (tok->isNumber() &&
MathLib::isInt(tok->str()) &&
MathLib::toLongNumber(tok->str()) == 0)
{
tok->str("0");
}
}
// simplify references // simplify references
simplifyReference(); simplifyReference();

View File

@ -27,7 +27,7 @@ sub checkfile
} }
# set comment variable # set comment variable
if ($line =~ /\/\//) if (($line =~ /\/\//) || ($line =~ /\/\*/))
{ {
$comment = 1; $comment = 1;
} }

View File

@ -262,6 +262,7 @@ private:
ASSERT_EQUALS(false , MathLib::isFloat("+1E+10000")); ASSERT_EQUALS(false , MathLib::isFloat("+1E+10000"));
ASSERT_EQUALS(false , MathLib::isFloat("-1E+1")); ASSERT_EQUALS(false , MathLib::isFloat("-1E+1"));
ASSERT_EQUALS(false , MathLib::isFloat("-1E+10000")); ASSERT_EQUALS(false , MathLib::isFloat("-1E+10000"));
ASSERT_EQUALS(true , MathLib::isFloat(".1250E+04"));
ASSERT_EQUALS(true , MathLib::isFloat("-1E-1")); ASSERT_EQUALS(true , MathLib::isFloat("-1E-1"));
ASSERT_EQUALS(true , MathLib::isFloat("-1E-10000")); ASSERT_EQUALS(true , MathLib::isFloat("-1E-10000"));

View File

@ -1625,7 +1625,7 @@ private:
"}\n" "}\n"
); );
ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0" ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0"
" bytes of \"p\". Second and third arguments might be inverted.\n", errout.str()); " bytes of \'p\'\n", errout.str());
check("void f() {\n" check("void f() {\n"
" memset(p, sizeof(p), 0)\n" " memset(p, sizeof(p), 0)\n"
@ -1633,6 +1633,7 @@ private:
); );
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0" TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) memset() called to fill 0"
" bytes of \"p\". Second and third arguments might be inverted.\n", errout.str()); " bytes of \"p\". Second and third arguments might be inverted.\n", errout.str());
ASSERT_EQUALS("", errout.str());
} }
}; };

View File

@ -232,6 +232,7 @@ private:
TEST_CASE(simplifyTypedef72); // ticket #2375 TEST_CASE(simplifyTypedef72); // ticket #2375
TEST_CASE(simplifyTypedef73); // ticket #2412 TEST_CASE(simplifyTypedef73); // ticket #2412
TEST_CASE(simplifyTypedef74); // ticket #2414 TEST_CASE(simplifyTypedef74); // ticket #2414
TEST_CASE(simplifyTypedef75); // ticket #2426
TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -4786,6 +4787,14 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void simplifyTypedef75() // ticket #2426
{
const char code[] = "typedef _Packed struct S { long l; }; \n";
const std::string expected = ";";
ASSERT_EQUALS(expected, sizeof_(code));
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedefFunction1() void simplifyTypedefFunction1()
{ {
{ {

View File

@ -3776,19 +3776,19 @@ private:
// ticket #346 // ticket #346
const char code1[] = "void *p = NULL;"; const char code1[] = "void *p = NULL;";
const char res1[] = "void * p ; p = NULL ;"; const char res1[] = "void * p ; p = 0 ;";
ASSERT_EQUALS(res1, tokenizeAndStringify(code1)); ASSERT_EQUALS(res1, tokenizeAndStringify(code1));
const char code2[] = "const void *p = NULL;"; const char code2[] = "const void *p = NULL;";
const char res2[] = "const void * p ; p = NULL ;"; const char res2[] = "const void * p ; p = 0 ;";
ASSERT_EQUALS(res2, tokenizeAndStringify(code2)); ASSERT_EQUALS(res2, tokenizeAndStringify(code2));
const char code3[] = "void * const p = NULL;"; const char code3[] = "void * const p = NULL;";
const char res3[] = "void * const p ; p = NULL ;"; const char res3[] = "void * const p ; p = 0 ;";
ASSERT_EQUALS(res3, tokenizeAndStringify(code3)); ASSERT_EQUALS(res3, tokenizeAndStringify(code3));
const char code4[] = "const void * const p = NULL;"; const char code4[] = "const void * const p = NULL;";
const char res4[] = "const void * const p ; p = NULL ;"; const char res4[] = "const void * const p ; p = 0 ;";
ASSERT_EQUALS(res4, tokenizeAndStringify(code4)); ASSERT_EQUALS(res4, tokenizeAndStringify(code4));
} }
@ -3909,7 +3909,7 @@ private:
{ {
// ticket #696 // ticket #696
const char code[] = "char a[10]={'\\0'}, b[10]={'\\0'};"; const char code[] = "char a[10]={'\\0'}, b[10]={'\\0'};";
const char res[] = "char a [ 10 ] = { '\\0' } ; char b [ 10 ] = { '\\0' } ;"; const char res[] = "char a [ 10 ] = { 0 } ; char b [ 10 ] = { 0 } ;";
ASSERT_EQUALS(res, tokenizeAndStringify(code)); ASSERT_EQUALS(res, tokenizeAndStringify(code));
} }
@ -3917,7 +3917,7 @@ private:
void vardecl9() void vardecl9()
{ {
const char code[] = "char a[2] = {'A', '\\0'}, b[2] = {'B', '\\0'};"; const char code[] = "char a[2] = {'A', '\\0'}, b[2] = {'B', '\\0'};";
const char res[] = "char a [ 2 ] = { 'A' , '\\0' } ; char b [ 2 ] = { 'B' , '\\0' } ;"; const char res[] = "char a [ 2 ] = { 'A' , 0 } ; char b [ 2 ] = { 'B' , 0 } ;";
ASSERT_EQUALS(res, tokenizeAndStringify(code)); ASSERT_EQUALS(res, tokenizeAndStringify(code));
} }