@@ -201,8 +201,6 @@ def freeze_internal(kind, path, script, opt):
201
201
if not os .path .isdir (path ):
202
202
raise FreezeError ("freeze path must be a directory: {}" .format (path ))
203
203
if script is None and kind == KIND_AS_STR :
204
- if any (f [0 ] == KIND_AS_STR for f in manifest_list ):
205
- raise FreezeError ("can only freeze one str directory" )
206
204
manifest_list .append ((KIND_AS_STR , path , script , opt ))
207
205
elif script is None or isinstance (script , str ) and script .find ("." ) == - 1 :
208
206
# Recursively search `path` for files to freeze, optionally restricted
@@ -235,6 +233,70 @@ def freeze_internal(kind, path, script, opt):
235
233
manifest_list .append ((kind , path , script , opt ))
236
234
237
235
236
+ def generate_frozen_str_content (paths ):
237
+ def module_name (f ):
238
+ return f
239
+
240
+ modules = []
241
+ output = []
242
+
243
+ for path in paths :
244
+ root = path .rstrip ("/" )
245
+ root_len = len (root )
246
+
247
+ for dirpath , dirnames , filenames in os .walk (root ):
248
+ for f in filenames :
249
+ fullpath = dirpath + "/" + f
250
+ st = os .stat (fullpath )
251
+ modules .append ((path , fullpath [root_len + 1 :], st ))
252
+
253
+ output .append ("#include <stdint.h>\n " )
254
+ output .append ("const char mp_frozen_str_names[] = {\n " )
255
+ for _path , f , st in modules :
256
+ m = module_name (f )
257
+ output .append ('"%s\\ 0"\n ' % m )
258
+ output .append ('"\\ 0"};\n ' )
259
+
260
+ output .append ("const uint32_t mp_frozen_str_sizes[] = {\n " )
261
+
262
+ for _path , f , st in modules :
263
+ output .append ("%d," % st .st_size )
264
+
265
+ output .append ("0};\n " )
266
+
267
+ output .append ("const char mp_frozen_str_content[] = {\n " )
268
+ for path , f , st in modules :
269
+ data = open (path + "/" + f , "rb" ).read ()
270
+
271
+ # We need to properly escape the script data to create a C string.
272
+ # When C parses hex characters of the form \x00 it keeps parsing the hex
273
+ # data until it encounters a non-hex character. Thus one must create
274
+ # strings of the form "data\x01" "abc" to properly encode this kind of
275
+ # data. We could just encode all characters as hex digits but it's nice
276
+ # to be able to read the resulting C code as ASCII when possible.
277
+
278
+ data = bytearray (data ) # so Python2 extracts each byte as an integer
279
+ esc_dict = {ord ("\n " ): "\\ n" , ord ("\r " ): "\\ r" , ord ('"' ): '\\ "' , ord ("\\ " ): "\\ \\ " }
280
+ output .append ('"' )
281
+ break_str = False
282
+ for c in data :
283
+ try :
284
+ output .append (esc_dict [c ])
285
+ except KeyError :
286
+ if 32 <= c <= 126 :
287
+ if break_str :
288
+ output .append ('" "' )
289
+ break_str = False
290
+ output .append (chr (c ))
291
+ else :
292
+ output .append ("\\ x%02x" % c )
293
+ break_str = True
294
+ output .append ('\\ 0"\n ' )
295
+
296
+ output .append ('"\\ 0"};\n ' )
297
+ return "" .join (output )
298
+
299
+
238
300
def main ():
239
301
# Parse arguments
240
302
import argparse
@@ -264,7 +326,6 @@ def main():
264
326
sys .exit (1 )
265
327
266
328
# Get paths to tools
267
- MAKE_FROZEN = VARS ["MPY_DIR" ] + "/tools/make-frozen.py"
268
329
MPY_CROSS = VARS ["MPY_DIR" ] + "/mpy-cross/mpy-cross"
269
330
if sys .platform == "win32" :
270
331
MPY_CROSS += ".exe"
@@ -327,10 +388,7 @@ def main():
327
388
return
328
389
329
390
# Freeze paths as strings
330
- res , output_str = system ([sys .executable , MAKE_FROZEN ] + str_paths )
331
- if res != 0 :
332
- print ("error freezing strings {}: {}" .format (str_paths , output_str ))
333
- sys .exit (1 )
391
+ output_str = generate_frozen_str_content (str_paths )
334
392
335
393
# Freeze .mpy files
336
394
if mpy_files :
@@ -365,7 +423,7 @@ def main():
365
423
mkdir (args .output )
366
424
with open (args .output , "wb" ) as f :
367
425
f .write (b"//\n // Content for MICROPY_MODULE_FROZEN_STR\n //\n " )
368
- f .write (output_str )
426
+ f .write (output_str . encode () )
369
427
f .write (b"//\n // Content for MICROPY_MODULE_FROZEN_MPY\n //\n " )
370
428
f .write (output_mpy )
371
429
0 commit comments