Added Token::nextArgument()
This commit is contained in:
parent
b7ab1e7d7e
commit
54b3d72ee3
|
@ -115,8 +115,9 @@ 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%")) {
|
||||||
(value == 0 && Token::Match(&tok, "%var% ( %any% , 0 ,|)"))) {
|
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())
|
if (functionNames2.find(tok.str()) != functionNames2.end())
|
||||||
var.push_back(tok.tokAt(4));
|
var.push_back(tok.tokAt(4));
|
||||||
}
|
}
|
||||||
|
@ -125,16 +126,30 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
||||||
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%")) {
|
||||||
formatString = tok.strAt(2);
|
formatString = tok.strAt(2);
|
||||||
|
if (tok.strAt(3) == ",")
|
||||||
argListTok = tok.tokAt(4);
|
argListTok = tok.tokAt(4);
|
||||||
} else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf ( %var% , %str% , %any%")) {
|
else
|
||||||
formatString = tok.strAt(4);
|
argListTok = 0;
|
||||||
argListTok = tok.tokAt(6);
|
} else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf ( %any%")) {
|
||||||
} else if (Token::Match(&tok, "snprintf|fnprintf ( %var% , %any% , %str% , %any%")) {
|
const Token* formatStringTok = tok.tokAt(2)->nextArgument(); // Find second parameter (format string)
|
||||||
formatString = tok.strAt(6);
|
if (formatStringTok && Token::Match(formatStringTok, "%str%")) {
|
||||||
argListTok = tok.tokAt(8);
|
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) {
|
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) {
|
||||||
|
@ -147,18 +162,10 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; argListTok; argListTok = argListTok->next()) { // Find next argument
|
argListTok = argListTok->nextArgument(); // Find next argument
|
||||||
if (argListTok->str() == "(")
|
|
||||||
argListTok = argListTok->link();
|
|
||||||
if (argListTok == 0)
|
|
||||||
break;
|
|
||||||
if (argListTok->str() == ",") {
|
|
||||||
argListTok = argListTok->next();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!argListTok)
|
if (!argListTok)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
percent = false;
|
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
|
// Compare the first character of the string for optimization reasons
|
||||||
// before doing more detailed checks.
|
// before doing more detailed checks.
|
||||||
bool patternUnderstood = false;
|
|
||||||
if (p[0] == '%') {
|
if (p[0] == '%') {
|
||||||
|
bool patternUnderstood = false;
|
||||||
switch (p[1]) {
|
switch (p[1]) {
|
||||||
case 'v':
|
case 'v':
|
||||||
// TODO: %var% should match only for
|
// TODO: %var% should match only for
|
||||||
|
@ -696,6 +696,19 @@ void Token::move(Token *srcStart, Token *srcEnd, Token *newLocation)
|
||||||
tok->_progressValue = newLocation->_progressValue;
|
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)
|
const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned int varId)
|
||||||
|
|
|
@ -388,6 +388,12 @@ public:
|
||||||
tok->_progressValue = count++ * 100 / total_count;
|
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:
|
private:
|
||||||
void next(Token *nextToken) {
|
void next(Token *nextToken) {
|
||||||
_next = nextToken;
|
_next = nextToken;
|
||||||
|
|
|
@ -38,6 +38,7 @@ private:
|
||||||
TEST_CASE(strValue);
|
TEST_CASE(strValue);
|
||||||
|
|
||||||
TEST_CASE(deleteLast);
|
TEST_CASE(deleteLast);
|
||||||
|
TEST_CASE(nextArgument);
|
||||||
|
|
||||||
TEST_CASE(matchAny);
|
TEST_CASE(matchAny);
|
||||||
TEST_CASE(matchSingleChar);
|
TEST_CASE(matchSingleChar);
|
||||||
|
@ -129,6 +130,17 @@ private:
|
||||||
ASSERT_EQUALS(true, tokensBack == &tok);
|
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() {
|
void matchAny() {
|
||||||
givenACodeSampleToTokenize varBitOrVar("abc|def");
|
givenACodeSampleToTokenize varBitOrVar("abc|def");
|
||||||
|
|
Loading…
Reference in New Issue