2009-01-08 07:22:14 +01:00
/*
* cppcheck - c / c + + syntax checking
* Copyright ( C ) 2007 - 2009 Daniel Marjamäki , Reijo Tomperi , Nicolas Le Cam
*
* 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/
*/
2009-01-06 16:02:34 +01:00
2009-01-08 18:29:44 +01:00
# include <fstream>
2009-01-06 16:02:34 +01:00
# include <iostream>
# include <list>
# include <string>
class Message
{
private :
std : : string _funcname ;
std : : string _msg ;
std : : string _par1 ;
2009-01-10 18:11:47 +01:00
std : : string _par2 ;
2009-01-06 17:25:42 +01:00
unsigned int _settings ;
2009-01-06 16:02:34 +01:00
2009-01-08 21:56:51 +01:00
std : : string msg ( bool code ) const ;
2009-01-06 16:02:34 +01:00
public :
2009-01-10 18:11:47 +01:00
Message ( std : : string funcname , unsigned int settings , std : : string msg ) ;
2009-01-08 21:56:51 +01:00
Message ( std : : string funcname , unsigned int settings , std : : string msg , std : : string par1 ) ;
2009-01-10 18:11:47 +01:00
Message ( std : : string funcname , unsigned int settings , std : : string msg , std : : string par1 , std : : string par2 ) ;
2009-01-06 16:02:34 +01:00
2009-01-06 17:25:42 +01:00
static const unsigned int ALL = 1 ;
static const unsigned int STYLE = 2 ;
2009-01-08 21:56:51 +01:00
void generateCode ( std : : ostream & ostr ) const ;
2009-01-06 18:09:27 +01:00
2009-01-08 21:56:51 +01:00
void generateDoc ( std : : ostream & ostr , unsigned int i ) const ;
2009-01-06 16:02:34 +01:00
} ;
int main ( )
{
// Error messages..
std : : list < Message > err ;
2009-01-08 21:56:51 +01:00
2009-01-10 20:23:21 +01:00
// checkbufferoverrun.cpp
err . push_back ( Message ( " arrayIndexOutOfBounds " , Message : : ALL , " Array index out of bounds " ) ) ;
err . push_back ( Message ( " bufferOverrun " , Message : : ALL , " Buffer overrun " ) ) ;
2009-01-10 15:29:59 +01:00
// checkclass.cpp..
err . push_back ( Message ( " noConstructor " , Message : : STYLE , " The class '%1' has no constructor " , " classname " ) ) ;
2009-01-10 18:11:47 +01:00
err . push_back ( Message ( " uninitVar " , 0 , " Uninitialized member variable '%1::%2' " , " classname " , " varname " ) ) ;
2009-01-10 18:35:41 +01:00
err . push_back ( Message ( " unusedPrivateFunction " , Message : : STYLE , " Unused private function '%1::%2' " , " classname " , " funcname " ) ) ;
2009-01-10 18:57:31 +01:00
err . push_back ( Message ( " memsetClass " , 0 , " Using '%1' on class " , " memfunc " ) ) ;
err . push_back ( Message ( " memsetStruct " , 0 , " Using '%1' on struct that contains a 'std::%2' " , " memfunc " , " classname " ) ) ;
err . push_back ( Message ( " operatorEq " , Message : : STYLE , " 'operator=' should return something " ) ) ;
2009-01-10 19:03:56 +01:00
err . push_back ( Message ( " virtualDestructor " , 0 , " Class %1 which is inherited by class %2 does not have a virtual destructor " , " Base " , " Derived " ) ) ;
2009-01-10 14:08:44 +01:00
2009-01-11 07:44:32 +01:00
// checkfunctionusage.cpp..
err . push_back ( Message ( " unusedFunction " , Message : : STYLE | Message : : ALL , " [%1]: The function '%2' is never used " , " filename " , " funcname " ) ) ;
2009-01-08 21:56:51 +01:00
// checkmemoryleak.cpp..
2009-01-10 20:30:41 +01:00
err . push_back ( Message ( " mismatchAllocDealloc " , 0 , " Mismatching allocation and deallocation: %1 " , " varname " ) ) ;
2009-01-06 17:25:42 +01:00
err . push_back ( Message ( " memleak " , 0 , " Memory leak: %1 " , " varname " ) ) ;
2009-01-08 18:29:44 +01:00
err . push_back ( Message ( " resourceLeak " , 0 , " Resource leak: %1 " , " varname " ) ) ;
2009-01-06 16:02:34 +01:00
2009-01-08 21:56:51 +01:00
// checkother.cpp..
2009-01-10 18:11:47 +01:00
err . push_back ( Message ( " cstyleCast " , Message : : STYLE , " C-style pointer casting " ) ) ;
err . push_back ( Message ( " redundantIfDelete0 " , Message : : STYLE , " Redundant condition. It is safe to deallocate a NULL pointer " ) ) ;
err . push_back ( Message ( " redundantIfRemove " , Message : : STYLE , " Redundant condition. The remove function in the STL will not do anything if element doesn't exist " ) ) ;
err . push_back ( Message ( " dangerousUsageStrtol " , 0 , " Invalid radix in call to strtol or strtoul. Must be 0 or 2-36 " ) ) ;
2009-01-12 07:44:47 +01:00
err . push_back ( Message ( " ifNoAction " , Message : : STYLE , " Found redundant if condition - 'if (condition);' " ) ) ;
2009-01-08 21:56:51 +01:00
2009-01-06 16:02:34 +01:00
// Generate code..
2009-01-07 16:17:02 +01:00
std : : cout < < " Generate code.. " < < std : : endl ;
2009-01-08 18:29:44 +01:00
std : : ofstream fout ( " errormessage.h " ) ;
2009-01-08 21:51:07 +01:00
fout < < " /* \n " ;
fout < < " * cppcheck - c/c++ syntax checking \n " ;
fout < < " * Copyright (C) 2007-2009 Daniel Marjamäki, Reijo Tomperi, Nicolas Le Cam \n " ;
fout < < " * \n " ;
fout < < " * This program is free software: you can redistribute it and/or modify \n " ;
fout < < " * it under the terms of the GNU General Public License as published by \n " ;
fout < < " * the Free Software Foundation, either version 3 of the License, or \n " ;
fout < < " * (at your option) any later version. \n " ;
fout < < " * \n " ;
fout < < " * This program is distributed in the hope that it will be useful, \n " ;
fout < < " * but WITHOUT ANY WARRANTY; without even the implied warranty of \n " ;
fout < < " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \n " ;
fout < < " * GNU General Public License for more details. \n " ;
fout < < " * \n " ;
fout < < " * You should have received a copy of the GNU General Public License \n " ;
fout < < " * along with this program. If not, see <http://www.gnu.org/licenses/ \n " ;
fout < < " */ \n \n " ;
fout < < " // THIS FILE IS GENERATED BY MACHINE, SEE ../tools/errmsg.cpp ! \n \n " ;
2009-01-08 18:29:44 +01:00
fout < < " #ifndef errormessageH \n " ;
fout < < " #define errormessageH \n " ;
fout < < " #include <string> \n " ;
fout < < " #include \" settings.h \" \n " ;
fout < < " class Token; \n " ;
fout < < " class Tokenizer; \n " ;
fout < < " class ErrorMessage \n " ;
fout < < " { \n " ;
fout < < " private: \n " ;
fout < < " ErrorMessage() { } \n " ;
fout < < " static std::string msg1(const Tokenizer *tokenizer, const Token *Location); \n " ;
fout < < " public: \n " ;
2009-01-06 16:02:34 +01:00
for ( std : : list < Message > : : const_iterator it = err . begin ( ) ; it ! = err . end ( ) ; + + it )
2009-01-08 18:29:44 +01:00
it - > generateCode ( fout ) ;
fout < < " }; \n " ;
fout < < " #endif \n " ;
2009-01-07 16:17:02 +01:00
std : : cout < < std : : endl ;
// Generate documentation..
std : : cout < < " Generate doc.. " < < std : : endl ;
for ( unsigned int i = 0 ; i < 4 ; + + i )
{
const char * suite [ 4 ] = { " standard " , " all " , " style " , " all + style " } ;
std : : cout < < " = " < < suite [ i ] < < " = " < < std : : endl ;
for ( std : : list < Message > : : const_iterator it = err . begin ( ) ; it ! = err . end ( ) ; + + it )
it - > generateDoc ( std : : cout , i ) ;
}
std : : cout < < std : : endl ;
2009-01-06 16:02:34 +01:00
return 0 ;
}
2009-01-08 21:56:51 +01:00
2009-01-10 18:11:47 +01:00
Message : : Message ( std : : string funcname , unsigned int settings , std : : string msg )
: _funcname ( funcname ) , _msg ( msg ) , _par1 ( " " ) , _par2 ( " " ) , _settings ( settings )
{ }
2009-01-08 21:56:51 +01:00
Message : : Message ( std : : string funcname , unsigned int settings , std : : string msg , std : : string par1 )
2009-01-10 18:11:47 +01:00
: _funcname ( funcname ) , _msg ( msg ) , _par1 ( par1 ) , _par2 ( " " ) , _settings ( settings )
{ }
Message : : Message ( std : : string funcname , unsigned int settings , std : : string msg , std : : string par1 , std : : string par2 )
: _funcname ( funcname ) , _msg ( msg ) , _par1 ( par1 ) , _par2 ( par2 ) , _settings ( settings )
2009-01-08 21:56:51 +01:00
{ }
std : : string Message : : msg ( bool code ) const
{
const char * str = code ? " \" " : " " ;
std : : string ret ( str + _msg + str ) ;
2009-01-10 18:11:47 +01:00
2009-01-08 21:56:51 +01:00
if ( ! _par1 . empty ( ) )
{
std : : string : : size_type pos = 0 ;
while ( ( pos = ret . find ( " %1 " , pos ) ) ! = std : : string : : npos )
{
ret . erase ( pos , 2 ) ;
if ( code )
ret . insert ( pos , " \" + " + _par1 + " + \" " ) ;
else
ret . insert ( pos , _par1 ) ;
}
}
2009-01-10 18:11:47 +01:00
if ( ! _par2 . empty ( ) )
{
std : : string : : size_type pos = 0 ;
while ( ( pos = ret . find ( " %2 " , pos ) ) ! = std : : string : : npos )
{
ret . erase ( pos , 2 ) ;
if ( code )
ret . insert ( pos , " \" + " + _par2 + " + \" " ) ;
else
ret . insert ( pos , _par2 ) ;
}
}
2009-01-08 21:56:51 +01:00
return ret ;
}
void Message : : generateCode ( std : : ostream & ostr ) const
{
2009-01-11 09:10:51 +01:00
bool loc = bool ( _msg . substr ( 0 , 4 ) ! = " [%1] " ) ;
2009-01-08 21:56:51 +01:00
// Error message..
2009-01-11 09:10:51 +01:00
ostr < < " static std::string " < < _funcname < < " ( " ;
if ( loc )
ostr < < " const Tokenizer *tokenizer, const Token *Location " ;
2009-01-08 21:56:51 +01:00
if ( ! _par1 . empty ( ) )
2009-01-11 09:10:51 +01:00
ostr < < ( loc ? " , " : " " ) < < " const std::string & " < < _par1 ;
2009-01-10 18:11:47 +01:00
if ( ! _par2 . empty ( ) )
ostr < < " , const std::string & " < < _par2 ;
2009-01-08 21:56:51 +01:00
ostr < < " ) \n " ;
2009-01-10 08:43:15 +01:00
ostr < < " { \n " ;
2009-01-11 09:10:51 +01:00
ostr < < " return " ;
if ( loc )
ostr < < " msg1(tokenizer, Location) + " ;
ostr < < msg ( true ) < < " ; \n " ;
2009-01-10 08:43:15 +01:00
ostr < < " } \n " ;
2009-01-08 21:56:51 +01:00
// Settings..
ostr < < " static bool " < < _funcname < < " (const Settings &s) " < < std : : endl ;
2009-01-10 08:43:15 +01:00
ostr < < " { \n " ;
2009-01-10 12:17:00 +01:00
ostr < < " return " ;
2009-01-08 21:56:51 +01:00
if ( _settings = = 0 )
ostr < < " true " ;
else
{
2009-01-10 13:03:18 +01:00
if ( _settings = = ALL )
2009-01-08 21:56:51 +01:00
ostr < < " s._showAll " ;
2009-01-10 13:03:18 +01:00
else if ( _settings = = STYLE )
2009-01-08 21:56:51 +01:00
ostr < < " s._checkCodingStyle " ;
2009-01-10 13:03:18 +01:00
else if ( _settings = = ( ALL | STYLE ) )
ostr < < " s._showAll & s._checkCodingStyle " ;
2009-01-08 21:56:51 +01:00
}
2009-01-10 08:43:15 +01:00
ostr < < " ; \n " ;
2009-01-10 12:17:00 +01:00
ostr < < " } \n \n " ;
2009-01-08 21:56:51 +01:00
}
void Message : : generateDoc ( std : : ostream & ostr , unsigned int i ) const
{
if ( _settings = = i )
{
ostr < < " " < < msg ( false ) < < std : : endl ;
}
}