Merge branch 'master' of http://github.com/danmar/cppcheck
This commit is contained in:
commit
a69fbffa76
|
@ -98,7 +98,7 @@ QStringList ProjectFileDialog::GetIncludePaths() const
|
|||
QListWidgetItem *item = mUI.mListIncludeDirs->item(i);
|
||||
includePaths << QDir::fromNativeSeparators(item->text());
|
||||
}
|
||||
return includePaths;
|
||||
return includePaths;
|
||||
}
|
||||
|
||||
QStringList ProjectFileDialog::GetDefines() const
|
||||
|
|
|
@ -266,7 +266,6 @@ void CheckAutoVariables::returnPointerToLocalArray()
|
|||
tok2 = tok2->next()->link();
|
||||
|
||||
unsigned int indentlevel = 0;
|
||||
std::set<unsigned int> arrayVar;
|
||||
for (; tok2; tok2 = tok2->next())
|
||||
{
|
||||
// indentlevel..
|
||||
|
@ -279,21 +278,13 @@ void CheckAutoVariables::returnPointerToLocalArray()
|
|||
--indentlevel;
|
||||
}
|
||||
|
||||
// Declaring a local array..
|
||||
if (Token::Match(tok2, "[;{}] %type% %var% ["))
|
||||
{
|
||||
const unsigned int varid = tok2->tokAt(2)->varId();
|
||||
if (varid > 0)
|
||||
{
|
||||
arrayVar.insert(varid);
|
||||
}
|
||||
}
|
||||
|
||||
// Return pointer to local array variable..
|
||||
if (Token::Match(tok2, "return %var% ;"))
|
||||
{
|
||||
const unsigned int varid = tok2->next()->varId();
|
||||
if (varid > 0 && arrayVar.find(varid) != arrayVar.end())
|
||||
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
||||
|
||||
if (var && var->isLocal() && !var->isStatic() && var->isArray())
|
||||
{
|
||||
errorReturnPointerToLocalArray(tok2);
|
||||
}
|
||||
|
@ -361,7 +352,6 @@ void CheckAutoVariables::returnReference()
|
|||
tok2 = tok2->link();
|
||||
|
||||
unsigned int indentlevel = 0;
|
||||
std::set<unsigned int> localvar; // local variables in function
|
||||
for (; tok2; tok2 = tok2->next())
|
||||
{
|
||||
// indentlevel..
|
||||
|
@ -374,33 +364,14 @@ void CheckAutoVariables::returnReference()
|
|||
--indentlevel;
|
||||
}
|
||||
|
||||
// declare local variable..
|
||||
if (Token::Match(tok2, "[{};] %type%") && tok2->next()->str() != "return")
|
||||
{
|
||||
// goto next token..
|
||||
tok2 = tok2->next();
|
||||
|
||||
// skip "const"
|
||||
if (Token::Match(tok2, "const %type%"))
|
||||
tok2 = tok2->next();
|
||||
|
||||
// skip "std::" if it is seen
|
||||
if (Token::simpleMatch(tok2, "std ::"))
|
||||
tok2 = tok2->tokAt(2);
|
||||
|
||||
// is it a variable declaration?
|
||||
if (Token::Match(tok2, "%type% %var% ;"))
|
||||
localvar.insert(tok2->next()->varId());
|
||||
else if (Token::Match(tok2, "%type% < %any% > %var% ;"))
|
||||
localvar.insert(tok2->tokAt(4)->varId());
|
||||
}
|
||||
|
||||
// return..
|
||||
else if (Token::Match(tok2, "return %var% ;"))
|
||||
if (Token::Match(tok2, "return %var% ;"))
|
||||
{
|
||||
// is the returned variable a local variable?
|
||||
if ((tok2->next()->varId() > 0) &&
|
||||
(localvar.find(tok2->next()->varId()) != localvar.end()))
|
||||
const unsigned int varid = tok2->next()->varId();
|
||||
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
||||
|
||||
if (var && var->isLocal() && !var->isStatic())
|
||||
{
|
||||
// report error..
|
||||
errorReturnReference(tok2);
|
||||
|
@ -462,7 +433,6 @@ void CheckAutoVariables::returncstr()
|
|||
tok2 = tok2->next()->link();
|
||||
|
||||
unsigned int indentlevel = 0;
|
||||
std::set<unsigned int> localvar; // local variables in function
|
||||
for (; tok2; tok2 = tok2->next())
|
||||
{
|
||||
// indentlevel..
|
||||
|
@ -475,31 +445,14 @@ void CheckAutoVariables::returncstr()
|
|||
--indentlevel;
|
||||
}
|
||||
|
||||
// declare local variable..
|
||||
if (Token::Match(tok2, "[{};] %type%") && tok2->next()->str() != "return")
|
||||
{
|
||||
// goto next token..
|
||||
tok2 = tok2->next();
|
||||
|
||||
// skip "const"
|
||||
if (Token::Match(tok2, "const %type%"))
|
||||
tok2 = tok2->next();
|
||||
|
||||
// skip "std::" if it is seen
|
||||
if (Token::simpleMatch(tok2, "std ::"))
|
||||
tok2 = tok2->tokAt(2);
|
||||
|
||||
// is it a variable declaration?
|
||||
if (Token::Match(tok2, "%type% %var% [;=]"))
|
||||
localvar.insert(tok2->next()->varId());
|
||||
}
|
||||
|
||||
// return..
|
||||
else if (Token::Match(tok2, "return %var% . c_str ( ) ;"))
|
||||
if (Token::Match(tok2, "return %var% . c_str ( ) ;"))
|
||||
{
|
||||
// is the returned variable a local variable?
|
||||
if ((tok2->next()->varId() > 0) &&
|
||||
(localvar.find(tok2->next()->varId()) != localvar.end()))
|
||||
const unsigned int varid = tok2->next()->varId();
|
||||
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
|
||||
|
||||
if (var && var->isLocal() && !var->isStatic())
|
||||
{
|
||||
// report error..
|
||||
errorReturnAutocstr(tok2);
|
||||
|
|
|
@ -178,10 +178,6 @@ std::string Preprocessor::read(std::istream &istr, const std::string &filename,
|
|||
// Remove all comments..
|
||||
result = removeComments(result, filename, settings);
|
||||
|
||||
// Remove '#if 0' blocks
|
||||
if (result.find("#if 0\n") != std::string::npos)
|
||||
result = removeIf0(result);
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Clean up all preprocessor statements
|
||||
|
@ -192,6 +188,10 @@ std::string Preprocessor::read(std::istream &istr, const std::string &filename,
|
|||
// Clean up preprocessor #if statements with Parantheses
|
||||
result = removeParantheses(result);
|
||||
|
||||
// Remove '#if 0' blocks
|
||||
if (result.find("#if 0\n") != std::string::npos)
|
||||
result = removeIf0(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -563,19 +563,33 @@ std::string Preprocessor::removeIf0(const std::string &code)
|
|||
else
|
||||
{
|
||||
// replace '#if 0' with empty line
|
||||
ret << "\n";
|
||||
ret << line << "\n";
|
||||
|
||||
// goto the end of the '#if 0' block
|
||||
unsigned int level = 1;
|
||||
bool in = false;
|
||||
while (level > 0 && std::getline(istr,line))
|
||||
{
|
||||
if (line.compare(0,3,"#if") == 0)
|
||||
++level;
|
||||
else if (line == "#endif")
|
||||
--level;
|
||||
else if (line == "#else")
|
||||
{
|
||||
if (level == 1)
|
||||
in = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in)
|
||||
ret << line << "\n";
|
||||
else
|
||||
// replace code within '#if 0' block with empty lines
|
||||
ret << "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// replace code within '#if 0' block with empty lines
|
||||
ret << "\n";
|
||||
ret << line << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -623,22 +623,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
scope = *it;
|
||||
|
||||
if (scope->isClassOrStruct() && scope->needInitialization == Scope::Unknown)
|
||||
{
|
||||
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
||||
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||
loc.line = scope->classDef->linenr();
|
||||
loc.setfile(_tokenizer->file(scope->classDef));
|
||||
locationList.push_back(loc);
|
||||
|
||||
const ErrorLogger::ErrorMessage errmsg(locationList,
|
||||
Severity::debug,
|
||||
"SymbolDatabase::SymbolDatabase couldn't resolve all user defined types.",
|
||||
"debug");
|
||||
if (_errorLogger)
|
||||
_errorLogger->reportErr(errmsg);
|
||||
else
|
||||
Check::reportError(errmsg);
|
||||
}
|
||||
debugMessage(scope->classDef, "SymbolDatabase::SymbolDatabase couldn't resolve all user defined types.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1078,6 +1063,27 @@ const Token *SymbolDatabase::initBaseInfo(Scope *scope, const Token *tok)
|
|||
return tok2;
|
||||
}
|
||||
|
||||
void SymbolDatabase::debugMessage(const Token *tok, const std::string &msg) const
|
||||
{
|
||||
if (tok && _settings->debugwarnings)
|
||||
{
|
||||
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
||||
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||
loc.line = tok->linenr();
|
||||
loc.setfile(_tokenizer->file(tok));
|
||||
locationList.push_back(loc);
|
||||
|
||||
const ErrorLogger::ErrorMessage errmsg(locationList,
|
||||
Severity::debug,
|
||||
msg,
|
||||
"debug");
|
||||
if (_errorLogger)
|
||||
_errorLogger->reportErr(errmsg);
|
||||
else
|
||||
Check::reportError(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
unsigned int Function::argCount() const
|
||||
|
@ -1124,6 +1130,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
const Token *endTok;
|
||||
const Token *nameTok;
|
||||
bool isConstVar;
|
||||
bool isArrayVar;
|
||||
const Token *tok = arg->next();
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1131,6 +1138,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
endTok = NULL;
|
||||
nameTok = NULL;
|
||||
isConstVar = bool(tok->str() == "const");
|
||||
isArrayVar = false;
|
||||
|
||||
while (tok->str() != "," && tok->str() != ")")
|
||||
{
|
||||
|
@ -1139,12 +1147,28 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
nameTok = tok;
|
||||
endTok = tok->previous();
|
||||
}
|
||||
else if (tok->str() == "[")
|
||||
isArrayVar = true;
|
||||
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
// check for argument with no name
|
||||
// check for argument with no name or missing varid
|
||||
if (!endTok)
|
||||
endTok = tok->previous();
|
||||
{
|
||||
if (tok->previous()->isName())
|
||||
{
|
||||
if (tok->previous() != startTok->tokAt(isConstVar ? 1 : 0))
|
||||
{
|
||||
nameTok = tok->previous();
|
||||
endTok = nameTok->previous();
|
||||
|
||||
symbolDatabase->debugMessage(nameTok, "Function::addArguments found argument \'" + nameTok->str() + "\' with varid 0.");
|
||||
}
|
||||
}
|
||||
else
|
||||
endTok = tok->previous();
|
||||
}
|
||||
|
||||
const Token *typeTok = startTok;
|
||||
if (isConstVar)
|
||||
|
@ -1156,7 +1180,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
|
||||
bool isClassVar = startTok == endTok && !startTok->isStandardType();
|
||||
|
||||
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, scope, false));
|
||||
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, scope, isArrayVar));
|
||||
|
||||
if (tok->str() == ")")
|
||||
break;
|
||||
|
@ -1429,23 +1453,8 @@ void Scope::getVariableList()
|
|||
// If the vartok was set in the if-blocks above, create a entry for this variable..
|
||||
if (vartok && vartok->str() != "operator")
|
||||
{
|
||||
if (vartok->varId() == 0 && !vartok->isBoolean() && check->_settings->debugwarnings)
|
||||
{
|
||||
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
||||
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||
loc.line = vartok->linenr();
|
||||
loc.setfile(check->_tokenizer->file(vartok));
|
||||
locationList.push_back(loc);
|
||||
|
||||
const ErrorLogger::ErrorMessage errmsg(locationList,
|
||||
Severity::debug,
|
||||
"Scope::getVariableList found variable \'" + vartok->str() + "\' with varid 0.",
|
||||
"debug");
|
||||
if (check->_errorLogger)
|
||||
check->_errorLogger->reportErr(errmsg);
|
||||
else
|
||||
Check::reportError(errmsg);
|
||||
}
|
||||
if (vartok->varId() == 0 && !vartok->isBoolean())
|
||||
check->debugMessage(vartok, "Scope::getVariableList found variable \'" + vartok->str() + "\' with varid 0.");
|
||||
|
||||
const Scope *scope = NULL;
|
||||
|
||||
|
|
|
@ -500,6 +500,11 @@ public:
|
|||
return _variableList[varId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief output a debug message
|
||||
*/
|
||||
void debugMessage(const Token *tok, const std::string &msg) const;
|
||||
|
||||
private:
|
||||
|
||||
// Needed by Borland C++:
|
||||
|
|
|
@ -1790,6 +1790,7 @@ void Tokenizer::simplifyTypedef()
|
|||
{
|
||||
if (!inCast && !inSizeof)
|
||||
tok2 = tok2->next();
|
||||
|
||||
tok2 = copyTokens(tok2, arrayStart, arrayEnd);
|
||||
tok2 = tok2->next();
|
||||
|
||||
|
@ -4600,9 +4601,6 @@ void Tokenizer::simplifyIfAddBraces()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (tok->previous() && !Token::Match(tok->previous(), ";|{|}|else|)|:"))
|
||||
continue;
|
||||
|
||||
if (Token::Match(tok, "if|for|while ("))
|
||||
{
|
||||
// don't add "{}" around ";" in "do {} while();" (#609)
|
||||
|
@ -6639,6 +6637,12 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign
|
|||
Token::Match(tok3, ("!|==|!=|<|<=|>|>= " + structname + " %varid% ==|!=|<|<=|>|>=|)|;").c_str(), varid) ||
|
||||
Token::Match(tok3->previous(), "strlen|free ( %varid% )", varid))
|
||||
{
|
||||
if (value[0] == '\"' && tok3->strAt(-1) != "strlen")
|
||||
{
|
||||
// bail out if value is a string unless if it's just given
|
||||
// as parameter to strlen
|
||||
break;
|
||||
}
|
||||
if (!structname.empty())
|
||||
{
|
||||
tok3->deleteNext();
|
||||
|
@ -6737,6 +6741,8 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign
|
|||
Token::Match(tok3, ("<<|>> " + structname + " %varid% [+-*/%^|;])]").c_str(), varid) ||
|
||||
Token::Match(tok3->previous(), ("[=+-*/%^|[] ( " + structname + " %varid%").c_str(), varid))
|
||||
{
|
||||
if (value[0] == '\"')
|
||||
break;
|
||||
if (!structname.empty())
|
||||
{
|
||||
tok3->deleteNext();
|
||||
|
@ -6853,13 +6859,14 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign
|
|||
|
||||
// return variable..
|
||||
if (Token::Match(tok3, "return %varid% %any%", varid) &&
|
||||
isOp(tok3->tokAt(2)))
|
||||
isOp(tok3->tokAt(2)) &&
|
||||
value[0] != '\"')
|
||||
{
|
||||
tok3->next()->str(value);
|
||||
tok3->next()->varId(valueVarId);
|
||||
}
|
||||
|
||||
else if (pointeralias && Token::Match(tok3, "return * %varid% ;", varid))
|
||||
else if (pointeralias && Token::Match(tok3, "return * %varid% ;", varid) && value[0] != '\"')
|
||||
{
|
||||
tok3->deleteNext();
|
||||
tok3->next()->str(value);
|
||||
|
@ -9124,7 +9131,8 @@ void Tokenizer::simplifyBitfields()
|
|||
{
|
||||
Token *last = 0;
|
||||
|
||||
if (Token::Match(tok, ";|{|}|public:|protected:|private: const| %type% %var% : %any% ;|,"))
|
||||
if (Token::Match(tok, ";|{|}|public:|protected:|private: const| %type% %var% : %any% ;|,") &&
|
||||
tok->next()->str() != "case")
|
||||
{
|
||||
int offset = 0;
|
||||
if (tok->next()->str() == "const")
|
||||
|
@ -9133,7 +9141,8 @@ void Tokenizer::simplifyBitfields()
|
|||
last = tok->tokAt(5 + offset);
|
||||
Token::eraseTokens(tok->tokAt(2 + offset), tok->tokAt(5 + offset));
|
||||
}
|
||||
else if (Token::Match(tok, ";|{|}|public:|protected:|private: const| %type% : %any% ;"))
|
||||
else if (Token::Match(tok, ";|{|}|public:|protected:|private: const| %type% : %any% ;") &&
|
||||
tok->next()->str() != "default")
|
||||
{
|
||||
int offset = 0;
|
||||
if (tok->next()->str() == "const")
|
||||
|
@ -9349,26 +9358,56 @@ const SymbolDatabase *Tokenizer::getSymbolDatabase() const
|
|||
|
||||
void Tokenizer::simplifyOperatorName()
|
||||
{
|
||||
for (const Token *tok = _tokens; tok; tok = tok->next())
|
||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||
{
|
||||
if (Token::Match(tok, ") const| {|;|="))
|
||||
if (tok->str() == "operator")
|
||||
{
|
||||
Token *tok1 = tok->link();
|
||||
Token *tok2 = tok1;
|
||||
|
||||
tok1 = tok1->previous();
|
||||
while (tok1 && !Token::Match(tok1, "operator|{|}|;|public:|private|protected:"))
|
||||
// operator op
|
||||
std::string op;
|
||||
Token *par = tok->next();
|
||||
bool done = false;
|
||||
while (!done && par)
|
||||
{
|
||||
tok1 = tok1->previous();
|
||||
done = true;
|
||||
if (par && par->isName())
|
||||
{
|
||||
op += par->str();
|
||||
par = par->next();
|
||||
done = false;
|
||||
}
|
||||
if (Token::Match(par, "[<>+-*&/=.]") || Token::Match(par, "==|!=|<=|>="))
|
||||
{
|
||||
op += par->str();
|
||||
par = par->next();
|
||||
done = false;
|
||||
}
|
||||
if (Token::simpleMatch(par, "[ ]"))
|
||||
{
|
||||
op += "[]";
|
||||
par = par->next()->next();
|
||||
done = false;
|
||||
}
|
||||
if (Token::Match(par, "( *| )"))
|
||||
{
|
||||
// break out and simplify..
|
||||
if (Token::Match(par, "( ) const| [=;{),]"))
|
||||
break;
|
||||
|
||||
while (par->str() != ")")
|
||||
{
|
||||
op += par->str();
|
||||
par = par->next();
|
||||
}
|
||||
op += ")";
|
||||
par = par->next();
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (tok1 && tok1->str() == "operator")
|
||||
if (par && Token::Match(par->link(), ") const| [=;{),]"))
|
||||
{
|
||||
while (tok1->next() != tok2)
|
||||
{
|
||||
tok1->str(tok1->str() + tok1->next()->str());
|
||||
tok1->deleteNext();
|
||||
}
|
||||
tok->str("operator" + op);
|
||||
Token::eraseTokens(tok,par);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ private:
|
|||
" EventPtr event = *eventP;\n"
|
||||
" *actionsP = &event->actions;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
TODO_ASSERT_EQUALS("", "[test.cpp:1]: (debug) Function::addArguments found argument 'eventP' with varid 0.\n", errout.str());
|
||||
}
|
||||
|
||||
void returnLocalVariable1()
|
||||
|
|
|
@ -92,6 +92,11 @@ private:
|
|||
|
||||
TEST_CASE(error3);
|
||||
|
||||
TEST_CASE(if0_exclude);
|
||||
TEST_CASE(if0_whitespace);
|
||||
TEST_CASE(if0_else);
|
||||
TEST_CASE(if0_elif);
|
||||
|
||||
// Don't handle include in a #if 0 block
|
||||
TEST_CASE(if0_include_1);
|
||||
TEST_CASE(if0_include_2);
|
||||
|
@ -641,6 +646,74 @@ private:
|
|||
ASSERT_EQUALS("[test.c:1]: (error) #error hello world!\n", errout.str());
|
||||
}
|
||||
|
||||
void if0_exclude()
|
||||
{
|
||||
Settings settings;
|
||||
Preprocessor preprocessor(&settings, this);
|
||||
|
||||
std::istringstream code("#if 0\n"
|
||||
"A\n"
|
||||
"#endif\n"
|
||||
"B\n");
|
||||
ASSERT_EQUALS("#if 0\n\n#endif\nB\n", preprocessor.read(code,"",NULL));
|
||||
|
||||
std::istringstream code2("#if (0)\n"
|
||||
"A\n"
|
||||
"#endif\n"
|
||||
"B\n");
|
||||
ASSERT_EQUALS("#if 0\n\n#endif\nB\n", preprocessor.read(code2,"",NULL));
|
||||
}
|
||||
|
||||
void if0_whitespace()
|
||||
{
|
||||
Settings settings;
|
||||
Preprocessor preprocessor(&settings, this);
|
||||
|
||||
std::istringstream code(" # if 0 \n"
|
||||
"A\n"
|
||||
" # endif \n"
|
||||
"B\n");
|
||||
ASSERT_EQUALS("#if 0\n\n#endif\nB\n", preprocessor.read(code,"",NULL));
|
||||
}
|
||||
|
||||
void if0_else()
|
||||
{
|
||||
Settings settings;
|
||||
Preprocessor preprocessor(&settings, this);
|
||||
|
||||
std::istringstream code("#if 0\n"
|
||||
"A\n"
|
||||
"#else\n"
|
||||
"B\n"
|
||||
"#endif\n"
|
||||
"C\n");
|
||||
ASSERT_EQUALS("#if 0\n\n#else\nB\n#endif\nC\n", preprocessor.read(code,"",NULL));
|
||||
|
||||
std::istringstream code2("#if 1\n"
|
||||
"A\n"
|
||||
"#else\n"
|
||||
"B\n"
|
||||
"#endif\n"
|
||||
"C\n");
|
||||
TODO_ASSERT_EQUALS("#if 1\nA\n#else\n\n#endif\nC\n",
|
||||
"#if 1\nA\n#else\nB\n#endif\nC\n", preprocessor.read(code2,"",NULL));
|
||||
}
|
||||
|
||||
void if0_elif()
|
||||
{
|
||||
Settings settings;
|
||||
Preprocessor preprocessor(&settings, this);
|
||||
|
||||
std::istringstream code("#if 0\n"
|
||||
"A\n"
|
||||
"#elif 1\n"
|
||||
"B\n"
|
||||
"#endif\n"
|
||||
"C\n");
|
||||
TODO_ASSERT_EQUALS("#if 0\n\n#elif 1\nB\n#endif\nC\n",
|
||||
"#if 0\n\n\n\n#endif\nC\n", preprocessor.read(code,"",NULL));
|
||||
}
|
||||
|
||||
void if0_include_1()
|
||||
{
|
||||
Settings settings;
|
||||
|
@ -650,7 +723,7 @@ private:
|
|||
"#include \"a.h\"\n"
|
||||
"#endif\n"
|
||||
"AB\n");
|
||||
ASSERT_EQUALS("\n\n\nAB\n", preprocessor.read(code,"",NULL));
|
||||
ASSERT_EQUALS("#if 0\n\n#endif\nAB\n", preprocessor.read(code,"",NULL));
|
||||
}
|
||||
|
||||
void if0_include_2()
|
||||
|
@ -665,7 +738,7 @@ private:
|
|||
"#endif\n"
|
||||
"#endif\n"
|
||||
"AB\n");
|
||||
ASSERT_EQUALS("\n\n\n\n\n\nAB\n", preprocessor.read(code,"",NULL));
|
||||
ASSERT_EQUALS("#if 0\n\n#ifdef WIN32\n#else\n#endif\n#endif\nAB\n", preprocessor.read(code,"",NULL));
|
||||
}
|
||||
|
||||
void includeguard1()
|
||||
|
|
|
@ -80,6 +80,7 @@ private:
|
|||
TEST_CASE(ifAddBraces12);
|
||||
TEST_CASE(ifAddBraces13);
|
||||
TEST_CASE(ifAddBraces14); // #2610 - segfault: if()<{}
|
||||
TEST_CASE(ifAddBraces15); // #2616 - unknown macro before if
|
||||
|
||||
TEST_CASE(whileAddBraces);
|
||||
TEST_CASE(doWhileAddBraces);
|
||||
|
@ -305,7 +306,10 @@ private:
|
|||
// Tokenize JAVA
|
||||
TEST_CASE(java);
|
||||
|
||||
TEST_CASE(simplifyOperatorName);
|
||||
TEST_CASE(simplifyOperatorName1);
|
||||
TEST_CASE(simplifyOperatorName2);
|
||||
TEST_CASE(simplifyOperatorName3);
|
||||
TEST_CASE(simplifyOperatorName4);
|
||||
|
||||
// Some simple cleanups of unhandled macros in the global scope
|
||||
TEST_CASE(removeMacrosInGlobalScope);
|
||||
|
@ -858,6 +862,12 @@ private:
|
|||
tokenizeAndStringify("if()<{}", false);
|
||||
}
|
||||
|
||||
void ifAddBraces15()
|
||||
{
|
||||
// ticket #2616 - unknown macro before if
|
||||
ASSERT_EQUALS("{ A if ( x ) { y ( ) ; } }", tokenizeAndStringify("{A if(x)y();}", false));
|
||||
}
|
||||
|
||||
|
||||
void whileAddBraces()
|
||||
{
|
||||
|
@ -2043,17 +2053,45 @@ private:
|
|||
|
||||
void simplifyKnownVariables42()
|
||||
{
|
||||
const char code[] = "void f() {\n"
|
||||
" char str1[10], str2[10];\n"
|
||||
" strcpy(str1, \"abc\");\n"
|
||||
" strcpy(str2, str1);\n"
|
||||
"}";
|
||||
const char expected[] = "void f ( ) {\n"
|
||||
"char str1 [ 10 ] ; char str2 [ 10 ] ;\n"
|
||||
"strcpy ( str1 , \"abc\" ) ;\n"
|
||||
"strcpy ( str2 , \"abc\" ) ;\n"
|
||||
{
|
||||
const char code[] = "void f() {\n"
|
||||
" char str1[10], str2[10];\n"
|
||||
" strcpy(str1, \"abc\");\n"
|
||||
" strcpy(str2, str1);\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||||
const char expected[] = "void f ( ) {\n"
|
||||
"char str1 [ 10 ] ; char str2 [ 10 ] ;\n"
|
||||
"strcpy ( str1 , \"abc\" ) ;\n"
|
||||
"strcpy ( str2 , \"abc\" ) ;\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "void f() {"
|
||||
" char *s = malloc(10);"
|
||||
" strcpy(s, \"\");"
|
||||
" free(s);"
|
||||
"}";
|
||||
const char expected[] = "void f ( ) {"
|
||||
" char * s ; s = malloc ( 10 ) ;"
|
||||
" strcpy ( s , \"\" ) ;"
|
||||
" free ( s ) ; "
|
||||
"}";
|
||||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "void f(char *p, char *q) {"
|
||||
" strcpy(p, \"abc\");"
|
||||
" q = p;"
|
||||
"}";
|
||||
const char expected[] = "void f ( char * p , char * q ) {"
|
||||
" strcpy ( p , \"abc\" ) ;"
|
||||
" q = p ; "
|
||||
"}";
|
||||
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
|
||||
}
|
||||
}
|
||||
|
||||
void simplifyKnownVariablesBailOutAssign()
|
||||
|
@ -5118,6 +5156,12 @@ private:
|
|||
|
||||
const char code3[] = "struct A { bool : true; };";
|
||||
ASSERT_EQUALS("struct A { } ;", tokenizeAndStringify(code3,false));
|
||||
|
||||
const char code4[] = "void f(int a) { switch (a) { case b: break; } }";
|
||||
ASSERT_EQUALS("void f ( int a ) { switch ( a ) { case b : ; break ; } }", tokenizeAndStringify(code4,true));
|
||||
|
||||
const char code5[] = "void f(int a) { switch (a) { default: break; } }";
|
||||
ASSERT_EQUALS("void f ( int a ) { switch ( a ) { default : ; break ; } }", tokenizeAndStringify(code5,true));
|
||||
}
|
||||
|
||||
void microsoftMFC()
|
||||
|
@ -5312,36 +5356,56 @@ private:
|
|||
ASSERT_EQUALS("void f ( ) { }", javatest("void f() throws Exception { }"));
|
||||
}
|
||||
|
||||
void simplifyOperatorName()
|
||||
void simplifyOperatorName1()
|
||||
{
|
||||
// make sure C code doesn't get changed
|
||||
const char code1[] = "void operator () {}"
|
||||
"int main()"
|
||||
"{"
|
||||
" operator();"
|
||||
"}";
|
||||
const char code[] = "void operator () {}"
|
||||
"int main()"
|
||||
"{"
|
||||
" operator();"
|
||||
"}";
|
||||
|
||||
const char result1 [] = "void operator ( ) { } "
|
||||
"int main ( ) "
|
||||
"{ "
|
||||
"operator ( ) ; "
|
||||
"}";
|
||||
const char result [] = "void operator ( ) { } "
|
||||
"int main ( ) "
|
||||
"{ "
|
||||
"operator ( ) ; "
|
||||
"}";
|
||||
|
||||
ASSERT_EQUALS(result1, tokenizeAndStringify(code1,false));
|
||||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
||||
}
|
||||
|
||||
const char code2[] = "class Fred"
|
||||
"{"
|
||||
" Fred(const Fred & f) { operator = (f); }"
|
||||
" operator = ();"
|
||||
"}";
|
||||
void simplifyOperatorName2()
|
||||
{
|
||||
const char code[] = "class Fred"
|
||||
"{"
|
||||
" Fred(const Fred & f) { operator = (f); }"
|
||||
" operator = ();"
|
||||
"}";
|
||||
|
||||
const char result2 [] = "class Fred "
|
||||
"{ "
|
||||
"Fred ( const Fred & f ) { operator= ( f ) ; } "
|
||||
"operator= ( ) ; "
|
||||
"}";
|
||||
const char result [] = "class Fred "
|
||||
"{ "
|
||||
"Fred ( const Fred & f ) { operator= ( f ) ; } "
|
||||
"operator= ( ) ; "
|
||||
"}";
|
||||
|
||||
ASSERT_EQUALS(result2, tokenizeAndStringify(code2,false));
|
||||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
||||
}
|
||||
|
||||
void simplifyOperatorName3()
|
||||
{
|
||||
// #2615
|
||||
const char code[] = "void f() {"
|
||||
"static_cast<ScToken*>(xResult.operator->())->GetMatrix();"
|
||||
"}";
|
||||
const char result[] = "void f ( ) { static_cast < ScToken * > ( xResult . operator. ( ) ) . GetMatrix ( ) ; }";
|
||||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
||||
}
|
||||
|
||||
void simplifyOperatorName4()
|
||||
{
|
||||
const char code[] = "void operator==() { }";
|
||||
const char result[] = "void operator== ( ) { }";
|
||||
ASSERT_EQUALS(result, tokenizeAndStringify(code,false));
|
||||
}
|
||||
|
||||
void removeMacrosInGlobalScope()
|
||||
|
|
Loading…
Reference in New Issue