2009-01-26 17:38:08 +01:00
|
|
|
/*
|
|
|
|
* Cppcheck - A tool for static C/C++ code analysis
|
2009-05-30 07:48:12 +02:00
|
|
|
* Copyright (C) 2007-2009 Daniel Marjamäki and Cppcheck team.
|
2009-01-26 17:38:08 +01:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
#ifndef tokenizeH
|
|
|
|
#define tokenizeH
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include <list>
|
|
|
|
#include <string>
|
|
|
|
#include <map>
|
|
|
|
#include <vector>
|
2009-08-12 22:50:03 +02:00
|
|
|
#include "classinfo.h"
|
2009-07-13 19:11:31 +02:00
|
|
|
|
|
|
|
class Token;
|
|
|
|
class ErrorLogger;
|
|
|
|
class Settings;
|
2009-01-26 17:38:08 +01:00
|
|
|
|
2009-07-17 10:49:01 +02:00
|
|
|
/// @addtogroup Core
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
/** @brief The main purpose is to tokenize the source code. It also has functions that simplify the token list */
|
2009-01-26 17:38:08 +01:00
|
|
|
class Tokenizer
|
|
|
|
{
|
|
|
|
private:
|
2009-07-17 10:49:01 +02:00
|
|
|
/** Deallocate lists.. */
|
2009-07-05 22:16:43 +02:00
|
|
|
void deallocateTokens();
|
2009-01-26 17:38:08 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
Tokenizer();
|
2009-07-13 19:11:31 +02:00
|
|
|
Tokenizer(const Settings * settings, ErrorLogger *errorLogger);
|
2009-01-26 17:38:08 +01:00
|
|
|
~Tokenizer();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tokenize code
|
2009-06-20 22:13:19 +02:00
|
|
|
* @param code input stream for code, e.g.
|
2009-07-18 10:25:22 +02:00
|
|
|
* \code
|
2009-06-20 22:13:19 +02:00
|
|
|
* #file "p.h"
|
|
|
|
* class Foo
|
|
|
|
* {
|
|
|
|
* private:
|
|
|
|
* void Bar();
|
|
|
|
* };
|
|
|
|
*
|
|
|
|
* #endfile
|
|
|
|
* void Foo::Bar()
|
|
|
|
* {
|
|
|
|
* }
|
2009-07-18 10:25:22 +02:00
|
|
|
* \endcode
|
2009-06-20 22:13:19 +02:00
|
|
|
*
|
2009-01-26 17:38:08 +01:00
|
|
|
* @param FileName The filename
|
2009-05-07 22:17:29 +02:00
|
|
|
* @return false if Source code contains syntax errors
|
2009-01-26 17:38:08 +01:00
|
|
|
*/
|
2009-05-07 22:17:29 +02:00
|
|
|
bool tokenize(std::istream &code, const char FileName[]);
|
2009-01-26 17:38:08 +01:00
|
|
|
|
2009-05-09 21:32:29 +02:00
|
|
|
/**
|
|
|
|
* Create tokens from code.
|
2009-06-20 22:13:19 +02:00
|
|
|
* @param code input stream for code, same as what tokenize()
|
2009-05-09 21:32:29 +02:00
|
|
|
*/
|
|
|
|
void createTokens(std::istream &code);
|
|
|
|
|
2009-01-26 17:38:08 +01:00
|
|
|
/** Set variable id */
|
|
|
|
void setVarId();
|
|
|
|
|
|
|
|
/** Simplify tokenlist */
|
|
|
|
void simplifyTokenList();
|
|
|
|
|
|
|
|
static void deleteTokens(Token *tok);
|
|
|
|
static const char *getParameterName(const Token *ftok, int par);
|
|
|
|
|
|
|
|
std::string fileLine(const Token *tok) const;
|
|
|
|
|
|
|
|
// Return size.
|
2009-07-05 22:16:43 +02:00
|
|
|
int sizeOfType(const char type[]) const;
|
2009-01-26 17:38:08 +01:00
|
|
|
|
|
|
|
const std::vector<std::string> *getFiles() const;
|
|
|
|
|
|
|
|
void fillFunctionList();
|
2009-07-05 22:16:43 +02:00
|
|
|
const Token *getFunctionTokenByName(const char funcname[]) const;
|
2009-01-26 17:38:08 +01:00
|
|
|
const Token *tokens() const;
|
|
|
|
|
2009-02-09 21:51:04 +01:00
|
|
|
std::string file(const Token *tok) const;
|
|
|
|
|
2009-03-13 22:28:44 +01:00
|
|
|
/**
|
|
|
|
* Find a class member function
|
|
|
|
* @param tok where to begin the search
|
|
|
|
* @param classname name of class
|
|
|
|
* @param funcname name of function ("~ Fred" => destructor for fred, "%var%" => any function)
|
|
|
|
* @param indentlevel Just an integer that you initialize to 0 before the first call.
|
|
|
|
* @return First matching token or NULL.
|
|
|
|
*/
|
2009-07-05 22:16:43 +02:00
|
|
|
static const Token *findClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel);
|
2009-03-13 22:28:44 +01:00
|
|
|
|
2009-08-12 22:50:03 +02:00
|
|
|
/**
|
|
|
|
* List of classes in currently checked source code and
|
|
|
|
* their member functions and member variables.
|
|
|
|
*/
|
|
|
|
std::map<std::string, ClassInfo> _classInfoList;
|
|
|
|
|
2009-08-14 12:46:55 +02:00
|
|
|
#ifndef UNIT_TESTING
|
2009-08-04 21:32:14 +02:00
|
|
|
private:
|
2009-08-14 12:46:55 +02:00
|
|
|
#endif
|
2009-03-13 22:28:44 +01:00
|
|
|
|
2009-09-06 13:22:01 +02:00
|
|
|
/**
|
|
|
|
* Replace sizeof() to appropriate size.
|
|
|
|
*/
|
|
|
|
void simplifySizeof();
|
|
|
|
|
2009-03-18 20:32:05 +01:00
|
|
|
/**
|
|
|
|
* Simplify variable declarations
|
|
|
|
*/
|
2009-08-29 21:07:09 +02:00
|
|
|
void simplifyVarDecl();
|
2009-03-18 20:32:05 +01:00
|
|
|
|
2009-06-06 10:40:48 +02:00
|
|
|
/**
|
|
|
|
* insert an "int" after "unsigned" if needed:
|
|
|
|
* "unsigned i" => "unsigned int i"
|
|
|
|
*/
|
|
|
|
void unsignedint();
|
|
|
|
|
2009-06-05 23:33:13 +02:00
|
|
|
/**
|
|
|
|
* Simplify question mark - colon operator
|
|
|
|
* Example: 0 ? (2/0) : 0 => 0
|
2009-06-10 23:12:26 +02:00
|
|
|
* @return true if something is modified
|
|
|
|
* false if nothing is done.
|
2009-06-05 23:33:13 +02:00
|
|
|
*/
|
|
|
|
bool simplifyQuestionMark();
|
2009-03-18 20:32:05 +01:00
|
|
|
|
2009-03-23 18:20:56 +01:00
|
|
|
/**
|
|
|
|
* simplify if-assignments..
|
|
|
|
* Example: "if(a=b);" => "a=b;if(a);"
|
|
|
|
*/
|
2009-08-29 21:17:17 +02:00
|
|
|
void simplifyIfAssign();
|
2009-03-23 18:20:56 +01:00
|
|
|
|
2009-03-24 18:23:21 +01:00
|
|
|
/**
|
|
|
|
* simplify if-not..
|
|
|
|
* Example: "if(0==x);" => "if(!x);"
|
|
|
|
*/
|
2009-08-29 21:19:45 +02:00
|
|
|
void simplifyIfNot();
|
2009-03-24 18:23:21 +01:00
|
|
|
|
2009-07-25 13:11:29 +02:00
|
|
|
/**
|
|
|
|
* simplify if-not NULL..
|
|
|
|
* Example: "if(0!=x);" => "if(x);"
|
|
|
|
*/
|
2009-08-29 21:21:06 +02:00
|
|
|
void simplifyIfNotNull();
|
2009-07-25 13:11:29 +02:00
|
|
|
|
2009-05-31 10:42:27 +02:00
|
|
|
/**
|
2009-08-29 15:29:19 +02:00
|
|
|
* Simplify the "not" and "and" keywords to "!" and "&&"
|
|
|
|
* accordingly.
|
|
|
|
* Examples:
|
|
|
|
* "if (not p)" => "if (!p)"
|
|
|
|
* "if (p and q)" => "if (p && q)"
|
2009-05-31 10:42:27 +02:00
|
|
|
*/
|
2009-08-29 21:03:37 +02:00
|
|
|
void simplifyLogicalOperators();
|
2009-05-31 10:42:27 +02:00
|
|
|
|
2009-06-10 23:12:26 +02:00
|
|
|
/**
|
2009-07-05 20:29:09 +02:00
|
|
|
* Simplify comma into a semicolon when possible
|
2009-06-10 23:12:26 +02:00
|
|
|
* Example: "delete a, delete b" => "delete a; delete b;"
|
2009-07-05 20:29:09 +02:00
|
|
|
* Example: "a = 0, b = 0;" => "a = 0; b = 0;"
|
2009-07-26 13:00:11 +02:00
|
|
|
* Example: "return a(), b;" => "a(); return b;"
|
2009-06-10 23:12:26 +02:00
|
|
|
*/
|
2009-08-29 21:23:39 +02:00
|
|
|
void simplifyComma();
|
2009-06-10 23:12:26 +02:00
|
|
|
|
2009-02-07 21:06:00 +01:00
|
|
|
/** Add braces to an if-block
|
|
|
|
*/
|
2009-08-29 21:25:15 +02:00
|
|
|
void simplifyIfAddBraces();
|
2009-01-26 17:38:08 +01:00
|
|
|
|
2009-08-29 21:26:56 +02:00
|
|
|
/**
|
|
|
|
* Add braces to an do-while block
|
2009-08-22 12:42:19 +02:00
|
|
|
*/
|
2009-08-29 21:26:56 +02:00
|
|
|
void simplifyDoWhileAddBraces();
|
2009-08-22 12:42:19 +02:00
|
|
|
|
2009-08-29 21:06:14 +02:00
|
|
|
/**
|
|
|
|
* Simplify casts
|
2009-02-07 21:06:00 +01:00
|
|
|
*/
|
2009-08-29 21:06:14 +02:00
|
|
|
void simplifyCasts();
|
2009-02-07 21:06:00 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A simplify function that replaces a variable with its value in cases
|
|
|
|
* when the value is known. e.g. "x=10; if(x)" => "x=10;if(10)"
|
|
|
|
*
|
|
|
|
* @return true if modifications to token-list are done.
|
|
|
|
* false if no modifications are done.
|
|
|
|
*/
|
|
|
|
bool simplifyKnownVariables();
|
|
|
|
|
2009-08-24 23:10:12 +02:00
|
|
|
/** Replace a "goto" with the statements */
|
|
|
|
void simplifyGoto();
|
|
|
|
|
2009-09-05 18:46:27 +02:00
|
|
|
/** Expand nested strcat() calls. */
|
|
|
|
void simplifyNestedStrcat();
|
|
|
|
|
2009-02-17 20:18:26 +01:00
|
|
|
/** Simplify "if else" */
|
2009-08-29 21:28:39 +02:00
|
|
|
void elseif();
|
2009-02-17 20:18:26 +01:00
|
|
|
|
2009-02-07 21:06:00 +01:00
|
|
|
std::vector<const Token *> _functionList;
|
|
|
|
|
2009-01-26 17:38:08 +01:00
|
|
|
/**
|
|
|
|
* Finds matching "end" for "start".
|
|
|
|
* @param tok The start tag
|
|
|
|
* @param start e.g. "{"
|
|
|
|
* @param end e.g. "}"
|
|
|
|
* @return The end tag that matches given parameter or 0 if not found.
|
|
|
|
*/
|
|
|
|
static const Token *findClosing(const Token *tok, const char *start, const char *end);
|
|
|
|
|
|
|
|
void addtoken(const char str[], const unsigned int lineno, const unsigned int fileno);
|
|
|
|
|
2009-07-14 12:06:38 +02:00
|
|
|
/**
|
|
|
|
* Simplify the operator "?:"
|
|
|
|
*/
|
2009-08-29 21:30:13 +02:00
|
|
|
void simplifyConditionOperator();
|
2009-07-14 12:06:38 +02:00
|
|
|
|
2009-01-26 17:38:08 +01:00
|
|
|
/** Simplify conditions
|
|
|
|
* @return true if something is modified
|
|
|
|
* false if nothing is done.
|
|
|
|
*/
|
|
|
|
bool simplifyConditions();
|
|
|
|
|
|
|
|
/** Remove reduntant code, e.g. if( false ) { int a; } should be
|
|
|
|
* removed, because it is never executed.
|
|
|
|
* @return true if something is modified
|
|
|
|
* false if nothing is done.
|
|
|
|
*/
|
|
|
|
bool removeReduntantConditions();
|
|
|
|
|
|
|
|
/** Simplify function calls - constant return value
|
|
|
|
* @return true if something is modified
|
|
|
|
* false if nothing is done.
|
|
|
|
*/
|
|
|
|
bool simplifyFunctionReturn();
|
|
|
|
|
|
|
|
/**
|
2009-06-12 15:04:58 +02:00
|
|
|
* Remove redundant paranthesis:
|
|
|
|
* - "((x))" => "(x)"
|
|
|
|
* - "(function())" => "function()"
|
2009-06-12 16:14:01 +02:00
|
|
|
* - "(delete x)" => "delete x"
|
|
|
|
* - "(delete [] x)" => "delete [] x"
|
2009-01-26 17:38:08 +01:00
|
|
|
* @return true if modifications to token-list are done.
|
|
|
|
* false if no modifications are done.
|
|
|
|
*/
|
|
|
|
bool simplifyRedundantParanthesis();
|
|
|
|
|
2009-03-04 07:24:03 +01:00
|
|
|
/**
|
|
|
|
* Simplify constant calculations such as "1+2" => "3"
|
|
|
|
* @return true if modifications to token-list are done.
|
|
|
|
* false if no modifications are done.
|
|
|
|
*/
|
|
|
|
bool simplifyCalculations();
|
|
|
|
|
2009-01-26 23:26:50 +01:00
|
|
|
/**
|
|
|
|
* Simplify functions like "void f(x) int x; {"
|
|
|
|
* into "void f(int x) {"
|
|
|
|
*/
|
2009-08-29 21:37:15 +02:00
|
|
|
void simplifyFunctionParameters();
|
2009-01-26 23:26:50 +01:00
|
|
|
|
2009-03-13 00:07:05 +01:00
|
|
|
/**
|
|
|
|
* Simplify namespaces by removing them, e.g.
|
|
|
|
* "namespace b{ void f(){} }" becomes "void f(){}"
|
|
|
|
*/
|
|
|
|
void simplifyNamespaces();
|
|
|
|
|
2009-05-03 21:23:47 +02:00
|
|
|
/**
|
|
|
|
* Simplify templates
|
|
|
|
*/
|
|
|
|
void simplifyTemplates();
|
|
|
|
|
2009-09-12 22:54:47 +02:00
|
|
|
/**
|
|
|
|
* Simplify e.g. 'atol("0")' into '0'
|
|
|
|
*/
|
2009-09-13 09:35:02 +02:00
|
|
|
void simplifyMathFunctions();
|
2009-09-12 22:54:47 +02:00
|
|
|
|
2009-09-09 23:25:58 +02:00
|
|
|
void insertTokens(Token *dest, const Token *src, unsigned int n);
|
2009-01-26 17:38:08 +01:00
|
|
|
|
2009-03-15 00:39:45 +01:00
|
|
|
/**
|
|
|
|
* Setup links for tokens so that one can call Token::link().
|
|
|
|
*
|
|
|
|
* @return false if there was a mismatch with tokens, this
|
|
|
|
* should mean that source code was not valid.
|
|
|
|
*/
|
|
|
|
bool createLinks();
|
|
|
|
|
2009-05-07 22:17:29 +02:00
|
|
|
void syntaxError(const Token *tok, char c);
|
|
|
|
|
2009-08-12 22:50:03 +02:00
|
|
|
/**
|
|
|
|
* Update _classInfoList to contain class names and member
|
|
|
|
* functions and member variables.
|
|
|
|
*/
|
|
|
|
void updateClassList();
|
|
|
|
|
2009-09-13 09:03:48 +02:00
|
|
|
/** Disable assignments.. */
|
|
|
|
Tokenizer(const Tokenizer &);
|
|
|
|
|
2009-09-13 15:35:37 +02:00
|
|
|
/**
|
|
|
|
* assert that tokens are ok - used during debugging for example
|
|
|
|
* to catch problems in simplifyTokenList.
|
|
|
|
* @return always true.
|
|
|
|
*/
|
|
|
|
bool validate() const;
|
|
|
|
|
2009-09-13 09:03:48 +02:00
|
|
|
/** Disable assignment operator */
|
|
|
|
void operator=(const Tokenizer &);
|
|
|
|
|
2009-07-13 19:11:31 +02:00
|
|
|
Token *_tokens, *_tokensBack;
|
2009-01-26 17:38:08 +01:00
|
|
|
std::map<std::string, unsigned int> _typeSize;
|
|
|
|
std::vector<std::string> _files;
|
2009-07-13 19:11:31 +02:00
|
|
|
const Settings * const _settings;
|
|
|
|
ErrorLogger * const _errorLogger;
|
2009-01-26 17:38:08 +01:00
|
|
|
};
|
|
|
|
|
2009-07-17 10:49:01 +02:00
|
|
|
/// @}
|
|
|
|
|
2009-01-26 17:38:08 +01:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
#endif
|