2008-12-18 22:28:57 +01:00
/*
2009-01-21 21:04:20 +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 .
2008-12-18 22:28:57 +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
2009-09-27 17:08:31 +02:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2008-12-18 22:28:57 +01:00
*/
2009-07-05 22:16:43 +02:00
// The preprocessor that Cppcheck uses is a bit special. Instead of generating
2008-12-18 22:28:57 +01:00
// the code for a known configuration, it generates the code for each configuration.
# include "testsuite.h"
2009-01-06 15:18:36 +01:00
# include "../src/preprocessor.h"
2009-03-08 08:45:53 +01:00
# include "../src/tokenize.h"
2009-07-13 19:11:31 +02:00
# include "../src/token.h"
2008-12-18 22:28:57 +01:00
# include <map>
# include <string>
2009-04-27 21:29:03 +02:00
# include <sstream>
# include <stdexcept>
2008-12-18 22:28:57 +01:00
2009-04-03 21:09:12 +02:00
extern std : : ostringstream errout ;
2008-12-18 22:28:57 +01:00
class TestPreprocessor : public TestFixture
{
public :
TestPreprocessor ( ) : TestFixture ( " TestPreprocessor " )
{ }
2009-02-07 21:06:00 +01:00
class OurPreprocessor : public Preprocessor
{
public :
static std : : string replaceIfDefined ( const std : : string & str )
{
return Preprocessor : : replaceIfDefined ( str ) ;
}
2009-04-03 21:09:12 +02:00
static std : : string expandMacros ( std : : string code , ErrorLogger * errorLogger = 0 )
2009-02-07 21:06:00 +01:00
{
2009-04-03 21:09:12 +02:00
return Preprocessor : : expandMacros ( code , " file.cpp " , errorLogger ) ;
2009-02-07 21:06:00 +01:00
}
2009-05-22 22:59:07 +02:00
2009-05-22 23:18:48 +02:00
static int getHeaderFileName ( std : : string & str )
2009-05-22 22:59:07 +02:00
{
return Preprocessor : : getHeaderFileName ( str ) ;
}
2009-02-07 21:06:00 +01:00
} ;
2008-12-18 22:28:57 +01:00
private :
void run ( )
{
// Just read the code into a string. Perform simple cleanup of the code
TEST_CASE ( readCode ) ;
// The bug that started the whole work with the new preprocessor
2009-01-05 16:49:57 +01:00
TEST_CASE ( Bug2190219 ) ;
2008-12-18 22:28:57 +01:00
2009-01-05 16:49:57 +01:00
TEST_CASE ( test1 ) ;
TEST_CASE ( test2 ) ;
TEST_CASE ( test3 ) ;
TEST_CASE ( test4 ) ;
TEST_CASE ( test5 ) ;
2009-01-24 20:28:30 +01:00
TEST_CASE ( test6 ) ;
2008-12-18 22:28:57 +01:00
2009-01-22 19:19:17 +01:00
// Handling include guards (don't create extra configuration for it)
TEST_CASE ( includeguard ) ;
2009-01-12 07:43:56 +01:00
TEST_CASE ( newlines ) ;
2009-01-12 07:33:06 +01:00
2009-01-05 16:49:57 +01:00
TEST_CASE ( comments1 ) ;
2008-12-18 22:28:57 +01:00
2009-01-05 16:49:57 +01:00
TEST_CASE ( if0 ) ;
TEST_CASE ( if1 ) ;
2008-12-18 22:28:57 +01:00
2009-01-05 16:49:57 +01:00
TEST_CASE ( elif ) ;
2008-12-18 22:28:57 +01:00
2009-07-25 16:22:42 +02:00
// Test the Preprocessor::match_cfg_def
TEST_CASE ( match_cfg_def ) ;
2009-01-05 16:49:57 +01:00
TEST_CASE ( if_cond1 ) ;
2009-06-26 13:19:55 +02:00
TEST_CASE ( if_cond2 ) ;
TEST_CASE ( if_cond3 ) ;
2009-07-22 20:11:27 +02:00
TEST_CASE ( if_cond4 ) ;
2009-08-29 23:00:54 +02:00
TEST_CASE ( if_cond5 ) ;
2008-12-18 22:28:57 +01:00
2009-01-11 08:19:28 +01:00
TEST_CASE ( multiline1 ) ;
TEST_CASE ( multiline2 ) ;
2009-01-11 09:16:15 +01:00
TEST_CASE ( multiline3 ) ;
2009-05-11 20:12:29 +02:00
TEST_CASE ( multiline4 ) ;
2009-08-19 23:27:47 +02:00
TEST_CASE ( multiline5 ) ;
2009-01-02 19:27:50 +01:00
2009-09-11 21:22:41 +02:00
TEST_CASE ( remove_asm ) ;
2009-01-05 16:49:57 +01:00
TEST_CASE ( if_defined ) ; // "#if defined(AAA)" => "#ifdef AAA"
2009-06-21 08:03:42 +02:00
TEST_CASE ( if_not_defined ) ; // "#if !defined(AAA)" => "#ifndef AAA"
2009-01-05 10:26:00 +01:00
// Macros..
2009-01-06 09:49:54 +01:00
TEST_CASE ( macro_simple1 ) ;
TEST_CASE ( macro_simple2 ) ;
2009-01-11 16:07:13 +01:00
TEST_CASE ( macro_simple3 ) ;
2009-01-11 16:51:46 +01:00
TEST_CASE ( macro_simple4 ) ;
2009-01-11 17:06:37 +01:00
TEST_CASE ( macro_simple5 ) ;
2009-01-18 17:56:12 +01:00
TEST_CASE ( macro_simple6 ) ;
2009-01-21 18:11:24 +01:00
TEST_CASE ( macro_simple7 ) ;
2009-01-23 18:14:42 +01:00
TEST_CASE ( macro_simple8 ) ;
2009-06-05 22:45:31 +02:00
TEST_CASE ( macro_simple9 ) ;
2009-08-01 14:55:45 +02:00
TEST_CASE ( macro_simple10 ) ;
2009-08-22 13:03:52 +02:00
TEST_CASE ( macroInMacro ) ;
2009-01-06 09:49:54 +01:00
TEST_CASE ( macro_mismatch ) ;
2009-03-09 20:29:25 +01:00
TEST_CASE ( macro_linenumbers ) ;
2009-06-19 16:42:47 +02:00
TEST_CASE ( macro_nopar ) ;
2009-01-18 17:58:57 +01:00
TEST_CASE ( string1 ) ;
TEST_CASE ( string2 ) ;
2009-01-18 17:37:40 +01:00
TEST_CASE ( preprocessor_undef ) ;
2009-01-22 21:19:07 +01:00
TEST_CASE ( defdef ) ; // Defined multiple times
2009-01-20 19:28:24 +01:00
TEST_CASE ( preprocessor_doublesharp ) ;
2009-01-19 20:24:41 +01:00
TEST_CASE ( preprocessor_include_in_str ) ;
2009-02-13 14:31:40 +01:00
TEST_CASE ( fmt1 ) ;
2009-02-13 14:34:24 +01:00
TEST_CASE ( fmt2 ) ;
2009-06-18 23:09:11 +02:00
TEST_CASE ( fmt3 ) ;
2009-01-21 22:45:17 +01:00
TEST_CASE ( multi_character_character ) ;
2009-01-25 14:30:15 +01:00
TEST_CASE ( stringify ) ;
2009-03-15 22:09:27 +01:00
TEST_CASE ( stringify2 ) ;
2009-03-16 22:20:55 +01:00
TEST_CASE ( stringify3 ) ;
2009-05-05 17:19:06 +02:00
TEST_CASE ( stringify4 ) ;
2009-03-08 08:45:53 +01:00
TEST_CASE ( ifdefwithfile ) ;
2009-03-15 13:23:12 +01:00
TEST_CASE ( pragma ) ;
2009-08-10 20:07:55 +02:00
TEST_CASE ( pragma_asm ) ;
2009-03-18 00:10:26 +01:00
TEST_CASE ( endifsemicolon ) ;
2009-04-03 21:09:12 +02:00
TEST_CASE ( missing_doublequote ) ;
2009-08-13 23:22:51 +02:00
TEST_CASE ( handle_error ) ;
2009-04-27 21:29:03 +02:00
2009-06-19 15:43:46 +02:00
TEST_CASE ( unicodeInCode ) ;
TEST_CASE ( unicodeInComment ) ;
TEST_CASE ( unicodeInString ) ;
2009-05-09 21:32:29 +02:00
TEST_CASE ( define_part_of_func ) ;
2009-05-13 21:38:57 +02:00
TEST_CASE ( conditionalDefine ) ;
2009-05-12 23:01:53 +02:00
TEST_CASE ( multiline_comment ) ;
2009-05-18 22:32:04 +02:00
TEST_CASE ( macro_parameters ) ;
2009-05-20 20:36:59 +02:00
TEST_CASE ( newline_in_macro ) ;
2009-05-22 22:59:07 +02:00
TEST_CASE ( includes ) ;
2009-06-14 22:37:18 +02:00
TEST_CASE ( ifdef_ifdefined ) ;
2009-07-22 18:47:50 +02:00
// define and then ifdef
TEST_CASE ( define_ifdef ) ;
2008-12-18 22:28:57 +01:00
}
void readCode ( )
{
const char code [ ] = " \t a // \n "
" #aa \t /* remove this */ \t b \r \n " ;
Preprocessor p ;
std : : istringstream istr ( code ) ;
2009-01-05 16:49:57 +01:00
std : : string codestr ( p . read ( istr ) ) ;
ASSERT_EQUALS ( " a \n #aa b \n " , codestr ) ;
2008-12-18 22:28:57 +01:00
}
void Bug2190219 ( )
{
const char filedata [ ] = " int main() \n "
" { \n "
" #ifdef __cplusplus \n "
" int* flags = new int[10]; \n "
" #else \n "
" int* flags = (int*)malloc((10)*sizeof(int)); \n "
" #endif \n "
" \n "
" #ifdef __cplusplus \n "
" delete [] flags; \n "
" #else \n "
" free(flags); \n "
" #endif \n "
" } \n " ;
// Expected result..
std : : map < std : : string , std : : string > expected ;
expected [ " " ] = " int main() \n "
" { \n "
" \n "
" \n "
" \n "
" int* flags = (int*)malloc((10)*sizeof(int)); \n "
" \n "
" \n "
" \n "
" \n "
" \n "
" free(flags); \n "
" \n "
" } \n " ;
expected [ " __cplusplus " ] = " int main() \n "
2009-01-05 16:49:57 +01:00
" { \n "
" \n "
" int* flags = new int[10]; \n "
" \n "
" \n "
" \n "
" \n "
" \n "
" delete [] flags; \n "
" \n "
" \n "
" \n "
" } \n " ;
2008-12-18 22:28:57 +01:00
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( expected [ " " ] , actual [ " " ] ) ;
ASSERT_EQUALS ( expected [ " __cplusplus " ] , actual [ " __cplusplus " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
void test1 ( )
{
const char filedata [ ] = " #ifdef WIN32 \n "
" abcdef \n "
" #else \n "
" qwerty \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n qwerty \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n abcdef \n \n \n \n " , actual [ " WIN32 " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
void test2 ( )
{
const char filedata [ ] = " # ifndef WIN32 \n "
" \" # ifdef WIN32 \" // a comment \n "
" # else \n "
" qwerty \n "
" # endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-05-13 21:18:02 +02:00
ASSERT_EQUALS ( " \n \" #ifdef WIN32 \" \n \n \n \n " , actual [ " " ] ) ;
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n qwerty \n \n " , actual [ " WIN32 " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
void test3 ( )
{
const char filedata [ ] = " #ifdef ABC \n "
" a \n "
" #ifdef DEF \n "
" b \n "
" #endif \n "
" c \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n a \n \n \n \n c \n \n " , actual [ " ABC " ] ) ;
ASSERT_EQUALS ( " \n a \n \n b \n \n c \n \n " , actual [ " ABC;DEF " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
void test4 ( )
{
const char filedata [ ] = " #ifdef ABC \n "
" A \n "
" #endif \t \n "
" #ifdef ABC \n "
" A \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n A \n \n \n A \n \n " , actual [ " ABC " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
void test5 ( )
{
const char filedata [ ] = " #ifdef ABC \n "
" A \n "
" #else \n "
" B \n "
" #ifdef DEF \n "
" C \n "
" #endif \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n B \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n A \n \n \n \n \n \n \n " , actual [ " ABC " ] ) ;
ASSERT_EQUALS ( " \n \n \n B \n \n C \n \n \n " , actual [ " DEF " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-01-24 20:28:30 +01:00
void test6 ( )
{
2009-10-04 07:25:30 +02:00
const char filedata [ ] = " #if(A) \n "
" #if ( A ) \n "
" #if A \n " ;
2009-01-24 20:28:30 +01:00
std : : istringstream istr ( filedata ) ;
const std : : string actual ( Preprocessor : : read ( istr ) ) ;
// Compare results..
2009-10-04 07:25:30 +02:00
ASSERT_EQUALS ( " #if A \n #if A \n #if A \n " , actual ) ;
2009-01-24 20:28:30 +01:00
}
2009-08-12 20:28:43 +02:00
void test7 ( )
{
const char filedata [ ] = " #ifdef ABC \n "
" A \n "
" #ifdef ABC \n "
" B \n "
" #endif \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
errout . str ( " " ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Make sure an error message is written..
ASSERT_EQUALS ( " " , errout . str ( ) ) ; // no change?
TODO_ASSERT_EQUALS ( " [test.cpp:3]: this preprocessor condition is always true " , errout . str ( ) ) ;
// Compare results..
ASSERT_EQUALS ( " \n \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n A \n \n B \n \n \n " , actual [ " ABC " ] ) ;
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2008-12-18 22:28:57 +01:00
2009-01-22 19:19:17 +01:00
void includeguard ( )
{
// Handling include guards..
const char filedata [ ] = " #file \" abc.h \" \n "
" #ifndef abcH \n "
" #define abcH \n "
" #endif \n "
" #endfile \n "
" #ifdef ABC \n "
" #endif " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Expected configurations: "" and "ABC"
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2009-01-22 19:19:17 +01:00
}
2009-03-08 08:45:53 +01:00
void ifdefwithfile ( )
{
// Handling include guards..
const char filedata [ ] = " #ifdef ABC \n "
" #file \" abc.h \" \n "
" class A{};/* \n \n \n \n \n \n \n */ \n "
" #endfile \n "
" #endif \n "
" int main() {} \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
Tokenizer tok ;
2009-03-08 08:49:04 +01:00
std : : istringstream codeStream ( actual [ " " ] ) ;
tok . tokenize ( codeStream , " main.cpp " ) ;
2009-03-08 08:45:53 +01:00
2009-03-08 08:49:04 +01:00
ASSERT_EQUALS ( " \n \n ##file 0 \n 1: \n 2: \n 3: \n 4: int main ( ) { } \n " , tok . tokens ( ) - > stringifyList ( ) ) ;
2009-03-08 08:45:53 +01:00
// Expected configurations: "" and "ABC"
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n #file \" abc.h \" \n \n \n \n \n \n \n \n \n #endfile \n \n int main() {} \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n #file \" abc.h \" \n class A{}; \n \n \n \n \n \n \n \n #endfile \n \n int main() {} \n " , actual [ " ABC " ] ) ;
}
2008-12-18 22:28:57 +01:00
2009-01-12 07:33:06 +01:00
void newlines ( )
{
const char filedata [ ] = " \r \r \n \n " ;
// Preprocess
std : : istringstream istr ( filedata ) ;
Preprocessor preprocessor ;
ASSERT_EQUALS ( " \n \n \n " , preprocessor . read ( istr ) ) ;
}
2008-12-18 22:28:57 +01:00
void comments1 ( )
{
2009-05-13 21:18:02 +02:00
{
const char filedata [ ] = " /* \n "
" #ifdef WIN32 \n "
" #endif \n "
" */ \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( " \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2008-12-18 22:28:57 +01:00
2009-05-13 21:18:02 +02:00
{
const char filedata [ ] = " /* \n "
" \x080 #ifdef WIN32 \n "
" #endif \n "
" */ \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( " \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2009-05-14 21:53:49 +02:00
{
const char filedata [ ] = " void f() \n "
" { \n "
" *p = a / *b / *c; \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( " void f() \n { \n *p = a / *b / *c; \n } \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2008-12-18 22:28:57 +01:00
}
void if0 ( )
{
const char filedata [ ] = " # if /* comment */ 0 // comment \n "
" #ifdef WIN32 \n "
" #endif \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n \n " , actual [ " " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
void if1 ( )
{
const char filedata [ ] = " # if /* comment */ 1 // comment \n "
" ABC \n "
" # endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n ABC \n \n " , actual [ " " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
void elif ( )
{
const char filedata [ ] = " #if DEF1 \n "
" ABC \n "
" #elif DEF2 \n "
" DEF \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n ABC \n \n \n \n " , actual [ " DEF1 " ] ) ;
ASSERT_EQUALS ( " \n \n \n DEF \n \n " , actual [ " DEF2 " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-07-25 16:22:42 +02:00
void match_cfg_def ( )
{
2009-07-30 10:10:34 +02:00
{
std : : map < std : : string , std : : string > cfg ;
cfg [ " ABC " ] = " " ;
ASSERT_EQUALS ( false , Preprocessor : : match_cfg_def ( cfg , " defined(A) " ) ) ;
TODO_ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " !defined(A) " ) ) ;
2009-07-25 17:04:13 +02:00
2009-07-30 10:10:34 +02:00
ASSERT_EQUALS ( false , Preprocessor : : match_cfg_def ( cfg , " !defined(ABC)&&!defined(DEF) " ) ) ;
TODO_ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " !defined(A)&&!defined(B) " ) ) ;
}
2009-07-25 17:04:13 +02:00
2009-07-30 10:10:34 +02:00
{
std : : map < std : : string , std : : string > cfg ;
cfg [ " A " ] = " 1 " ;
cfg [ " B " ] = " 2 " ;
TODO_ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " A==1 " ) ) ;
TODO_ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " A<2 " ) ) ;
ASSERT_EQUALS ( false , Preprocessor : : match_cfg_def ( cfg , " A==2 " ) ) ;
ASSERT_EQUALS ( false , Preprocessor : : match_cfg_def ( cfg , " A<1 " ) ) ;
TODO_ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " A>=1&&B<=A " ) ) ;
}
2009-07-25 16:22:42 +02:00
}
2008-12-18 22:28:57 +01:00
void if_cond1 ( )
{
const char filedata [ ] = " #if LIBVER>100 \n "
" A \n "
" #else \n "
" B \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n B \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n A \n \n \n \n " , actual [ " LIBVER>100 " ] ) ;
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-06-26 13:19:55 +02:00
void if_cond2 ( )
{
const char filedata [ ] = " #ifdef A \n "
" a \n "
" #endif \n "
" #if defined(A) && defined(B) \n "
" ab \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n a \n \n \n \n \n " , actual [ " A " ] ) ;
ASSERT_EQUALS ( " \n a \n \n \n ab \n \n " , actual [ " A;B " ] ) ;
}
void if_cond3 ( )
{
const char filedata [ ] = " #ifdef A \n "
" a \n "
" #if defined(B) && defined(C) \n "
" abc \n "
" #endif \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n a \n \n \n \n \n " , actual [ " A " ] ) ;
ASSERT_EQUALS ( " \n a \n \n abc \n \n \n " , actual [ " A;B;C " ] ) ;
}
2009-07-22 20:11:27 +02:00
void if_cond4 ( )
{
const char filedata [ ] = " #define A \n "
" #define B \n "
" #if defined A || defined B \n "
" ab \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n \n ab \n \n " , actual [ " " ] ) ;
}
2009-06-26 13:19:55 +02:00
2009-08-29 23:00:54 +02:00
void if_cond5 ( )
{
const char filedata [ ] = " #if defined(A) && defined(B) \n "
" ab \n "
" #endif \n "
" cd \n "
" #if defined(B) && defined(A) \n "
" ef \n "
" #endif \n " ;
2009-06-26 13:19:55 +02:00
2009-08-29 23:00:54 +02:00
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n \n cd \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n ab \n \n cd \n \n ef \n \n " , actual [ " A;B " ] ) ;
}
2009-06-26 13:19:55 +02:00
2008-12-18 22:28:57 +01:00
2009-01-11 08:19:28 +01:00
void multiline1 ( )
2008-12-18 22:28:57 +01:00
{
2009-01-11 08:19:28 +01:00
const char filedata [ ] = " #define str \" abc \" \\ \n "
2009-01-06 10:43:26 +01:00
" \" def \" \n "
" abcdef = str; \n " ;
2008-12-18 22:28:57 +01:00
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
Preprocessor preprocessor ;
2009-05-14 21:53:49 +02:00
ASSERT_EQUALS ( " #define str \" abc \" \" def \" \n \n abcdef = str; \n " , preprocessor . read ( istr ) ) ;
2009-01-11 08:19:28 +01:00
}
2008-12-18 22:28:57 +01:00
2009-01-11 08:19:28 +01:00
void multiline2 ( )
{
const char filedata [ ] = " #define sqr(aa) aa * \\ \n "
" aa \n "
" sqr(5); \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
Preprocessor preprocessor ;
2009-05-14 21:53:49 +02:00
ASSERT_EQUALS ( " #define sqr(aa) aa * aa \n \n sqr(5); \n " , preprocessor . read ( istr ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-01-11 09:16:15 +01:00
void multiline3 ( )
{
const char filedata [ ] = " const char *str = \" abc \\ \n "
" def \\ \n "
" ghi \" \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
Preprocessor preprocessor ;
ASSERT_EQUALS ( " const char *str = \" abcdefghi \" \n \n \n " , preprocessor . read ( istr ) ) ;
}
2009-05-11 20:12:29 +02:00
void multiline4 ( )
{
errout . str ( " " ) ;
const char filedata [ ] = " #define A int a = 4; \\ \n "
" int b = 5; \n "
" A \n " ;
2009-01-11 09:16:15 +01:00
2009-05-11 20:12:29 +02:00
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n int a = 4; int b = 5; \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-01-02 19:27:50 +01:00
2009-08-19 23:27:47 +02:00
void multiline5 ( )
{
errout . str ( " " ) ;
const char filedata [ ] = " #define ABC int a /* \n "
" */= 4; \n "
" int main(){ \n "
" ABC \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n int main(){ \n int a = 4; \n } \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-11 21:22:41 +02:00
void remove_asm ( )
{
std : : string str1 ( " \n asm( \n \n \n ); " ) ;
Preprocessor : : removeAsm ( str1 ) ;
ASSERT_EQUALS ( " \n \n \n \n ; " , str1 ) ;
2009-09-11 23:34:24 +02:00
std : : string str2 ( " \n asm __volatile( \" \n lw iScale, 0x00(pScale) \n \" , ()); " ) ;
2009-09-11 21:22:41 +02:00
Preprocessor : : removeAsm ( str2 ) ;
2009-09-11 23:34:24 +02:00
ASSERT_EQUALS ( " \n \n \n ; " , str2 ) ;
2009-09-11 21:22:41 +02:00
}
2009-01-02 19:27:50 +01:00
void if_defined ( )
{
const char filedata [ ] = " #if defined(AAA) \n "
" #endif \n " ;
2009-06-21 08:03:42 +02:00
ASSERT_EQUALS ( " #ifdef AAA \n #endif \n " , OurPreprocessor : : replaceIfDefined ( filedata ) ) ;
}
2009-01-02 19:27:50 +01:00
2009-06-21 08:03:42 +02:00
void if_not_defined ( )
{
const char filedata [ ] = " #if !defined(AAA) \n "
" #endif \n " ;
ASSERT_EQUALS ( " #ifndef AAA \n #endif \n " , OurPreprocessor : : replaceIfDefined ( filedata ) ) ;
2009-01-02 19:27:50 +01:00
}
2009-01-18 11:54:07 +01:00
2009-01-06 09:49:54 +01:00
void macro_simple1 ( )
2009-01-05 10:26:00 +01:00
{
2009-05-24 22:57:12 +02:00
{
const char filedata [ ] = " #define AAA(aa) f(aa) \n "
" AAA(5); \n " ;
ASSERT_EQUALS ( " \n f(5); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] = " #define AAA(aa) f(aa) \n "
" AAA (5); \n " ;
ASSERT_EQUALS ( " \n f(5); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
2009-01-05 21:41:34 +01:00
}
2009-01-06 09:49:54 +01:00
void macro_simple2 ( )
2009-01-05 21:41:34 +01:00
{
const char filedata [ ] = " #define min(x,y) x<y?x:y \n "
" min(a(),b()); \n " ;
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n a()<b()?a():b(); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-05 21:41:34 +01:00
}
2009-01-11 16:07:13 +01:00
void macro_simple3 ( )
{
const char filedata [ ] = " #define A 4 \n "
" A AA \n " ;
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n 4 AA \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-11 16:07:13 +01:00
}
2009-01-11 16:51:46 +01:00
void macro_simple4 ( )
{
const char filedata [ ] = " #define TEMP_1 if( temp > 0 ) return 1; \n "
" TEMP_1 \n " ;
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n if( temp > 0 ) return 1; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-11 16:51:46 +01:00
}
2009-01-11 17:06:37 +01:00
void macro_simple5 ( )
{
const char filedata [ ] = " #define ABC if( temp > 0 ) return 1; \n "
" \n "
" void foo() \n "
" { \n "
" int temp = 0; \n "
" ABC \n "
" } \n " ;
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n \n void foo() \n { \n int temp = 0; \n if( temp > 0 ) return 1; \n } \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-11 17:06:37 +01:00
}
2009-01-18 17:56:12 +01:00
void macro_simple6 ( )
{
const char filedata [ ] = " #define ABC (a+b+c) \n "
" ABC " ;
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n (a+b+c) " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-18 17:56:12 +01:00
}
2009-01-21 18:11:24 +01:00
void macro_simple7 ( )
{
const char filedata [ ] = " #define ABC(str) str \n "
" ABC( \" ( \" ) " ;
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n \" ( \" " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-23 18:14:42 +01:00
}
void macro_simple8 ( )
{
const char filedata [ ] = " #define ABC 123 \n "
" #define ABCD 1234 \n "
" ABC ABCD " ;
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n \n 123 1234 " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-21 18:11:24 +01:00
}
2009-06-05 22:45:31 +02:00
void macro_simple9 ( )
{
const char filedata [ ] = " #define ABC(a) f(a) \n "
" ABC( \" \\ \" \" ); \n "
" ABC( \" g \" ); " ;
ASSERT_EQUALS ( " \n f( \" \\ \" \" ); \n f( \" g \" ); " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
2009-08-01 14:55:45 +02:00
void macro_simple10 ( )
{
const char filedata [ ] = " #define ABC(t) t x \n "
" ABC(unsigned long); " ;
ASSERT_EQUALS ( " \n unsigned long x; " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
2009-08-22 13:03:52 +02:00
void macroInMacro ( )
{
2009-09-14 21:53:57 +02:00
{
const char filedata [ ] = " #define A(m) long n = m; n++; \n "
" #define B(n) A(n) \n "
" B(0) " ;
ASSERT_EQUALS ( " \n \n long n=0;n++; " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] = " #define A B \n "
" #define B 3 \n "
" A " ;
2009-09-19 23:09:05 +02:00
ASSERT_EQUALS ( " \n \n 3 " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] = " #define DBG(fmt, args...) printf(fmt, ## args) \n "
" #define D(fmt, args...) DBG(fmt, ## args) \n "
" DBG( \" hello \" ); " ;
ASSERT_EQUALS ( " \n \n printf( \" hello \" ); " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] = " #define DBG(fmt, args...) printf(fmt, ## args) \n "
" #define D(fmt, args...) DBG(fmt, ## args) \n "
" DBG( \" hello: %d \" ,3); " ;
ASSERT_EQUALS ( " \n \n printf( \" hello: %d \" ,3); " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-09-14 21:53:57 +02:00
}
2009-09-21 22:27:06 +02:00
{
const char filedata [ ] = " #define A 4 \n "
" #define B(a) a,A \n "
" B(2); " ;
ASSERT_EQUALS ( " \n \n 2,4; " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
2009-08-22 13:03:52 +02:00
}
2009-01-06 09:49:54 +01:00
void macro_mismatch ( )
2009-01-05 21:41:34 +01:00
{
const char filedata [ ] = " #define AAA(aa,bb) f(aa) \n "
" AAA(5); \n " ;
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n AAA(5); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-05 10:26:00 +01:00
}
2009-03-08 21:28:12 +01:00
void macro_linenumbers ( )
{
const char filedata [ ] = " #define AAA(a) \n "
" AAA(5 \n "
" \n "
" ) \n "
" int a; \n " ;
2009-03-10 23:49:16 +01:00
ASSERT_EQUALS ( " \n "
" \n "
" \n "
" \n "
" int a; \n " ,
OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-03-08 21:28:12 +01:00
}
2009-06-19 16:42:47 +02:00
void macro_nopar ( )
{
const char filedata [ ] = " #define AAA( ) { NULL } \n "
" AAA() " ;
ASSERT_EQUALS ( " \n { NULL } " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
2009-01-18 17:58:57 +01:00
void string1 ( )
2009-01-08 23:28:54 +01:00
{
const char filedata [ ] = " int main() "
" { "
" const char *a = \" #define A \n \" ; "
" } " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2009-01-05 10:26:00 +01:00
2009-01-08 23:28:54 +01:00
// Compare results..
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2009-01-08 23:28:54 +01:00
ASSERT_EQUALS ( " int main(){ const char *a = \" #define A \n \" ;} \n " , actual [ " " ] ) ;
}
2009-01-12 19:23:53 +01:00
2009-01-18 17:58:57 +01:00
void string2 ( )
{
const char filedata [ ] = " #define AAA 123 \n "
" str = \" AAA \" " ;
// Compare results..
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n str = \" AAA \" " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-18 17:58:57 +01:00
}
2009-01-12 19:23:53 +01:00
void preprocessor_undef ( )
{
2009-06-14 06:21:20 +02:00
{
const char filedata [ ] = " #define AAA int a; \n "
" #undef AAA \n "
" #define AAA char b=0; \n "
" AAA \n " ;
2009-01-12 19:23:53 +01:00
2009-06-14 06:21:20 +02:00
// Compare results..
ASSERT_EQUALS ( " \n \n \n char b=0; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
// ticket #403
const char filedata [ ] = " #define z p[2] \n "
" #undef z \n "
" int z; \n "
" z = 0; \n " ;
ASSERT_EQUALS ( " \n \n int z; \n z = 0; \n " , OurPreprocessor : : getcode ( filedata , " " , " " , NULL ) ) ;
}
2009-01-12 19:23:53 +01:00
}
2009-01-19 20:24:41 +01:00
2009-01-22 21:19:07 +01:00
void defdef ( )
{
const char filedata [ ] = " #define AAA 123 \n "
" #define AAA 456 \n "
" #define AAA 789 \n "
" AAA \n " ;
// Compare results..
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n \n \n 789 \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-22 21:19:07 +01:00
}
2009-01-19 22:45:59 +01:00
void preprocessor_doublesharp ( )
{
const char filedata [ ] = " #define TEST(var,val) var = val \n "
" TEST(foo,20); \n " ;
// Compare results..
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n foo=20; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-19 22:45:59 +01:00
const char filedata2 [ ] = " #define TEST(var,val) var##_##val = val \n "
" TEST(foo,20); \n " ;
// Compare results..
2009-02-07 21:06:00 +01:00
ASSERT_EQUALS ( " \n foo_20=20; \n " , OurPreprocessor : : expandMacros ( filedata2 ) ) ;
2009-01-19 22:45:59 +01:00
}
2009-01-19 20:24:41 +01:00
void preprocessor_include_in_str ( )
{
const char filedata [ ] = " int main() \n "
" { \n "
" const char *a = \" #include <string> \n \" ; \n "
" return 0; \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2009-01-19 20:24:41 +01:00
// Compare results..
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2009-01-19 20:24:41 +01:00
ASSERT_EQUALS ( " int main() \n { \n const char *a = \" #include <string> \n \" ; \n return 0; \n } \n " , actual [ " " ] ) ;
}
2009-01-21 08:22:44 +01:00
2009-01-22 21:19:07 +01:00
2009-01-28 21:19:46 +01:00
void fmt1 ( )
2009-01-21 08:22:44 +01:00
{
2009-01-21 18:11:24 +01:00
const char filedata [ ] = " #define DBG(fmt...) printf(fmt) \n "
2009-01-21 08:22:44 +01:00
" DBG( \" [0x%lx-0x%lx) \" , pstart, pend); " ;
// Preprocess..
2009-02-07 21:06:00 +01:00
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-01-21 18:11:24 +01:00
2009-03-16 22:20:55 +01:00
ASSERT_EQUALS ( " \n printf( \" [0x%lx-0x%lx) \" ,pstart,pend); " , actual ) ;
2009-01-21 08:22:44 +01:00
}
2009-01-28 21:19:46 +01:00
void fmt2 ( )
{
const char filedata [ ] = " #define DBG(fmt, args...) printf(fmt, ## args) \n "
" DBG( \" hello \" ); " ;
// Preprocess..
2009-02-07 21:06:00 +01:00
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-01-28 21:19:46 +01:00
ASSERT_EQUALS ( " \n printf( \" hello \" ); " , actual ) ;
}
2009-06-18 23:09:11 +02:00
void fmt3 ( )
{
const char filedata [ ] = " #define FRED(...) { fred(__VA_ARGS__); } \n "
" FRED(123) " ;
ASSERT_EQUALS ( " \n { fred(123); } " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
2009-01-28 21:19:46 +01:00
2009-01-21 20:12:28 +01:00
void multi_character_character ( )
{
const char filedata [ ] = " #define FOO 'ABCD' \n "
" int main() \n "
" { \n "
" if( FOO == 0 ); \n "
" return 0; \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2009-01-21 20:12:28 +01:00
// Compare results..
2009-02-07 21:55:25 +01:00
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2009-01-21 22:45:17 +01:00
ASSERT_EQUALS ( " \n int main() \n { \n if( 'ABCD' == 0 ); \n return 0; \n } \n " , actual [ " " ] ) ;
2009-01-21 20:12:28 +01:00
}
2009-01-22 21:19:07 +01:00
2009-01-25 14:30:15 +01:00
void stringify ( )
{
const char filedata [ ] = " #define STRINGIFY(x) #x \n "
" STRINGIFY(abc) " ;
// expand macros..
2009-02-07 21:06:00 +01:00
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-01-25 14:30:15 +01:00
ASSERT_EQUALS ( " \n \" abc \" " , actual ) ;
}
2009-03-15 15:05:23 +01:00
void stringify2 ( )
{
const char filedata [ ] = " #define A(x) g(#x) \n "
" A(abc); " ;
// expand macros..
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
ASSERT_EQUALS ( " \n g( \" abc \" ); " , actual ) ;
}
2009-03-15 22:39:58 +01:00
void stringify3 ( )
{
const char filedata [ ] = " #define A(x) g(#x) \n "
" A( abc); " ;
// expand macros..
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
ASSERT_EQUALS ( " \n g( \" abc \" ); " , actual ) ;
}
2009-05-05 17:19:06 +02:00
void stringify4 ( )
{
const char filedata [ ] = " #define A(x) #x \n "
" 1 A( \n "
" abc \n "
" ) 2 " ;
// expand macros..
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
ASSERT_EQUALS ( " \n 1 \n \n \" abc \" 2 " , actual ) ;
}
2009-03-15 13:23:12 +01:00
void pragma ( )
{
const char filedata [ ] = " #pragma once \n "
" void f() \n "
" { \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n void f() \n { \n } \n " , actual [ " " ] ) ;
}
2009-03-18 00:10:26 +01:00
2009-08-10 20:07:55 +02:00
void pragma_asm ( )
{
const char filedata [ ] = " #pragma asm \n "
" mov r1, 11 \n "
" #pragma endasm \n "
2009-08-26 21:54:43 +02:00
" aaa \n "
" #pragma asm foo \n "
" mov r1, 11 \n "
" #pragma endasm bar \n "
" bbb " ;
2009-08-10 20:07:55 +02:00
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2009-08-26 21:54:43 +02:00
ASSERT_EQUALS ( " \n \n \n aaa \n \n \n \n bbb \n " , actual [ " " ] ) ;
2009-08-10 20:07:55 +02:00
}
2009-03-18 00:10:26 +01:00
void endifsemicolon ( )
{
const char filedata [ ] = " void f() \n "
" { \n "
" #ifdef A \n "
" #endif; \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " void f() \n "
" { \n "
" \n "
" \n "
" } \n " , actual [ " " ] ) ;
}
2009-04-03 21:09:12 +02:00
2009-08-13 23:22:51 +02:00
void handle_error ( )
{
{
const char filedata [ ] = " #define A \n "
" #error don't want to \\ \n "
" more text \n "
" void f() \n "
" { \n "
" char a = 'a'; // ' \n "
" } \n " ;
const char expected [ ] = " \n "
" \n "
" \n "
" void f() \n "
" { \n "
" char a = 'a'; \n "
" } \n " ;
errout . str ( " " ) ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
ASSERT_EQUALS ( expected , actual [ " " ] ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
}
2009-04-03 21:09:12 +02:00
void missing_doublequote ( )
{
2009-04-26 11:05:32 +02:00
{
const char filedata [ ] = " #define a \n "
" #ifdef 1 \n "
" \" \n "
" #endif \n " ;
2009-04-03 21:09:12 +02:00
2009-04-26 11:05:32 +02:00
// expand macros..
errout . str ( " " ) ;
const std : : string actual ( OurPreprocessor : : expandMacros ( filedata , this ) ) ;
ASSERT_EQUALS ( " " , actual ) ;
ASSERT_EQUALS ( " [file.cpp:3]: (error) No pair for character ( \" ). Can't process file. File is either invalid or unicode, which is currently not supported. \n " , errout . str ( ) ) ;
}
2009-04-03 21:09:12 +02:00
2009-04-26 11:05:32 +02:00
{
2009-05-19 21:19:15 +02:00
const char filedata [ ] = " #file \" abc.h \" \n "
2009-04-26 11:05:32 +02:00
" #define a \n "
" \" \n "
" #endfile \n " ;
// expand macros..
errout . str ( " " ) ;
const std : : string actual ( OurPreprocessor : : expandMacros ( filedata , this ) ) ;
ASSERT_EQUALS ( " " , actual ) ;
ASSERT_EQUALS ( " [abc.h:2]: (error) No pair for character ( \" ). Can't process file. File is either invalid or unicode, which is currently not supported. \n " , errout . str ( ) ) ;
}
2009-04-26 21:19:08 +02:00
2009-05-19 21:19:15 +02:00
{
const char filedata [ ] = " #file \" abc.h \" \n "
" #define a \n "
" #endfile \n "
" \" \n " ;
// expand macros..
errout . str ( " " ) ;
const std : : string actual ( OurPreprocessor : : expandMacros ( filedata , this ) ) ;
ASSERT_EQUALS ( " " , actual ) ;
ASSERT_EQUALS ( " [file.cpp:2]: (error) No pair for character ( \" ). Can't process file. File is either invalid or unicode, which is currently not supported. \n " , errout . str ( ) ) ;
}
2009-04-26 21:19:08 +02:00
{
const char filedata [ ] = " #define A 1 \n "
" #define B \" \n "
" int a = A; \n " ;
// expand macros..
errout . str ( " " ) ;
const std : : string actual ( OurPreprocessor : : expandMacros ( filedata , this ) ) ;
ASSERT_EQUALS ( " \n \n int a = 1; \n " , actual ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-04-03 21:09:12 +02:00
}
2009-04-27 21:29:03 +02:00
2009-06-19 15:43:46 +02:00
void unicodeInCode ( )
2009-04-27 21:29:03 +02:00
{
2009-06-19 15:43:46 +02:00
const std : : string filedata ( std : : string ( " a " ) + char ( 200 ) ) ;
2009-04-27 21:29:03 +02:00
std : : istringstream istr ( filedata ) ;
2009-06-19 09:20:15 +02:00
ASSERT_THROW ( Preprocessor : : read ( istr ) , std : : runtime_error ) ;
2009-04-27 21:29:03 +02:00
}
2009-05-09 21:32:29 +02:00
2009-06-19 15:43:46 +02:00
void unicodeInComment ( )
{
const std : : string filedata ( std : : string ( " // " ) + char ( 200 ) ) ;
std : : istringstream istr ( filedata . c_str ( ) ) ;
ASSERT_EQUALS ( " " , Preprocessor : : read ( istr ) ) ;
}
void unicodeInString ( )
{
const std : : string filedata ( std : : string ( " \" " ) + char ( 200 ) + " \" " ) ;
std : : istringstream istr ( filedata . c_str ( ) ) ;
ASSERT_EQUALS ( filedata , Preprocessor : : read ( istr ) ) ;
}
2009-05-09 21:32:29 +02:00
void define_part_of_func ( )
{
2009-05-11 20:12:29 +02:00
errout . str ( " " ) ;
2009-05-09 21:32:29 +02:00
const char filedata [ ] = " #define A g( \n "
" void f() { \n "
" A ); \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n void f() { \n g( ); \n } \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-05-13 21:38:57 +02:00
void conditionalDefine ( )
{
const char filedata [ ] = " #ifdef A \n "
" #define N 10 \n "
" #else \n "
" #define N 20 \n "
" #endif \n "
" N " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n \n \n \n 20 \n " , actual [ " " ] ) ;
2009-05-17 18:51:29 +02:00
ASSERT_EQUALS ( " \n \n \n \n \n 10 \n " , actual [ " A " ] ) ;
2009-05-13 21:38:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-05-12 23:01:53 +02:00
void multiline_comment ( )
{
errout . str ( " " ) ;
const char filedata [ ] = " #define ABC {// \\ \n "
" } \n "
" void f() ABC } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2009-05-13 21:18:02 +02:00
ASSERT_EQUALS ( " \n \n void f() { } \n " , actual [ " " ] ) ;
2009-05-12 23:01:53 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-05-18 22:32:04 +02:00
void macro_parameters ( )
{
errout . str ( " " ) ;
const char filedata [ ] = " #define BC(a, b, c, arg...) \\ \n "
" AB(a, b, c, ## arg) \n "
" \n "
" void f() \n "
" { \n "
" BC(3); \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
2009-07-25 21:10:30 +02:00
Preprocessor preprocessor ( 0 , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " , std : : list < std : : string > ( ) ) ;
2009-05-18 22:32:04 +02:00
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " " , actual [ " " ] ) ;
ASSERT_EQUALS ( " [file.c:6]: (error) Syntax error. Not enough parameters for macro 'BC'. \n " , errout . str ( ) ) ;
}
2009-05-12 23:01:53 +02:00
2009-05-20 20:36:59 +02:00
void newline_in_macro ( )
{
errout . str ( " " ) ;
const char filedata [ ] = " #define ABC(str) printf( str ) \n "
" void f() \n "
" { \n "
" ABC( \" \\ n \" ); \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
2009-07-25 21:10:30 +02:00
Preprocessor preprocessor ( 0 , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " , std : : list < std : : string > ( ) ) ;
2009-05-20 20:36:59 +02:00
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n void f() \n { \n printf( \" \\ n \" ); \n } \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-05-22 22:59:07 +02:00
void includes ( )
{
2009-05-22 23:18:48 +02:00
{
std : : string src = " #include a.h " ;
ASSERT_EQUALS ( 0 , OurPreprocessor : : getHeaderFileName ( src ) ) ;
ASSERT_EQUALS ( " " , src ) ;
}
{
std : : string src = " #include \" b.h \" " ;
ASSERT_EQUALS ( 1 , OurPreprocessor : : getHeaderFileName ( src ) ) ;
ASSERT_EQUALS ( " b.h " , src ) ;
}
{
std : : string src = " #include <c.h> " ;
ASSERT_EQUALS ( 2 , OurPreprocessor : : getHeaderFileName ( src ) ) ;
ASSERT_EQUALS ( " c.h " , src ) ;
}
2009-05-22 22:59:07 +02:00
}
2009-06-14 22:37:18 +02:00
void ifdef_ifdefined ( )
{
const char filedata [ ] = " #ifdef ABC \n "
" A \n "
" #endif \t \n "
" #if defined ABC \n "
" A \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( " \n \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n A \n \n \n A \n \n " , actual [ " ABC " ] ) ;
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2009-07-22 18:47:50 +02:00
void define_ifdef ( )
{
2009-07-25 13:58:34 +02:00
{
const char filedata [ ] = " #define ABC \n "
" #ifndef ABC \n "
" A \n "
" #else \n "
" B \n "
" #endif \n " ;
2009-07-22 18:47:50 +02:00
2009-07-25 13:58:34 +02:00
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2009-07-22 18:47:50 +02:00
2009-07-25 13:58:34 +02:00
// Compare results..
ASSERT_EQUALS ( " \n \n \n \n B \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
}
{
const char filedata [ ] = " #define A 1 \n "
" #ifdef A \n "
" A \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( " \n \n 1 \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
}
{
const char filedata [ ] = " #define A 1 \n "
" #if A==1 \n "
" A \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
TODO_ASSERT_EQUALS ( " \n \n 1 \n \n " , actual [ " " ] ) ;
TODO_ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
}
2009-08-31 20:36:25 +02:00
{
const char filedata [ ] = " #define A 1 \n "
" #ifdef A>0 \n "
" A \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
TODO_ASSERT_EQUALS ( " \n \n 1 \n \n " , actual [ " " ] ) ;
TODO_ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
}
2009-07-22 18:47:50 +02:00
}
2008-12-18 22:28:57 +01:00
} ;
2009-01-05 16:49:57 +01:00
REGISTER_TEST ( TestPreprocessor )