Library: Support variadic functions which are not a formatstr-function
This commit is contained in:
parent
263c3596d5
commit
92414b923a
|
@ -557,9 +557,11 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
|
|||
if (!argNrString)
|
||||
return Error(MISSING_ATTRIBUTE, "nr");
|
||||
const bool bAnyArg = strcmp(argNrString, "any") == 0;
|
||||
const int nr = bAnyArg ? -1 : std::atoi(argNrString);
|
||||
const bool bVariadicArg = strcmp(argNrString, "variadic") == 0;
|
||||
const int nr = (bAnyArg || bVariadicArg) ? -1 : std::atoi(argNrString);
|
||||
ArgumentChecks &ac = func.argumentChecks[nr];
|
||||
ac.optional = functionnode->Attribute("default") != nullptr;
|
||||
ac.variadic = bVariadicArg;
|
||||
for (const tinyxml2::XMLElement *argnode = functionnode->FirstChildElement(); argnode; argnode = argnode->NextSiblingElement()) {
|
||||
const std::string argnodename = argnode->Name();
|
||||
if (argnodename == "not-bool")
|
||||
|
@ -942,7 +944,7 @@ bool Library::matchArguments(const Token *ftok, const std::string &functionName)
|
|||
if (it2->second.optional && (firstOptionalArg == -1 || firstOptionalArg > it2->first))
|
||||
firstOptionalArg = it2->first;
|
||||
|
||||
if (it2->second.formatstr)
|
||||
if (it2->second.formatstr || it2->second.variadic)
|
||||
return args <= callargs;
|
||||
}
|
||||
return (firstOptionalArg < 0) ? args == callargs : (callargs >= firstOptionalArg-1 && callargs <= args);
|
||||
|
|
|
@ -223,6 +223,7 @@ public:
|
|||
formatstr(false),
|
||||
strz(false),
|
||||
optional(false),
|
||||
variadic(false),
|
||||
iteratorInfo() {
|
||||
}
|
||||
|
||||
|
@ -232,14 +233,15 @@ public:
|
|||
bool formatstr;
|
||||
bool strz;
|
||||
bool optional;
|
||||
bool variadic;
|
||||
std::string valid;
|
||||
|
||||
class IteratorInfo {
|
||||
public:
|
||||
IteratorInfo() : it(false), container(0), first(false), last(false) {}
|
||||
IteratorInfo() : container(0), it(false), first(false), last(false) {}
|
||||
|
||||
bool it;
|
||||
int container;
|
||||
bool it;
|
||||
bool first;
|
||||
bool last;
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<bookinfo>
|
||||
<title>Cppcheck 1.78 dev</title>
|
||||
|
||||
<date>2016-08-13</date>
|
||||
<date>2017-03-14</date>
|
||||
</bookinfo>
|
||||
|
||||
<chapter>
|
||||
|
@ -918,11 +918,9 @@ Checking pen1.c...
|
|||
<para>The arguments a function takes can be specified by
|
||||
<literal><arg></literal> tags. Each of them takes the number of
|
||||
the argument (starting from 1) in the <literal>nr</literal> attribute,
|
||||
or <literal>nr="any"</literal> for variadic arguments. Optional
|
||||
arguments can be specified by providing a default value:
|
||||
<literal>default="value"</literal>. Specifying <literal>-1</literal>
|
||||
as the argument number is going to apply a check to all arguments of
|
||||
that function. The specifications for individual arguments override
|
||||
<literal>nr="any"</literal> for arbitrary arguments, or <literal>nr="variadic"</literal> for variadic arguments.
|
||||
Optional arguments can be specified by providing a default value:
|
||||
<literal>default="value"</literal>. The specifications for individual arguments override
|
||||
this setting.</para>
|
||||
|
||||
<section>
|
||||
|
|
|
@ -41,6 +41,7 @@ private:
|
|||
TEST_CASE(function_match_var);
|
||||
TEST_CASE(function_arg);
|
||||
TEST_CASE(function_arg_any);
|
||||
TEST_CASE(function_arg_variadic);
|
||||
TEST_CASE(function_arg_valid);
|
||||
TEST_CASE(function_arg_minsize);
|
||||
TEST_CASE(function_namespace);
|
||||
|
@ -242,6 +243,30 @@ private:
|
|||
ASSERT_EQUALS(true, library.functions["foo"].argumentChecks[-1].notuninit);
|
||||
}
|
||||
|
||||
void function_arg_variadic() const {
|
||||
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
||||
"<def>\n"
|
||||
"<function name=\"foo\">\n"
|
||||
" <arg nr=\"1\"></arg>\n"
|
||||
" <arg nr=\"variadic\"><not-uninit/></arg>\n"
|
||||
"</function>\n"
|
||||
"</def>";
|
||||
|
||||
Library library;
|
||||
readLibrary(library, xmldata);
|
||||
ASSERT_EQUALS(true, library.functions["foo"].argumentChecks[-1].notuninit);
|
||||
|
||||
TokenList tokenList(nullptr);
|
||||
std::istringstream istr("foo(a,b,c,d,e);");
|
||||
tokenList.createTokens(istr);
|
||||
tokenList.front()->next()->astOperand1(tokenList.front());
|
||||
|
||||
ASSERT_EQUALS(false, library.isuninitargbad(tokenList.front(), 1));
|
||||
ASSERT_EQUALS(true, library.isuninitargbad(tokenList.front(), 2));
|
||||
ASSERT_EQUALS(true, library.isuninitargbad(tokenList.front(), 3));
|
||||
ASSERT_EQUALS(true, library.isuninitargbad(tokenList.front(), 4));
|
||||
}
|
||||
|
||||
void function_arg_valid() const {
|
||||
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
||||
"<def>\n"
|
||||
|
|
Loading…
Reference in New Issue