3737import string
3838
3939
40- def ToCString(contents):
41- step = 20
42- slices = (contents[i:i+step] for i in xrange(0, len(contents), step))
43- slices = map(lambda s: ','.join(str(ord(c)) for c in s), slices)
44- return ',\n'.join(slices)
40+ def ToCArray(filename, lines):
41+ return ','.join(str(ord(c)) for c in lines)
4542
4643
4744def ReadFile(filename):
@@ -64,6 +61,21 @@ def ReadLines(filename):
6461 return result
6562
6663
64+ def LoadConfigFrom(name):
65+ import ConfigParser
66+ config = ConfigParser.ConfigParser()
67+ config.read(name)
68+ return config
69+
70+
71+ def ParseValue(string):
72+ string = string.strip()
73+ if string.startswith('[') and string.endswith(']'):
74+ return string.lstrip('[').rstrip(']').split()
75+ else:
76+ return string
77+
78+
6779def ExpandConstants(lines, constants):
6880 for key, value in constants.items():
6981 lines = lines.replace(key, str(value))
@@ -162,37 +174,53 @@ def ReadMacros(lines):
162174
163175
164176HEADER_TEMPLATE = """\
165- #ifndef NODE_NATIVES_H_
166- #define NODE_NATIVES_H_
177+ #ifndef node_natives_h
178+ #define node_natives_h
179+ namespace node {
167180
168- #include <stdint.h>
181+ %(source_lines)s\
182+
183+ struct _native {
184+ const char* name;
185+ const unsigned char* source;
186+ size_t source_len;
187+ };
188+
189+ static const struct _native natives[] = { %(native_lines)s };
190+
191+ }
192+ #endif
193+ """
169194
170- #define NODE_NATIVES_MAP(V) \\
171- {node_natives_map}
172195
173- namespace node {{
174- {sources}
175- }} // namespace node
196+ NATIVE_DECLARATION = """\
197+ { "%(id)s", %(escaped_id)s_native, sizeof(%(escaped_id)s_native) },
198+ """
176199
177- #endif // NODE_NATIVES_H_
200+ SOURCE_DECLARATION = """\
201+ const unsigned char %(escaped_id)s_native[] = { %(data)s };
178202"""
179203
180204
181- NODE_NATIVES_MAP = """\
182- V({escaped_id}) \\
205+ GET_DELAY_INDEX_CASE = """\
206+ if (strcmp(name, "%(id)s") == 0) return %(i)i;
183207"""
184208
185209
186- SOURCES = """\
187- static const uint8_t {escaped_id}_name[] = {{
188- {name}}};
189- static const uint8_t {escaped_id}_data[] = {{
190- {data}}};
210+ GET_DELAY_SCRIPT_SOURCE_CASE = """\
211+ if (index == %(i)i) return Vector<const char>(%(id)s, %(length)i);
191212"""
192213
193214
215+ GET_DELAY_SCRIPT_NAME_CASE = """\
216+ if (index == %(i)i) return Vector<const char>("%(name)s", %(length)i);
217+ """
218+
194219def JS2C(source, target):
220+ ids = []
221+ delay_ids = []
195222 modules = []
223+ # Locate the macros file name.
196224 consts = {}
197225 macros = {}
198226 macro_lines = []
@@ -207,14 +235,18 @@ def JS2C(source, target):
207235 (consts, macros) = ReadMacros(macro_lines)
208236
209237 # Build source code lines
210- node_natives_map = []
211- sources = []
238+ source_lines = [ ]
239+ source_lines_empty = []
240+
241+ native_lines = []
212242
213243 for s in modules:
244+ delay = str(s).endswith('-delay.js')
214245 lines = ReadFile(str(s))
246+
215247 lines = ExpandConstants(lines, consts)
216248 lines = ExpandMacros(lines, macros)
217- data = ToCString( lines)
249+ data = ToCArray(s, lines)
218250
219251 # On Windows, "./foo.bar" in the .gyp file is passed as "foo.bar"
220252 # so don't assume there is always a slash in the file path.
@@ -229,22 +261,93 @@ def JS2C(source, target):
229261 if '.' in id:
230262 id = id.split('.', 1)[0]
231263
232- name = ToCString(id)
264+ if delay: id = id[:-6]
265+ if delay:
266+ delay_ids.append((id, len(lines)))
267+ else:
268+ ids.append((id, len(lines)))
269+
233270 if '__enclose_io_memfs__' in id:
234271 escaped_id = re.sub('\W', '_', id.replace('/', '__'))
235272 else:
236273 escaped_id = id.replace('-', '_').replace('/', '_')
237- node_natives_map.append(NODE_NATIVES_MAP.format(**locals()))
238- sources.append(SOURCES.format(**locals()))
239274
240- node_natives_map = ''.join(node_natives_map)
241- sources = ''.join(sources)
275+ source_lines.append(SOURCE_DECLARATION % {
276+ 'id': id,
277+ 'escaped_id': escaped_id,
278+ 'data': data
279+ })
280+ source_lines_empty.append(SOURCE_DECLARATION % {
281+ 'id': id,
282+ 'escaped_id': escaped_id,
283+ 'data': 0
284+ })
285+ native_lines.append(NATIVE_DECLARATION % {
286+ 'id': id,
287+ 'escaped_id': escaped_id
288+ })
289+
290+ # Build delay support functions
291+ get_index_cases = [ ]
292+ get_script_source_cases = [ ]
293+ get_script_name_cases = [ ]
294+
295+ i = 0
296+ for (id, length) in delay_ids:
297+ native_name = "native %s.js" % id
298+ get_index_cases.append(GET_DELAY_INDEX_CASE % { 'id': id, 'i': i })
299+ get_script_source_cases.append(GET_DELAY_SCRIPT_SOURCE_CASE % {
300+ 'id': id,
301+ 'length': length,
302+ 'i': i
303+ })
304+ get_script_name_cases.append(GET_DELAY_SCRIPT_NAME_CASE % {
305+ 'name': native_name,
306+ 'length': len(native_name),
307+ 'i': i
308+ });
309+ i = i + 1
310+
311+ for (id, length) in ids:
312+ native_name = "native %s.js" % id
313+ get_index_cases.append(GET_DELAY_INDEX_CASE % { 'id': id, 'i': i })
314+ get_script_source_cases.append(GET_DELAY_SCRIPT_SOURCE_CASE % {
315+ 'id': id,
316+ 'length': length,
317+ 'i': i
318+ })
319+ get_script_name_cases.append(GET_DELAY_SCRIPT_NAME_CASE % {
320+ 'name': native_name,
321+ 'length': len(native_name),
322+ 'i': i
323+ });
324+ i = i + 1
242325
243326 # Emit result
244327 output = open(str(target[0]), "w")
245- output.write(HEADER_TEMPLATE.format(**locals()))
328+ output.write(HEADER_TEMPLATE % {
329+ 'builtin_count': len(ids) + len(delay_ids),
330+ 'delay_count': len(delay_ids),
331+ 'source_lines': "\n".join(source_lines),
332+ 'native_lines': "\n".join(native_lines),
333+ 'get_index_cases': "".join(get_index_cases),
334+ 'get_script_source_cases': "".join(get_script_source_cases),
335+ 'get_script_name_cases': "".join(get_script_name_cases)
336+ })
246337 output.close()
247338
339+ if len(target) > 1:
340+ output = open(str(target[1]), "w")
341+ output.write(HEADER_TEMPLATE % {
342+ 'builtin_count': len(ids) + len(delay_ids),
343+ 'delay_count': len(delay_ids),
344+ 'source_lines': "\n".join(source_lines_empty),
345+ 'get_index_cases': "".join(get_index_cases),
346+ 'get_script_source_cases': "".join(get_script_source_cases),
347+ 'get_script_name_cases': "".join(get_script_name_cases)
348+ })
349+ output.close()
350+
248351def main():
249352 natives = sys.argv[1]
250353 source_files = sys.argv[2:]
0 commit comments