~ubuntu-branches/ubuntu/lucid/blender/lucid

« back to all changes in this revision

Viewing changes to scons/scons-local-1.1.0/SCons/cpp.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2009-08-06 22:32:19 UTC
  • mfrom: (1.2.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806223219-8z4eej1u8levu4pz
Tags: 2.49a+dfsg-0ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/control: Build-depend on python-2.6 rather than python-2.5.
  - debian/misc/*.desktop: Add Spanish translation to .desktop 
    files.
  - debian/pyversions: 2.6.
  - debian/rules: Clean *.o of source/blender/python/api2_2x/
* New upstream release (LP: #382153).
* Refreshed patches:
  - 01_sanitize_sys.patch
  - 02_tmp_in_HOME
  - 10_use_systemwide_ftgl
  - 70_portability_platform_detection
* Removed patches merged upstream:
  - 30_fix_python_syntax_warning
  - 90_ubuntu_ffmpeg_52_changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
 
3
#
 
4
# Permission is hereby granted, free of charge, to any person obtaining
 
5
# a copy of this software and associated documentation files (the
 
6
# "Software"), to deal in the Software without restriction, including
 
7
# without limitation the rights to use, copy, modify, merge, publish,
 
8
# distribute, sublicense, and/or sell copies of the Software, and to
 
9
# permit persons to whom the Software is furnished to do so, subject to
 
10
# the following conditions:
 
11
#
 
12
# The above copyright notice and this permission notice shall be included
 
13
# in all copies or substantial portions of the Software.
 
14
#
 
15
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 
16
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 
17
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
18
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
19
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
20
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
21
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
#
 
23
 
 
24
__revision__ = "src/engine/SCons/cpp.py 3603 2008/10/10 05:46:45 scons"
 
25
 
 
26
__doc__ = """
 
27
SCons C Pre-Processor module
 
28
"""
 
29
 
 
30
# TODO(1.5):  remove this import
 
31
# This module doesn't use anything from SCons by name, but we import SCons
 
32
# here to pull in zip() from the SCons.compat layer for early Pythons.
 
33
import SCons
 
34
 
 
35
import os
 
36
import re
 
37
import string
 
38
 
 
39
#
 
40
# First "subsystem" of regular expressions that we set up:
 
41
#
 
42
# Stuff to turn the C preprocessor directives in a file's contents into
 
43
# a list of tuples that we can process easily.
 
44
#
 
45
 
 
46
# A table of regular expressions that fetch the arguments from the rest of
 
47
# a C preprocessor line.  Different directives have different arguments
 
48
# that we want to fetch, using the regular expressions to which the lists
 
49
# of preprocessor directives map.
 
50
cpp_lines_dict = {
 
51
    # Fetch the rest of a #if/#elif/#ifdef/#ifndef as one argument,
 
52
    # separated from the keyword by white space.
 
53
    ('if', 'elif', 'ifdef', 'ifndef',)
 
54
                        : '\s+(.+)',
 
55
 
 
56
    # Fetch the rest of a #import/#include/#include_next line as one
 
57
    # argument, with white space optional.
 
58
    ('import', 'include', 'include_next',)
 
59
                        : '\s*(.+)',
 
60
 
 
61
    # We don't care what comes after a #else or #endif line.
 
62
    ('else', 'endif',)  : '',
 
63
 
 
64
    # Fetch three arguments from a #define line:
 
65
    #   1) The #defined keyword.
 
66
    #   2) The optional parentheses and arguments (if it's a function-like
 
67
    #      macro, '' if it's not).
 
68
    #   3) The expansion value.
 
69
    ('define',)         : '\s+([_A-Za-z][_A-Za-z0-9_]+)(\([^)]*\))?\s*(.*)',
 
70
 
 
71
    # Fetch the #undefed keyword from a #undef line.
 
72
    ('undef',)          : '\s+([_A-Za-z][A-Za-z0-9_]+)',
 
73
}
 
74
 
 
75
# Create a table that maps each individual C preprocessor directive to
 
76
# the corresponding compiled regular expression that fetches the arguments
 
77
# we care about.
 
78
Table = {}
 
79
for op_list, expr in cpp_lines_dict.items():
 
80
    e = re.compile(expr)
 
81
    for op in op_list:
 
82
        Table[op] = e
 
83
del e
 
84
del op
 
85
del op_list
 
86
 
 
87
# Create a list of the expressions we'll use to match all of the
 
88
# preprocessor directives.  These are the same as the directives
 
89
# themselves *except* that we must use a negative lookahead assertion
 
90
# when matching "if" so it doesn't match the "if" in "ifdef."
 
91
override = {
 
92
    'if'                        : 'if(?!def)',
 
93
}
 
94
l = map(lambda x, o=override: o.get(x, x), Table.keys())
 
95
 
 
96
 
 
97
# Turn the list of expressions into one big honkin' regular expression
 
98
# that will match all the preprocessor lines at once.  This will return
 
99
# a list of tuples, one for each preprocessor line.  The preprocessor
 
100
# directive will be the first element in each tuple, and the rest of
 
101
# the line will be the second element.
 
102
e = '^\s*#\s*(' + string.join(l, '|') + ')(.*)$'
 
103
 
 
104
# And last but not least, compile the expression.
 
105
CPP_Expression = re.compile(e, re.M)
 
106
 
 
107
 
 
108
 
 
109
 
 
110
#
 
111
# Second "subsystem" of regular expressions that we set up:
 
112
#
 
113
# Stuff to translate a C preprocessor expression (as found on a #if or
 
114
# #elif line) into an equivalent Python expression that we can eval().
 
115
#
 
116
 
 
117
# A dictionary that maps the C representation of Boolean operators
 
118
# to their Python equivalents.
 
119
CPP_to_Python_Ops_Dict = {
 
120
    '!'         : ' not ',
 
121
    '!='        : ' != ',
 
122
    '&&'        : ' and ',
 
123
    '||'        : ' or ',
 
124
    '?'         : ' and ',
 
125
    ':'         : ' or ',
 
126
    '\r'        : '',
 
127
}
 
128
 
 
129
CPP_to_Python_Ops_Sub = lambda m, d=CPP_to_Python_Ops_Dict: d[m.group(0)]
 
130
 
 
131
# We have to sort the keys by length so that longer expressions
 
132
# come *before* shorter expressions--in particular, "!=" must
 
133
# come before "!" in the alternation.  Without this, the Python
 
134
# re module, as late as version 2.2.2, empirically matches the
 
135
# "!" in "!=" first, instead of finding the longest match.
 
136
# What's up with that?
 
137
l = CPP_to_Python_Ops_Dict.keys()
 
138
l.sort(lambda a, b: cmp(len(b), len(a)))
 
139
 
 
140
# Turn the list of keys into one regular expression that will allow us
 
141
# to substitute all of the operators at once.
 
142
expr = string.join(map(re.escape, l), '|')
 
143
 
 
144
# ...and compile the expression.
 
145
CPP_to_Python_Ops_Expression = re.compile(expr)
 
146
 
 
147
# A separate list of expressions to be evaluated and substituted
 
148
# sequentially, not all at once.
 
149
CPP_to_Python_Eval_List = [
 
150
    ['defined\s+(\w+)',         '__dict__.has_key("\\1")'],
 
151
    ['defined\s*\((\w+)\)',     '__dict__.has_key("\\1")'],
 
152
    ['/\*.*\*/',                ''],
 
153
    ['/\*.*',                   ''],
 
154
    ['//.*',                    ''],
 
155
    ['(0x[0-9A-Fa-f]*)[UL]+',   '\\1L'],
 
156
]
 
157
 
 
158
# Replace the string representations of the regular expressions in the
 
159
# list with compiled versions.
 
160
for l in CPP_to_Python_Eval_List:
 
161
    l[0] = re.compile(l[0])
 
162
 
 
163
# Wrap up all of the above into a handy function.
 
164
def CPP_to_Python(s):
 
165
    """
 
166
    Converts a C pre-processor expression into an equivalent
 
167
    Python expression that can be evaluated.
 
168
    """
 
169
    s = CPP_to_Python_Ops_Expression.sub(CPP_to_Python_Ops_Sub, s)
 
170
    for expr, repl in CPP_to_Python_Eval_List:
 
171
        s = expr.sub(repl, s)
 
172
    return s
 
173
 
 
174
 
 
175
 
 
176
del expr
 
177
del l
 
178
del override
 
179
 
 
180
 
 
181
 
 
182
class FunctionEvaluator:
 
183
    """
 
184
    Handles delayed evaluation of a #define function call.
 
185
    """
 
186
    def __init__(self, name, args, expansion):
 
187
        """
 
188
        Squirrels away the arguments and expansion value of a #define
 
189
        macro function for later evaluation when we must actually expand
 
190
        a value that uses it.
 
191
        """
 
192
        self.name = name
 
193
        self.args = function_arg_separator.split(args)
 
194
        try:
 
195
            expansion = string.split(expansion, '##')
 
196
        except (AttributeError, TypeError):
 
197
            # Python 1.5 throws TypeError if "expansion" isn't a string,
 
198
            # later versions throw AttributeError.
 
199
            pass
 
200
        self.expansion = expansion
 
201
    def __call__(self, *values):
 
202
        """
 
203
        Evaluates the expansion of a #define macro function called
 
204
        with the specified values.
 
205
        """
 
206
        if len(self.args) != len(values):
 
207
            raise ValueError, "Incorrect number of arguments to `%s'" % self.name
 
208
        # Create a dictionary that maps the macro arguments to the
 
209
        # corresponding values in this "call."  We'll use this when we
 
210
        # eval() the expansion so that arguments will get expanded to
 
211
        # the right values.
 
212
        locals = {}
 
213
        for k, v in zip(self.args, values):
 
214
            locals[k] = v
 
215
 
 
216
        parts = []
 
217
        for s in self.expansion:
 
218
            if not s in self.args:
 
219
                s = repr(s)
 
220
            parts.append(s)
 
221
        statement = string.join(parts, ' + ')
 
222
 
 
223
        return eval(statement, globals(), locals)
 
224
 
 
225
 
 
226
 
 
227
# Find line continuations.
 
228
line_continuations = re.compile('\\\\\r?\n')
 
229
 
 
230
# Search for a "function call" macro on an expansion.  Returns the
 
231
# two-tuple of the "function" name itself, and a string containing the
 
232
# arguments within the call parentheses.
 
233
function_name = re.compile('(\S+)\(([^)]*)\)')
 
234
 
 
235
# Split a string containing comma-separated function call arguments into
 
236
# the separate arguments.
 
237
function_arg_separator = re.compile(',\s*')
 
238
 
 
239
 
 
240
 
 
241
class PreProcessor:
 
242
    """
 
243
    The main workhorse class for handling C pre-processing.
 
244
    """
 
245
    def __init__(self, current=os.curdir, cpppath=(), dict={}, all=0):
 
246
        global Table
 
247
 
 
248
        cpppath = tuple(cpppath)
 
249
 
 
250
        self.searchpath = {
 
251
            '"' :       (current,) + cpppath,
 
252
            '<' :       cpppath + (current,),
 
253
        }
 
254
 
 
255
        # Initialize our C preprocessor namespace for tracking the
 
256
        # values of #defined keywords.  We use this namespace to look
 
257
        # for keywords on #ifdef/#ifndef lines, and to eval() the
 
258
        # expressions on #if/#elif lines (after massaging them from C to
 
259
        # Python).
 
260
        self.cpp_namespace = dict.copy()
 
261
        self.cpp_namespace['__dict__'] = self.cpp_namespace
 
262
 
 
263
        if all:
 
264
           self.do_include = self.all_include
 
265
 
 
266
        # For efficiency, a dispatch table maps each C preprocessor
 
267
        # directive (#if, #define, etc.) to the method that should be
 
268
        # called when we see it.  We accomodate state changes (#if,
 
269
        # #ifdef, #ifndef) by pushing the current dispatch table on a
 
270
        # stack and changing what method gets called for each relevant
 
271
        # directive we might see next at this level (#else, #elif).
 
272
        # #endif will simply pop the stack.
 
273
        d = {
 
274
            'scons_current_file'    : self.scons_current_file
 
275
        }
 
276
        for op in Table.keys():
 
277
            d[op] = getattr(self, 'do_' + op)
 
278
        self.default_table = d
 
279
 
 
280
    # Controlling methods.
 
281
 
 
282
    def tupleize(self, contents):
 
283
        """
 
284
        Turns the contents of a file into a list of easily-processed
 
285
        tuples describing the CPP lines in the file.
 
286
 
 
287
        The first element of each tuple is the line's preprocessor
 
288
        directive (#if, #include, #define, etc., minus the initial '#').
 
289
        The remaining elements are specific to the type of directive, as
 
290
        pulled apart by the regular expression.
 
291
        """
 
292
        global CPP_Expression, Table
 
293
        contents = line_continuations.sub('', contents)
 
294
        cpp_tuples = CPP_Expression.findall(contents)
 
295
        return  map(lambda m, t=Table:
 
296
                           (m[0],) + t[m[0]].match(m[1]).groups(),
 
297
                    cpp_tuples)
 
298
 
 
299
    def __call__(self, file):
 
300
        """
 
301
        Pre-processes a file.
 
302
 
 
303
        This is the main public entry point.
 
304
        """
 
305
        self.current_file = file
 
306
        return self.process_contents(self.read_file(file), file)
 
307
 
 
308
    def process_contents(self, contents, fname=None):
 
309
        """
 
310
        Pre-processes a file contents.
 
311
 
 
312
        This is the main internal entry point.
 
313
        """
 
314
        self.stack = []
 
315
        self.dispatch_table = self.default_table.copy()
 
316
        self.current_file = fname
 
317
        self.tuples = self.tupleize(contents)
 
318
 
 
319
        self.initialize_result(fname)
 
320
        while self.tuples:
 
321
            t = self.tuples.pop(0)
 
322
            # Uncomment to see the list of tuples being processed (e.g.,
 
323
            # to validate the CPP lines are being translated correctly).
 
324
            #print t
 
325
            self.dispatch_table[t[0]](t)
 
326
        return self.finalize_result(fname)
 
327
 
 
328
    # Dispatch table stack manipulation methods.
 
329
 
 
330
    def save(self):
 
331
        """
 
332
        Pushes the current dispatch table on the stack and re-initializes
 
333
        the current dispatch table to the default.
 
334
        """
 
335
        self.stack.append(self.dispatch_table)
 
336
        self.dispatch_table = self.default_table.copy()
 
337
 
 
338
    def restore(self):
 
339
        """
 
340
        Pops the previous dispatch table off the stack and makes it the
 
341
        current one.
 
342
        """
 
343
        try: self.dispatch_table = self.stack.pop()
 
344
        except IndexError: pass
 
345
 
 
346
    # Utility methods.
 
347
 
 
348
    def do_nothing(self, t):
 
349
        """
 
350
        Null method for when we explicitly want the action for a
 
351
        specific preprocessor directive to do nothing.
 
352
        """
 
353
        pass
 
354
 
 
355
    def scons_current_file(self, t):
 
356
        self.current_file = t[1]
 
357
 
 
358
    def eval_expression(self, t):
 
359
        """
 
360
        Evaluates a C preprocessor expression.
 
361
 
 
362
        This is done by converting it to a Python equivalent and
 
363
        eval()ing it in the C preprocessor namespace we use to
 
364
        track #define values.
 
365
        """
 
366
        t = CPP_to_Python(string.join(t[1:]))
 
367
        try: return eval(t, self.cpp_namespace)
 
368
        except (NameError, TypeError): return 0
 
369
 
 
370
    def initialize_result(self, fname):
 
371
        self.result = [fname]
 
372
 
 
373
    def finalize_result(self, fname):
 
374
        return self.result[1:]
 
375
 
 
376
    def find_include_file(self, t):
 
377
        """
 
378
        Finds the #include file for a given preprocessor tuple.
 
379
        """
 
380
        fname = t[2]
 
381
        for d in self.searchpath[t[1]]:
 
382
            if d == os.curdir:
 
383
                f = fname
 
384
            else:
 
385
                f = os.path.join(d, fname)
 
386
            if os.path.isfile(f):
 
387
                return f
 
388
        return None
 
389
 
 
390
    def read_file(self, file):
 
391
        return open(file).read()
 
392
 
 
393
    # Start and stop processing include lines.
 
394
 
 
395
    def start_handling_includes(self, t=None):
 
396
        """
 
397
        Causes the PreProcessor object to start processing #import,
 
398
        #include and #include_next lines.
 
399
 
 
400
        This method will be called when a #if, #ifdef, #ifndef or #elif
 
401
        evaluates True, or when we reach the #else in a #if, #ifdef,
 
402
        #ifndef or #elif block where a condition already evaluated
 
403
        False.
 
404
 
 
405
        """
 
406
        d = self.dispatch_table
 
407
        d['import'] = self.do_import
 
408
        d['include'] =  self.do_include
 
409
        d['include_next'] =  self.do_include
 
410
 
 
411
    def stop_handling_includes(self, t=None):
 
412
        """
 
413
        Causes the PreProcessor object to stop processing #import,
 
414
        #include and #include_next lines.
 
415
 
 
416
        This method will be called when a #if, #ifdef, #ifndef or #elif
 
417
        evaluates False, or when we reach the #else in a #if, #ifdef,
 
418
        #ifndef or #elif block where a condition already evaluated True.
 
419
        """
 
420
        d = self.dispatch_table
 
421
        d['import'] = self.do_nothing
 
422
        d['include'] =  self.do_nothing
 
423
        d['include_next'] =  self.do_nothing
 
424
 
 
425
    # Default methods for handling all of the preprocessor directives.
 
426
    # (Note that what actually gets called for a given directive at any
 
427
    # point in time is really controlled by the dispatch_table.)
 
428
 
 
429
    def _do_if_else_condition(self, condition):
 
430
        """
 
431
        Common logic for evaluating the conditions on #if, #ifdef and
 
432
        #ifndef lines.
 
433
        """
 
434
        self.save()
 
435
        d = self.dispatch_table
 
436
        if condition:
 
437
            self.start_handling_includes()
 
438
            d['elif'] = self.stop_handling_includes
 
439
            d['else'] = self.stop_handling_includes
 
440
        else:
 
441
            self.stop_handling_includes()
 
442
            d['elif'] = self.do_elif
 
443
            d['else'] = self.start_handling_includes
 
444
 
 
445
    def do_ifdef(self, t):
 
446
        """
 
447
        Default handling of a #ifdef line.
 
448
        """
 
449
        self._do_if_else_condition(self.cpp_namespace.has_key(t[1]))
 
450
 
 
451
    def do_ifndef(self, t):
 
452
        """
 
453
        Default handling of a #ifndef line.
 
454
        """
 
455
        self._do_if_else_condition(not self.cpp_namespace.has_key(t[1]))
 
456
 
 
457
    def do_if(self, t):
 
458
        """
 
459
        Default handling of a #if line.
 
460
        """
 
461
        self._do_if_else_condition(self.eval_expression(t))
 
462
 
 
463
    def do_elif(self, t):
 
464
        """
 
465
        Default handling of a #elif line.
 
466
        """
 
467
        d = self.dispatch_table
 
468
        if self.eval_expression(t):
 
469
            self.start_handling_includes()
 
470
            d['elif'] = self.stop_handling_includes
 
471
            d['else'] = self.stop_handling_includes
 
472
 
 
473
    def do_else(self, t):
 
474
        """
 
475
        Default handling of a #else line.
 
476
        """
 
477
        pass
 
478
 
 
479
    def do_endif(self, t):
 
480
        """
 
481
        Default handling of a #endif line.
 
482
        """
 
483
        self.restore()
 
484
 
 
485
    def do_define(self, t):
 
486
        """
 
487
        Default handling of a #define line.
 
488
        """
 
489
        _, name, args, expansion = t
 
490
        try:
 
491
            expansion = int(expansion)
 
492
        except (TypeError, ValueError):
 
493
            pass
 
494
        if args:
 
495
            evaluator = FunctionEvaluator(name, args[1:-1], expansion)
 
496
            self.cpp_namespace[name] = evaluator
 
497
        else:
 
498
            self.cpp_namespace[name] = expansion
 
499
 
 
500
    def do_undef(self, t):
 
501
        """
 
502
        Default handling of a #undef line.
 
503
        """
 
504
        try: del self.cpp_namespace[t[1]]
 
505
        except KeyError: pass
 
506
 
 
507
    def do_import(self, t):
 
508
        """
 
509
        Default handling of a #import line.
 
510
        """
 
511
        # XXX finish this -- maybe borrow/share logic from do_include()...?
 
512
        pass
 
513
 
 
514
    def do_include(self, t):
 
515
        """
 
516
        Default handling of a #include line.
 
517
        """
 
518
        t = self.resolve_include(t)
 
519
        include_file = self.find_include_file(t)
 
520
        if include_file:
 
521
            #print "include_file =", include_file
 
522
            self.result.append(include_file)
 
523
            contents = self.read_file(include_file)
 
524
            new_tuples = [('scons_current_file', include_file)] + \
 
525
                         self.tupleize(contents) + \
 
526
                         [('scons_current_file', self.current_file)]
 
527
            self.tuples[:] = new_tuples + self.tuples
 
528
 
 
529
    # Date: Tue, 22 Nov 2005 20:26:09 -0500
 
530
    # From: Stefan Seefeld <seefeld@sympatico.ca>
 
531
    #
 
532
    # By the way, #include_next is not the same as #include. The difference
 
533
    # being that #include_next starts its search in the path following the
 
534
    # path that let to the including file. In other words, if your system
 
535
    # include paths are ['/foo', '/bar'], and you are looking at a header
 
536
    # '/foo/baz.h', it might issue an '#include_next <baz.h>' which would
 
537
    # correctly resolve to '/bar/baz.h' (if that exists), but *not* see
 
538
    # '/foo/baz.h' again. See http://www.delorie.com/gnu/docs/gcc/cpp_11.html
 
539
    # for more reasoning.
 
540
    #
 
541
    # I have no idea in what context 'import' might be used.
 
542
 
 
543
    # XXX is #include_next really the same as #include ?
 
544
    do_include_next = do_include
 
545
 
 
546
    # Utility methods for handling resolution of include files.
 
547
 
 
548
    def resolve_include(self, t):
 
549
        """Resolve a tuple-ized #include line.
 
550
 
 
551
        This handles recursive expansion of values without "" or <>
 
552
        surrounding the name until an initial " or < is found, to handle
 
553
                #include FILE
 
554
        where FILE is a #define somewhere else.
 
555
        """
 
556
        s = t[1]
 
557
        while not s[0] in '<"':
 
558
            #print "s =", s
 
559
            try:
 
560
                s = self.cpp_namespace[s]
 
561
            except KeyError:
 
562
                m = function_name.search(s)
 
563
                s = self.cpp_namespace[m.group(1)]
 
564
                if callable(s):
 
565
                    args = function_arg_separator.split(m.group(2))
 
566
                    s = apply(s, args)
 
567
            if not s:
 
568
                return None
 
569
        return (t[0], s[0], s[1:-1])
 
570
 
 
571
    def all_include(self, t):
 
572
        """
 
573
        """
 
574
        self.result.append(self.resolve_include(t))
 
575
 
 
576
class DumbPreProcessor(PreProcessor):
 
577
    """A preprocessor that ignores all #if/#elif/#else/#endif directives
 
578
    and just reports back *all* of the #include files (like the classic
 
579
    SCons scanner did).
 
580
 
 
581
    This is functionally equivalent to using a regular expression to
 
582
    find all of the #include lines, only slower.  It exists mainly as
 
583
    an example of how the main PreProcessor class can be sub-classed
 
584
    to tailor its behavior.
 
585
    """
 
586
    def __init__(self, *args, **kw):
 
587
        apply(PreProcessor.__init__, (self,)+args, kw)
 
588
        d = self.default_table
 
589
        for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']:
 
590
            d[func] = d[func] = self.do_nothing
 
591
 
 
592
del __revision__