@@ -74,20 +74,27 @@ def ExpandConstants(lines, constants):
7474
7575
7676def ExpandMacros (lines , macros ):
77+ def expander (s ):
78+ return ExpandMacros (s , macros )
7779 for name , macro in macros .items ():
78- start = lines .find (name + '(' , 0 )
79- while start != - 1 :
80+ name_pattern = re .compile ("\\ b%s\\ (" % name )
81+ pattern_match = name_pattern .search (lines , 0 )
82+ while pattern_match is not None :
8083 # Scan over the arguments
81- assert lines [start + len (name )] == '('
8284 height = 1
83- end = start + len (name ) + 1
85+ start = pattern_match .start ()
86+ end = pattern_match .end ()
87+ assert lines [end - 1 ] == '('
8488 last_match = end
85- arg_index = 0
86- mapping = { }
89+ arg_index = [ 0 ] # Wrap state into array, to work around Python "scoping"
90+ mapping = {}
8791 def add_arg (str ):
8892 # Remember to expand recursively in the arguments
89- replacement = ExpandMacros (str .strip (), macros )
90- mapping [macro .args [arg_index ]] = replacement
93+ if arg_index [0 ] >= len (macro .args ):
94+ return
95+ replacement = expander (str .strip ())
96+ mapping [macro .args [arg_index [0 ]]] = replacement
97+ arg_index [0 ] += 1
9198 while end < len (lines ) and height > 0 :
9299 # We don't count commas at higher nesting levels.
93100 if lines [end ] == ',' and height == 1 :
@@ -100,10 +107,13 @@ def add_arg(str):
100107 end = end + 1
101108 # Remember to add the last match.
102109 add_arg (lines [last_match :end - 1 ])
110+ if arg_index [0 ] < len (macro .args ) - 1 :
111+ lineno = lines .count (os .linesep , 0 , start ) + 1
112+ raise Exception ('line %s: Too few arguments for macro "%s"' % (lineno , name ))
103113 result = macro .expand (mapping )
104114 # Replace the occurrence of the macro with the expansion
105115 lines = lines [:start ] + result + lines [end :]
106- start = lines . find ( name + '(' , start )
116+ pattern_match = name_pattern . search ( lines , start + len ( result ) )
107117 return lines
108118
109119
0 commit comments