CheckHeaders: Improved the check that checks included headers.
This commit is contained in:
parent
0bea996e4d
commit
f0f117d4f6
165
CheckHeaders.cpp
165
CheckHeaders.cpp
|
@ -2,7 +2,9 @@
|
||||||
#include "CheckHeaders.h"
|
#include "CheckHeaders.h"
|
||||||
#include "Tokenize.h"
|
#include "Tokenize.h"
|
||||||
#include "CommonCheck.h"
|
#include "CommonCheck.h"
|
||||||
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,144 +74,135 @@ void WarningIncludeHeader()
|
||||||
// * It contains some needed constant value
|
// * It contains some needed constant value
|
||||||
// * It contains some needed variable
|
// * It contains some needed variable
|
||||||
// * It contains some needed enum
|
// * It contains some needed enum
|
||||||
bool Needed = false;
|
|
||||||
bool NeedDeclaration = false;
|
std::list<std::string> classlist;
|
||||||
|
std::list<std::string> namelist;
|
||||||
|
|
||||||
|
// Extract classes and names in the header..
|
||||||
int indentlevel = 0;
|
int indentlevel = 0;
|
||||||
for (TOKEN *tok1 = tokens; tok1; tok1 = tok1->next)
|
for ( TOKEN *tok1 = tokens; tok1; tok1 = tok1->next )
|
||||||
{
|
{
|
||||||
if (tok1->FileIndex != hfile)
|
if ( tok1->FileIndex != hfile )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!tok1->next)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!tok1->next->next)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// I'm only interested in stuff that is declared at indentlevel 0
|
// I'm only interested in stuff that is declared at indentlevel 0
|
||||||
if (tok1->str[0] == '{')
|
if (tok1->str[0] == '{')
|
||||||
indentlevel++;
|
indentlevel++;
|
||||||
if (tok1->str[0] == '}')
|
|
||||||
|
else if (tok1->str[0] == '}')
|
||||||
indentlevel--;
|
indentlevel--;
|
||||||
|
|
||||||
if (indentlevel != 0)
|
if (indentlevel != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Class or namespace declaration..
|
// Class or namespace declaration..
|
||||||
if (match(tok1,"class var {") ||
|
// --------------------------------------
|
||||||
match(tok1,"class var :") ||
|
if (match(tok1,"class var {") || match(tok1,"class var :") || match(tok1,"namespace var {"))
|
||||||
match(tok1,"namespace var {"))
|
classlist.push_back(getstr(tok1, 1));
|
||||||
{
|
|
||||||
std::string classname = getstr(tok1, 1);
|
|
||||||
|
|
||||||
// Try to find class usage in "parent" file..
|
// Variable declaration..
|
||||||
for (TOKEN *tok2 = tokens; tok2; tok2 = tok2->next)
|
// --------------------------------------
|
||||||
{
|
else if (match(tok1, "type var ;") || match(tok1, "type var ["))
|
||||||
if (tok2->FileIndex != includetok->FileIndex)
|
namelist.push_back(getstr(tok1, 1));
|
||||||
continue;
|
|
||||||
|
|
||||||
// Inheritage..
|
else if (match(tok1, "type * var ;") || match(tok1, "type * var ["))
|
||||||
Needed |= match(tok2, "class var : " + classname);
|
namelist.push_back(getstr(tok1, 2));
|
||||||
Needed |= match(tok2, "class var : type " + classname);
|
|
||||||
|
|
||||||
// Allocating..
|
else if (match(tok1, "const type var =") || match(tok1, "const type var ["))
|
||||||
Needed |= match(tok2, "new " + classname);
|
namelist.push_back(getstr(tok1, 2));
|
||||||
|
|
||||||
// Using class..
|
else if (match(tok1, "const type * var =") || match(tok1, "const type * var ["))
|
||||||
Needed |= match(tok2, classname + " ::");
|
namelist.push_back(getstr(tok1, 3));
|
||||||
Needed |= match(tok2, classname + " var");
|
|
||||||
NeedDeclaration |= match(tok2, classname + " *");
|
|
||||||
if (Needed | NeedDeclaration)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Needed | NeedDeclaration)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variable..
|
|
||||||
std::string varname = "";
|
|
||||||
if (match(tok1, "type var ;") || match(tok1, "type var ["))
|
|
||||||
varname = getstr(tok1, 1);
|
|
||||||
if (match(tok1, "type * var ;") || match(tok1, "type * var ["))
|
|
||||||
varname = getstr(tok1, 2);
|
|
||||||
if (match(tok1, "const type var =") || match(tok1, "const type var ["))
|
|
||||||
varname = getstr(tok1, 2);
|
|
||||||
if (match(tok1, "const type * var =") || match(tok1, "const type * var ["))
|
|
||||||
varname = getstr(tok1, 3);
|
|
||||||
|
|
||||||
// enum..
|
// enum..
|
||||||
std::string enumname = "";
|
// --------------------------------------
|
||||||
if (match(tok1, "enum var {"))
|
else if (strcmp(tok1->str, "enum") == 0)
|
||||||
enumname = getstr(tok1, 1);
|
{
|
||||||
|
tok1 = tok1->next;
|
||||||
|
while (tok1->next && tok1->str[0]!=';')
|
||||||
|
{
|
||||||
|
if ( IsName(tok1->str) )
|
||||||
|
namelist.push_back(tok1->str);
|
||||||
|
tok1 = tok1->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// function..
|
||||||
|
// --------------------------------------
|
||||||
|
else if (match(tok1,"type var ("))
|
||||||
|
namelist.push_back(getstr(tok1, 1));
|
||||||
|
|
||||||
// function..
|
|
||||||
std::string funcname = "";
|
|
||||||
if (match(tok1,"type var ("))
|
|
||||||
funcname = getstr(tok1, 1);
|
|
||||||
else if (match(tok1,"type * var ("))
|
else if (match(tok1,"type * var ("))
|
||||||
funcname = getstr(tok1, 2);
|
namelist.push_back(getstr(tok1, 2));
|
||||||
|
|
||||||
else if (match(tok1,"const type var ("))
|
else if (match(tok1,"const type var ("))
|
||||||
funcname = getstr(tok1, 2);
|
namelist.push_back(getstr(tok1, 2));
|
||||||
|
|
||||||
else if (match(tok1,"const type * var ("))
|
else if (match(tok1,"const type * var ("))
|
||||||
funcname = getstr(tok1, 3);
|
namelist.push_back(getstr(tok1, 3));
|
||||||
|
|
||||||
// typedef..
|
// typedef..
|
||||||
std::string typedefname = "";
|
// --------------------------------------
|
||||||
if (strcmp(tok1->str,"typedef")==0)
|
else if (strcmp(tok1->str,"typedef")==0)
|
||||||
{
|
{
|
||||||
|
if (strcmp(getstr(tok1,1),"enum")==0)
|
||||||
|
continue;
|
||||||
int parlevel = 0;
|
int parlevel = 0;
|
||||||
while (tok1)
|
while (tok1->next)
|
||||||
{
|
{
|
||||||
if ( strchr("({", tok1->str[0]) )
|
if ( strchr("({", tok1->str[0]) )
|
||||||
{
|
|
||||||
parlevel++;
|
parlevel++;
|
||||||
}
|
|
||||||
else if ( strchr(")}", tok1->str[0]) )
|
else if ( strchr(")}", tok1->str[0]) )
|
||||||
{
|
|
||||||
parlevel--;
|
parlevel--;
|
||||||
if (parlevel < 0)
|
|
||||||
break;
|
else if (parlevel == 0)
|
||||||
}
|
|
||||||
else if ( parlevel == 0 )
|
|
||||||
{
|
{
|
||||||
if (match(tok1,"var ;"))
|
if ( tok1->str[0] == ';' )
|
||||||
{
|
|
||||||
typedefname = tok1->str;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (tok1->str[0] == ';')
|
if ( match(tok1, "var ;") )
|
||||||
{
|
namelist.push_back(tok1->str);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tok1 = tok1->next;
|
tok1 = tok1->next;
|
||||||
}
|
}
|
||||||
if (!tok1)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( varname.empty() && enumname.empty() && funcname.empty() && typedefname.empty() )
|
// Check if the extracted names are used...
|
||||||
|
bool Needed = false;
|
||||||
|
bool NeedDeclaration = false;
|
||||||
|
for (TOKEN *tok1 = tokens; tok1; tok1 = tok1->next)
|
||||||
|
{
|
||||||
|
if (tok1->FileIndex != includetok->FileIndex)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
varname = varname + enumname + funcname + typedefname;
|
if ( match(tok1, ": var {") || match(tok1, ": type var {") )
|
||||||
|
|
||||||
for (TOKEN *tok2 = tokens; tok2; tok2 = tok2->next)
|
|
||||||
{
|
{
|
||||||
if (tok2->FileIndex == includetok->FileIndex &&
|
std::string classname = getstr(tok1, (strcmp(getstr(tok1,2),"{")) ? 2 : 1);
|
||||||
tok2->str == varname)
|
if (std::find(classlist.begin(),classlist.end(),classname)!=classlist.end())
|
||||||
{
|
{
|
||||||
Needed = true;
|
Needed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Needed | NeedDeclaration)
|
if ( ! IsName(tok1->str) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (std::find(namelist.begin(),namelist.end(),tok1->str ) != namelist.end())
|
||||||
|
{
|
||||||
|
Needed = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! NeedDeclaration )
|
||||||
|
NeedDeclaration = (std::find(classlist.begin(),classlist.end(),tok1->str ) != classlist.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Not a header file?
|
// Not a header file?
|
||||||
if (includetok->FileIndex == 0)
|
if (includetok->FileIndex == 0)
|
||||||
Needed |= NeedDeclaration;
|
Needed |= NeedDeclaration;
|
||||||
|
|
Loading…
Reference in New Issue