Function list: Remove functions with duplicate names to prevent false positives
This commit is contained in:
parent
2e445b195c
commit
63bc26d662
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* c++check - c/c++ syntax checking
|
||||
* Copyright (C) 2007 Daniel Marjamäki
|
||||
*
|
||||
|
@ -22,6 +22,7 @@
|
|||
|
||||
|
||||
#include "testsuite.h"
|
||||
#define UNIT_TESTING // Get access to "private" data in Tokenizer
|
||||
#include "tokenize.h"
|
||||
|
||||
class TestTokenizer : public TestFixture
|
||||
|
@ -38,6 +39,8 @@ private:
|
|||
TEST_CASE( longtok );
|
||||
|
||||
TEST_CASE( inlineasm );
|
||||
|
||||
TEST_CASE( dupfuncname );
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,9 +62,9 @@ private:
|
|||
" \"def\"\n";
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.getFiles()->push_back( "test.cpp" );
|
||||
std::istringstream istr(filedata);
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.getFiles()->push_back( "test.cpp" );
|
||||
std::istringstream istr(filedata);
|
||||
tokenizer.TokenizeCode(istr, 0);
|
||||
|
||||
// Expected result..
|
||||
|
@ -85,9 +88,9 @@ private:
|
|||
std::string filedata(10000,'a');
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.getFiles()->push_back( "test.cpp" );
|
||||
std::istringstream istr(filedata);
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.getFiles()->push_back( "test.cpp" );
|
||||
std::istringstream istr(filedata);
|
||||
tokenizer.TokenizeCode(istr, 0);
|
||||
|
||||
// Expected result..
|
||||
|
@ -109,9 +112,9 @@ private:
|
|||
"}\n";
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.getFiles()->push_back( "test.cpp" );
|
||||
std::istringstream istr(filedata);
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.getFiles()->push_back( "test.cpp" );
|
||||
std::istringstream istr(filedata);
|
||||
tokenizer.TokenizeCode(istr, 0);
|
||||
|
||||
// Expected result..
|
||||
|
@ -131,6 +134,27 @@ private:
|
|||
|
||||
tokenizer.DeallocateTokens();
|
||||
}
|
||||
|
||||
|
||||
void dupfuncname()
|
||||
{
|
||||
const char code[] = "void a()\n"
|
||||
"{ }\n"
|
||||
"void a(int i)\n"
|
||||
"{ }\n"
|
||||
"void b()\n"
|
||||
"{ }\n";
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
tokenizer.getFiles()->push_back( "test.cpp" );
|
||||
std::istringstream istr(code);
|
||||
tokenizer.TokenizeCode(istr, 0);
|
||||
|
||||
tokenizer.FillFunctionList(0);
|
||||
|
||||
ASSERT_EQUALS( 1, tokenizer.FunctionList.size() );
|
||||
ASSERT_EQUALS( std::string("b"), tokenizer.FunctionList[0]->str );
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST( TestTokenizer )
|
||||
|
|
526
tokenize.cpp
526
tokenize.cpp
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* c++check - c/c++ syntax checking
|
||||
* Copyright (C) 2007 Daniel Marjamäki
|
||||
*
|
||||
|
@ -27,7 +27,7 @@
|
|||
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <stdlib.h> // <- strtoul
|
||||
|
@ -42,41 +42,41 @@
|
|||
#define _strdup(str) strdup(str)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
Tokenizer::Tokenizer()
|
||||
{
|
||||
_tokens = 0;
|
||||
tokens_back = 0;
|
||||
dsymlist = 0;
|
||||
Tokenizer::Tokenizer()
|
||||
{
|
||||
_tokens = 0;
|
||||
tokens_back = 0;
|
||||
dsymlist = 0;
|
||||
}
|
||||
|
||||
Tokenizer::~Tokenizer()
|
||||
{
|
||||
|
||||
|
||||
Tokenizer::~Tokenizer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Helper functions..
|
||||
|
||||
TOKEN *Tokenizer::_gettok(TOKEN *tok, int index)
|
||||
{
|
||||
while (tok && index>0)
|
||||
{
|
||||
tok = tok->next;
|
||||
index--;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::tokens() const
|
||||
{
|
||||
return _tokens;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Helper functions..
|
||||
|
||||
TOKEN *Tokenizer::_gettok(TOKEN *tok, int index)
|
||||
{
|
||||
while (tok && index>0)
|
||||
{
|
||||
tok = tok->next;
|
||||
index--;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::tokens() const
|
||||
{
|
||||
return _tokens;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Defined symbols.
|
||||
|
@ -84,11 +84,11 @@ const TOKEN *Tokenizer::tokens() const
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
std::vector<std::string> *Tokenizer::getFiles()
|
||||
{
|
||||
return &Files;
|
||||
}
|
||||
|
||||
std::vector<std::string> *Tokenizer::getFiles()
|
||||
{
|
||||
return &Files;
|
||||
}
|
||||
|
||||
void Tokenizer::Define(const char Name[], const char Value[])
|
||||
{
|
||||
|
@ -755,13 +755,13 @@ void Tokenizer::SimplifyTokenList()
|
|||
DeleteNextToken(tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (Match(tok, "sizeof ( * %var% )"))
|
||||
{
|
||||
tok->setstr("100");
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
DeleteNextToken(tok);
|
||||
}
|
||||
|
||||
else if (Match(tok, "sizeof ( * %var% )"))
|
||||
{
|
||||
tok->setstr("100");
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
DeleteNextToken(tok);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1016,23 +1016,23 @@ void Tokenizer::SimplifyTokenList()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace NULL with 0..
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok, "NULL") )
|
||||
tok->setstr("0");
|
||||
}
|
||||
|
||||
// Replace pointer casts of 0.. "(char *)0" => "0"
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok->next, "( %type% * ) 0") || Match(tok->next,"( %type% %type% * ) 0") )
|
||||
{
|
||||
while (!Match(tok->next,"0"))
|
||||
DeleteNextToken(tok);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace NULL with 0..
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok, "NULL") )
|
||||
tok->setstr("0");
|
||||
}
|
||||
|
||||
// Replace pointer casts of 0.. "(char *)0" => "0"
|
||||
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( Match(tok->next, "( %type% * ) 0") || Match(tok->next,"( %type% %type% * ) 0") )
|
||||
{
|
||||
while (!Match(tok->next,"0"))
|
||||
DeleteNextToken(tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1111,197 +1111,225 @@ void Tokenizer::DeallocateTokens()
|
|||
free(dsymlist->value);
|
||||
delete dsymlist;
|
||||
dsymlist = next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Files.clear();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::GetFunctionTokenByName( const char funcname[] ) const
|
||||
{
|
||||
std::list<const TOKEN *>::const_iterator it;
|
||||
for ( it = FunctionList.begin(); it != FunctionList.end(); it++ )
|
||||
{
|
||||
if ( strcmp( (*it)->str, funcname ) == 0 )
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const TOKEN *Tokenizer::GetFunctionTokenByName( const char funcname[] ) const
|
||||
{
|
||||
for ( unsigned int i = 0; i < FunctionList.size(); ++i )
|
||||
{
|
||||
if ( strcmp( FunctionList[i]->str, funcname ) == 0 )
|
||||
{
|
||||
return FunctionList[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void Tokenizer::FillFunctionList(const unsigned int file_id)
|
||||
{
|
||||
FunctionList.clear();
|
||||
|
||||
std::list<const char *> _usedfunc;
|
||||
if ( file_id == 0 )
|
||||
{
|
||||
GlobalFunctions.clear();
|
||||
}
|
||||
|
||||
bool staticfunc = false;
|
||||
bool classfunc = false;
|
||||
|
||||
int indentlevel = 0;
|
||||
for ( const TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( tok->str[0] == '{' )
|
||||
indentlevel++;
|
||||
|
||||
else if ( tok->str[0] == '}' )
|
||||
indentlevel--;
|
||||
|
||||
|
||||
if (indentlevel > 0)
|
||||
{
|
||||
if ( _settings._checkCodingStyle )
|
||||
{
|
||||
const char *funcname = 0;
|
||||
|
||||
if ( Match(tok,"%var% (") )
|
||||
funcname = tok->str;
|
||||
else if ( Match(tok, "= %var% ;") ||
|
||||
Match(tok, "= %var% ,") )
|
||||
funcname = tok->next->str;
|
||||
|
||||
if ( std::find(_usedfunc.begin(), _usedfunc.end(), funcname) == _usedfunc.end() )
|
||||
_usedfunc.push_back( funcname );
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strchr("};", tok->str[0]))
|
||||
staticfunc = classfunc = false;
|
||||
|
||||
else if ( strcmp( tok->str, "static" ) == 0 )
|
||||
staticfunc = true;
|
||||
|
||||
else if ( strcmp( tok->str, "::" ) == 0 )
|
||||
classfunc = true;
|
||||
|
||||
else if (Match(tok, "%var% ("))
|
||||
{
|
||||
// Check if this is the first token of a function implementation..
|
||||
for ( const TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( tok2->str[0] == ';' )
|
||||
{
|
||||
tok = tok2;
|
||||
break;
|
||||
}
|
||||
|
||||
else if ( tok2->str[0] == '{' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
else if ( tok2->str[0] == ')' )
|
||||
{
|
||||
if ( Match(tok2, ") {") )
|
||||
{
|
||||
if (_settings._checkCodingStyle && !staticfunc && !classfunc && tok->FileIndex==0)
|
||||
GlobalFunctions.push_back( GlobalFunction(file_id, tok->str) );
|
||||
FunctionList.push_back( tok );
|
||||
tok = tok2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tok = tok2;
|
||||
while (tok->next && !strchr(";{", tok->next->str[0]))
|
||||
tok = tok->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::list<const char *>::const_iterator it = _usedfunc.begin(); it != _usedfunc.end(); ++it)
|
||||
{
|
||||
if ( *it != 0 )
|
||||
{
|
||||
UsedGlobalFunctions.push_back( GlobalFunction(file_id, *it) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
void Tokenizer::CheckGlobalFunctionUsage(const std::vector<std::string> &filenames)
|
||||
{
|
||||
// Iterator for GlobalFunctions
|
||||
std::list<GlobalFunction>::const_iterator func;
|
||||
|
||||
// Iterator for UsedGlobalFunctions
|
||||
std::list<GlobalFunction>::const_iterator usedfunc;
|
||||
|
||||
unsigned int i1 = 0;
|
||||
unsigned int i2 = 1;
|
||||
|
||||
// Check that every function in GlobalFunctions are used
|
||||
for ( func = GlobalFunctions.begin(); func != GlobalFunctions.end(); func++ )
|
||||
{
|
||||
if ( GlobalFunctions.size() > 100 )
|
||||
{
|
||||
++i1;
|
||||
if ( i1 > (i2 * GlobalFunctions.size()) / 100 )
|
||||
{
|
||||
if ( (i2 % 10) == 0 )
|
||||
std::cout << i2 << "%";
|
||||
else
|
||||
std::cout << ".";
|
||||
std::cout.flush();
|
||||
++i2;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string &funcname = func->name();
|
||||
|
||||
if ( funcname == "main" || funcname == "WinMain" )
|
||||
continue;
|
||||
|
||||
// Check if this global function is used in any of the other files..
|
||||
bool UsedOtherFile = false;
|
||||
bool UsedAnyFile = false;
|
||||
for ( usedfunc = UsedGlobalFunctions.begin(); usedfunc != UsedGlobalFunctions.end(); usedfunc++ )
|
||||
{
|
||||
if ( funcname == usedfunc->name() )
|
||||
{
|
||||
UsedAnyFile = true;
|
||||
if (func->file_id() != usedfunc->file_id())
|
||||
{
|
||||
UsedOtherFile = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! UsedAnyFile )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "[" << filenames[func->file_id()] << "]: "
|
||||
<< "The function '" << func->name() << "' is never used.";
|
||||
ReportErr( errmsg.str() );
|
||||
}
|
||||
else if ( ! UsedOtherFile )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "[" << filenames[func->file_id()] << "]: "
|
||||
<< "The linkage of the function '" << func->name() << "' can be local (static) instead of global";
|
||||
ReportErr( errmsg.str() );
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void Tokenizer::settings( const Settings &settings )
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
void Tokenizer::FillFunctionList(const unsigned int file_id)
|
||||
{
|
||||
FunctionList.clear();
|
||||
|
||||
std::list<const char *> _usedfunc;
|
||||
if ( file_id == 0 )
|
||||
{
|
||||
GlobalFunctions.clear();
|
||||
}
|
||||
|
||||
bool staticfunc = false;
|
||||
bool classfunc = false;
|
||||
|
||||
int indentlevel = 0;
|
||||
for ( const TOKEN *tok = _tokens; tok; tok = tok->next )
|
||||
{
|
||||
if ( tok->str[0] == '{' )
|
||||
indentlevel++;
|
||||
|
||||
else if ( tok->str[0] == '}' )
|
||||
indentlevel--;
|
||||
|
||||
|
||||
if (indentlevel > 0)
|
||||
{
|
||||
if ( _settings._checkCodingStyle )
|
||||
{
|
||||
const char *funcname = 0;
|
||||
|
||||
if ( Match(tok,"%var% (") )
|
||||
funcname = tok->str;
|
||||
else if ( Match(tok, "= %var% ;") ||
|
||||
Match(tok, "= %var% ,") )
|
||||
funcname = tok->next->str;
|
||||
|
||||
if ( std::find(_usedfunc.begin(), _usedfunc.end(), funcname) == _usedfunc.end() )
|
||||
_usedfunc.push_back( funcname );
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strchr("};", tok->str[0]))
|
||||
staticfunc = classfunc = false;
|
||||
|
||||
else if ( strcmp( tok->str, "static" ) == 0 )
|
||||
staticfunc = true;
|
||||
|
||||
else if ( strcmp( tok->str, "::" ) == 0 )
|
||||
classfunc = true;
|
||||
|
||||
else if (Match(tok, "%var% ("))
|
||||
{
|
||||
// Check if this is the first token of a function implementation..
|
||||
for ( const TOKEN *tok2 = tok; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( tok2->str[0] == ';' )
|
||||
{
|
||||
tok = tok2;
|
||||
break;
|
||||
}
|
||||
|
||||
else if ( tok2->str[0] == '{' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
else if ( tok2->str[0] == ')' )
|
||||
{
|
||||
if ( Match(tok2, ") {") )
|
||||
{
|
||||
if (_settings._checkCodingStyle && !staticfunc && !classfunc && tok->FileIndex==0)
|
||||
GlobalFunctions.push_back( GlobalFunction(file_id, tok->str) );
|
||||
FunctionList.push_back( tok );
|
||||
tok = tok2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tok = tok2;
|
||||
while (tok->next && !strchr(";{", tok->next->str[0]))
|
||||
tok = tok->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the FunctionList functions with duplicate names, remove them
|
||||
// TODO this will need some better handling
|
||||
for ( unsigned int func1 = 0; func1 < FunctionList.size(); )
|
||||
{
|
||||
bool hasDuplicates = false;
|
||||
for ( unsigned int func2 = func1 + 1; func2 < FunctionList.size(); )
|
||||
{
|
||||
if ( strcmp(FunctionList[func1]->str, FunctionList[func2]->str) == 0 )
|
||||
{
|
||||
hasDuplicates = true;
|
||||
FunctionList.erase( FunctionList.begin() + func2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
++func2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! hasDuplicates )
|
||||
{
|
||||
++func1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FunctionList.erase( FunctionList.begin() + func1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (std::list<const char *>::const_iterator it = _usedfunc.begin(); it != _usedfunc.end(); ++it)
|
||||
{
|
||||
if ( *it != 0 )
|
||||
{
|
||||
UsedGlobalFunctions.push_back( GlobalFunction(file_id, *it) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
void Tokenizer::CheckGlobalFunctionUsage(const std::vector<std::string> &filenames)
|
||||
{
|
||||
// Iterator for GlobalFunctions
|
||||
std::list<GlobalFunction>::const_iterator func;
|
||||
|
||||
// Iterator for UsedGlobalFunctions
|
||||
std::list<GlobalFunction>::const_iterator usedfunc;
|
||||
|
||||
unsigned int i1 = 0;
|
||||
unsigned int i2 = 1;
|
||||
|
||||
// Check that every function in GlobalFunctions are used
|
||||
for ( func = GlobalFunctions.begin(); func != GlobalFunctions.end(); func++ )
|
||||
{
|
||||
if ( GlobalFunctions.size() > 100 )
|
||||
{
|
||||
++i1;
|
||||
if ( i1 > (i2 * GlobalFunctions.size()) / 100 )
|
||||
{
|
||||
if ( (i2 % 10) == 0 )
|
||||
std::cout << i2 << "%";
|
||||
else
|
||||
std::cout << ".";
|
||||
std::cout.flush();
|
||||
++i2;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string &funcname = func->name();
|
||||
|
||||
if ( funcname == "main" || funcname == "WinMain" )
|
||||
continue;
|
||||
|
||||
// Check if this global function is used in any of the other files..
|
||||
bool UsedOtherFile = false;
|
||||
bool UsedAnyFile = false;
|
||||
for ( usedfunc = UsedGlobalFunctions.begin(); usedfunc != UsedGlobalFunctions.end(); usedfunc++ )
|
||||
{
|
||||
if ( funcname == usedfunc->name() )
|
||||
{
|
||||
UsedAnyFile = true;
|
||||
if (func->file_id() != usedfunc->file_id())
|
||||
{
|
||||
UsedOtherFile = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! UsedAnyFile )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "[" << filenames[func->file_id()] << "]: "
|
||||
<< "The function '" << func->name() << "' is never used.";
|
||||
ReportErr( errmsg.str() );
|
||||
}
|
||||
else if ( ! UsedOtherFile )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "[" << filenames[func->file_id()] << "]: "
|
||||
<< "The linkage of the function '" << func->name() << "' can be local (static) instead of global";
|
||||
ReportErr( errmsg.str() );
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void Tokenizer::settings( const Settings &settings )
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
|
192
tokenize.h
192
tokenize.h
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* c++check - c/c++ syntax checking
|
||||
* Copyright (C) 2007 Daniel Marjamäki
|
||||
*
|
||||
|
@ -22,11 +22,11 @@
|
|||
#define tokenizeH
|
||||
//---------------------------------------------------------------------------
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "settings.h"
|
||||
|
||||
class TOKEN
|
||||
|
@ -57,95 +57,99 @@ public:
|
|||
unsigned int FileIndex;
|
||||
unsigned int linenr;
|
||||
TOKEN *next;
|
||||
};
|
||||
|
||||
class Tokenizer
|
||||
{
|
||||
public:
|
||||
Tokenizer();
|
||||
~Tokenizer();
|
||||
|
||||
void Tokenize(std::istream &code, const char FileName[]);
|
||||
|
||||
// Deallocate lists..
|
||||
void DeallocateTokens();
|
||||
|
||||
// Simplify tokenlist
|
||||
// -----------------------------
|
||||
void SimplifyTokenList();
|
||||
|
||||
void TokenizeCode(std::istream &code, const unsigned int FileIndex=0);
|
||||
|
||||
// Helper functions for handling the tokens list..
|
||||
static const TOKEN *findtoken(const TOKEN *tok1, const char *tokenstr[]);
|
||||
static const TOKEN *gettok(const TOKEN *tok, int index);
|
||||
static const char *getstr(const TOKEN *tok, int index);
|
||||
|
||||
// Return size.
|
||||
int SizeOfType(const char type[]);
|
||||
|
||||
void initTokens();
|
||||
|
||||
std::vector<std::string> *getFiles();
|
||||
|
||||
|
||||
|
||||
void FillFunctionList(const unsigned int file_id);
|
||||
const TOKEN *GetFunctionTokenByName( const char funcname[] ) const;
|
||||
void CheckGlobalFunctionUsage(const std::vector<std::string> &filenames);
|
||||
void settings( const Settings &settings );
|
||||
const TOKEN *tokens() const;
|
||||
private:
|
||||
|
||||
struct DefineSymbol
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
struct DefineSymbol *next;
|
||||
};
|
||||
|
||||
class GlobalFunction
|
||||
{
|
||||
private:
|
||||
unsigned int _FileId;
|
||||
std::string _FuncName;
|
||||
|
||||
public:
|
||||
GlobalFunction( const unsigned int FileId, const char FuncName[] )
|
||||
{
|
||||
_FileId = FileId;
|
||||
_FuncName = FuncName;
|
||||
}
|
||||
|
||||
unsigned int file_id() const { return _FileId; }
|
||||
const std::string &name() const { return _FuncName; }
|
||||
};
|
||||
|
||||
void Define(const char Name[], const char Value[]);
|
||||
|
||||
void addtoken(const char str[], const unsigned int lineno, const unsigned int fileno);
|
||||
|
||||
void combine_2tokens(TOKEN *tok, const char str1[], const char str2[]);
|
||||
|
||||
void DeleteNextToken(TOKEN *tok);
|
||||
|
||||
TOKEN *_gettok(TOKEN *tok, int index);
|
||||
|
||||
void InsertTokens(TOKEN *dest, TOKEN *src, unsigned int n);
|
||||
|
||||
TOKEN *tokens_back;
|
||||
std::map<std::string, unsigned int> TypeSize;
|
||||
std::list<const TOKEN *> FunctionList;
|
||||
std::list< GlobalFunction > GlobalFunctions;
|
||||
std::list< GlobalFunction > UsedGlobalFunctions;
|
||||
std::vector<std::string> Files;
|
||||
Settings _settings;
|
||||
|
||||
|
||||
struct DefineSymbol * dsymlist;
|
||||
TOKEN *_tokens;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class Tokenizer
|
||||
{
|
||||
public:
|
||||
Tokenizer();
|
||||
~Tokenizer();
|
||||
|
||||
void Tokenize(std::istream &code, const char FileName[]);
|
||||
|
||||
// Deallocate lists..
|
||||
void DeallocateTokens();
|
||||
|
||||
// Simplify tokenlist
|
||||
// -----------------------------
|
||||
void SimplifyTokenList();
|
||||
|
||||
void TokenizeCode(std::istream &code, const unsigned int FileIndex=0);
|
||||
|
||||
// Helper functions for handling the tokens list..
|
||||
static const TOKEN *findtoken(const TOKEN *tok1, const char *tokenstr[]);
|
||||
static const TOKEN *gettok(const TOKEN *tok, int index);
|
||||
static const char *getstr(const TOKEN *tok, int index);
|
||||
|
||||
// Return size.
|
||||
int SizeOfType(const char type[]);
|
||||
|
||||
void initTokens();
|
||||
|
||||
std::vector<std::string> *getFiles();
|
||||
|
||||
|
||||
|
||||
void FillFunctionList(const unsigned int file_id);
|
||||
const TOKEN *GetFunctionTokenByName( const char funcname[] ) const;
|
||||
void CheckGlobalFunctionUsage(const std::vector<std::string> &filenames);
|
||||
void settings( const Settings &settings );
|
||||
const TOKEN *tokens() const;
|
||||
|
||||
|
||||
#ifndef UNIT_TESTING
|
||||
private:
|
||||
#endif
|
||||
|
||||
struct DefineSymbol
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
struct DefineSymbol *next;
|
||||
};
|
||||
|
||||
class GlobalFunction
|
||||
{
|
||||
private:
|
||||
unsigned int _FileId;
|
||||
std::string _FuncName;
|
||||
|
||||
public:
|
||||
GlobalFunction( const unsigned int FileId, const char FuncName[] )
|
||||
{
|
||||
_FileId = FileId;
|
||||
_FuncName = FuncName;
|
||||
}
|
||||
|
||||
unsigned int file_id() const { return _FileId; }
|
||||
const std::string &name() const { return _FuncName; }
|
||||
};
|
||||
|
||||
void Define(const char Name[], const char Value[]);
|
||||
|
||||
void addtoken(const char str[], const unsigned int lineno, const unsigned int fileno);
|
||||
|
||||
void combine_2tokens(TOKEN *tok, const char str1[], const char str2[]);
|
||||
|
||||
void DeleteNextToken(TOKEN *tok);
|
||||
|
||||
TOKEN *_gettok(TOKEN *tok, int index);
|
||||
|
||||
void InsertTokens(TOKEN *dest, TOKEN *src, unsigned int n);
|
||||
|
||||
TOKEN *tokens_back;
|
||||
std::map<std::string, unsigned int> TypeSize;
|
||||
std::vector<const TOKEN *> FunctionList;
|
||||
std::list< GlobalFunction > GlobalFunctions;
|
||||
std::list< GlobalFunction > UsedGlobalFunctions;
|
||||
std::vector<std::string> Files;
|
||||
Settings _settings;
|
||||
|
||||
|
||||
struct DefineSymbol * dsymlist;
|
||||
TOKEN *_tokens;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue