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
2015-01-03 12:14:58 +01:00
* Copyright ( C ) 2007 - 2015 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"
2010-07-26 22:05:17 +02:00
# include "settings.h"
2008-12-18 22:28:57 +01:00
# include <map>
# include <string>
2013-10-27 10:33:37 +01:00
# include <set>
2008-12-18 22:28:57 +01:00
2009-04-03 21:09:12 +02:00
2012-07-18 00:48:45 +02:00
# ifdef _MSC_VER
2012-06-10 15:51:56 +02:00
// Visual Studio complains about truncated values for '(char)0xff' and '(char)0xfe'
// TODO: Is there any nice way to fix these warnings?
# pragma warning( disable : 4310 )
2012-07-18 00:48:45 +02:00
# endif
2012-06-10 15:51:56 +02:00
2011-10-13 20:53:06 +02:00
class TestPreprocessor : public TestFixture {
2008-12-18 22:28:57 +01:00
public :
2014-11-20 14:20:09 +01:00
TestPreprocessor ( ) : TestFixture ( " TestPreprocessor " ) {
2012-03-27 19:35:41 +02:00
Preprocessor : : macroChar = ' $ ' ;
}
2008-12-18 22:28:57 +01:00
2011-10-13 20:53:06 +02:00
class OurPreprocessor : public Preprocessor {
2009-02-07 21:06:00 +01:00
public :
2015-03-12 21:16:54 +01:00
static std : : string replaceIfDefined ( const char str [ ] ) {
2013-07-24 13:06:59 +02:00
Preprocessor p ;
2015-03-12 21:16:54 +01:00
std : : string ret ( str ) ;
p . replaceIfDefined ( ret ) ;
return ret ;
2009-02-07 21:06:00 +01:00
}
2015-03-12 21:16:54 +01:00
static std : : string expandMacros ( const char code [ ] , ErrorLogger * errorLogger = 0 ) {
2012-02-05 20:48:28 +01:00
return Preprocessor : : expandMacros ( code , " file.cpp " , " " , errorLogger ) ;
2009-02-07 21:06:00 +01:00
}
2009-05-22 22:59:07 +02:00
2014-11-20 14:20:09 +01: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 :
2014-11-20 14:20:09 +01:00
void run ( ) {
2008-12-18 22:28:57 +01:00
// Just read the code into a string. Perform simple cleanup of the code
2010-09-13 19:36:40 +02:00
TEST_CASE ( readCode1 ) ;
2012-11-30 13:46:46 +01:00
TEST_CASE ( readCode2 ) ; // #4308 - convert C++11 raw string to plain old C string
2012-09-12 16:10:45 +02:00
TEST_CASE ( readCode3 ) ;
2012-12-02 18:04:19 +01:00
TEST_CASE ( readCode4 ) ; // #4351 - escaped whitespace in gcc
2008-12-18 22:28:57 +01:00
2012-06-10 11:00:27 +02:00
// reading utf-16 file
TEST_CASE ( utf16 ) ;
2012-09-30 09:35:32 +02:00
// remove comments
TEST_CASE ( removeComments ) ;
2008-12-18 22:28:57 +01:00
// 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 ) ;
2011-02-07 20:26:29 +01:00
TEST_CASE ( test7a ) ;
TEST_CASE ( test7b ) ;
TEST_CASE ( test7c ) ;
TEST_CASE ( test7d ) ;
TEST_CASE ( test7e ) ;
2012-02-29 19:08:01 +01:00
TEST_CASE ( test8 ) ; // #if A==1 => cfg: A=1
2013-10-18 06:47:55 +02:00
TEST_CASE ( test9 ) ; // Don't crash for invalid code
2013-11-01 11:14:50 +01:00
TEST_CASE ( test10 ) ; // Ticket #5139
2009-11-13 22:12:29 +01:00
2009-12-22 20:38:12 +01:00
2014-06-18 17:26:51 +02:00
TEST_CASE ( error1 ) ; // #error => don't extract any code
TEST_CASE ( error2 ) ; // #error with extended chars
2010-09-12 21:30:47 +02:00
TEST_CASE ( error3 ) ;
2011-08-03 07:28:37 +02:00
TEST_CASE ( error4 ) ; // #2919 - wrong filename is reported
2014-06-18 17:26:51 +02:00
TEST_CASE ( error5 ) ;
2010-09-12 21:30:47 +02:00
2011-03-01 07:30:42 +01:00
TEST_CASE ( if0_exclude ) ;
2011-03-01 07:32:47 +01:00
TEST_CASE ( if0_whitespace ) ;
2011-03-01 08:04:11 +01:00
TEST_CASE ( if0_else ) ;
2011-03-01 08:17:54 +01:00
TEST_CASE ( if0_elif ) ;
2011-03-01 07:30:42 +01:00
2011-02-26 19:04:38 +01:00
// Don't handle include in a #if 0 block
TEST_CASE ( if0_include_1 ) ;
TEST_CASE ( if0_include_2 ) ;
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-12-15 20:18:32 +01:00
TEST_CASE ( if_cond8 ) ;
2010-01-09 21:54:20 +01:00
TEST_CASE ( if_cond9 ) ;
2010-08-17 20:06:20 +02:00
TEST_CASE ( if_cond10 ) ;
2010-09-02 23:01:12 +02:00
TEST_CASE ( if_cond11 ) ;
2011-02-20 20:11:51 +01:00
TEST_CASE ( if_cond12 ) ;
2011-11-03 20:01:31 +01:00
TEST_CASE ( if_cond13 ) ;
2012-03-26 19:01:45 +02:00
TEST_CASE ( if_cond14 ) ;
2013-01-03 08:44:32 +01:00
TEST_CASE ( if_cond15 ) ; // #4456 - segfault
2008-12-18 22:28:57 +01:00
2010-08-26 21:33:45 +02:00
TEST_CASE ( if_or_1 ) ;
TEST_CASE ( if_or_2 ) ;
2009-12-13 17:18:27 +01:00
2012-03-15 20:04:34 +01:00
TEST_CASE ( if_macro_eq_macro ) ; // #3536
2012-03-23 00:45:47 +01:00
TEST_CASE ( ticket_3675 ) ;
2012-04-22 06:49:42 +02:00
TEST_CASE ( ticket_3699 ) ;
2013-08-04 14:34:28 +02:00
TEST_CASE ( ticket_4922 ) ; // #4922
2012-03-15 20:04:34 +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-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 ) ;
2011-02-11 06:30:42 +01:00
TEST_CASE ( macro_simple14 ) ;
2011-02-11 18:01:27 +01:00
TEST_CASE ( macro_simple15 ) ;
2013-08-10 23:28:02 +02:00
TEST_CASE ( macro_simple16 ) ; // #4703: Macro parameters not trimmed
2013-10-13 17:42:06 +02:00
TEST_CASE ( macro_simple17 ) ; // #5074: isExpandedMacro not set
2013-12-29 21:51:01 +01:00
TEST_CASE ( macro_simple18 ) ; // (1e-7)
2011-04-07 16:53:42 +02:00
TEST_CASE ( macroInMacro1 ) ;
TEST_CASE ( macroInMacro2 ) ;
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 ) ;
2013-01-13 15:01:31 +01:00
TEST_CASE ( macro_NULL ) ; // skip #define NULL .. it is replaced in the tokenizer
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 ) ;
2011-01-02 10:09:50 +01:00
TEST_CASE ( va_args_1 ) ;
TEST_CASE ( va_args_2 ) ;
TEST_CASE ( va_args_3 ) ;
TEST_CASE ( va_args_4 ) ;
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 ) ;
2013-08-18 18:04:06 +02:00
TEST_CASE ( pragma_once ) ;
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 ) ;
2011-01-30 09:09:12 +01:00
TEST_CASE ( dup_defines ) ;
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
2011-07-18 21:44:23 +02:00
TEST_CASE ( define_if1 ) ;
TEST_CASE ( define_if2 ) ;
2011-11-17 19:19:43 +01:00
TEST_CASE ( define_if3 ) ;
2012-11-28 07:33:24 +01:00
TEST_CASE ( define_if4 ) ; // #4079 - #define X +123
2013-01-26 12:37:46 +01:00
TEST_CASE ( define_if5 ) ; // #4516 - #define B (A & 0x00f0)
2013-06-19 21:29:39 +02:00
TEST_CASE ( define_if6 ) ; // #4863 - #define B (A?-1:1)
2009-07-22 18:47:50 +02:00
TEST_CASE ( define_ifdef ) ;
2010-09-14 17:45:37 +02:00
TEST_CASE ( define_ifndef1 ) ;
TEST_CASE ( define_ifndef2 ) ;
2012-05-04 17:53:47 +02:00
TEST_CASE ( ifndef_define ) ;
2012-01-24 07:43:26 +01:00
TEST_CASE ( undef_ifdef ) ;
2009-10-10 22:23:48 +02:00
TEST_CASE ( endfile ) ;
2010-04-15 18:37:51 +02:00
TEST_CASE ( redundant_config ) ;
2011-02-11 06:30:42 +01:00
TEST_CASE ( testPreprocessorRead1 ) ;
TEST_CASE ( testPreprocessorRead2 ) ;
TEST_CASE ( testPreprocessorRead3 ) ;
TEST_CASE ( testPreprocessorRead4 ) ;
2011-02-22 19:55:02 +01:00
2012-09-05 20:50:25 +02:00
TEST_CASE ( invalid_define_1 ) ; // #2605 - hang for: '#define ='
TEST_CASE ( invalid_define_2 ) ; // #4036 - hang for: '#define () {(int f(x) }'
2011-04-22 20:25:17 +02:00
2011-11-06 08:59:07 +01:00
// Show 'missing include' warnings
TEST_CASE ( missingInclude ) ;
2011-04-22 20:25:17 +02:00
// inline suppression, missingInclude
TEST_CASE ( inline_suppression_for_missing_include ) ;
2011-07-16 09:24:27 +02:00
// Using -D to predefine symbols
TEST_CASE ( predefine1 ) ;
TEST_CASE ( predefine2 ) ;
2011-07-16 16:59:06 +02:00
TEST_CASE ( predefine3 ) ;
2012-02-05 20:48:28 +01:00
TEST_CASE ( predefine4 ) ;
2012-05-08 20:49:43 +02:00
TEST_CASE ( predefine5 ) ; // automatically define __cplusplus
2013-06-08 16:46:54 +02:00
TEST_CASE ( predefine6 ) ; // using -D and -f => check all matching configurations
2011-07-20 23:50:57 +02:00
// Test Preprocessor::simplifyCondition
TEST_CASE ( simplifyCondition ) ;
2011-08-02 21:06:27 +02:00
TEST_CASE ( invalidElIf ) ; // #2942 segfault
2011-10-17 20:12:46 +02:00
2011-11-02 20:29:14 +01:00
// Defines are given: test Preprocessor::handleIncludes
TEST_CASE ( def_handleIncludes ) ;
TEST_CASE ( def_missingInclude ) ;
2012-09-15 09:34:41 +02:00
TEST_CASE ( def_handleIncludes_ifelse1 ) ; // problems in handleIncludes for #else
TEST_CASE ( def_handleIncludes_ifelse2 ) ;
2013-06-21 20:10:46 +02:00
TEST_CASE ( def_handleIncludes_ifelse3 ) ; // #4868 - crash
2011-11-30 20:24:01 +01:00
2013-01-16 15:37:07 +01:00
TEST_CASE ( def_valueWithParentheses ) ; // #3531
2012-01-21 12:51:54 +01:00
2011-11-30 20:24:01 +01:00
// Using -U to undefine symbols
TEST_CASE ( undef1 ) ;
TEST_CASE ( undef2 ) ;
TEST_CASE ( undef3 ) ;
TEST_CASE ( undef4 ) ;
TEST_CASE ( undef5 ) ;
TEST_CASE ( undef6 ) ;
TEST_CASE ( undef7 ) ;
2011-12-09 21:57:06 +01:00
TEST_CASE ( undef8 ) ;
TEST_CASE ( undef9 ) ;
2012-07-18 20:57:00 +02:00
TEST_CASE ( undef10 ) ;
TEST_CASE ( handleUndef ) ;
2011-11-30 20:24:01 +01:00
2012-03-27 19:35:41 +02:00
TEST_CASE ( macroChar ) ;
2012-07-10 20:29:04 +02:00
TEST_CASE ( validateCfg ) ;
2012-08-22 17:28:06 +02:00
TEST_CASE ( if_sizeof ) ;
2014-04-23 20:50:16 +02:00
TEST_CASE ( double_include ) ; // #5717
2015-05-12 14:00:43 +02:00
TEST_CASE ( invalid_ifs ) ; // #5909
TEST_CASE ( garbage ) ;
2008-12-18 22:28:57 +01:00
}
2014-11-20 14:20:09 +01:00
void readCode1 ( ) {
2008-12-18 22:28:57 +01:00
const char code [ ] = " \t a // \n "
" #aa \t /* remove this */ \t b \r \n " ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2008-12-18 22:28:57 +01:00
std : : istringstream istr ( code ) ;
2012-01-05 18:37:15 +01:00
std : : string codestr ( preprocessor . read ( istr , " test.c " ) ) ;
2011-02-11 06:30:42 +01:00
ASSERT_EQUALS ( " a \n #aa b \n " , codestr ) ;
2008-12-18 22:28:57 +01:00
}
2014-11-20 14:20:09 +01:00
void readCode2 ( ) {
2012-11-30 13:46:46 +01:00
const char code [ ] = " R \" ( \" /* abc */ \n ) \" ; " ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-09-13 19:36:40 +02:00
std : : istringstream istr ( code ) ;
2012-01-05 18:37:15 +01:00
std : : string codestr ( preprocessor . read ( istr , " test.c " ) ) ;
2012-11-30 13:46:46 +01:00
ASSERT_EQUALS ( " \" \\ \" /* abc */ \\ n \" \n ; " , codestr ) ;
2010-09-13 19:36:40 +02:00
}
2014-11-20 14:20:09 +01:00
void readCode3 ( ) {
2012-09-12 16:10:45 +02:00
const char code [ ] = " func(#errorname) " ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream istr ( code ) ;
std : : string codestr ( preprocessor . read ( istr , " test.c " ) ) ;
ASSERT_EQUALS ( " func(#errorname) " , codestr ) ;
}
2014-11-20 14:20:09 +01:00
void readCode4 ( ) {
2012-12-02 18:04:19 +01:00
const char code [ ] = " char c = ' \\ '; " ;
Settings settings ;
2013-03-30 13:49:56 +01:00
errout . str ( " " ) ;
2012-12-02 18:04:19 +01:00
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream istr ( code ) ;
ASSERT_EQUALS ( " char c = ' \\ '; " , preprocessor . read ( istr , " test.c " ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
void utf16 ( ) {
2012-06-10 11:00:27 +02:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
// a => a
{
const char code [ ] = { ( char ) 0xff , ( char ) 0xfe , ' a ' , ' \0 ' } ;
std : : string s ( code , sizeof ( code ) ) ;
std : : istringstream istr ( s ) ;
ASSERT_EQUALS ( " a " , preprocessor . read ( istr , " test.c " ) ) ;
}
{
const char code [ ] = { ( char ) 0xfe , ( char ) 0xff , ' \0 ' , ' a ' } ;
std : : string s ( code , sizeof ( code ) ) ;
std : : istringstream istr ( s ) ;
ASSERT_EQUALS ( " a " , preprocessor . read ( istr , " test.c " ) ) ;
}
// extended char => 0xff
{
const char code [ ] = { ( char ) 0xff , ( char ) 0xfe , ' a ' , ' a ' } ;
std : : string s ( code , sizeof ( code ) ) ;
std : : istringstream istr ( s ) ;
const char expected [ ] = { ( char ) 0xff , 0 } ;
ASSERT_EQUALS ( expected , preprocessor . read ( istr , " test.c " ) ) ;
}
{
const char code [ ] = { ( char ) 0xfe , ( char ) 0xff , ' a ' , ' a ' } ;
std : : string s ( code , sizeof ( code ) ) ;
std : : istringstream istr ( s ) ;
const char expected [ ] = { ( char ) 0xff , 0 } ;
ASSERT_EQUALS ( expected , preprocessor . read ( istr , " test.c " ) ) ;
}
// \r\n => \n
{
const char code [ ] = { ( char ) 0xff , ( char ) 0xfe , ' \r ' , ' \0 ' , ' \n ' , ' \0 ' } ;
std : : string s ( code , sizeof ( code ) ) ;
std : : istringstream istr ( s ) ;
ASSERT_EQUALS ( " \n " , preprocessor . read ( istr , " test.c " ) ) ;
}
{
const char code [ ] = { ( char ) 0xfe , ( char ) 0xff , ' \0 ' , ' \r ' , ' \0 ' , ' \n ' } ;
std : : string s ( code , sizeof ( code ) ) ;
std : : istringstream istr ( s ) ;
ASSERT_EQUALS ( " \n " , preprocessor . read ( istr , " test.c " ) ) ;
}
}
2014-11-20 14:20:09 +01:00
void removeComments ( ) {
2012-09-30 09:35:32 +02:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
// #3837 - asm comments
const char code [ ] = " void test(void) { \n "
" __asm \n "
" { \n "
" ;---- тест \n "
" } \n "
" } \n " ;
ASSERT_EQUALS ( true , std : : string : : npos = = preprocessor . removeComments ( code , " 3837.c " ) . find ( " ---- " ) ) ;
ASSERT_EQUALS ( " __asm123 " , preprocessor . removeComments ( " __asm123 " , " 3837.cpp " ) ) ;
ASSERT_EQUALS ( " \" __asm { ; } \" " , preprocessor . removeComments ( " \" __asm { ; } \" " , " 3837.cpp " ) ) ;
2012-11-04 12:21:34 +01:00
ASSERT_EQUALS ( " __asm__ volatile { \" \" } " , preprocessor . removeComments ( " __asm__ volatile { \" \" } " , " 3837.cpp " ) ) ;
2013-06-25 06:45:11 +02:00
// #4873
ASSERT_EQUALS ( " __asm { } " , preprocessor . removeComments ( " __asm { /* This is a comment */ } " , " 4873.cpp " ) ) ;
2014-01-01 12:44:59 +01:00
// #5169
ASSERT_EQUALS ( " #define A(B) __asm__( \" int $3 \" ); int wait=1; \n " ,
preprocessor . removeComments ( " #define A(B) __asm__( \" int $3 \" ); /**/ int wait=1; \n " , " 5169.c " ) ) ;
2012-09-30 09:35:32 +02:00
}
2014-11-20 14:20:09 +01:00
void Bug2190219 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
}
2014-11-20 14:20:09 +01:00
void test1 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
}
2014-11-20 14:20:09 +01:00
void test2 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-01-21 22:03:46 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2008-12-18 22:28:57 +01:00
// Compare results..
2011-02-11 06:30:42 +01: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
}
2014-11-20 14:20:09 +01:00
void test3 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
}
2014-11-20 14:20:09 +01:00
void test4 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
}
2014-11-20 14:20:09 +01:00
void test5 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
}
2014-11-20 14:20:09 +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 ) ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
const std : : string actual ( preprocessor . read ( istr , " test.c " ) ) ;
2009-01-24 20:28:30 +01:00
// 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
}
2014-11-20 14:20:09 +01:00
void test7 ( ) {
2009-08-12 20:28:43 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-08-12 20:28:43 +02:00
errout . str ( " " ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Make sure an error message is written..
2011-02-07 20:26:29 +01:00
TODO_ASSERT_EQUALS ( " [file.c:3]: (error) ABC is already guaranteed to be defined \n " ,
" " ,
errout . str ( ) ) ;
2009-08-12 20:28:43 +02:00
// 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 ( ) ) ) ;
2011-01-30 19:47:17 +01:00
test7a ( ) ;
test7b ( ) ;
test7c ( ) ;
test7d ( ) ;
}
2014-11-20 14:20:09 +01:00
void test7a ( ) {
2011-01-30 19:47:17 +01:00
const char filedata [ ] = " #ifndef ABC \n "
" A \n "
" #ifndef ABC \n "
" B \n "
" #endif \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
errout . str ( " " ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Make sure an error message is written..
TODO_ASSERT_EQUALS ( " [file.c:3]: (error) ABC is already guaranteed NOT to be defined \n " ,
" " , errout . str ( ) ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2014-11-20 14:20:09 +01:00
void test7b ( ) {
2011-01-30 19:47:17 +01:00
const char filedata [ ] = " #ifndef 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 ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
errout . str ( " " ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Make sure an error message is written..
TODO_ASSERT_EQUALS ( " [file.c:3]: (error) ABC is already guaranteed NOT to be defined \n " ,
" " , errout . str ( ) ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2014-11-20 14:20:09 +01:00
void test7c ( ) {
2011-01-30 19:47:17 +01:00
const char filedata [ ] = " #ifdef ABC \n "
" A \n "
" #ifndef ABC \n "
" B \n "
" #endif \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
errout . str ( " " ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Make sure an error message is written..
2011-02-07 20:26:29 +01:00
TODO_ASSERT_EQUALS ( " [file.c:3]: (error) ABC is already guaranteed to be defined \n " ,
" " ,
errout . str ( ) ) ;
2011-01-30 19:47:17 +01:00
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2014-11-20 14:20:09 +01:00
void test7d ( ) {
2011-01-30 19:47:17 +01:00
const char filedata [ ] = " #if defined(ABC) \n "
" A \n "
" #if defined(ABC) \n "
" B \n "
" #endif \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
errout . str ( " " ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Make sure an error message is written..
2011-02-07 20:26:29 +01:00
TODO_ASSERT_EQUALS ( " [file.c:3]: (error) ABC is already guaranteed to be defined \n " ,
" " ,
errout . str ( ) ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
}
2014-11-20 14:20:09 +01:00
void test7e ( ) {
2011-02-07 20:26:29 +01:00
const char filedata [ ] = " #ifdef ABC \n "
" #file \" test.h \" \n "
" #ifndef test_h \n "
" #define test_h \n "
" #ifdef ABC \n "
" #endif \n "
" #endif \n "
" #endfile \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
errout . str ( " " ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Make sure an error message is written..
ASSERT_EQUALS ( " " ,
2011-01-31 17:26:07 +01:00
errout . str ( ) ) ;
2011-01-30 19:47:17 +01:00
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2009-08-12 20:28:43 +02:00
}
2014-11-20 14:20:09 +01:00
void test8 ( ) {
2012-03-01 20:24:00 +01:00
const char filedata [ ] = " #if A == 1 \n "
2012-02-29 19:08:01 +01:00
" 1 \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
errout . str ( " " ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// No error..
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// Compare results..
ASSERT_EQUALS ( 2U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n 1 \n \n " , actual [ " A=1 " ] ) ;
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
void test9 ( ) {
2013-10-18 06:47:55 +02:00
const char filedata [ ] = " #if \n "
" #else \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
settings . _maxConfigs = 1 ;
settings . userDefines = " X " ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ; // <- don't crash
}
2013-11-02 22:58:47 +01:00
2014-11-20 14:20:09 +01:00
void test10 ( ) { // Ticket #5139
2013-11-01 11:14:50 +01:00
const char filedata [ ] = " #define foo a.foo \n "
" #define bar foo \n "
" #define baz bar+0 \n "
" #if 0 \n "
" #endif " ;
2013-11-02 22:58:47 +01:00
2013-11-01 11:14:50 +01:00
// 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 " ) ;
}
2013-10-18 06:47:55 +02:00
2014-11-20 14:20:09 +01:00
void error1 ( ) {
2009-11-13 22:12:29 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-11-13 22:12:29 +01:00
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 " ] ) ;
}
2014-11-20 14:20:09 +01:00
void error2 ( ) {
2011-08-03 07:28:37 +02:00
errout . str ( " " ) ;
2012-09-04 16:29:06 +02:00
const char filedata [ ] = " #error \xAB \n "
" #warning \xAB \n "
2009-12-22 20:38:12 +01:00
" 123 " ;
// Read string..
std : : istringstream istr ( filedata ) ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #error \n \n 123 " , preprocessor . read ( istr , " test.c " ) ) ;
2009-12-22 20:38:12 +01:00
}
2014-11-20 14:20:09 +01:00
void error3 ( ) {
2011-08-03 07:28:37 +02:00
errout . str ( " " ) ;
2010-09-12 21:30:47 +02:00
Settings settings ;
settings . userDefines = " __cplusplus " ;
2012-01-06 08:01:50 +01:00
Preprocessor preprocessor ( & settings , this ) ;
2010-09-12 21:30:47 +02:00
const std : : string code ( " #error hello world! \n " ) ;
2012-01-06 08:01:50 +01:00
preprocessor . getcode ( code , " X " , " test.c " ) ;
2010-09-12 21:30:47 +02:00
ASSERT_EQUALS ( " [test.c:1]: (error) #error hello world! \n " , errout . str ( ) ) ;
}
2011-08-03 07:28:37 +02:00
// Ticket #2919 - wrong filename reported for #error
2014-11-20 14:20:09 +01:00
void error4 ( ) {
2011-08-03 07:28:37 +02:00
// In included file
{
errout . str ( " " ) ;
Settings settings ;
settings . userDefines = " TEST " ;
2012-01-06 08:01:50 +01:00
Preprocessor preprocessor ( & settings , this ) ;
2011-08-03 07:28:37 +02:00
const std : : string code ( " #file \" ab.h \" \n #error hello world! \n #endfile " ) ;
2012-01-06 08:01:50 +01:00
preprocessor . getcode ( code , " TEST " , " test.c " ) ;
2011-08-03 07:28:37 +02:00
ASSERT_EQUALS ( " [ab.h:1]: (error) #error hello world! \n " , errout . str ( ) ) ;
}
// After including a file
{
errout . str ( " " ) ;
Settings settings ;
settings . userDefines = " TEST " ;
2012-01-06 08:01:50 +01:00
Preprocessor preprocessor ( & settings , this ) ;
2011-08-03 07:28:37 +02:00
const std : : string code ( " #file \" ab.h \" \n \n #endfile \n #error aaa " ) ;
2012-01-06 08:01:50 +01:00
preprocessor . getcode ( code , " TEST " , " test.c " ) ;
2011-08-03 07:28:37 +02:00
ASSERT_EQUALS ( " [test.c:2]: (error) #error aaa \n " , errout . str ( ) ) ;
}
}
2014-11-20 14:20:09 +01:00
void error5 ( ) {
2014-06-18 17:26:51 +02:00
errout . str ( " " ) ;
Settings settings ;
settings . userDefines = " FOO " ;
settings . _force = true ; // No message if --force is given
Preprocessor preprocessor ( & settings , this ) ;
const std : : string code ( " #error hello world! \n " ) ;
preprocessor . getcode ( code , " X " , " test.c " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void if0_exclude ( ) {
2011-03-01 07:30:42 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream code ( " #if 0 \n "
" A \n "
" #endif \n "
" B \n " ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #if 0 \n \n #endif \n B \n " , preprocessor . read ( code , " " ) ) ;
2011-03-01 07:50:17 +01:00
std : : istringstream code2 ( " #if (0) \n "
2011-03-01 17:58:15 +01:00
" A \n "
" #endif \n "
" B \n " ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #if 0 \n \n #endif \n B \n " , preprocessor . read ( code2 , " " ) ) ;
2011-03-01 07:30:42 +01:00
}
2014-11-20 14:20:09 +01:00
void if0_whitespace ( ) {
2011-03-01 07:32:47 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream code ( " # if 0 \n "
" A \n "
" # endif \n "
" B \n " ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #if 0 \n \n #endif \n B \n " , preprocessor . read ( code , " " ) ) ;
2011-03-01 08:04:11 +01:00
}
2014-11-20 14:20:09 +01:00
void if0_else ( ) {
2011-03-01 08:04:11 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream code ( " #if 0 \n "
" A \n "
" #else \n "
" B \n "
" #endif \n "
" C \n " ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #if 0 \n \n #else \n B \n #endif \n C \n " , preprocessor . read ( code , " " ) ) ;
2011-03-01 08:17:54 +01:00
std : : istringstream code2 ( " #if 1 \n "
" A \n "
" #else \n "
" B \n "
" #endif \n "
" C \n " ) ;
TODO_ASSERT_EQUALS ( " #if 1 \n A \n #else \n \n #endif \n C \n " ,
2012-01-05 18:37:15 +01:00
" #if 1 \n A \n #else \n B \n #endif \n C \n " , preprocessor . read ( code2 , " " ) ) ;
2011-03-01 08:17:54 +01:00
}
2014-11-20 14:20:09 +01:00
void if0_elif ( ) {
2011-03-01 08:17:54 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream code ( " #if 0 \n "
" A \n "
" #elif 1 \n "
" B \n "
" #endif \n "
" C \n " ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #if 0 \n \n #elif 1 \n B \n #endif \n C \n " , preprocessor . read ( code , " " ) ) ;
2011-03-01 07:32:47 +01:00
}
2014-11-20 14:20:09 +01:00
void if0_include_1 ( ) {
2011-02-26 19:04:38 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream code ( " #if 0 \n "
" #include \" a.h \" \n "
" #endif \n "
" AB \n " ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #if 0 \n \n #endif \n AB \n " , preprocessor . read ( code , " " ) ) ;
2011-02-26 19:04:38 +01:00
}
2014-11-20 14:20:09 +01:00
void if0_include_2 ( ) {
2011-02-26 19:04:38 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream code ( " #if 0 \n "
" #include \" a.h \" \n "
" #ifdef WIN32 \n "
" #else \n "
" #endif \n "
" #endif \n "
" AB \n " ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #if 0 \n \n #ifdef WIN32 \n #else \n #endif \n #endif \n AB \n " , preprocessor . read ( code , " " ) ) ;
2011-02-26 19:04:38 +01:00
}
2010-09-12 21:30:47 +02:00
2014-11-20 14:20:09 +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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-01-22 19:19:17 +01:00
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
}
2014-11-20 14:20:09 +01:00
void includeguard2 ( ) {
2010-02-06 09:30:48 +01:00
// 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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-02-06 09:30:48 +01:00
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 ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void ifdefwithfile ( ) {
2009-03-08 08:45:53 +01:00
// 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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-03-08 08:45:53 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// 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
2014-11-20 14:20:09 +01:00
void newlines ( ) {
2009-01-12 07:33:06 +01:00
const char filedata [ ] = " \r \r \n \n " ;
// Preprocess
std : : istringstream istr ( filedata ) ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " \n \n \n " , preprocessor . read ( istr , " test.c " ) ) ;
2009-01-12 07:33:06 +01:00
}
2014-11-20 14:20:09 +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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-05-13 21:18:02 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-05-13 21:18:02 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-05-14 21:53:49 +02:00
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
}
2014-11-20 14:20:09 +01:00
void if0 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
}
2014-11-20 14:20:09 +01:00
void if1 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
}
2014-11-20 14:20:09 +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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-03-28 14:15:25 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-03-28 14:15:25 +02:00
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
}
2014-11-20 14:20:09 +01:00
void match_cfg_def ( ) {
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:15:48 +01:00
2009-12-11 19:28:37 +01:00
{
std : : map < std : : string , std : : string > cfg ;
2012-01-06 08:15:48 +01:00
ASSERT_EQUALS ( false , preprocessor . match_cfg_def ( cfg , " A>1||defined(B) " ) ) ;
2009-12-11 19:28:37 +01:00
}
{
std : : map < std : : string , std : : string > cfg ;
cfg [ " A " ] = " " ;
cfg [ " B " ] = " " ;
2012-01-06 08:15:48 +01:00
ASSERT_EQUALS ( true , preprocessor . match_cfg_def ( cfg , " defined(A)&&defined(B) " ) ) ;
2009-12-11 19:28:37 +01:00
}
2009-07-30 10:10:34 +02:00
{
std : : map < std : : string , std : : string > cfg ;
cfg [ " ABC " ] = " " ;
2012-01-06 08:15:48 +01:00
ASSERT_EQUALS ( false , preprocessor . match_cfg_def ( cfg , " defined(A) " ) ) ;
ASSERT_EQUALS ( true , preprocessor . match_cfg_def ( cfg , " !defined(A) " ) ) ;
2009-07-25 17:04:13 +02:00
2012-01-06 08:15:48 +01:00
ASSERT_EQUALS ( false , preprocessor . match_cfg_def ( cfg , " !defined(ABC)&&!defined(DEF) " ) ) ;
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 " ;
2012-01-06 08:15:48 +01:00
ASSERT_EQUALS ( true , preprocessor . match_cfg_def ( cfg , " A==1 " ) ) ;
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 " ) ) ;
ASSERT_EQUALS ( false , preprocessor . match_cfg_def ( cfg , " A>=1&&B<=A " ) ) ;
ASSERT_EQUALS ( true , preprocessor . match_cfg_def ( cfg , " A==1 && A==1 " ) ) ;
2009-07-30 10:10:34 +02:00
}
2009-07-25 16:22:42 +02:00
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
void if_cond1 ( ) {
2008-12-18 22:28:57 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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 [ " " ] ) ;
2011-01-30 12:54:19 +01:00
TODO_ASSERT_EQUALS ( " \n A \n \n \n \n " ,
" " , actual [ " LIBVER=101 " ] ) ;
2008-12-18 22:28:57 +01:00
}
2014-11-20 14:20:09 +01:00
void if_cond2 ( ) {
2009-06-26 13:19:55 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-06-26 13:19:55 +02:00
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 ( ) ;
2011-01-31 00:33:44 +01:00
if_cond2e ( ) ;
2010-03-19 16:13:45 +01:00
}
2014-11-20 14:20:09 +01:00
void if_cond2b ( ) {
2010-03-19 16:13:45 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-03-19 16:13:45 +01:00
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 " ] ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond2c ( ) {
2010-03-19 16:13:45 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-03-19 16:13:45 +01:00
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 " ] ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond2d ( ) {
2010-03-19 16:13:45 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-03-19 16:13:45 +01:00
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
}
2014-11-20 14:20:09 +01:00
void if_cond2e ( ) {
2011-01-31 00:33:44 +01:00
const char filedata [ ] = " #if !defined(A) \n "
" !a \n "
" #elif !defined(B) \n "
" !b \n "
" #endif \n " ;
// Preprocess => actual result..
errout . str ( " " ) ;
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
settings . debug = settings . debugwarnings = true ;
Preprocessor preprocessor ( & settings , this ) ;
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 " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n \n \n !b \n \n " , actual [ " A " ] ) ;
TODO_ASSERT_EQUALS ( " \n \n \n \n \n " , " " , actual [ " A;B " ] ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond3 ( ) {
2009-06-26 13:19:55 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-06-26 13:19:55 +02:00
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 " ] ) ;
}
2014-11-20 14:20:09 +01: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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-10-06 10:47:36 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-10-06 10:47:36 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-10-06 10:47:36 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-10-06 10:47:36 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-03-04 18:51:25 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
2011-01-30 12:54:19 +01:00
TODO_ASSERT_EQUALS ( 2 , 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2010-03-04 18:51:25 +01:00
ASSERT_EQUALS ( " \n foo(); \n \n " , actual [ " " ] ) ;
}
2009-07-22 20:11:27 +02:00
}
2009-06-26 13:19:55 +02:00
2014-11-20 14:20:09 +01:00
void if_cond5 ( ) {
2009-08-29 23:00:54 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-08-29 23:00:54 +02:00
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
2014-11-20 14:20:09 +01:00
void if_cond6 ( ) {
2009-11-20 19:18:57 +01:00
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 ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond8 ( ) {
2009-12-15 20:18:32 +01:00
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..
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 1 , ( int ) actual . size ( ) ) ;
2009-12-15 20:18:32 +01:00
ASSERT_EQUALS ( " \n \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond9 ( ) {
2010-01-09 21:54:20 +01:00
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..
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 1 , ( int ) actual . size ( ) ) ;
2010-01-09 21:54:20 +01:00
ASSERT_EQUALS ( " \n abc \n \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond10 ( ) {
2010-08-17 20:06:20 +02:00
const char filedata [ ] = " #if !defined(a) && !defined(b) \n "
" #if defined(and) \n "
" #endif \n "
" #endif \n " ;
// Preprocess => don't crash..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond11 ( ) {
2010-09-02 23:01:12 +02:00
errout . str ( " " ) ;
const char filedata [ ] = " #if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE \n "
" #if LIBGCC2_HAS_DF_MODE \n "
" #elif FLT_MANT_DIG < W_TYPE_SIZE \n "
" #endif \n "
" #endif \n " ;
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond12 ( ) {
2011-02-20 20:11:51 +01:00
const char filedata [ ] = " #define A (1) \n "
" #if A == 1 \n "
" ; \n "
" #endif \n " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n \n ; \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
2011-02-20 20:11:51 +01:00
}
2014-11-20 14:20:09 +01:00
void if_cond13 ( ) {
2011-11-03 20:01:31 +01:00
const char filedata [ ] = " #if ('A' == 0x41) \n "
" 123 \n "
" #endif \n " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-03-26 19:01:45 +02:00
ASSERT_EQUALS ( " \n 123 \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
}
2014-11-20 14:20:09 +01:00
void if_cond14 ( ) {
2012-03-26 19:01:45 +02:00
const char filedata [ ] = " #if !(A) \n "
" 123 \n "
" #endif \n " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n 123 \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
2011-11-03 20:01:31 +01:00
}
2014-11-20 14:20:09 +01:00
void if_cond15 ( ) { // #4456 - segmentation fault
2013-01-03 08:44:32 +01:00
const char filedata [ ] = " #if ((A >= B) && (C != D)) \n "
" #if (E < F(1)) \n "
" #endif \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 , " 4456.c " ) ; // <- don't crash in Preprocessor::getcfgs -> Tokenize -> number of template parameters
}
2010-01-09 21:54:20 +01:00
2009-12-15 20:18:32 +01:00
2014-11-20 14:20:09 +01:00
void if_or_1 ( ) {
2009-12-13 17:18:27 +01:00
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 ;
2010-08-27 20:28:00 +02:00
settings . debug = settings . debugwarnings = true ;
2013-04-09 13:57:42 +02:00
settings . addEnabled ( " missingInclude " ) ;
2009-12-13 17:18:27 +01:00
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 1 , ( int ) actual . size ( ) ) ;
2009-12-13 17:18:27 +01:00
ASSERT_EQUALS ( " \n \n \n " , actual [ " " ] ) ;
// the "defined(DEF_10) || defined(DEF_11)" are not handled correctly..
2010-08-27 20:28:00 +02:00
ASSERT_EQUALS ( " (debug) unhandled configuration: defined(DEF_10)||defined(DEF_11) \n " , errout . str ( ) ) ;
2011-01-30 12:54:19 +01:00
TODO_ASSERT_EQUALS ( 2 , 1 , actual . size ( ) ) ;
TODO_ASSERT_EQUALS ( " \n a1; \n \n " ,
" " , actual [ " DEF_10 " ] ) ;
2009-12-13 17:18:27 +01:00
}
2014-11-20 14:20:09 +01:00
void if_or_2 ( ) {
2010-08-26 21:33:45 +02:00
const std : : string code ( " #if X || Y \n "
" a1; \n "
" #endif \n " ) ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n a1; \n \n " , preprocessor . getcode ( code , " X " , " test.c " ) ) ;
ASSERT_EQUALS ( " \n a1; \n \n " , preprocessor . getcode ( code , " Y " , " test.c " ) ) ;
2010-08-26 21:33:45 +02:00
}
2014-11-20 14:20:09 +01:00
void if_macro_eq_macro ( ) {
2012-03-15 20:04:34 +01:00
const std : : string code ( " #define A B \n "
" #define B 1 \n "
" #define C 1 \n "
" #if A == C \n "
" Wilma \n "
" #else \n "
" Betty \n "
" #endif \n " ) ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream istr ( code ) ;
std : : map < std : : string , std : : string > actual ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
ASSERT_EQUALS ( " \n \n \n \n Wilma \n \n \n \n " , actual [ " " ] ) ;
}
2009-12-13 17:18:27 +01:00
2014-11-20 14:20:09 +01:00
void ticket_3675 ( ) {
2012-03-23 00:45:47 +01:00
const std : : string code ( " #ifdef YYSTACKSIZE \n "
" #define YYMAXDEPTH YYSTACKSIZE \n "
" #else \n "
" #define YYSTACKSIZE YYMAXDEPTH \n "
" #endif \n "
" #if YYDEBUG \n "
" #endif \n " ) ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream istr ( code ) ;
std : : map < std : : string , std : : string > actual ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// There's nothing to assert. It just needs to not hang.
}
2014-11-20 14:20:09 +01:00
void ticket_3699 ( ) {
2012-04-22 06:49:42 +02:00
const std : : string code ( " #define INLINE __forceinline \n "
" #define inline __forceinline \n "
" #define __forceinline inline \n "
" #if !defined(_WIN32) \n "
" #endif \n "
" INLINE inline __forceinline \n "
) ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream istr ( code ) ;
std : : map < std : : string , std : : string > actual ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// First, it must not hang. Second, inline must becomes inline, and __forceinline must become __forceinline.
ASSERT_EQUALS ( " \n \n \n \n \n $$$__forceinline $$inline $$__forceinline \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void ticket_4922 ( ) { // #4922
2013-08-04 14:34:28 +02:00
const std : : string code ( " __asm__ \n "
" { int extern __value) 0; (double return ( \" \" } extern \n "
" __typeof __finite (__finite) __finite __inline \" __GI___finite \" ); " ) ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream istr ( code ) ;
std : : map < std : : string , std : : string > actual ;
preprocessor . preprocess ( istr , actual , " file.cpp " ) ;
}
2014-11-20 14:20:09 +01:00
void multiline1 ( ) {
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 ) ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #define str \" abc \" \" def \" \n \n abcdef = str; \n " , preprocessor . read ( istr , " test.c " ) ) ;
2009-01-11 08:19:28 +01:00
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
void multiline2 ( ) {
2009-01-11 08:19:28 +01:00
const char filedata [ ] = " #define sqr(aa) aa * \\ \n "
" aa \n "
" sqr(5); \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #define sqr(aa) aa * aa \n \n sqr(5); \n " , preprocessor . read ( istr , " test.c " ) ) ;
2008-12-18 22:28:57 +01:00
}
2014-11-20 14:20:09 +01:00
void multiline3 ( ) {
2009-01-11 09:16:15 +01:00
const char filedata [ ] = " const char *str = \" abc \\ \n "
" def \\ \n "
" ghi \" \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " const char *str = \" abcdefghi \" \n \n \n " , preprocessor . read ( istr , " test.c " ) ) ;
2009-01-11 09:16:15 +01:00
}
2014-11-20 14:20:09 +01:00
void multiline4 ( ) {
2009-05-11 20:12:29 +02:00
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..
2012-01-06 08:01:50 +01:00
Settings settings ;
2009-05-11 20:12:29 +02:00
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
2010-12-01 18:00:55 +01:00
Preprocessor preprocessor ( & settings , this ) ;
2009-05-11 20:12:29 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2010-08-07 21:05:14 +02:00
# ifdef __GNUC__
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n $int $a = $4; $int $b = $5; \n " , actual [ " " ] ) ;
2010-08-07 21:05:14 +02:00
# else
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n int b = 5; \n $int $a = $4; \\ \n " , actual [ " " ] ) ;
2010-08-07 21:05:14 +02:00
# endif
2009-05-11 20:12:29 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-01-02 19:27:50 +01:00
2014-11-20 14:20:09 +01:00
void multiline5 ( ) {
2009-08-19 23:27:47 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-08-19 23:27:47 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n int main(){ \n $int $a = $4; \n } \n " , actual [ " " ] ) ;
2009-08-19 23:27:47 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2015-01-19 18:00:05 +01:00
void remove_asm ( ) const {
2012-01-02 12:58:34 +01:00
std : : string str1 ( " #asm \n mov ax,bx \n #endasm " ) ;
2009-09-11 21:22:41 +02:00
Preprocessor : : removeAsm ( str1 ) ;
2012-01-02 12:58:34 +01:00
ASSERT_EQUALS ( " asm( \n mov ax,bx \n ); " , str1 ) ;
2009-09-11 21:22:41 +02:00
2012-01-02 12:58:34 +01:00
std : : string str2 ( " \n #asm \n mov ax,bx \n #endasm \n " ) ;
2009-09-11 21:22:41 +02:00
Preprocessor : : removeAsm ( str2 ) ;
2012-01-02 12:58:34 +01:00
ASSERT_EQUALS ( " \n asm( \n mov ax,bx \n ); \n " , str2 ) ;
2009-09-11 21:22:41 +02:00
}
2015-01-19 18:00:05 +01:00
void if_defined ( ) const {
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
2015-01-19 18:00:05 +01:00
void if_not_defined ( ) const {
2009-06-21 08:03:42 +02:00
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
2015-01-19 18:00:05 +01:00
void macro_simple1 ( ) const {
2009-05-24 22:57:12 +02:00
{
const char filedata [ ] = " #define AAA(aa) f(aa) \n "
" AAA(5); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $f($5); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-05-24 22:57:12 +02:00
}
{
const char filedata [ ] = " #define AAA(aa) f(aa) \n "
" AAA (5); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $f($5); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-05-24 22:57:12 +02:00
}
2009-01-05 21:41:34 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple2 ( ) const {
2009-01-05 21:41:34 +01:00
const char filedata [ ] = " #define min(x,y) x<y?x:y \n "
" min(a(),b()); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $a()<$b()?$a():$b(); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-05 21:41:34 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple3 ( ) const {
2009-01-11 16:07:13 +01:00
const char filedata [ ] = " #define A 4 \n "
" A AA \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $4 AA \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-11 16:07:13 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple4 ( ) const {
2009-01-11 16:51:46 +01:00
const char filedata [ ] = " #define TEMP_1 if( temp > 0 ) return 1; \n "
" TEMP_1 \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $if( $temp > $0 ) $return $1; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-11 16:51:46 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple5 ( ) const {
2009-01-11 17:06:37 +01:00
const char filedata [ ] = " #define ABC if( temp > 0 ) return 1; \n "
" \n "
" void foo() \n "
" { \n "
" int temp = 0; \n "
" ABC \n "
" } \n " ;
2013-10-13 17:42:06 +02: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
}
2015-01-19 18:00:05 +01:00
void macro_simple6 ( ) const {
2009-01-18 17:56:12 +01:00
const char filedata [ ] = " #define ABC (a+b+c) \n "
2009-12-09 17:13:48 +01:00
" ABC \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $($a+$b+$c) \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-18 17:56:12 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple7 ( ) const {
2009-01-21 18:11:24 +01:00
const char filedata [ ] = " #define ABC(str) str \n "
2009-12-09 17:13:48 +01:00
" ABC( \" ( \" ) \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $ \" ( \" \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-23 18:14:42 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple8 ( ) const {
2009-01-23 18:14:42 +01:00
const char filedata [ ] = " #define ABC 123 \n "
" #define ABCD 1234 \n "
2009-12-09 17:13:48 +01:00
" ABC ABCD \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n $123 $1234 \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-21 18:11:24 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple9 ( ) const {
2009-06-05 22:45:31 +02:00
const char filedata [ ] = " #define ABC(a) f(a) \n "
" ABC( \" \\ \" \" ); \n "
2009-12-09 17:13:48 +01:00
" ABC( \" g \" ); \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $f( \" \\ \" \" ); \n $f( \" g \" ); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-06-05 22:45:31 +02:00
}
2015-01-19 18:00:05 +01:00
void macro_simple10 ( ) const {
2009-08-01 14:55:45 +02:00
const char filedata [ ] = " #define ABC(t) t x \n "
2009-12-09 17:13:48 +01:00
" ABC(unsigned long); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $unsigned $long $x; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-08-01 14:55:45 +02:00
}
2015-01-19 18:00:05 +01:00
void macro_simple11 ( ) const {
2009-11-26 17:32:18 +01:00
const char filedata [ ] = " #define ABC(x) delete x \n "
2009-12-09 17:13:48 +01:00
" ABC(a); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $delete $a; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-12-09 17:13:48 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple12 ( ) const {
2009-12-09 17:13:48 +01:00
const char filedata [ ] = " #define AB ab.AB \n "
" AB.CD \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $ab.$AB.CD \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-11-26 17:32:18 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple13 ( ) const {
2010-01-02 20:54:52 +01:00
const char filedata [ ] = " #define TRACE(x) \n "
" TRACE(;if(a)) \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $ \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2010-01-02 20:54:52 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple14 ( ) const {
2011-02-11 06:30:42 +01:00
const char filedata [ ] = " #define A \" a \" \n "
" printf(A); \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n printf($ \" a \" ); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2011-02-11 06:30:42 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple15 ( ) const {
2011-02-11 18:01:27 +01:00
const char filedata [ ] = " #define FOO \" foo \" \n "
" FOO \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $ \" foo \" \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2011-02-11 18:01:27 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_simple16 ( ) const { // # 4703
2013-08-10 23:28:02 +02:00
const char filedata [ ] = " #define MACRO( A, B, C ) class A##B##C##Creator {}; \n "
" MACRO( B \t , U , G ) " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $class $BUGCreator{}; " , OurPreprocessor : : expandMacros ( filedata ) ) ;
}
2015-01-19 18:00:05 +01:00
void macro_simple17 ( ) const { // # 5074 - the Token::isExpandedMacro() doesn't always indicate properly if token comes from macro
2013-10-13 17:42:06 +02:00
// It would probably be OK if the generated code was
// "\n123+$123" since the first 123 comes from the source code
const char filedata [ ] = " #define MACRO(A) A+123 \n "
" MACRO(123) " ;
ASSERT_EQUALS ( " \n $123+$123 " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2013-08-10 23:28:02 +02:00
}
2015-01-19 18:00:05 +01:00
void macro_simple18 ( ) const { // (1e-7)
2013-12-30 18:03:24 +01:00
const char filedata1 [ ] = " #define A (1e-7) \n "
" a=A; " ;
ASSERT_EQUALS ( " \n a=$($1e-7); " , OurPreprocessor : : expandMacros ( filedata1 ) ) ;
const char filedata2 [ ] = " #define A (1E-7) \n "
" a=A; " ;
ASSERT_EQUALS ( " \n a=$($1E-7); " , OurPreprocessor : : expandMacros ( filedata2 ) ) ;
const char filedata3 [ ] = " #define A (1e+7) \n "
" a=A; " ;
ASSERT_EQUALS ( " \n a=$($1e+7); " , OurPreprocessor : : expandMacros ( filedata3 ) ) ;
2013-12-31 10:24:14 +01:00
const char filedata4 [ ] = " #define A (1.e+7) \n "
" a=A; " ;
ASSERT_EQUALS ( " \n a=$($1.e+7); " , OurPreprocessor : : expandMacros ( filedata4 ) ) ;
const char filedata5 [ ] = " #define A (1.7f) \n "
" a=A; " ;
ASSERT_EQUALS ( " \n a=$($1.7f); " , OurPreprocessor : : expandMacros ( filedata5 ) ) ;
2014-01-02 11:21:23 +01:00
const char filedata6 [ ] = " #define A (.1) \n "
" a=A; " ;
ASSERT_EQUALS ( " \n a=$($.1); " , OurPreprocessor : : expandMacros ( filedata6 ) ) ;
const char filedata7 [ ] = " #define A (1.) \n "
" a=A; " ;
ASSERT_EQUALS ( " \n a=$($1.); " , OurPreprocessor : : expandMacros ( filedata7 ) ) ;
2014-01-08 18:05:14 +01:00
const char filedata8 [ ] = " #define A (8.0E+007) \n "
" a=A; " ;
ASSERT_EQUALS ( " \n a=$($8.0E+007); " , OurPreprocessor : : expandMacros ( filedata8 ) ) ;
2013-12-29 21:51:01 +01:00
}
2015-01-19 18:00:05 +01:00
void macroInMacro1 ( ) const {
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 " ;
2013-10-13 17:42:06 +02:00
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 " ;
2011-12-18 13:33:23 +01:00
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 " ;
2011-12-18 13:33:23 +01:00
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 " ;
2013-10-13 17:42:06 +02:00
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
2013-10-13 17:42:06 +02: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 " ;
2013-10-13 17:42:06 +02:00
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 " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n foo $$(($i)*$2); \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-11-18 23:34:00 +01:00
}
{
const char filedata [ ] = " #define foo foo \n "
" foo \n " ;
2011-12-18 13:33:23 +01:00
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 " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n $void $foo0(){$do{$$}$while($0);} \n $void $foo1(){$do{$$}$while($0);} \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-12-14 23:06:05 +01:00
}
{
const char filedata [ ] =
" #define B(x) ( \n "
" #define A() B(xx) \n "
" B(1) A() ) ) \n " ;
2011-12-18 13:33:23 +01:00
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 " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n int $$( $$( $$( $$( foo )))) = 0; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-12-20 22:50:57 +01:00
}
{
const char filedata [ ] =
" #define PTR1 ( \n "
" PTR1 PTR1 \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $( $( \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-12-20 22:50:57 +01:00
}
2009-08-22 13:03:52 +02:00
}
2015-01-19 18:00:05 +01:00
void macroInMacro2 ( ) const {
2011-04-07 16:53:42 +02:00
const char filedata [ ] = " #define A(x) a##x \n "
" #define B 0 \n "
" A(B) \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n $aB \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2011-04-07 16:53:42 +02:00
}
2015-01-19 18:00:05 +01:00
void macro_mismatch ( ) const {
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
}
2015-01-19 18:00:05 +01:00
void macro_linenumbers ( ) const {
2009-03-08 21:28:12 +01:00
const char filedata [ ] = " #define AAA(a) \n "
" AAA(5 \n "
" \n "
" ) \n "
" int a; \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $ "
2009-03-10 23:49:16 +01:00
" \n "
" \n "
" \n "
" int a; \n " ,
OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-03-08 21:28:12 +01:00
}
2015-01-19 18:00:05 +01:00
void macro_nopar ( ) const {
2009-06-19 16:42:47 +02:00
const char filedata [ ] = " #define AAA( ) { NULL } \n "
2009-12-09 17:13:48 +01:00
" AAA() \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n ${ $NULL } \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-06-19 16:42:47 +02:00
}
2015-01-19 18:00:05 +01:00
void macro_switchCase ( ) const {
2010-04-15 22:21:00 +02:00
{
// Make sure "case 2" doesn't become "case2"
const char filedata [ ] = " #define A( b ) "
" switch( a ){ "
" case 2: "
" break; "
" } \n "
" A( 5 ); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $switch($a){$case $2:$break;}; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2010-04-15 22:21:00 +02:00
}
{
// Make sure "2 BB" doesn't become "2BB"
const char filedata [ ] = " #define A() AA : 2 BB \n "
" A(); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $AA : $2 $BB; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2010-04-15 22:21:00 +02:00
}
{
const char filedata [ ] = " #define A } \n "
" #define B() A \n "
" #define C( a ) B() break; \n "
" {C( 2 ); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n \n {$$$}$break;; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2010-04-15 22:21:00 +02:00
}
{
const char filedata [ ] = " #define A } \n "
" #define B() A \n "
" #define C( a ) B() _break; \n "
" {C( 2 ); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n \n {$$$}$_break;; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2010-04-15 22:21:00 +02:00
}
{
const char filedata [ ] = " #define A } \n "
" #define B() A \n "
" #define C( a ) B() 5; \n "
" {C( 2 ); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n \n {$$$}$5;; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2010-04-15 22:21:00 +02:00
}
}
2009-06-19 16:42:47 +02:00
2015-01-19 18:00:05 +01:00
void macro_NULL ( ) const {
2013-01-14 06:44:52 +01:00
// Let the tokenizer handle NULL.
// See ticket #4482 - UB when passing NULL to variadic function
2013-01-13 15:01:31 +01:00
ASSERT_EQUALS ( " \n $0 " , OurPreprocessor : : expandMacros ( " #define null 0 \n null " ) ) ;
ASSERT_EQUALS ( " \n NULL " , OurPreprocessor : : expandMacros ( " #define NULL 0 \n NULL " ) ) ;
}
2014-11-20 14:20:09 +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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
2015-01-19 18:00:05 +01:00
void string2 ( ) const {
2009-01-18 17:58:57 +01:00
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 ) ) ;
}
2015-01-19 18:00:05 +01:00
void string3 ( ) const {
2009-12-09 17:13:48 +01:00
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
}
2014-11-20 14:20:09 +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..
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n \n \n $char $b=$0; \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-06-14 06:21:20 +02:00
}
{
// ticket #403
const char filedata [ ] = " #define z p[2] \n "
" #undef z \n "
" int z; \n "
" z = 0; \n " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n \n int z; \n z = 0; \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
2009-06-14 06:21:20 +02:00
}
2009-01-12 19:23:53 +01:00
}
2009-01-19 20:24:41 +01:00
2015-01-19 18:00:05 +01:00
void defdef ( ) const {
2009-01-22 21:19:07 +01:00
const char filedata [ ] = " #define AAA 123 \n "
" #define AAA 456 \n "
" #define AAA 789 \n "
" AAA \n " ;
// Compare results..
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n \n $789 \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-01-22 21:19:07 +01:00
}
2015-01-19 18:00:05 +01:00
void preprocessor_doublesharp ( ) const {
2010-06-19 12:03:39 +02:00
// simple testcase without ##
const char filedata1 [ ] = " #define TEST(var,val) var = val \n "
" TEST(foo,20); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $foo=$20; \n " , OurPreprocessor : : expandMacros ( filedata1 ) ) ;
2009-01-19 22:45:59 +01:00
2010-06-19 12:03:39 +02:00
// simple testcase with ##
2009-01-19 22:45:59 +01:00
const char filedata2 [ ] = " #define TEST(var,val) var##_##val = val \n "
" TEST(foo,20); \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $foo_20=$20; \n " , OurPreprocessor : : expandMacros ( filedata2 ) ) ;
2009-12-09 19:14:07 +01:00
2010-06-19 12:03:39 +02:00
// concat macroname
2009-12-09 19:14:07 +01:00
const char filedata3 [ ] = " #define ABCD 123 \n "
" #define A(B) A##B \n "
" A(BCD) \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n $$123 \n " , OurPreprocessor : : expandMacros ( filedata3 ) ) ;
2010-06-19 12:03:39 +02:00
// Ticket #1802 - inner ## must be expanded before outer macro
const char filedata4 [ ] = " #define A(B) A##B \n "
" #define a(B) A(B) \n "
" a(A(B)) \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n $$AAB \n " , OurPreprocessor : : expandMacros ( filedata4 ) ) ;
2010-06-19 12:03:39 +02:00
// Ticket #1802 - inner ## must be expanded before outer macro
const char filedata5 [ ] = " #define AB(A,B) A##B \n "
" #define ab(A,B) AB(A,B) \n "
" ab(a,AB(b,c)) \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n $$abc \n " , OurPreprocessor : : expandMacros ( filedata5 ) ) ;
2010-09-18 22:20:01 +02:00
// Ticket #1802
const char filedata6 [ ] = " #define AB_(A,B) A ## B \n "
" #define AB(A,B) AB_(A,B) \n "
" #define ab(suf) AB(X, AB_(_, suf)) \n "
" #define X x \n "
" ab(y) \n " ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n \n \n $$$x_y \n " , OurPreprocessor : : expandMacros ( filedata6 ) ) ;
2009-01-19 22:45:59 +01:00
}
2014-11-20 14:20:09 +01:00
void preprocessor_include_in_str ( ) {
2009-01-19 20:24:41 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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
2015-01-19 18:00:05 +01:00
void va_args_1 ( ) const {
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
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $printf( \" [0x%lx-0x%lx) \" ,$pstart,$pend); \n " , actual ) ;
2009-01-21 08:22:44 +01:00
}
2015-01-19 18:00:05 +01:00
void va_args_2 ( ) const {
2009-01-28 21:19:46 +01:00
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
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $printf( \" hello \" ); \n " , actual ) ;
2009-01-28 21:19:46 +01:00
}
2015-01-19 18:00:05 +01:00
void va_args_3 ( ) const {
2009-06-18 23:09:11 +02:00
const char filedata [ ] = " #define FRED(...) { fred(__VA_ARGS__); } \n "
2009-12-09 17:13:48 +01:00
" FRED(123) \n " ;
2013-10-13 17:42:06 +02:00
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
2015-01-19 18:00:05 +01:00
void va_args_4 ( ) const {
2011-01-02 11:19:37 +01:00
const char filedata [ ] = " #define FRED(name, ...) name (__VA_ARGS__) \n "
" FRED(abc, 123) \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $abc($123) \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2011-01-02 10:09:50 +01:00
}
2009-01-28 21:19:46 +01:00
2014-11-20 14:20:09 +01:00
void multi_character_character ( ) {
2009-01-21 20:12:28 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
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 ( ) ) ) ;
2011-12-18 13:33:23 +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
2015-01-19 18:00:05 +01:00
void stringify ( ) const {
2009-01-25 14:30:15 +01:00
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
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $ \" abc \" \n " , actual ) ;
2009-01-25 14:30:15 +01:00
}
2015-01-19 18:00:05 +01:00
void stringify2 ( ) const {
2009-03-15 15:05:23 +01:00
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 ) ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $g( \" abc \" ); \n " , actual ) ;
2009-03-15 15:05:23 +01:00
}
2015-01-19 18:00:05 +01:00
void stringify3 ( ) const {
2009-03-15 22:39:58 +01:00
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 ) ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n $g( \" abc \" ); \n " , actual ) ;
2009-03-15 22:39:58 +01:00
}
2015-01-19 18:00:05 +01:00
void stringify4 ( ) const {
2009-05-05 17:19:06 +02:00
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 ) ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n 1 $ \n \n \" abc \" 2 \n " , actual ) ;
2009-05-05 17:19:06 +02:00
}
2015-01-19 18:00:05 +01:00
void stringify5 ( ) const {
2009-10-14 20:40:17 +02:00
const char filedata [ ] = " #define A(x) a(#x,x) \n "
" A(foo( \" \\ \" \" )) \n " ;
2013-10-13 17:42:06 +02:00
ASSERT_EQUALS ( " \n $a( \" foo( \\ \" \\ \\ \\ \" \\ \" ) \" ,$foo( \" \\ \" \" )) \n " , OurPreprocessor : : expandMacros ( filedata ) ) ;
2009-10-14 20:40:17 +02:00
}
2014-11-20 14:20:09 +01:00
void pragma ( ) {
2009-03-15 13:23:12 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-03-15 13:23:12 +01:00
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
2014-11-20 14:20:09 +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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-08-10 20:07:55 +02:00
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
}
2014-11-20 14:20:09 +01:00
void pragma_asm_2 ( ) {
2010-02-12 18:15:15 +01:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-02-12 18:15:15 +01:00
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 [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void pragma_once ( ) {
2013-08-18 18:04:06 +02:00
const char code [ ] = " #pragma once \n "
" int x " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2013-08-18 18:04:06 +02:00
const std : : list < std : : string > includePaths ;
std : : map < std : : string , std : : string > defs ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " 123.h " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
ASSERT_EQUALS ( 1U , pragmaOnce . size ( ) ) ;
ASSERT_EQUALS ( " 123.h " , * ( pragmaOnce . begin ( ) ) ) ;
}
2014-11-20 14:20:09 +01:00
void endifsemicolon ( ) {
2011-12-17 15:23:55 +01:00
const char filedata [ ] = " void f() { \n "
2009-03-18 00:10:26 +01:00
" #ifdef A \n "
" #endif; \n "
" } \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-03-18 00:10:26 +01:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2011-12-17 15:23:55 +01:00
const std : : string expected ( " void f() { \n \n \n } \n " ) ;
ASSERT_EQUALS ( expected , actual [ " " ] ) ;
ASSERT_EQUALS ( expected , actual [ " A " ] ) ;
2009-03-18 00:10:26 +01:00
}
2009-04-03 21:09:12 +02:00
2014-11-20 14:20:09 +01:00
void handle_error ( ) {
2009-08-13 23:22:51 +02:00
{
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-08-13 23:22:51 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
ASSERT_EQUALS ( expected , actual [ " " ] ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
}
2014-11-20 14:20:09 +01: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 ) ) ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n int a = $1; \n " , actual ) ;
2009-04-26 21:19:08 +02:00
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 ( " " ) ;
2014-03-28 18:55:16 +01:00
OurPreprocessor : : expandMacros ( filedata , this ) ;
2010-02-26 22:11:23 +01:00
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
2014-11-20 14:20:09 +01:00
void unicodeInCode ( ) {
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 ) ;
2010-07-23 13:54:52 +02:00
errout . str ( " " ) ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
preprocessor . read ( istr , " test.cpp " ) ;
2014-08-07 14:19:43 +02:00
ASSERT_EQUALS ( " [test.cpp:1]: (error) The code contains unhandled characters (character code = 0xc8). Checking continues, but do not expect valid results. \n " , errout . str ( ) ) ;
2009-04-27 21:29:03 +02:00
}
2009-05-09 21:32:29 +02:00
2014-11-20 14:20:09 +01:00
void unicodeInComment ( ) {
2010-04-13 22:39:41 +02:00
const std : : string filedata ( " // \xC8 " ) ;
2011-12-08 21:28:34 +01:00
std : : istringstream istr ( filedata ) ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " " , preprocessor . read ( istr , " test.cpp " ) ) ;
2009-06-19 15:43:46 +02:00
}
2014-11-20 14:20:09 +01:00
void unicodeInString ( ) {
2010-04-13 22:39:41 +02:00
const std : : string filedata ( " \" \xC8 \" " ) ;
2011-12-08 21:28:34 +01:00
std : : istringstream istr ( filedata ) ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( filedata , preprocessor . read ( istr , " test.cpp " ) ) ;
2009-06-19 15:43:46 +02:00
}
2014-11-20 14:20:09 +01: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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-05-09 21:32:29 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n void f() { \n $g( ); \n } \n " , actual [ " " ] ) ;
2009-05-09 21:32:29 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void conditionalDefine ( ) {
2009-05-13 21:38:57 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-05-13 21:38:57 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 2 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n \n \n \n $20 \n " , actual [ " " ] ) ;
ASSERT_EQUALS ( " \n \n \n \n \n $10 \n " , actual [ " A " ] ) ;
2009-05-13 21:38:57 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void multiline_comment ( ) {
2009-05-12 23:01:53 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-05-12 23:01:53 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n void f() ${ } \n " , actual [ " " ] ) ;
2009-05-12 23:01:53 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void macro_parameters ( ) {
2009-05-18 22:32:04 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-07-25 21:10:30 +02:00
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
2014-11-20 14:20:09 +01:00
void newline_in_macro ( ) {
2009-05-20 20:36:59 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-07-25 21:10:30 +02:00
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 ( ) ) ) ;
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n void f() \n { \n $printf( \" \\ n \" ); \n } \n " , actual [ " " ] ) ;
2009-05-20 20:36:59 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2015-01-19 18:00:05 +01:00
void includes ( ) const {
2009-05-22 23:18:48 +02:00
{
std : : string src = " #include a.h " ;
2010-07-21 11:50:04 +02:00
ASSERT_EQUALS ( OurPreprocessor : : NoHeader , OurPreprocessor : : getHeaderFileName ( src ) ) ;
2009-05-22 23:18:48 +02:00
ASSERT_EQUALS ( " " , src ) ;
}
{
std : : string src = " #include \" b.h \" " ;
2010-07-21 11:50:04 +02:00
ASSERT_EQUALS ( OurPreprocessor : : UserHeader , OurPreprocessor : : getHeaderFileName ( src ) ) ;
2009-05-22 23:18:48 +02:00
ASSERT_EQUALS ( " b.h " , src ) ;
}
{
std : : string src = " #include <c.h> " ;
2010-07-21 11:50:04 +02:00
ASSERT_EQUALS ( OurPreprocessor : : SystemHeader , OurPreprocessor : : getHeaderFileName ( src ) ) ;
2009-05-22 23:18:48 +02:00
ASSERT_EQUALS ( " c.h " , src ) ;
}
2010-07-21 13:16:42 +02:00
{
std : : string src = " #include \" d/d.h \" " ;
ASSERT_EQUALS ( OurPreprocessor : : UserHeader , OurPreprocessor : : getHeaderFileName ( src ) ) ;
ASSERT_EQUALS ( " d/d.h " , src ) ;
}
{
std : : string src = " #include \" e \\ e.h \" " ;
ASSERT_EQUALS ( OurPreprocessor : : UserHeader , OurPreprocessor : : getHeaderFileName ( src ) ) ;
ASSERT_EQUALS ( " e/e.h " , src ) ;
}
2009-05-22 22:59:07 +02:00
}
2009-06-14 22:37:18 +02:00
2014-11-20 14:20:09 +01:00
void ifdef_ifdefined ( ) {
2009-06-14 22:37:18 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-06-14 22:37:18 +02:00
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
2014-11-20 14:20:09 +01:00
void define_if1 ( ) {
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
2011-02-23 22:08:24 +01:00
{
const char filedata [ ] = " #define A 0 \n "
" #if A \n "
" FOO \n "
" #endif " ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n \n \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
2011-02-23 22:08:24 +01:00
}
{
const char filedata [ ] = " #define A 1 \n "
" #if A==1 \n "
" FOO \n "
" #endif " ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n \n FOO \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
2011-02-23 22:08:24 +01:00
}
}
2014-11-20 14:20:09 +01:00
void define_if2 ( ) {
2011-07-18 21:44:23 +02:00
const char filedata [ ] = " #define A 22 \n "
" #define B A \n "
" #if (B==A) || (B==C) \n "
" FOO \n "
" #endif " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n \n \n FOO \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
2011-07-18 21:44:23 +02:00
}
2014-11-20 14:20:09 +01:00
void define_if3 ( ) {
2011-11-17 19:19:43 +01:00
const char filedata [ ] = " #define A 0 \n "
" #if (A==0) \n "
" FOO \n "
" #endif " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n \n FOO \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
2011-11-17 19:19:43 +01:00
}
2014-11-20 14:20:09 +01:00
void define_if4 ( ) {
2012-11-28 07:33:24 +01:00
const char filedata [ ] = " #define X +123 \n "
2012-11-28 08:48:00 +01:00
" #if X==123 \n "
" FOO \n "
" #endif " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-11-28 07:33:24 +01:00
ASSERT_EQUALS ( " \n \n FOO \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
}
2014-11-20 14:20:09 +01:00
void define_if5 ( ) { // #4516 - #define B (A & 0x00f0)
2013-01-26 16:21:33 +01:00
{
const char filedata [ ] = " #define A 0x0010 \n "
" #define B (A & 0x00f0) \n "
" #if B==0x0010 \n "
" FOO \n "
" #endif " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2013-01-26 16:21:33 +01:00
ASSERT_EQUALS ( " \n \n \n FOO \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
}
{
const char filedata [ ] = " #define A 0x00f0 \n "
" #define B (16) \n "
" #define C (B & A) \n "
" #if C==0x0010 \n "
" FOO \n "
" #endif " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2013-01-26 16:21:33 +01:00
ASSERT_EQUALS ( " \n \n \n \n FOO \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
}
2013-01-27 02:53:29 +01:00
{
const char filedata [ ] = " #define A (1+A) \n " // don't hang for recursive macros
" #if A==1 \n "
" FOO \n "
" #endif " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2013-01-27 02:53:29 +01:00
ASSERT_EQUALS ( " \n \n \n \n " , preprocessor . getcode ( filedata , " " , " " ) ) ;
}
2013-01-26 12:37:46 +01:00
}
2014-11-20 14:20:09 +01:00
void define_if6 ( ) { // #4516 - #define B (A?1:-1)
2013-06-19 21:29:39 +02:00
const char filedata [ ] = " #ifdef A \n "
" #define B (A?1:-1) \n "
" #endif \n "
" \n "
" #if B < 0 \n "
" 123 \n "
" #endif \n "
" \n "
" #if B >= 0 \n "
" 456 \n "
" #endif \n " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2013-06-19 21:29:39 +02:00
const std : : string actualA0 = preprocessor . getcode ( filedata , " A=0 " , " test.c " ) ;
ASSERT_EQUALS ( true , actualA0 . find ( " 123 " ) ! = std : : string : : npos ) ;
ASSERT_EQUALS ( false , actualA0 . find ( " 456 " ) ! = std : : string : : npos ) ;
const std : : string actualA1 = preprocessor . getcode ( filedata , " A=1 " , " test.c " ) ;
ASSERT_EQUALS ( false , actualA1 . find ( " 123 " ) ! = std : : string : : npos ) ;
ASSERT_EQUALS ( true , actualA1 . find ( " 456 " ) ! = std : : string : : npos ) ;
}
2014-11-20 14:20:09 +01: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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-07-25 13:58:34 +02:00
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 [ " " ] ) ;
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 1 , ( int ) actual . size ( ) ) ;
2009-07-25 13:58:34 +02:00
}
{
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-07-25 13:58:34 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n $1 \n \n " , actual [ " " ] ) ;
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 1 , ( int ) actual . size ( ) ) ;
2009-07-25 13:58:34 +02:00
}
{
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-07-25 13:58:34 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n $1 \n \n " , actual [ " " ] ) ;
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 1 , ( int ) 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 "
2013-06-19 21:29:39 +02:00
" #if A>0 \n "
2009-08-31 20:36:25 +02:00
" A \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-08-31 20:36:25 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n $1 \n \n " , actual [ " " ] ) ;
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 1 , ( int ) actual . size ( ) ) ;
2009-08-31 20:36:25 +02:00
}
2011-02-11 18:51:22 +01:00
{
const char filedata [ ] = " #define A 1 \n "
" #if 0 \n "
" #undef A \n "
" #endif \n "
" A \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..
2011-12-18 13:33:23 +01:00
ASSERT_EQUALS ( " \n \n \n \n $1 \n " , actual [ " " ] ) ;
2011-02-11 18:51:22 +01:00
ASSERT_EQUALS ( 1 , ( int ) actual . size ( ) ) ;
}
2009-07-22 18:47:50 +02:00
}
2009-10-10 22:23:48 +02:00
2014-11-20 14:20:09 +01:00
void define_ifndef1 ( ) {
2010-07-25 15:19:25 +02:00
const char filedata [ ] = " #define A(x) (x) \n "
" #ifndef A \n "
" ; \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-07-25 15:19:25 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( " \n \n \n \n " , actual [ " " ] ) ;
2012-05-04 17:53:47 +02:00
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
2010-07-25 15:19:25 +02:00
}
2014-11-20 14:20:09 +01:00
void define_ifndef2 ( ) {
2010-09-14 17:45:37 +02:00
const char filedata [ ] = " #ifdef A \n "
" #define B char \n "
" #endif \n "
" #ifndef B \n "
" #define B int \n "
" #endif \n "
" B me; \n " ;
// Preprocess => actual result..
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
ASSERT_EQUALS ( " \n \n \n \n \n \n $int me; \n " , preprocessor . getcode ( filedata , " " , " a.cpp " ) ) ;
ASSERT_EQUALS ( " \n \n \n \n \n \n $char me; \n " , preprocessor . getcode ( filedata , " A " , " a.cpp " ) ) ;
2010-09-14 17:45:37 +02:00
}
2014-11-20 14:20:09 +01:00
void ifndef_define ( ) {
2012-05-04 17:53:47 +02:00
const char filedata [ ] = " #ifndef A \n "
" #define A(x) x \n "
" #endif \n "
" A(123); " ;
// 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 " ) ;
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n \n $123; \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef_ifdef ( ) {
2012-01-24 07:43:26 +01:00
const char filedata [ ] = " #undef A \n "
" #ifdef A \n "
" 123 \n "
" #endif \n " ;
// Preprocess => actual result..
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-24 07:43:26 +01:00
ASSERT_EQUALS ( " \n \n \n \n " , preprocessor . getcode ( filedata , " " , " a.cpp " ) ) ;
ASSERT_EQUALS ( " \n \n \n \n " , preprocessor . getcode ( filedata , " A " , " a.cpp " ) ) ;
}
2014-11-20 14:20:09 +01:00
void redundant_config ( ) {
2010-04-15 18:37:51 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2010-04-15 18:37:51 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 4 , ( int ) actual . size ( ) ) ;
2010-04-15 18:37:51 +02:00
ASSERT ( actual . find ( " " ) ! = actual . end ( ) ) ;
ASSERT ( actual . find ( " BAR " ) ! = actual . end ( ) ) ;
ASSERT ( actual . find ( " FOO " ) ! = actual . end ( ) ) ;
ASSERT ( actual . find ( " BAR;FOO " ) ! = actual . end ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void endfile ( ) {
2009-10-10 22:23:48 +02:00
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 ;
2010-12-01 18:00:55 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2009-10-10 22:23:48 +02:00
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( " char a[] = \" #endfile \" ; \n char b[] = \" #endfile \" ; \n \n " , actual [ " " ] ) ;
2011-01-01 09:16:31 +01:00
ASSERT_EQUALS ( 1 , ( int ) actual . size ( ) ) ;
2009-10-10 22:23:48 +02:00
}
2011-01-30 09:09:12 +01:00
2014-11-20 14:20:09 +01:00
void dup_defines ( ) {
2011-01-30 09:09:12 +01:00
const char filedata [ ] = " #ifdef A \n "
" #define B \n "
" #if defined(B) && defined(A) \n "
" a \n "
" #else \n "
" b \n "
" #endif \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 " ) ;
// B will always be defined if A is defined; the following test
2011-01-30 12:54:19 +01:00
// cases should be fixed whenever this other bug is fixed
TODO_ASSERT_EQUALS ( 2 ,
3 , static_cast < unsigned int > ( actual . size ( ) ) ) ;
2011-01-30 09:09:12 +01:00
2011-10-13 20:53:06 +02:00
if ( actual . find ( " A " ) = = actual . end ( ) ) {
2011-01-30 12:54:19 +01:00
ASSERT_EQUALS ( " A is checked " , " failed " ) ;
2011-10-13 20:53:06 +02:00
} else {
2011-01-30 12:54:19 +01:00
ASSERT_EQUALS ( " A is checked " , " A is checked " ) ;
}
2011-10-13 20:53:06 +02:00
if ( actual . find ( " A;A;B " ) ! = actual . end ( ) ) {
2011-01-30 12:54:19 +01:00
ASSERT_EQUALS ( " A;A;B is NOT checked " , " failed " ) ;
2011-10-13 20:53:06 +02:00
} else {
2011-01-30 12:54:19 +01:00
ASSERT_EQUALS ( " A;A;B is NOT checked " , " A;A;B is NOT checked " ) ;
}
2011-01-30 09:09:12 +01:00
}
2011-02-11 06:30:42 +01:00
2014-11-20 14:20:09 +01:00
void testPreprocessorRead1 ( ) {
2011-02-11 06:30:42 +01:00
const std : : string filedata ( " /* \n */ # /* \n */ defi \\ \n ne FO \\ \n O 10 \\ \n 20 " ) ;
2011-12-08 21:28:34 +01:00
std : : istringstream istr ( filedata ) ;
2011-02-11 06:30:42 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #define FOO 1020 " , preprocessor . read ( istr , " test.cpp " ) ) ;
2011-02-11 06:30:42 +01:00
}
2014-11-20 14:20:09 +01:00
void testPreprocessorRead2 ( ) {
2011-02-11 06:30:42 +01:00
const std : : string filedata ( " \" foo \\ \\ \n bar \" " ) ;
2011-12-08 21:28:34 +01:00
std : : istringstream istr ( filedata ) ;
2011-02-11 06:30:42 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " \" foo \\ bar \" " , preprocessor . read ( istr , " test.cpp " ) ) ;
2011-02-11 06:30:42 +01:00
}
2014-11-20 14:20:09 +01:00
void testPreprocessorRead3 ( ) {
2011-02-11 06:30:42 +01:00
const std : : string filedata ( " #define A \" a \" \n \" b \" " ) ;
2011-12-08 21:28:34 +01:00
std : : istringstream istr ( filedata ) ;
2011-02-11 06:30:42 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( filedata , preprocessor . read ( istr , " test.cpp " ) ) ;
2011-02-11 06:30:42 +01:00
}
2014-11-20 14:20:09 +01:00
void testPreprocessorRead4 ( ) {
2011-02-11 06:30:42 +01:00
{
// test < \\> < > (unescaped)
const std : : string filedata ( " #define A \" \\ \\ \" /*space*/ \" \" " ) ;
2011-12-08 21:28:34 +01:00
std : : istringstream istr ( filedata ) ;
2011-02-11 06:30:42 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #define A \" \\ \\ \" \" \" " , preprocessor . read ( istr , " test.cpp " ) ) ;
2011-02-11 06:30:42 +01:00
}
{
// test <" \\\" "> (unescaped)
const std : : string filedata ( " #define A \" \\ \\ \\ \" \" " ) ;
2011-12-08 21:28:34 +01:00
std : : istringstream istr ( filedata ) ;
2011-02-11 06:30:42 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #define A \" \\ \\ \\ \" \" " , preprocessor . read ( istr , " test.cpp " ) ) ;
2011-02-11 06:30:42 +01:00
}
{
// test <" \\\\"> <" "> (unescaped)
const std : : string filedata ( " #define A \" \\ \\ \\ \\ \" /*space*/ \" \" " ) ;
2011-12-08 21:28:34 +01:00
std : : istringstream istr ( filedata ) ;
2011-02-11 06:30:42 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-01-05 18:37:15 +01:00
ASSERT_EQUALS ( " #define A \" \\ \\ \\ \\ \" \" \" " , preprocessor . read ( istr , " test.cpp " ) ) ;
2011-02-11 06:30:42 +01:00
}
}
2011-02-22 19:55:02 +01:00
2014-11-20 14:20:09 +01:00
void invalid_define_1 ( ) {
2011-02-22 19:55:02 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream src ( " #define = \n " ) ;
std : : string processedFile ;
std : : list < std : : string > cfg ;
std : : list < std : : string > paths ;
2011-12-08 21:28:34 +01:00
preprocessor . preprocess ( src , processedFile , cfg , " " , paths ) ; // don't hang
2012-08-25 13:24:17 +02:00
}
2014-11-20 14:20:09 +01:00
void invalid_define_2 ( ) { // #4036 - hang
2012-08-25 13:24:17 +02:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream src ( " #define () {(int f(x) } \n " ) ;
std : : string processedFile ;
std : : list < std : : string > cfg ;
std : : list < std : : string > paths ;
preprocessor . preprocess ( src , processedFile , cfg , " " , paths ) ; // don't hang
2011-02-22 19:55:02 +01:00
}
2011-04-22 20:25:17 +02:00
2014-11-20 14:20:09 +01:00
void missingInclude ( ) {
2011-11-06 08:59:07 +01:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
Preprocessor : : missingIncludeFlag = false ;
std : : istringstream src ( " #include \" missing.h \" \n " ) ;
std : : string processedFile ;
std : : list < std : : string > cfg ;
std : : list < std : : string > paths ;
ASSERT_EQUALS ( false , Preprocessor : : missingIncludeFlag ) ;
preprocessor . preprocess ( src , processedFile , cfg , " test.c " , paths ) ;
ASSERT_EQUALS ( true , Preprocessor : : missingIncludeFlag ) ;
}
2014-11-20 14:20:09 +01:00
void inline_suppression_for_missing_include ( ) {
2012-05-16 11:59:45 +02:00
Preprocessor : : missingIncludeFlag = false ;
2011-04-22 20:25:17 +02:00
Settings settings ;
settings . _inlineSuppressions = true ;
settings . addEnabled ( " all " ) ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream src ( " // cppcheck-suppress missingInclude \n "
" #include \" missing.h \" \n "
" int x; " ) ;
std : : string processedFile ;
std : : list < std : : string > cfg ;
std : : list < std : : string > paths ;
// Don't report that the include is missing
errout . str ( " " ) ;
preprocessor . preprocess ( src , processedFile , cfg , " test.c " , paths ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-05-16 11:59:45 +02:00
ASSERT_EQUALS ( false , Preprocessor : : missingIncludeFlag ) ;
2011-04-22 20:25:17 +02:00
}
2011-07-16 09:24:27 +02:00
2014-11-20 14:20:09 +01:00
void predefine1 ( ) {
2013-06-19 21:29:39 +02:00
const std : : string src ( " #if defined X || Y \n "
2011-07-16 09:24:27 +02:00
" Fred & Wilma \n "
" #endif \n " ) ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
std : : string actual = preprocessor . getcode ( src , " X=1 " , " test.c " ) ;
2011-07-16 09:24:27 +02:00
ASSERT_EQUALS ( " \n Fred & Wilma \n \n " , actual ) ;
}
2014-11-20 14:20:09 +01:00
void predefine2 ( ) {
2013-06-19 21:29:39 +02:00
const std : : string src ( " #if defined(X) && Y \n "
2011-07-16 09:24:27 +02:00
" Fred & Wilma \n "
" #endif \n " ) ;
{
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
std : : string actual = preprocessor . getcode ( src , " X=1 " , " test.c " ) ;
2011-07-16 09:24:27 +02:00
ASSERT_EQUALS ( " \n \n \n " , actual ) ;
}
{
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
std : : string actual = preprocessor . getcode ( src , " X=1;Y=2 " , " test.c " ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n Fred & Wilma \n \n " , actual ) ;
}
}
2014-11-20 14:20:09 +01:00
void predefine3 ( ) {
2012-01-02 12:10:53 +01:00
// #2871 - define in source is not used if -D is used
const char code [ ] = " #define X 1 \n "
" #define Y X \n "
" #if (X == Y) \n "
" Fred & Wilma \n "
" #endif \n " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
const std : : string actual = preprocessor . getcode ( code , " TEST " , " test.c " ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n \n \n Fred & Wilma \n \n " , actual ) ;
}
2014-11-20 14:20:09 +01:00
void predefine4 ( ) {
2012-02-05 20:48:28 +01:00
// #3577
const char code [ ] = " char buf[X]; \n " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-02-05 20:48:28 +01:00
const std : : string actual = preprocessor . getcode ( code , " X=123 " , " test.c " ) ;
ASSERT_EQUALS ( " char buf[$123]; \n " , actual ) ;
}
2014-11-20 14:20:09 +01:00
void predefine5 ( ) { // #3737, #5119 - automatically define __cplusplus
2013-11-15 19:21:21 +01:00
// #3737...
2012-05-08 20:49:43 +02:00
const char code [ ] = " #ifdef __cplusplus \n 123 \n #endif " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-05-08 20:49:43 +02:00
ASSERT_EQUALS ( " \n \n \n " , preprocessor . getcode ( code , " X=123 " , " test.c " ) ) ;
ASSERT_EQUALS ( " \n 123 \n \n " , preprocessor . getcode ( code , " X=123 " , " test.cpp " ) ) ;
2013-11-15 19:21:21 +01:00
// #5119...
2014-02-16 10:32:10 +01:00
ASSERT_EQUALS ( false , Preprocessor : : cplusplus ( nullptr , " test.c " ) ) ;
ASSERT_EQUALS ( true , Preprocessor : : cplusplus ( nullptr , " test.cpp " ) ) ;
2013-11-15 19:21:21 +01:00
Settings settings ;
ASSERT_EQUALS ( true , Preprocessor : : cplusplus ( & settings , " test.cpp " ) ) ;
settings . userUndefs . insert ( " __cplusplus " ) ;
ASSERT_EQUALS ( false , Preprocessor : : cplusplus ( & settings , " test.cpp " ) ) ;
2012-05-08 20:49:43 +02:00
}
2014-11-20 14:20:09 +01:00
void predefine6 ( ) { // #3737 - using -D and -f => check all matching configurations
2013-06-08 16:46:54 +02:00
const char filedata [ ] = " #ifdef A \n "
" 1 \n "
" #else \n "
" 2 \n "
" #endif \n "
" #ifdef B \n "
" 3 \n "
" #else \n "
" 4 \n "
" #endif " ;
// actual result..
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : map < std : : string , std : : string > defs ;
defs [ " A " ] = " 1 " ;
const std : : list < std : : string > configs = preprocessor . getcfgs ( filedata , " test1.c " , defs ) ;
// Compare actual result with expected result..
ASSERT_EQUALS ( 2U , configs . size ( ) ) ;
ASSERT_EQUALS ( " " , configs . front ( ) ) ;
ASSERT_EQUALS ( " B " , configs . back ( ) ) ;
}
2012-09-15 09:34:41 +02:00
2014-11-20 14:20:09 +01:00
void simplifyCondition ( ) {
2012-01-02 12:10:53 +01:00
// Ticket #2794
std : : map < std : : string , std : : string > cfg ;
cfg [ " C " ] = " " ;
std : : string condition ( " defined(A) || defined(B) || defined(C) " ) ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:42:07 +01:00
preprocessor . simplifyCondition ( cfg , condition , true ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " 1 " , condition ) ;
}
2014-11-20 14:20:09 +01:00
void invalidElIf ( ) {
2012-01-02 12:10:53 +01:00
// #2942 - segfault
const char code [ ] = " #elif (){ \n " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-06 08:01:50 +01:00
const std : : string actual = preprocessor . getcode ( code , " TEST " , " test.c " ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n " , actual ) ;
}
2014-11-20 14:20:09 +01:00
void def_handleIncludes ( ) {
2012-01-02 12:10:53 +01:00
const std : : string filePath ( " test.c " ) ;
const std : : list < std : : string > includePaths ;
std : : map < std : : string , std : : string > defs ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-02 12:10:53 +01:00
// ifdef
{
defs . clear ( ) ;
defs [ " A " ] = " " ;
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
const std : : string code ( " #ifdef A \n 123 \n #endif \n " ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n 123 \n \n " , actual ) ;
} {
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
const std : : string code ( " #ifdef B \n 123 \n #endif \n " ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n \n \n " , actual ) ;
}
}
// ifndef
{
defs . clear ( ) ;
defs [ " A " ] = " " ;
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
const std : : string code ( " #ifndef A \n 123 \n #endif \n " ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n \n \n " , actual ) ;
} {
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
const std : : string code ( " #ifndef B \n 123 \n #endif \n " ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n 123 \n \n " , actual ) ;
}
}
// define - ifndef
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
const std : : string code ( " #ifndef X \n #define X \n 123 \n #endif \n "
" #ifndef X \n #define X \n 123 \n #endif \n " ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n #define X \n 123 \n \n " " \n \n \n \n " , actual ) ;
}
// #define => #if
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
const std : : string code ( " #define X 123 \n "
" #if X==123 \n "
" 456 \n "
" #endif \n " ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " #define X 123 \n \n 456 \n \n " , actual ) ;
}
// #elif
{
const std : : string code ( " #if defined(A) \n "
" 1 \n "
" #elif defined(B) \n "
" 2 \n "
" #elif defined(C) \n "
" 3 \n "
" #else \n "
" 4 \n "
" #endif " ) ;
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
defs [ " A " ] = " " ;
defs [ " C " ] = " " ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n 1 \n \n \n \n \n \n \n \n " , actual ) ;
}
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
defs [ " B " ] = " " ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n \n \n 2 \n \n \n \n \n \n " , actual ) ;
}
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n \n \n \n \n \n \n 4 \n \n " , actual ) ;
}
}
// #endif
{
// see also endifsemicolon
const std : : string code ( " { \n #ifdef X \n #endif; \n } " ) ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
defs [ " Z " ] = " " ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " { \n \n \n } \n " , actual ) ;
}
// #undef
{
const std : : string code ( " #ifndef X \n "
" #define X \n "
" 123 \n "
" #endif \n " ) ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2013-08-18 18:04:06 +02:00
pragmaOnce . clear ( ) ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual1 ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
2013-08-18 18:04:06 +02:00
pragmaOnce . clear ( ) ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code + " #undef X \n " + code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( actual1 + " #undef X \n " + actual1 , actual ) ;
}
// #error
{
errout . str ( " " ) ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
const std : : string code ( " #ifndef X \n #error abc \n #endif " ) ;
2013-08-18 18:04:06 +02:00
const std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " \n #error abc \n \n " , actual ) ;
}
}
2014-11-20 14:20:09 +01:00
void def_missingInclude ( ) {
2012-01-02 12:10:53 +01:00
const std : : list < std : : string > includePaths ;
std : : map < std : : string , std : : string > defs ;
defs [ " AA " ] = " " ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
// missing local include
{
const std : : string code ( " #include \" missing-include!!.h \" \n " ) ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
2013-08-18 18:04:06 +02:00
pragmaOnce . clear ( ) ;
2012-01-02 12:10:53 +01:00
errout . str ( " " ) ;
2013-01-20 14:22:05 +01:00
settings = Settings ( ) ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
2013-01-20 14:22:05 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-08-18 18:04:06 +02:00
pragmaOnce . clear ( ) ;
2013-01-20 14:22:05 +01:00
errout . str ( " " ) ;
settings . checkConfiguration = true ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
2014-03-11 20:55:02 +01:00
ASSERT_EQUALS ( " [test.c:1]: (information) Include file: \" missing-include!!.h \" not found. \n " , errout . str ( ) ) ;
2012-01-02 12:10:53 +01:00
2013-08-18 18:04:06 +02:00
pragmaOnce . clear ( ) ;
2012-01-02 12:10:53 +01:00
errout . str ( " " ) ;
settings . nomsg . addSuppression ( " missingInclude " ) ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
// missing system header
{
const std : : string code ( " #include <missing-include!!.h> \n " ) ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
2013-08-18 18:04:06 +02:00
pragmaOnce . clear ( ) ;
2012-01-02 12:10:53 +01:00
errout . str ( " " ) ;
settings = Settings ( ) ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-08-18 18:04:06 +02:00
pragmaOnce . clear ( ) ;
2012-01-02 12:10:53 +01:00
errout . str ( " " ) ;
2013-01-20 14:22:05 +01:00
settings . checkConfiguration = true ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
2014-03-26 15:22:22 +01:00
ASSERT_EQUALS ( " [test.c:1]: (information) Include file: <missing-include!!.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. \n " , errout . str ( ) ) ;
2012-01-02 12:10:53 +01:00
2013-08-18 18:04:06 +02:00
pragmaOnce . clear ( ) ;
2012-01-02 12:10:53 +01:00
errout . str ( " " ) ;
2013-03-13 06:48:33 +01:00
settings . nomsg . addSuppression ( " missingIncludeSystem " ) ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-05-03 19:31:15 +02:00
pragmaOnce . clear ( ) ;
errout . str ( " " ) ;
settings = Settings ( ) ;
settings . nomsg . addSuppression ( " missingInclude " ) ;
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2012-01-02 12:10:53 +01:00
}
// #3285 - #elif
{
const std : : string code ( " #ifdef GNU \n "
" #elif defined(WIN32) \n "
" #include \" missing-include!!.h \" \n "
" #endif " ) ;
defs . clear ( ) ;
defs [ " GNU " ] = " " ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
errout . str ( " " ) ;
settings = Settings ( ) ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
}
2014-11-20 14:20:09 +01:00
void def_handleIncludes_ifelse1 ( ) {
2012-01-02 12:10:53 +01:00
const std : : string filePath ( " test.c " ) ;
const std : : list < std : : string > includePaths ;
std : : map < std : : string , std : : string > defs ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-02 12:10:53 +01:00
// #3405
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
defs [ " A " ] = " " ;
const std : : string code ( " \n #ifndef PAL_UTIL_UTILS_H_ \n "
" #define PAL_UTIL_UTILS_H_ \n "
" 1 \n "
" #ifndef USE_BOOST \n "
" 2 \n "
" #else \n "
" 3 \n "
" #endif \n "
" 4 \n "
" #endif \n "
" \n "
" #ifndef PAL_UTIL_UTILS_H_ \n "
" #define PAL_UTIL_UTILS_H_ \n "
" 5 \n "
" #ifndef USE_BOOST \n "
" 6 \n "
" #else \n "
" 7 \n "
" #endif \n "
" 8 \n "
" #endif \n "
" \n " ) ;
2013-08-18 18:04:06 +02:00
std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
// the 1,2,4 should be in the result
actual . erase ( 0 , actual . find ( " 1 " ) ) ;
while ( actual . find ( " \n " ) ! = std : : string : : npos )
actual . erase ( actual . find ( " \n " ) , 1 ) ;
ASSERT_EQUALS ( " 124 " , actual ) ;
}
// #3418
{
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-01-02 12:10:53 +01:00
defs . clear ( ) ;
const char code [ ] = " #define A 1 \n "
" #define B A \n "
" #if A == B \n "
" 123 \n "
" #endif \n " ;
2013-08-18 18:04:06 +02:00
std : : string actual ( preprocessor . handleIncludes ( code , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ) ;
2012-01-02 12:10:53 +01:00
ASSERT_EQUALS ( " #define A 1 \n #define B A \n \n 123 \n \n " , actual ) ;
}
}
2014-11-20 14:20:09 +01:00
void def_handleIncludes_ifelse2 ( ) { // #3651
2012-09-15 09:34:41 +02:00
const char code [ ] = " #if defined(A) \n "
" \n "
" #if defined(B) \n "
" #endif \n "
" \n "
" #elif defined(C) \n "
" \n "
" #else \n "
" \n "
" 123 \n "
" \n "
" #endif " ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-09-15 09:34:41 +02:00
const std : : list < std : : string > includePaths ;
std : : map < std : : string , std : : string > defs ;
defs [ " A " ] = " 1 " ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2012-09-15 09:34:41 +02:00
ASSERT_EQUALS ( std : : string : : npos , // No "123" in the output
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) . find ( " 123 " ) ) ;
2012-09-15 09:34:41 +02:00
}
2014-11-20 14:20:09 +01:00
void def_handleIncludes_ifelse3 ( ) { // #4865
2013-06-21 20:10:46 +02:00
const char code [ ] = " #ifdef A \n "
" #if defined(SOMETHING_NOT_DEFINED) \n "
" #else \n "
" #endif \n "
" #else \n "
" #endif " ;
Settings settings ;
settings . userUndefs . insert ( " A " ) ;
Preprocessor preprocessor ( & settings , this ) ;
const std : : list < std : : string > includePaths ;
std : : map < std : : string , std : : string > defs ;
defs [ " B " ] = " 1 " ;
defs [ " C " ] = " 1 " ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( code , " test.c " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ; // don't crash
2013-06-21 20:10:46 +02:00
}
2014-11-20 14:20:09 +01:00
void def_valueWithParentheses ( ) {
2013-01-16 15:37:07 +01:00
// #define should introduce a new symbol regardless of parentheses in the value
2012-01-21 12:51:54 +01:00
// and regardless of white space in weird places (people do this for some reason).
const char code [ ] = " #define A (Fred) \n "
" # define B (Flintstone) \n "
" #define C (Barney) \n "
" \t # \t define \t D \t (Rubble) \t \t \t \n " ;
const std : : string filePath ( " test.c " ) ;
const std : : list < std : : string > includePaths ;
std : : map < std : : string , std : : string > defs ;
2013-10-27 10:33:37 +01:00
std : : set < std : : string > pragmaOnce ;
2014-02-16 10:32:10 +01:00
Preprocessor preprocessor ( nullptr , this ) ;
2012-01-21 12:51:54 +01:00
std : : istringstream istr ( code ) ;
const std : : string s ( preprocessor . read ( istr , " " ) ) ;
2013-08-18 18:04:06 +02:00
preprocessor . handleIncludes ( s , filePath , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
2012-01-21 12:51:54 +01:00
ASSERT ( defs . find ( " A " ) ! = defs . end ( ) ) ;
ASSERT_EQUALS ( " (Fred) " , defs [ " A " ] ) ;
ASSERT ( defs . find ( " B " ) ! = defs . end ( ) ) ;
ASSERT_EQUALS ( " (Flintstone) " , defs [ " B " ] ) ;
ASSERT ( defs . find ( " C " ) ! = defs . end ( ) ) ;
ASSERT_EQUALS ( " (Barney) " , defs [ " C " ] ) ;
ASSERT ( defs . find ( " D " ) ! = defs . end ( ) ) ;
ASSERT_EQUALS ( " (Rubble) " , defs [ " D " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef1 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #ifdef X \n "
" Fred & Wilma \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef2 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #ifndef X \n "
" Fred & Wilma \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n Fred & Wilma \n \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef3 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #define X \n "
" #ifdef X \n "
" Fred & Wilma \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ; // User undefs should override internal defines
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n \n \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef4 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #define X Y \n "
" #ifdef X \n "
" Fred & Wilma \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ; // User undefs should override internal defines
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n \n \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef5 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #define X() Y \n "
" #ifdef X \n "
" Fred & Wilma \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ; // User undefs should override internal defines
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n \n \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef6 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #define X Y \n "
" #ifdef X \n "
" Fred & Wilma \n "
" #else \n "
" Barney & Betty \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ; // User undefs should override internal defines
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n \n \n Barney & Betty \n \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef7 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #define X XDefined \n "
" X; \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ; // User undefs should override internal defines
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
TODO_ASSERT_EQUALS ( " \n ; \n " , " \n $XDefined; \n " , actual [ " " ] ) ;
}
2014-11-20 14:20:09 +01:00
void undef8 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #ifdef HAVE_CONFIG_H \n "
" #include \" config.h \" \n "
" #endif \n "
" \n "
" void foo(); \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ; // User undefs should override internal defines
settings . checkConfiguration = true ;
errout . str ( " " ) ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
2014-03-11 20:55:02 +01:00
ASSERT_EQUALS ( " [file.c:2]: (information) Include file: \" config.h \" not found. \n " , errout . str ( ) ) ;
2013-09-01 07:13:48 +02:00
ASSERT_EQUALS ( " \n \n \n \n \n " , actual [ " " ] ) ;
2012-01-02 12:10:53 +01:00
}
2014-11-20 14:20:09 +01:00
void undef9 ( ) {
2012-01-02 12:10:53 +01:00
Settings settings ;
const char filedata [ ] = " #define X Y \n "
" #ifndef X \n "
" Fred & Wilma \n "
" #else \n "
" Barney & Betty \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
settings . userUndefs . insert ( " X " ) ; // User undefs should override internal defines
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
// Compare results..
ASSERT_EQUALS ( 1U , actual . size ( ) ) ;
ASSERT_EQUALS ( " \n \n Fred & Wilma \n \n \n \n " , actual [ " " ] ) ;
}
2012-03-27 19:35:41 +02:00
2014-11-20 14:20:09 +01:00
void undef10 ( ) {
2012-07-18 20:57:00 +02:00
Settings settings ;
const char filedata [ ] = " #ifndef X \n "
" #endif \n "
" #ifndef Y \n "
" #endif \n " ;
// Preprocess => actual result..
std : : istringstream istr ( filedata ) ;
settings . userUndefs . insert ( " X " ) ; // User undefs should override internal defines
Preprocessor preprocessor ( & settings , this ) ;
std : : string processedFile ;
std : : list < std : : string > resultConfigurations ;
const std : : list < std : : string > includePaths ;
preprocessor . preprocess ( istr , processedFile , resultConfigurations , " file.c " , includePaths ) ;
// Compare results. Two configurations "" and "Y". No "X".
ASSERT_EQUALS ( 2U , resultConfigurations . size ( ) ) ;
ASSERT_EQUALS ( " " , resultConfigurations . front ( ) ) ;
ASSERT_EQUALS ( " Y " , resultConfigurations . back ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void handleUndef ( ) {
2012-07-18 20:57:00 +02:00
Settings settings ;
settings . userUndefs . insert ( " X " ) ;
const Preprocessor preprocessor ( & settings , this ) ;
std : : list < std : : string > configurations ;
// configurations to keep
configurations . clear ( ) ;
configurations . push_back ( " XY; " ) ;
configurations . push_back ( " AX; " ) ;
configurations . push_back ( " A;XY " ) ;
preprocessor . handleUndef ( configurations ) ;
ASSERT_EQUALS ( 3U , configurations . size ( ) ) ;
// configurations to remove
configurations . clear ( ) ;
configurations . push_back ( " X;Y " ) ;
configurations . push_back ( " X=1;Y " ) ;
configurations . push_back ( " A;X;B " ) ;
configurations . push_back ( " A;X=1;B " ) ;
configurations . push_back ( " A;X " ) ;
configurations . push_back ( " A;X=1 " ) ;
preprocessor . handleUndef ( configurations ) ;
ASSERT_EQUALS ( 0U , configurations . size ( ) ) ;
}
2015-01-19 18:00:05 +01:00
void macroChar ( ) const {
2012-03-27 19:35:41 +02:00
const char filedata [ ] = " #define X 1 \n X \n " ;
2014-02-16 10:32:10 +01:00
ASSERT_EQUALS ( " \n $1 \n " , OurPreprocessor : : expandMacros ( filedata , nullptr ) ) ;
2012-03-27 20:48:22 +02:00
OurPreprocessor : : macroChar = char ( 1 ) ;
2014-02-16 10:32:10 +01:00
ASSERT_EQUALS ( " \n " + std : : string ( char ( 1 ) , 1U ) + " 1 \n " , OurPreprocessor : : expandMacros ( filedata , nullptr ) ) ;
2012-03-27 19:35:41 +02:00
OurPreprocessor : : macroChar = ' $ ' ;
}
2012-07-10 20:29:04 +02:00
2014-11-20 14:20:09 +01:00
void validateCfg ( ) {
2012-07-10 20:29:04 +02:00
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
2012-07-13 11:28:45 +02:00
ASSERT_EQUALS ( true , preprocessor . validateCfg ( " " , " X=42 " ) ) ; // don't hang when parsing cfg
2012-07-13 13:04:10 +02:00
ASSERT_EQUALS ( false , preprocessor . validateCfg ( " int y=Y; " , " X=42;Y " ) ) ;
2012-07-10 20:29:04 +02:00
ASSERT_EQUALS ( false , preprocessor . validateCfg ( " int x=X; " , " X " ) ) ;
ASSERT_EQUALS ( false , preprocessor . validateCfg ( " X=1; " , " X " ) ) ;
ASSERT_EQUALS ( true , preprocessor . validateCfg ( " int x=X; " , " Y " ) ) ;
2012-07-11 18:29:33 +02:00
ASSERT_EQUALS ( true , preprocessor . validateCfg ( " FOO_DEBUG() " , " DEBUG " ) ) ;
ASSERT_EQUALS ( true , preprocessor . validateCfg ( " \" DEBUG() \" " , " DEBUG " ) ) ;
ASSERT_EQUALS ( true , preprocessor . validateCfg ( " \" \\ \" DEBUG() \" " , " DEBUG " ) ) ;
ASSERT_EQUALS ( false , preprocessor . validateCfg ( " \" DEBUG() \" DEBUG " , " DEBUG " ) ) ;
2012-07-11 21:20:31 +02:00
ASSERT_EQUALS ( true , preprocessor . validateCfg ( " #undef DEBUG " , " DEBUG " ) ) ;
2012-11-03 11:25:40 +01:00
// #4301:
// #ifdef A
// int a = A; // <- using macro. must use -D so "A" will get a proper value
errout . str ( " " ) ;
settings . addEnabled ( " all " ) ;
preprocessor . setFile0 ( " test.c " ) ;
ASSERT_EQUALS ( false , preprocessor . validateCfg ( " int a=A; " , " A " ) ) ;
2013-06-26 09:47:02 +02:00
ASSERT_EQUALS ( " [test.c:1]: (information) Skipping configuration 'A' since the value of 'A' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly. \n " , errout . str ( ) ) ;
2013-08-12 18:12:49 +02:00
// #4949:
// #ifdef A
// a |= A; // <- using macro. must use -D so "A" will get a proper value
errout . str ( " " ) ;
2013-08-13 06:36:03 +02:00
Settings settings1 ;
settings = settings1 ;
2013-08-12 18:12:49 +02:00
ASSERT_EQUALS ( " " , preprocessor . getcode ( " if (x) a|=A; " , " A " , " test.c " ) ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2013-08-13 06:36:03 +02:00
settings . addEnabled ( " information " ) ;
2013-08-12 18:12:49 +02:00
ASSERT_EQUALS ( " " , preprocessor . getcode ( " if (x) a|=A; " , " A " , " test.c " ) ) ;
ASSERT_EQUALS ( " [test.c:1]: (information) Skipping configuration 'A' since the value of 'A' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly. \n " , errout . str ( ) ) ;
2012-07-10 20:29:04 +02:00
}
2014-11-20 14:20:09 +01:00
void if_sizeof ( ) { // #4071
2012-08-25 11:45:18 +02:00
static const char * code = " #if sizeof(unsigned short) == 2 \n "
2012-08-22 17:28:06 +02:00
" Fred & Wilma \n "
2012-08-25 11:45:18 +02:00
" #elif sizeof(unsigned short) == 4 \n "
2012-08-22 17:28:06 +02:00
" Fred & Wilma \n "
" #else \n "
" #endif " ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
std : : istringstream istr ( code ) ;
std : : map < std : : string , std : : string > actual ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
ASSERT_EQUALS ( " \n Fred & Wilma \n \n \n \n \n " , actual [ " " ] ) ;
}
2014-04-23 20:50:16 +02:00
2014-11-20 14:20:09 +01:00
void double_include ( ) {
2014-04-23 20:50:16 +02:00
const char code [ ] = " int x " ;
Preprocessor preprocessor ( nullptr , this ) ;
std : : list < std : : string > includePaths ;
includePaths . push_back ( " . " ) ;
includePaths . push_back ( " . " ) ;
std : : map < std : : string , std : : string > defs ;
std : : set < std : : string > pragmaOnce ;
preprocessor . handleIncludes ( code , " 123.h " , includePaths , defs , pragmaOnce , std : : list < std : : string > ( ) ) ;
}
2014-06-08 10:02:16 +02:00
2014-11-20 14:20:09 +01:00
void invalid_ifs ( ) {
2014-06-08 10:02:16 +02:00
const char filedata [ ] = " #ifdef \n "
" #endif \n "
" #ifdef ! \n "
" #endif \n "
" #if defined \n "
" #endif \n "
" #define f(x) x \n "
" #if f(2 \n "
" #endif \n "
" int x; \n " ;
// Preprocess => don't crash..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2015-05-12 14:00:43 +02:00
}
void garbage ( ) {
const char filedata [ ] = " V \n "
" #define X b #endif #line 0 \" x \" ; \n "
" #if ! defined ( Y ) #endif " ;
2014-06-08 10:02:16 +02:00
2015-05-12 14:00:43 +02:00
// Preprocess => don't crash..
std : : istringstream istr ( filedata ) ;
std : : map < std : : string , std : : string > actual ;
Settings settings ;
Preprocessor preprocessor ( & settings , this ) ;
preprocessor . preprocess ( istr , actual , " file.c " ) ;
2014-06-08 10:02:16 +02:00
}
2012-01-02 12:10:53 +01:00
} ;
REGISTER_TEST ( TestPreprocessor )