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
2010-04-13 21:23:17 +02:00
* Copyright ( C ) 2007 - 2010 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-10-25 12:49:06 +01:00
# include "preprocessor.h"
# include "tokenize.h"
# include "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 ;
2010-04-06 21:13:23 +02:00
extern std : : ostringstream output ;
2009-04-03 21:09:12 +02:00
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 ) ;
2009-11-13 22:12:29 +01:00
TEST_CASE ( test7 ) ;
// #error => don't extract any code
TEST_CASE ( error1 ) ;
2008-12-18 22:28:57 +01:00
2009-12-22 20:38:12 +01:00
// #error with extended chars
TEST_CASE ( error2 ) ;
2009-01-22 19:19:17 +01:00
// Handling include guards (don't create extra configuration for it)
2010-02-06 09:30:48 +01:00
TEST_CASE ( includeguard1 ) ;
TEST_CASE ( includeguard2 ) ;
2009-01-22 19:19:17 +01:00
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 ) ;
2009-11-20 19:18:57 +01:00
TEST_CASE ( if_cond6 ) ;
2009-11-21 19:53:07 +01:00
TEST_CASE ( if_cond7 ) ;
2009-12-15 20:18:32 +01:00
TEST_CASE ( if_cond8 ) ;
2010-01-09 21:54:20 +01:00
TEST_CASE ( if_cond9 ) ;
2008-12-18 22:28:57 +01:00
2009-12-13 17:18:27 +01:00
TEST_CASE ( if_or ) ;
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-11-26 17:32:18 +01:00
TEST_CASE ( macro_simple11 ) ;
2009-12-09 17:13:48 +01:00
TEST_CASE ( macro_simple12 ) ;
2010-01-02 20:54:52 +01:00
TEST_CASE ( macro_simple13 ) ;
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 ) ;
2010-04-15 22:21:00 +02:00
TEST_CASE ( macro_switchCase ) ;
2009-01-18 17:58:57 +01:00
TEST_CASE ( string1 ) ;
TEST_CASE ( string2 ) ;
2009-12-09 17:13:48 +01:00
TEST_CASE ( string3 ) ;
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-10-14 20:40:17 +02:00
TEST_CASE ( stringify5 ) ;
2009-03-08 08:45:53 +01:00
TEST_CASE ( ifdefwithfile ) ;
2009-03-15 13:23:12 +01:00
TEST_CASE ( pragma ) ;
2010-02-12 18:15:15 +01:00
TEST_CASE ( pragma_asm_1 ) ;
TEST_CASE ( pragma_asm_2 ) ;
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 ) ;
2009-10-10 22:23:48 +02:00
TEST_CASE ( endfile ) ;
2010-04-15 18:37:51 +02:00
TEST_CASE ( redundant_config ) ;
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 "
2009-10-04 15:41:50 +02:00
" #if A \n "
" #if defined((A)) \n "
" #elif defined (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 15:41:50 +02:00
ASSERT_EQUALS ( " #if A \n #if A \n #if A \n #if defined(A) \n #elif defined(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-11-13 22:12:29 +01:00
void error1 ( )
{
const char filedata [ ] = " #ifdef A \n "
" ; \n "
" #else \n "
" #error abcd \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 " ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n ; \n \n \n \n " , actual [ " A " ] ) ;
}
2009-12-22 20:38:12 +01:00
void error2 ( )
{
const char filedata [ ] = " #error ê \n "
" #warning ê \n "
" 123 " ;
// Read string..
std : : istringstream istr ( filedata ) ;
ASSERT_EQUALS ( " #error \n \n 123 " , Preprocessor : : read ( istr ) ) ;
}
2010-02-06 09:30:48 +01:00
void includeguard1 ( )
2009-01-22 19:19:17 +01:00
{
// 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
}
2010-02-06 09:30:48 +01:00
void includeguard2 ( )
{
// Handling include guards..
const char filedata [ ] = " #file \" abc.h \" \n "
" foo \n "
" #ifdef ABC \n "
" \n "
" #endif \n "
" #endfile \n " ;
// 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"
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( true , actual . find ( " " ) ! = actual . end ( ) ) ;
ASSERT_EQUALS ( true , actual . find ( " ABC " ) ! = actual . end ( ) ) ;
}
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 ( )
{
2010-03-28 14:15:25 +02:00
{
const char filedata [ ] = " #if DEF1 \n "
" ABC \n "
" #elif DEF2 \n "
" DEF \n "
" #endif \n " ;
2008-12-18 22:28:57 +01:00
2010-03-28 14:15:25 +02:00
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Preprocessor preprocessor ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
2010-03-28 14:15:25 +02:00
// Compare results..
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 " ] ) ;
ASSERT_EQUALS ( 3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
{
const char filedata [ ] = " #if(defined DEF1) \n "
" ABC \n "
" #elif(defined DEF2) \n "
" DEF \n "
" #else \n "
" GHI \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 GHI \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n ABC \n \n \n \n \n \n " , actual [ " DEF1 " ] ) ;
ASSERT_EQUALS ( " \n \n \n DEF \n \n \n \n " , actual [ " DEF2 " ] ) ;
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-12-11 19:28:37 +01:00
{
std : : map < std : : string , std : : string > cfg ;
ASSERT_EQUALS ( false , Preprocessor : : match_cfg_def ( cfg , " A>1||defined(B) " ) ) ;
}
{
std : : map < std : : string , std : : string > cfg ;
cfg [ " A " ] = " " ;
cfg [ " B " ] = " " ;
ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " defined(A)&&defined(B) " ) ) ;
}
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) " ) ) ;
2009-12-11 22:32:44 +01:00
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) " ) ) ;
2009-12-11 22:32:44 +01:00
ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " !defined(A)&&!defined(B) " ) ) ;
2009-07-30 10:10:34 +02:00
}
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 " ;
2009-11-21 19:53:07 +01:00
ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " A==1 " ) ) ;
ASSERT_EQUALS ( true , Preprocessor : : match_cfg_def ( cfg , " A<2 " ) ) ;
2009-07-30 10:10:34 +02:00
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-12-13 15:23:44 +01:00
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2009-01-06 10:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n B \n \n " , actual [ " " ] ) ;
2009-12-13 15:23:44 +01:00
TODO_ASSERT_EQUALS ( " \n A \n \n \n \n " , actual [ " LIBVER=101 " ] ) ;
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 " ] ) ;
2010-03-19 16:13:45 +01:00
if_cond2b ( ) ;
if_cond2c ( ) ;
if_cond2d ( ) ;
}
void if_cond2b ( )
{
const char filedata [ ] = " #ifndef A \n "
" !a \n "
" #ifdef B \n "
" b \n "
" #endif \n "
" #else \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 ( 3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n !a \n \n \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n \n \n \n \n \n a \n \n " , actual [ " A " ] ) ;
ASSERT_EQUALS ( " \n !a \n \n b \n \n \n \n \n " , actual [ " B " ] ) ;
}
void if_cond2c ( )
{
const char filedata [ ] = " #ifndef A \n "
" !a \n "
" #ifdef B \n "
" b \n "
" #else \n "
" !b \n "
" #endif \n "
" #else \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 ( 3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n !a \n \n \n \n !b \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n \n \n \n \n \n \n \n a \n \n " , actual [ " A " ] ) ;
ASSERT_EQUALS ( " \n !a \n \n b \n \n \n \n \n \n \n " , actual [ " B " ] ) ;
}
void if_cond2d ( )
{
const char filedata [ ] = " #ifndef A \n "
" !a \n "
" #ifdef B \n "
" b \n "
" #else \n "
" !b \n "
" #endif \n "
" #else \n "
" a \n "
" #ifdef B \n "
" b \n "
" #else \n "
" !b \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 ( 4 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n !a \n \n \n \n !b \n \n \n \n \n \n \n \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n \n \n \n \n \n \n \n a \n \n \n \n !b \n \n \n " , actual [ " A " ] ) ;
ASSERT_EQUALS ( " \n \n \n \n \n \n \n \n a \n \n b \n \n \n \n \n " , actual [ " A;B " ] ) ;
ASSERT_EQUALS ( " \n !a \n \n b \n \n \n \n \n \n \n \n \n \n \n \n " , actual [ " B " ] ) ;
2009-06-26 13:19:55 +02:00
}
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 ( )
{
2009-10-06 10:47:36 +02:00
{
const char filedata [ ] = " #define A \n "
" #define B \n "
" #if defined A || defined B \n "
" ab \n "
" #endif \n " ;
2009-07-22 20:11:27 +02:00
2009-10-06 10:47:36 +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 20:11:27 +02:00
2009-10-06 10:47:36 +02:00
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n \n ab \n \n " , actual [ " " ] ) ;
}
{
const char filedata [ ] = " #if A \n "
" { \n "
" #if (defined(B)) \n "
" foo(); \n "
" #endif \n "
" } \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 \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n { \n \n \n \n } \n \n " , actual [ " A " ] ) ;
ASSERT_EQUALS ( " \n { \n \n foo(); \n \n } \n \n " , actual [ " A;B " ] ) ;
}
{
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 [ " " ] ) ;
}
{
const char filedata [ ] = " #if (A) \n "
" foo(); \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 ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n foo(); \n \n " , actual [ " A " ] ) ;
}
2010-03-04 18:51:25 +01:00
{
const char filedata [ ] = " #if! A \n "
" foo(); \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 ( ) ) ) ;
TODO_ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
ASSERT_EQUALS ( " \n foo(); \n \n " , actual [ " " ] ) ;
}
2009-07-22 20:11:27 +02:00
}
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
2009-11-20 19:18:57 +01:00
void if_cond6 ( )
{
const char filedata [ ] = " \n "
" #if defined(A) && defined(B)) \n "
" #endif \n " ;
errout . str ( " " ) ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
2009-12-06 19:53:17 +01:00
Settings settings ;
2009-11-20 19:18:57 +01:00
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( " [file.c:2]: (error) mismatching number of '(' and ')' in this line: defined(A)&&defined(B)) \n " , errout . str ( ) ) ;
}
2009-11-21 19:53:07 +01:00
void if_cond7 ( )
{
const char filedata [ ] = " #define A 1 \n "
" #if A==1 \n "
" a1; \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
2009-12-06 19:53:17 +01:00
Settings settings ;
2009-11-21 19:53:07 +01:00
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n a1; \n \n " , actual [ " " ] ) ;
}
2008-12-18 22:28:57 +01:00
2009-12-15 20:18:32 +01:00
void if_cond8 ( )
{
const char filedata [ ] = " #if defined(A) + defined(B) + defined(C) != 1 \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n " , actual [ " " ] ) ;
}
2010-01-09 21:54:20 +01:00
void if_cond9 ( )
{
const char filedata [ ] = " #if !defined _A \n "
" abc \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n abc \n \n " , actual [ " " ] ) ;
}
2009-12-15 20:18:32 +01:00
2009-12-13 17:18:27 +01:00
void if_or ( )
{
const char filedata [ ] = " #if defined(DEF_10) || defined(DEF_11) \n "
" a1; \n "
" #endif \n " ;
errout . str ( " " ) ;
2010-04-06 21:13:23 +02:00
output . str ( " " ) ;
2009-12-13 17:18:27 +01:00
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
settings . _debug = true ;
2010-04-17 09:23:54 +02:00
settings . _verbose = true ;
2009-12-13 17:18:27 +01:00
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n \n " , actual [ " " ] ) ;
// the "defined(DEF_10) || defined(DEF_11)" are not handled correctly..
2010-04-06 21:13:23 +02:00
ASSERT_EQUALS ( " unhandled configuration: defined(DEF_10)||defined(DEF_11) \n " , output . str ( ) ) ;
2009-12-13 17:18:27 +01:00
TODO_ASSERT_EQUALS ( 2 , actual . size ( ) ) ;
TODO_ASSERT_EQUALS ( " \n a1; \n \n " , actual [ " DEF_10 " ] ) ;
}
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 ) ;
2009-11-02 18:31:22 +01:00
ASSERT_EQUALS ( " \n asm() \n \n \n ; " , str1 ) ;
2009-09-11 21:22:41 +02:00
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 ( )
{
2009-10-04 15:41:50 +02:00
{
const char filedata [ ] = " #if defined(AAA) \n "
" #endif \n " ;
ASSERT_EQUALS ( " #ifdef AAA \n #endif \n " , OurPreprocessor : : replaceIfDefined ( filedata ) ) ;
}
{
ASSERT_EQUALS ( " #elif A \n " , OurPreprocessor : : replaceIfDefined ( " #elif defined(A) \n " ) ) ;
}
2009-06-21 08:03:42 +02:00
}
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 "
2009-12-09 17:13:48 +01:00
" ABC \n " ;
ASSERT_EQUALS ( " \n (a+b+c) \n " , 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 "
2009-12-09 17:13:48 +01:00
" ABC( \" ( \" ) \n " ;
ASSERT_EQUALS ( " \n \" ( \" \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 "
2009-12-09 17:13:48 +01:00
" ABC ABCD \n " ;
ASSERT_EQUALS ( " \n \n 123 1234 \n " , 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 "
2009-12-09 17:13:48 +01:00
" ABC( \" g \" ); \n " ;
ASSERT_EQUALS ( " \n f( \" \\ \" \" ); \n f( \" g \" ); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-06-05 22:45:31 +02:00
}
2009-08-01 14:55:45 +02:00
void macro_simple10 ( )
{
const char filedata [ ] = " #define ABC(t) t x \n "
2009-12-09 17:13:48 +01:00
" ABC(unsigned long); \n " ;
ASSERT_EQUALS ( " \n unsigned long x; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-08-01 14:55:45 +02:00
}
2009-11-26 17:32:18 +01:00
void macro_simple11 ( )
{
const char filedata [ ] = " #define ABC(x) delete x \n "
2009-12-09 17:13:48 +01:00
" ABC(a); \n " ;
ASSERT_EQUALS ( " \n delete a; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
void macro_simple12 ( )
{
const char filedata [ ] = " #define AB ab.AB \n "
" AB.CD \n " ;
ASSERT_EQUALS ( " \n ab.AB.CD \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-11-26 17:32:18 +01:00
}
2010-01-02 20:54:52 +01:00
void macro_simple13 ( )
{
const char filedata [ ] = " #define TRACE(x) \n "
" TRACE(;if(a)) \n " ;
ASSERT_EQUALS ( " \n \n " , 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 "
2009-12-09 17:13:48 +01:00
" B(0) \n " ;
ASSERT_EQUALS ( " \n \n long n=0;n++; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-09-14 21:53:57 +02:00
}
{
const char filedata [ ] = " #define A B \n "
" #define B 3 \n "
2009-12-09 17:13:48 +01:00
" A \n " ;
ASSERT_EQUALS ( " \n \n 3 \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-09-19 23:09:05 +02:00
}
{
const char filedata [ ] = " #define DBG(fmt, args...) printf(fmt, ## args) \n "
" #define D(fmt, args...) DBG(fmt, ## args) \n "
2009-12-09 17:13:48 +01:00
" DBG( \" hello \" ); \n " ;
ASSERT_EQUALS ( " \n \n printf( \" hello \" ); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-09-19 23:09:05 +02:00
}
{
const char filedata [ ] = " #define DBG(fmt, args...) printf(fmt, ## args) \n "
" #define D(fmt, args...) DBG(fmt, ## args) \n "
2009-12-09 17:13:48 +01:00
" DBG( \" hello: %d \" ,3); \n " ;
ASSERT_EQUALS ( " \n \n printf( \" hello: %d \" ,3); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-09-14 21:53:57 +02:00
}
2009-09-21 22:27:06 +02:00
2010-03-24 19:24:53 +01:00
{
const char filedata [ ] = " #define BC(b, c...) 0##b * 0##c \n "
" #define ABC(a, b...) a + BC(b) \n "
" \n "
" ABC(1); \n "
" ABC(2,3); \n "
" ABC(4,5,6); \n " ;
2010-03-24 19:55:02 +01:00
2010-03-26 21:11:49 +01:00
ASSERT_EQUALS ( " \n \n \n 1+0*0; \n 2+03*0; \n 4+05*06; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2010-03-24 19:24:53 +01:00
}
2009-09-21 22:27:06 +02:00
{
const char filedata [ ] = " #define A 4 \n "
" #define B(a) a,A \n "
2009-12-09 17:13:48 +01:00
" B(2); \n " ;
ASSERT_EQUALS ( " \n \n 2,4; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-09-21 22:27:06 +02:00
}
2009-11-17 23:21:21 +01:00
{
const char filedata [ ] = " #define A(x) (x) \n "
" #define B )A( \n "
" #define C )A( \n " ;
2009-11-18 23:34:00 +01:00
ASSERT_EQUALS ( " \n \n \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-11-17 23:21:21 +01:00
}
{
const char filedata [ ] = " #define A(x) (x*2) \n "
" #define B A( \n "
" foo B(i)); \n " ;
2009-11-18 23:34:00 +01:00
ASSERT_EQUALS ( " \n \n foo ((i)*2); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] = " #define foo foo \n "
" foo \n " ;
ASSERT_EQUALS ( " \n foo \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-11-17 23:21:21 +01:00
}
2009-12-13 21:36:42 +01:00
{
const char filedata [ ] =
" #define B(A1, A2) } while (0) \n "
" #define A(name) void foo##name() { do { B(1, 2); } \n "
" A(0) \n "
" A(1) \n " ;
2009-12-14 23:06:05 +01:00
ASSERT_EQUALS ( " \n \n void foo0(){do{}while(0);} \n void foo1(){do{}while(0);} \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] =
" #define B(x) ( \n "
" #define A() B(xx) \n "
" B(1) A() ) ) \n " ;
ASSERT_EQUALS ( " \n \n ( ( ) ) \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-12-13 21:36:42 +01:00
}
2009-12-20 22:50:57 +01:00
{
const char filedata [ ] =
" #define PTR1 ( \n "
" #define PTR2 PTR1 PTR1 \n "
" int PTR2 PTR2 foo )))) = 0; \n " ;
ASSERT_EQUALS ( " \n \n int ( ( ( ( foo )))) = 0; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] =
" #define PTR1 ( \n "
" PTR1 PTR1 \n " ;
ASSERT_EQUALS ( " \n ( ( \n " , 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 "
2009-12-09 17:13:48 +01:00
" AAA() \n " ;
ASSERT_EQUALS ( " \n { NULL } \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-06-19 16:42:47 +02:00
}
2010-04-15 22:21:00 +02:00
void macro_switchCase ( )
{
{
// Make sure "case 2" doesn't become "case2"
const char filedata [ ] = " #define A( b ) "
" switch( a ){ "
" case 2: "
" break; "
" } \n "
" A( 5 ); \n " ;
ASSERT_EQUALS ( " \n switch(a){case 2:break;}; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
// Make sure "2 BB" doesn't become "2BB"
const char filedata [ ] = " #define A() AA : 2 BB \n "
" A(); \n " ;
ASSERT_EQUALS ( " \n AA : 2 BB; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] = " #define A } \n "
" #define B() A \n "
" #define C( a ) B() break; \n "
" {C( 2 ); \n " ;
ASSERT_EQUALS ( " \n \n \n {} break;; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] = " #define A } \n "
" #define B() A \n "
" #define C( a ) B() _break; \n "
" {C( 2 ); \n " ;
ASSERT_EQUALS ( " \n \n \n {} _break;; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
{
const char filedata [ ] = " #define A } \n "
" #define B() A \n "
" #define C( a ) B() 5; \n "
" {C( 2 ); \n " ;
ASSERT_EQUALS ( " \n \n \n {} 5;; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
}
2009-06-19 16:42:47 +02:00
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 \" ; "
2009-12-09 17:13:48 +01:00
" } \n " ;
2009-01-08 23:28:54 +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 " ) ;
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 "
2009-12-09 17:13:48 +01:00
" str = \" AAA \" \n " ;
// Compare results..
ASSERT_EQUALS ( " \n str = \" AAA \" \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
void string3 ( )
{
const char filedata [ ] = " str( \" ; \" ); \n " ;
2009-01-18 17:58:57 +01:00
// Compare results..
2009-12-09 17:13:48 +01:00
ASSERT_EQUALS ( " str( \" ; \" ); \n " , 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-12-09 19:14:07 +01:00
const char filedata3 [ ] = " #define ABCD 123 \n "
" #define A(B) A##B \n "
" A(BCD) \n " ;
// Compare results..
ASSERT_EQUALS ( " \n \n 123 \n " , OurPreprocessor : : expandMacros ( filedata3 ) ) ;
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-12-09 17:13:48 +01:00
" DBG( \" [0x%lx-0x%lx) \" , pstart, pend); \n " ;
2009-01-21 08:22:44 +01:00
// Preprocess..
2009-02-07 21:06:00 +01:00
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-01-21 18:11:24 +01:00
2009-12-09 17:13:48 +01:00
ASSERT_EQUALS ( " \n printf( \" [0x%lx-0x%lx) \" ,pstart,pend); \n " , 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 "
2009-12-09 17:13:48 +01:00
" DBG( \" hello \" ); \n " ;
2009-01-28 21:19:46 +01:00
// Preprocess..
2009-02-07 21:06:00 +01:00
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-01-28 21:19:46 +01:00
2009-12-09 17:13:48 +01:00
ASSERT_EQUALS ( " \n printf( \" hello \" ); \n " , actual ) ;
2009-01-28 21:19:46 +01:00
}
2009-06-18 23:09:11 +02:00
void fmt3 ( )
{
const char filedata [ ] = " #define FRED(...) { fred(__VA_ARGS__); } \n "
2009-12-09 17:13:48 +01:00
" FRED(123) \n " ;
ASSERT_EQUALS ( " \n { fred(123); } \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-06-18 23:09:11 +02:00
}
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 "
2009-12-09 17:13:48 +01:00
" STRINGIFY(abc) \n " ;
2009-01-25 14:30:15 +01:00
// expand macros..
2009-02-07 21:06:00 +01:00
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-01-25 14:30:15 +01:00
2009-12-09 17:13:48 +01:00
ASSERT_EQUALS ( " \n \" abc \" \n " , actual ) ;
2009-01-25 14:30:15 +01:00
}
2009-03-15 15:05:23 +01:00
void stringify2 ( )
{
const char filedata [ ] = " #define A(x) g(#x) \n "
2009-12-09 17:13:48 +01:00
" A(abc); \n " ;
2009-03-15 15:05:23 +01:00
// expand macros..
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-12-09 17:13:48 +01:00
ASSERT_EQUALS ( " \n g( \" abc \" ); \n " , actual ) ;
2009-03-15 15:05:23 +01:00
}
2009-03-15 22:39:58 +01:00
void stringify3 ( )
{
const char filedata [ ] = " #define A(x) g(#x) \n "
2009-12-09 17:13:48 +01:00
" A( abc); \n " ;
2009-03-15 22:39:58 +01:00
// expand macros..
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-12-09 17:13:48 +01:00
ASSERT_EQUALS ( " \n g( \" abc \" ); \n " , actual ) ;
2009-03-15 22:39:58 +01:00
}
2009-05-05 17:19:06 +02:00
void stringify4 ( )
{
const char filedata [ ] = " #define A(x) #x \n "
" 1 A( \n "
" abc \n "
2009-12-09 17:13:48 +01:00
" ) 2 \n " ;
2009-05-05 17:19:06 +02:00
// expand macros..
std : : string actual = OurPreprocessor : : expandMacros ( filedata ) ;
2009-12-09 17:13:48 +01:00
ASSERT_EQUALS ( " \n 1 \n \n \" abc \" 2 \n " , actual ) ;
2009-05-05 17:19:06 +02:00
}
2009-10-14 20:40:17 +02:00
void stringify5 ( )
{
const char filedata [ ] = " #define A(x) a(#x,x) \n "
" A(foo( \" \\ \" \" )) \n " ;
ASSERT_EQUALS ( " \n a( \" foo( \\ \" \\ \\ \\ \" \\ \" ) \" ,foo( \" \\ \" \" )) \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
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
2010-02-12 18:15:15 +01:00
void pragma_asm_1 ( )
2009-08-10 20:07:55 +02:00
{
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
}
2010-02-12 18:15:15 +01:00
void pragma_asm_2 ( )
{
const char filedata [ ] = " #pragma asm \n "
" mov @w1, 11 \n "
" #pragma endasm ( temp=@w1 ) \n "
" bbb " ;
// 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 asm(temp); \n bbb \n " , actual [ " " ] ) ;
}
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 "
2009-11-13 22:12:29 +01:00
" #define B don't want to \\ \n "
2009-08-13 23:22:51 +02:00
" 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 ( ) ) ;
}
2010-02-26 22:11:23 +01:00
{
const char filedata [ ] = " void foo() \n "
" { \n "
" \n "
" \n "
" \n "
" int a = 0; \n "
" printf(Text \" ); \n "
" } \n " ;
// expand macros..
errout . str ( " " ) ;
const std : : string actual ( OurPreprocessor : : expandMacros ( filedata , this ) ) ;
ASSERT_EQUALS ( " [file.cpp:7]: (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-27 21:29:03 +02:00
2009-06-19 15:43:46 +02:00
void unicodeInCode ( )
2009-04-27 21:29:03 +02:00
{
2010-04-13 22:39:41 +02:00
const std : : string filedata ( " a \xC8 " ) ;
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 ( )
{
2010-04-13 22:39:41 +02:00
const std : : string filedata ( " // \xC8 " ) ;
2009-06-19 15:43:46 +02:00
std : : istringstream istr ( filedata . c_str ( ) ) ;
ASSERT_EQUALS ( " " , Preprocessor : : read ( istr ) ) ;
}
void unicodeInString ( )
{
2010-04-13 22:39:41 +02:00
const std : : string filedata ( " \" \xC8 \" " ) ;
2009-06-19 15:43:46 +02:00
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..
2009-11-21 19:53:07 +01:00
ASSERT_EQUALS ( " \n \n 1 \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
2009-07-25 13:58:34 +02:00
}
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..
2009-11-21 19:53:07 +01:00
ASSERT_EQUALS ( " \n \n 1 \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
2009-08-31 20:36:25 +02:00
}
2009-07-22 18:47:50 +02:00
}
2009-10-10 22:23:48 +02:00
2010-04-15 18:37:51 +02:00
void redundant_config ( )
{
const char filedata [ ] = " int main() { \n "
" #ifdef FOO \n "
" #ifdef BAR \n "
" std::cout << 1; \n "
" #endif \n "
" #endif \n "
" \n "
" #ifdef BAR \n "
" #ifdef FOO \n "
" std::cout << 2; \n "
" #endif \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 ( 4U , actual . size ( ) ) ;
ASSERT ( actual . find ( " " ) ! = actual . end ( ) ) ;
ASSERT ( actual . find ( " BAR " ) ! = actual . end ( ) ) ;
ASSERT ( actual . find ( " FOO " ) ! = actual . end ( ) ) ;
ASSERT ( actual . find ( " BAR;FOO " ) ! = actual . end ( ) ) ;
}
2009-10-10 22:23:48 +02:00
void endfile ( )
{
const char filedata [ ] = " char a[] = \" #endfile \" ; \n "
" char b[] = \" #endfile \" ; \n "
" #include \" notfound.h \" \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 ( " char a[] = \" #endfile \" ; \n char b[] = \" #endfile \" ; \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( 1 , actual . size ( ) ) ;
}
2008-12-18 22:28:57 +01:00
} ;
2009-01-05 16:49:57 +01:00
REGISTER_TEST ( TestPreprocessor )