@@ -45,137 +45,6 @@ def ReadFile(filename):
4545 return lines
4646
4747
48- def ReadMacroFiles (filenames ):
49- """
50-
51- :rtype: List(str)
52- """
53- result = []
54- for filename in filenames :
55- with open (filename , "rt" ) as f :
56- # strip python-like comments and whitespace padding
57- lines = [line .split ('#' )[0 ].strip () for line in f ]
58- # filter empty lines
59- result .extend (filter (bool , lines ))
60- return result
61-
62-
63- def ExpandConstants (lines , constants ):
64- for key , value in constants .items ():
65- lines = lines .replace (key , str (value ))
66- return lines
67-
68-
69- def ExpandMacros (lines , macros ):
70- def expander (s ):
71- return ExpandMacros (s , macros )
72-
73- for name , macro in macros .items ():
74- name_pattern = re .compile ("\\ b%s\\ (" % name )
75- pattern_match = name_pattern .search (lines , 0 )
76- while pattern_match is not None :
77- # Scan over the arguments
78- height = 1
79- start = pattern_match .start ()
80- end = pattern_match .end ()
81- assert lines [end - 1 ] == '('
82- last_match = end
83- arg_index = [0 ] # Wrap state into array, to work around Python "scoping"
84- mapping = {}
85-
86- def add_arg (s ):
87- # Remember to expand recursively in the arguments
88- if arg_index [0 ] >= len (macro .args ):
89- return
90- replacement = expander (s .strip ())
91- mapping [macro .args [arg_index [0 ]]] = replacement
92- arg_index [0 ] += 1
93-
94- while end < len (lines ) and height > 0 :
95- # We don't count commas at higher nesting levels.
96- if lines [end ] == ',' and height == 1 :
97- add_arg (lines [last_match :end ])
98- last_match = end + 1
99- elif lines [end ] in ['(' , '{' , '[' ]:
100- height = height + 1
101- elif lines [end ] in [')' , '}' , ']' ]:
102- height = height - 1
103- end = end + 1
104- # Remember to add the last match.
105- add_arg (lines [last_match :end - 1 ])
106- if arg_index [0 ] < len (macro .args ) - 1 :
107- lineno = lines .count (os .linesep , 0 , start ) + 1
108- raise Exception (
109- 'line %s: Too few arguments for macro "%s"' % (lineno , name ))
110- result = macro .expand (mapping )
111- # Replace the occurrence of the macro with the expansion
112- lines = lines [:start ] + result + lines [end :]
113- pattern_match = name_pattern .search (lines , start + len (result ))
114- return lines
115-
116-
117- class TextMacro :
118- def __init__ (self , args , body ):
119- self .args = args
120- self .body = body
121-
122- def expand (self , mapping ):
123- result = self .body
124- for key , value in mapping .items ():
125- result = result .replace (key , value )
126- return result
127-
128-
129- class PythonMacro :
130- def __init__ (self , args , fun ):
131- self .args = args
132- self .fun = fun
133-
134- def expand (self , mapping ):
135- args = []
136- for arg in self .args :
137- args .append (mapping [arg ])
138- return str (self .fun (* args ))
139-
140-
141- CONST_PATTERN = re .compile ('^const\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$' )
142- MACRO_PATTERN = re .compile ('^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*);$' )
143- PYTHON_MACRO_PATTERN = re .compile ('^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*);$' )
144-
145-
146- def ReadMacros (macro_files ):
147- lines = ReadMacroFiles (macro_files )
148- constants = {}
149- macros = {}
150- for line in lines :
151- line = line .split ('#' )[0 ].strip ()
152- if len (line ) == 0 :
153- continue
154- const_match = CONST_PATTERN .match (line )
155- if const_match :
156- name = const_match .group (1 )
157- value = const_match .group (2 ).strip ()
158- constants [name ] = value
159- else :
160- macro_match = MACRO_PATTERN .match (line )
161- if macro_match :
162- name = macro_match .group (1 )
163- args = [p .strip () for p in macro_match .group (2 ).split (',' )]
164- body = macro_match .group (3 ).strip ()
165- macros [name ] = TextMacro (args , body )
166- else :
167- python_match = PYTHON_MACRO_PATTERN .match (line )
168- if python_match :
169- name = python_match .group (1 )
170- args = [p .strip () for p in macro_match .group (2 ).split (',' )]
171- body = python_match .group (3 ).strip ()
172- fun = eval ("lambda " + "," .join (args ) + ': ' + body )
173- macros [name ] = PythonMacro (args , fun )
174- else :
175- raise Exception ("Illegal line: " + line )
176- return constants , macros
177-
178-
17948TEMPLATE = """
18049#include "env-inl.h"
18150#include "node_native_module.h"
@@ -243,10 +112,8 @@ def GetDefinition(var, source, step=30):
243112 return definition , len (code_points )
244113
245114
246- def AddModule (filename , consts , macros , definitions , initializers ):
115+ def AddModule (filename , definitions , initializers ):
247116 code = ReadFile (filename )
248- code = ExpandConstants (code , consts )
249- code = ExpandMacros (code , macros )
250117 name = NormalizeFileName (filename )
251118 slug = SLUGGER_RE .sub ('_' , name )
252119 var = slug + '_raw'
@@ -267,15 +134,12 @@ def NormalizeFileName(filename):
267134
268135
269136def JS2C (source_files , target ):
270- # Process input from all *macro.py files
271- consts , macros = ReadMacros (source_files ['.py' ])
272-
273137 # Build source code lines
274138 definitions = []
275139 initializers = []
276140
277141 for filename in source_files ['.js' ]:
278- AddModule (filename , consts , macros , definitions , initializers )
142+ AddModule (filename , definitions , initializers )
279143
280144 config_def , config_size = handle_config_gypi (source_files ['config.gypi' ])
281145 definitions .append (config_def )
@@ -341,8 +205,8 @@ def main():
341205 global is_verbose
342206 is_verbose = options .verbose
343207 source_files = functools .reduce (SourceFileByExt , options .sources , {})
344- # Should have exactly 3 types: `.js`, `.py `, and `.gypi`
345- assert len (source_files ) == 3
208+ # Should have exactly 2 types: `.js`, and `.gypi`
209+ assert len (source_files ) == 2
346210 # Currently config.gypi is the only `.gypi` file allowed
347211 assert source_files ['.gypi' ] == ['config.gypi' ]
348212 source_files ['config.gypi' ] = source_files .pop ('.gypi' )[0 ]
0 commit comments