From 4fcc152faa3eecfb4f21219ffb373b9c743b0365 Mon Sep 17 00:00:00 2001 From: Tobias Herzog Date: Fri, 18 Jan 2019 21:35:49 +0100 Subject: [PATCH] Enhance cpp scanner regex logic to detect if/elif expressions without whitespaces correctly for example "#if(defined FOO)" or "#elif!(BAR)" --- src/CHANGES.txt | 4 ++ src/engine/SCons/cpp.py | 9 ++- src/engine/SCons/cppTests.py | 107 ++++++++++++++++++++++++++++++++++- src/script/scons.py | 0 4 files changed, 115 insertions(+), 5 deletions(-) mode change 100644 => 100755 src/script/scons.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 2c0cef6840..57f8c994cd 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -19,6 +19,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Improved support for VC14.1 and Visual Studio 2017, as well as arm and arm64 targets. - Update TempFileMunge class to use PRINT_CMD_LINE_FUNC + From Tobias Herzog + - Enhance cpp scanner regex logic to detect if/elif expressions without whitespaces but + parenthesis like "#if(defined FOO)" or "#elif!(BAR)" correctly. + RELEASE 3.0.3 - Mon, 07 Jan 2019 20:05:22 -0400 NOTE: 3.0.2 release was dropped because there was a packaging bug. Please consider all 3.0.2 content. diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py index d2178a766b..cdd3923e8b 100644 --- a/src/engine/SCons/cpp.py +++ b/src/engine/SCons/cpp.py @@ -43,10 +43,13 @@ # that we want to fetch, using the regular expressions to which the lists # of preprocessor directives map. cpp_lines_dict = { - # Fetch the rest of a #if/#elif/#ifdef/#ifndef as one argument, + # Fetch the rest of a #if/#elif as one argument, + # with white space optional. + ('if', 'elif') : '\s*(.+)', + + # Fetch the rest of a #ifdef/#ifndef as one argument, # separated from the keyword by white space. - ('if', 'elif', 'ifdef', 'ifndef',) - : '\s+(.+)', + ('ifdef', 'ifndef',): '\s+(.+)', # Fetch the rest of a #import/#include/#include_next line as one # argument, with white space optional. diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py index d496273cfe..ebf7fde2ef 100644 --- a/src/engine/SCons/cppTests.py +++ b/src/engine/SCons/cppTests.py @@ -363,6 +363,62 @@ """ +if_defined_no_space_input = """ +#define DEFINED 0 + +#if(defined DEFINED) +#include "file47-yes" +#endif + +#if(!defined DEFINED) +#include +#elif(!defined DEFINED) +#include +#else +#include +#endif + +#if!(defined DEFINED) +#include "file51-no" +#elif!(defined DEFINED) +#include +#else +#include "file53-yes" +#endif +""" + +if_no_space_input = """ +#define DEFINED 0 + +#if(DEFINED) +#include "file54-no" +#endif + +#if!(DEFINED) +#include +#elif!(DEFINED) +#include +#endif + +#if(DEFINED) +#include "file57-no" +#elif(!DEFINED) +#include +#endif + +#if!( DEFINED) +#include "file59-yes" +#elif!( DEFINED) +#include +#endif + +#if( DEFINED) +#include "file61-no" +#elif(! DEFINED) +#include +#endif +""" + # pp_class = PreProcessor # #pp_class = DumbPreProcessor @@ -450,6 +506,19 @@ def test_ifndef(self): result = self.cpp.process_contents(ifndef_input) assert expect == result, (expect, result) + def test_if_defined_no_space(self): + """Test #if(defined, i.e.without space but parenthesis""" + expect = self.if_defined_no_space_expect + result = self.cpp.process_contents(if_defined_no_space_input) + assert expect == result, (expect, result) + + def test_if_no_space(self): + """Test #if(, i.e. without space but parenthesis""" + expect = self.if_no_space_expect + result = self.cpp.process_contents(if_no_space_input) + assert expect == result, (expect, result) + + class cppAllTestCase(cppTestCase): def setUp(self): self.cpp = self.cpp_class(current = ".", @@ -541,7 +610,20 @@ class PreProcessorTestCase(cppAllTestCase): ('include', '"', 'file45-yes'), ('include', '<', 'file46-yes'), ] - + + if_defined_no_space_expect = [ + ('include', '"', 'file47-yes'), + ('include', '<', 'file50-yes'), + ('include', '"', 'file53-yes'), + ] + + if_no_space_expect = [ + ('include', '<', 'file55-yes'), + ('include', '<', 'file58-yes'), + ('include', '"', 'file59-yes'), + ('include', '<', 'file62-yes'), + ] + class DumbPreProcessorTestCase(cppAllTestCase): cpp_class = cpp.DumbPreProcessor @@ -654,7 +736,6 @@ class DumbPreProcessorTestCase(cppAllTestCase): ('include', '"', 'file7-yes') ] - ifndef_expect = [ ('include', '"', 'file45-no'), ('include', '"', 'file45-yes'), @@ -662,6 +743,28 @@ class DumbPreProcessorTestCase(cppAllTestCase): ('include', '<', 'file46-no'), ] + if_defined_no_space_expect = [ + ('include', '"', 'file47-yes'), + ('include', '<', 'file48-no'), + ('include', '<', 'file49-no'), + ('include', '<', 'file50-yes'), + ('include', '"', 'file51-no'), + ('include', '<', 'file52-no'), + ('include', '"', 'file53-yes'), + ] + + if_no_space_expect = [ + ('include', '"', 'file54-no'), + ('include', '<', 'file55-yes'), + ('include', '<', 'file56-no'), + ('include', '"', 'file57-no'), + ('include', '<', 'file58-yes'), + ('include', '"', 'file59-yes'), + ('include', '<', 'file60-no'), + ('include', '"', 'file61-no'), + ('include', '<', 'file62-yes'), + ] + import os import re import shutil diff --git a/src/script/scons.py b/src/script/scons.py old mode 100644 new mode 100755