Added Token::nextArgument()
This commit is contained in:
parent
b7ab1e7d7e
commit
54b3d72ee3
|
@ -115,26 +115,41 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
|||
}
|
||||
|
||||
// 2nd parameter..
|
||||
if ((Token::Match(&tok, "%var% ( %any% , %var% ,|)") && tok.tokAt(4)->varId() > 0) ||
|
||||
(value == 0 && Token::Match(&tok, "%var% ( %any% , 0 ,|)"))) {
|
||||
if (functionNames2.find(tok.str()) != functionNames2.end())
|
||||
var.push_back(tok.tokAt(4));
|
||||
if (Token::Match(&tok, "%var% ( %any%")) {
|
||||
const Token* secondParameter = tok.tokAt(2)->nextArgument();
|
||||
if (secondParameter && ((value == 0 && secondParameter->str() == "0") || (Token::Match(secondParameter, "%var%") && secondParameter->varId() > 0)))
|
||||
if (functionNames2.find(tok.str()) != functionNames2.end())
|
||||
var.push_back(tok.tokAt(4));
|
||||
}
|
||||
|
||||
if (Token::Match(&tok, "printf|sprintf|snprintf|fprintf|fnprintf|scanf|sscanf|fscanf")) {
|
||||
const Token* argListTok = 0; // Points to first va_list argument
|
||||
std::string formatString;
|
||||
bool scan = Token::Match(&tok, "scanf|sscanf|fscanf");
|
||||
if (Token::Match(&tok, "printf|scanf ( %str% , %any%")) {
|
||||
|
||||
if (Token::Match(&tok, "printf|scanf ( %str%")) {
|
||||
formatString = tok.strAt(2);
|
||||
argListTok = tok.tokAt(4);
|
||||
} else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf ( %var% , %str% , %any%")) {
|
||||
formatString = tok.strAt(4);
|
||||
argListTok = tok.tokAt(6);
|
||||
} else if (Token::Match(&tok, "snprintf|fnprintf ( %var% , %any% , %str% , %any%")) {
|
||||
formatString = tok.strAt(6);
|
||||
argListTok = tok.tokAt(8);
|
||||
if (tok.strAt(3) == ",")
|
||||
argListTok = tok.tokAt(4);
|
||||
else
|
||||
argListTok = 0;
|
||||
} else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf ( %any%")) {
|
||||
const Token* formatStringTok = tok.tokAt(2)->nextArgument(); // Find second parameter (format string)
|
||||
if (formatStringTok && Token::Match(formatStringTok, "%str%")) {
|
||||
argListTok = formatStringTok->nextArgument(); // Find third parameter (first argument of va_args)
|
||||
formatString = formatStringTok->str();
|
||||
}
|
||||
} else if (Token::Match(&tok, "snprintf|fnprintf ( %any%")) {
|
||||
const Token* formatStringTok = tok.tokAt(2);
|
||||
for (int i = 0; i < 2 && formatStringTok; i++) {
|
||||
formatStringTok = formatStringTok->nextArgument(); // Find third parameter (format string)
|
||||
}
|
||||
if (formatStringTok && Token::Match(formatStringTok, "%str%")) {
|
||||
argListTok = formatStringTok->nextArgument(); // Find fourth parameter (first argument of va_args)
|
||||
formatString = formatStringTok->str();
|
||||
}
|
||||
}
|
||||
|
||||
if (argListTok) {
|
||||
bool percent = false;
|
||||
for (std::string::iterator i = formatString.begin(); i != formatString.end(); ++i) {
|
||||
|
@ -147,18 +162,10 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
|||
}
|
||||
}
|
||||
|
||||
for (; argListTok; argListTok = argListTok->next()) { // Find next argument
|
||||
if (argListTok->str() == "(")
|
||||
argListTok = argListTok->link();
|
||||
if (argListTok == 0)
|
||||
break;
|
||||
if (argListTok->str() == ",") {
|
||||
argListTok = argListTok->next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
argListTok = argListTok->nextArgument(); // Find next argument
|
||||
if (!argListTok)
|
||||
break;
|
||||
|
||||
percent = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -429,8 +429,8 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
|||
|
||||
// Compare the first character of the string for optimization reasons
|
||||
// before doing more detailed checks.
|
||||
bool patternUnderstood = false;
|
||||
if (p[0] == '%') {
|
||||
bool patternUnderstood = false;
|
||||
switch (p[1]) {
|
||||
case 'v':
|
||||
// TODO: %var% should match only for
|
||||
|
@ -696,6 +696,19 @@ void Token::move(Token *srcStart, Token *srcEnd, Token *newLocation)
|
|||
tok->_progressValue = newLocation->_progressValue;
|
||||
}
|
||||
|
||||
const Token* Token::nextArgument() const
|
||||
{
|
||||
for (const Token* tok = this; tok; tok = tok->next()) {
|
||||
if (tok->str() == ",")
|
||||
return(tok->next());
|
||||
else if (tok->str() == "(" || tok->str() == "{" || tok->str() == "[")
|
||||
tok = tok->link();
|
||||
else if (tok->str() == ")")
|
||||
return(0);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned int varId)
|
||||
|
|
|
@ -388,6 +388,12 @@ public:
|
|||
tok->_progressValue = count++ * 100 / total_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first token of the next argument. Does only work on argument
|
||||
* lists. Returns 0, if there is no next argument
|
||||
*/
|
||||
const Token* nextArgument() const;
|
||||
|
||||
private:
|
||||
void next(Token *nextToken) {
|
||||
_next = nextToken;
|
||||
|
|
|
@ -38,6 +38,7 @@ private:
|
|||
TEST_CASE(strValue);
|
||||
|
||||
TEST_CASE(deleteLast);
|
||||
TEST_CASE(nextArgument);
|
||||
|
||||
TEST_CASE(matchAny);
|
||||
TEST_CASE(matchSingleChar);
|
||||
|
@ -129,6 +130,17 @@ private:
|
|||
ASSERT_EQUALS(true, tokensBack == &tok);
|
||||
}
|
||||
|
||||
void nextArgument() {
|
||||
givenACodeSampleToTokenize example1("foo(1, 2, 3, 4);");
|
||||
ASSERT_EQUALS(true, Token::Match(example1.tokens()->tokAt(2)->nextArgument(), "2 , 3"));
|
||||
|
||||
givenACodeSampleToTokenize example2("foo();");
|
||||
ASSERT_EQUALS(true, example2.tokens()->tokAt(2)->nextArgument() == 0);
|
||||
|
||||
givenACodeSampleToTokenize example3("foo(bar(a, b), 2, 3);");
|
||||
ASSERT_EQUALS(true, Token::Match(example3.tokens()->tokAt(2)->nextArgument(), "2 , 3"));
|
||||
}
|
||||
|
||||
|
||||
void matchAny() {
|
||||
givenACodeSampleToTokenize varBitOrVar("abc|def");
|
||||
|
|
Loading…
Reference in New Issue