+
+class Pre_processor:
+ def __init__ (self, raw_lines):
+ self.lines = []
+ self.active = [1]
+ self.process_function = self.process_line
+ self.macro_name = ''
+ self.macro_body = ''
+ self.process (raw_lines)
+
+ def process_line (self, line):
+ global macros
+ m = re.match ('^([ \t]*([a-zA-Z]+))', line)
+ s = line
+ if m:
+ word = m.group (2)
+ debug ('MACRO?: ' + `word`)
+ if word in pre_processor_commands:
+ line = line[len (m.group (1)):]
+ eval ('self.process_macro_%s (line)' % word)
+ s = ''
+ else:
+ if macros.has_key (word):
+ s = macros[word] + line[len (m.group (1)):]
+ if not self.active [-1]:
+ s = ''
+ return s
+
+ def process_macro_body (self, line):
+ global macros
+ # dig this: mup allows ifdefs inside macro bodies
+ s = self.process_line (line)
+ m = re.match ('(.*[^\\\\])(@)(.*)', s)
+ if m:
+ self.macro_body = self.macro_body + '\n' + m.group (1)
+ macros[self.macro_name] = self.macro_body
+ debug ('MACROS: ' + `macros`)
+ # don't do nested multi-line defines
+ self.process_function = self.process_line
+ if m.group (3):
+ s = m.group (3)
+ else:
+ s = ''
+ else:
+ self.macro_body = self.macro_body + '\n' + s
+ s = ''
+ return s
+
+ # duh: mup is strictly line-based, except for `define',
+ # which is `@' terminated and may span several lines
+ def process_macro_define (self, line):
+ global macros
+ # don't define new macros in unactive areas
+ if not self.active[-1]:
+ return
+ m = re.match ('^[ \t]*([a-zA-Z][a-zA-Z1-9_]*)(([^@]*)|(\\\\@))(@)?', line)
+ n = m.group (1)
+ if m.group (5):
+ if m.group (2):
+ e = m.group (2)
+ else:
+ e = ''
+ macros[n] = e
+ debug ('MACROS: ' + `macros`)
+ else:
+ # To support nested multi-line define's
+ # process_function and macro_name, macro_body
+ # should become lists (stacks)
+ # The mup manual is undetermined on this
+ # and I haven't seen examples doing it.
+ #
+ # don't do nested multi-line define's
+ if m.group (2):
+ self.macro_body = m.group (2)
+ else:
+ self.macro_body = ''
+ self.macro_name = n
+ self.process_function = self.process_macro_body