3
3
4
4
__author__ = 'Evan Plaice'
5
5
__coauthor__ = 'Hendi O L, Epikem, Laurent Pinson'
6
- __version__ = '0.8 '
6
+ __version__ = '1.0 '
7
7
8
8
import sys
9
9
import os
@@ -20,17 +20,19 @@ def append(self, var):
20
20
21
21
22
22
class preprocessor :
23
+ __overloaded = []
24
+ defines = customDict ()
25
+
23
26
def __init__ (self , inFile = sys .argv [0 ], outFile = '' , defines = {}, removeMeta = False ,
24
27
escapeChar = None , mode = None , escape = '#' , run = True , resume = False ,
25
28
save = True , overload = True , quiet = False ):
26
29
# public variables
27
- self .defines = customDict ()
28
- #support for <=0.7.7
30
+ # support for <=0.7.7
29
31
if isinstance (defines , collections .Sequence ):
30
32
for x in defines :
31
- self .define (x )
33
+ self .define (* x . split ( ':' ) )
32
34
else :
33
- for x ,y in defines :
35
+ for x ,y in defines . items () :
34
36
self .define (x ,y )
35
37
self .input = inFile
36
38
self .output = outFile
@@ -89,12 +91,16 @@ def deprecation(message):
89
91
def __reset_internal (self ):
90
92
self .__linenum = 0
91
93
self .__excludeblock = False
92
- self .__ifblocks = [] # contains the evaluated if conditions
93
- self .__ifconditions = [] # contains the if conditions
94
+ # contains the evaluated if conditions
95
+ # due to the introduction of #elif, elements of __ifblocks are duos of boolean
96
+ # the 1st is the evaluation of the current #if or #elif or #else
97
+ # the 2nd indicates if at least one #if or #elif was True in the whole #if/#endif block
98
+ self .__ifblocks = []
99
+ # contains the if conditions
100
+ self .__ifconditions = []
94
101
self .__outputBuffer = ''
95
102
self .__overloaded = list (self .defines .keys ()) if self .overload else []
96
103
97
-
98
104
def define (self , name , val = True ):
99
105
"""
100
106
Adds variable definition to the store as expected from a #define directive.
@@ -164,7 +170,7 @@ def __validate_ifs(self):
164
170
165
171
"""
166
172
# no ifs mean we pass else check all ifs are True
167
- return not self .__ifblocks or all (self .__ifblocks )
173
+ return not self .__ifblocks or all (x [ 0 ] for x in self .__ifblocks )
168
174
169
175
def __is_directive (self , line , directive , * size ):
170
176
"""
@@ -243,41 +249,43 @@ def lexer(self, line):
243
249
elif self .__is_directive (line , 'ifdefnot' , 2 ) or \
244
250
self .__is_directive (line , 'ifnotdef' , 2 ) or \
245
251
self .__is_directive (line , 'ifndef' , 2 ):
246
- self .__ifblocks .append (not self .__is_defined (line .split ()[1 ]))
252
+ _check = not self .__is_defined (line .split ()[1 ])
253
+ self .__ifblocks .append ([ _check , _check ])
247
254
self .__ifconditions .append (line .split ()[1 ])
248
255
249
256
elif self .__is_directive (line , 'ifdef' , 2 ):
250
- self .__ifblocks .append (self .__is_defined (line .split ()[1 ]))
257
+ _check = self .__is_defined (line .split ()[1 ])
258
+ self .__ifblocks .append ([ _check , _check ])
251
259
self .__ifconditions .append (line .split ()[1 ])
252
260
253
261
elif self .__is_directive (line , 'if' ):
254
- self .__ifblocks .append (self .__evaluate_if (' ' .join (line .split ()[1 :])))
262
+ _check = self .__evaluate_if (' ' .join (line .split ()[1 :]))
263
+ self .__ifblocks .append ([ _check , _check ])
255
264
self .__ifconditions .append (' ' .join (line .split ()[1 :]))
256
265
257
266
# since in version <=0.7.7, it didn't handle #if it should be #elseifdef instead.
258
267
# kept elseif with 2 elements for retro-compatibility (equivalent to #elseifdef).
259
268
elif self .__is_directive (line , 'elseif' ) or \
260
269
self .__is_directive (line , 'elif' ):
261
- # do else
262
- self .__ifblocks [- 1 ] = not self .__ifblocks [- 1 ]
263
- # do if
270
+ _cur , _whole = self .__ifblocks [- 1 ]
264
271
if len (line .split ()) == 2 :
265
272
#old behaviour
266
- self . __ifblocks [ - 1 ] = self .__is_defined (line .split ()[1 ])
273
+ _check = self .__is_defined (line .split ()[1 ])
267
274
else :
268
275
#new behaviour
269
- self .__ifblocks [- 1 ] = self .__evaluate_if (' ' .join (line .split ()[1 :]))
270
- self .__ifconditions .append (' ' .join (line .split ()[1 :]))
276
+ _check = self .__evaluate_if (' ' .join (line .split ()[1 :]))
277
+ self .__ifblocks [- 1 ]= [ not _whole and _check , _whole or _check ]
278
+ self .__ifconditions [- 1 ]= ' ' .join (line .split ()[1 :])
271
279
272
280
elif self .__is_directive (line , 'elseifdef' , 2 ):
273
- # do else
274
- self .__ifblocks [- 1 ] = not self .__ifblocks [- 1 ]
275
- # do if
276
- self .__ifblocks [- 1 ]= self .__is_defined (line .split ()[1 ])
277
- self .__ifconditions .append (' ' .join (line .split ()[1 :]))
281
+ _cur , _whole = self .__ifblocks [- 1 ]
282
+ _check = self .__is_defined (line .split ()[1 ])
283
+ self .__ifblocks [- 1 ]= [ not _whole and _check , _whole or _check ]
284
+ self .__ifconditions [- 1 ]= ' ' .join (line .split ()[1 :])
278
285
279
286
elif self .__is_directive (line , 'else' , 1 ):
280
- self .__ifblocks [- 1 ] = not self .__ifblocks [- 1 ] #opposite of last if
287
+ _cur , _whole = self .__ifblocks [- 1 ]
288
+ self .__ifblocks [- 1 ] = [not _whole , not _whole ] #opposite of the whole if/elif block
281
289
282
290
elif self .__is_directive (line , 'endififdef' , 2 ):
283
291
# do endif
@@ -299,19 +307,17 @@ def lexer(self, line):
299
307
except ValueError as VE :
300
308
number = 1
301
309
302
- if len ( self . __ifconditions ) >= number :
303
- for i in range ( 0 , number ) :
310
+ try :
311
+ while number :
304
312
self .__ifblocks .pop (- 1 )
305
313
self .__ifconditions .pop (- 1 )
306
- else :
314
+ number -= 1
315
+ except :
307
316
if not self .quiet :
308
317
print ('Warning trying to remove more blocks than present' ,
309
318
self .input , self .__linenum )
310
- self .__ifblocks = []
311
- self .__ifconditions = []
312
319
313
320
else :
314
- # unknown directive or comment
315
321
# escapechar + space ==> comment
316
322
# starts with #!/ ==> shebang
317
323
# else print warning
0 commit comments