2015-07-06 12:46:48 +01:00
|
|
|
#!/usr/bin/env python
|
2015-01-20 09:52:12 +00:00
|
|
|
#
|
|
|
|
# Create frozen modules structure for MicroPython.
|
|
|
|
#
|
|
|
|
# Usage:
|
|
|
|
#
|
|
|
|
# Have a directory with modules to be frozen (only modules, not packages
|
|
|
|
# supported so far):
|
|
|
|
#
|
|
|
|
# frozen/foo.py
|
|
|
|
# frozen/bar.py
|
|
|
|
#
|
|
|
|
# Run script, passing path to the directory above:
|
|
|
|
#
|
|
|
|
# ./make-frozen.py frozen > frozen.c
|
|
|
|
#
|
2016-01-31 22:24:16 +00:00
|
|
|
# Include frozen.c in your build, having defined MICROPY_MODULE_FROZEN_STR in
|
2015-01-20 09:52:12 +00:00
|
|
|
# config.
|
|
|
|
#
|
2015-07-06 12:09:16 +01:00
|
|
|
from __future__ import print_function
|
2015-01-20 09:52:12 +00:00
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
|
|
def module_name(f):
|
2016-05-21 19:39:27 +01:00
|
|
|
return f
|
2015-01-20 09:52:12 +00:00
|
|
|
|
2020-02-27 04:36:53 +00:00
|
|
|
|
2015-01-20 09:52:12 +00:00
|
|
|
modules = []
|
|
|
|
|
2019-10-10 13:22:29 +01:00
|
|
|
if len(sys.argv) > 1:
|
|
|
|
root = sys.argv[1].rstrip("/")
|
|
|
|
root_len = len(root)
|
|
|
|
|
|
|
|
for dirpath, dirnames, filenames in os.walk(root):
|
|
|
|
for f in filenames:
|
|
|
|
fullpath = dirpath + "/" + f
|
|
|
|
st = os.stat(fullpath)
|
2020-02-27 04:36:53 +00:00
|
|
|
modules.append((fullpath[root_len + 1 :], st))
|
2015-01-20 09:52:12 +00:00
|
|
|
|
|
|
|
print("#include <stdint.h>")
|
2016-01-31 22:24:16 +00:00
|
|
|
print("const char mp_frozen_str_names[] = {")
|
2016-01-03 16:08:45 +00:00
|
|
|
for f, st in modules:
|
|
|
|
m = module_name(f)
|
2016-05-21 19:39:27 +01:00
|
|
|
print('"%s\\0"' % m)
|
2016-01-03 16:08:45 +00:00
|
|
|
print('"\\0"};')
|
|
|
|
|
2016-01-31 22:24:16 +00:00
|
|
|
print("const uint32_t mp_frozen_str_sizes[] = {")
|
2015-01-20 09:52:12 +00:00
|
|
|
|
|
|
|
for f, st in modules:
|
|
|
|
print("%d," % st.st_size)
|
|
|
|
|
2020-09-10 11:22:49 +01:00
|
|
|
print("0};")
|
2015-01-20 09:52:12 +00:00
|
|
|
|
2016-01-31 22:24:16 +00:00
|
|
|
print("const char mp_frozen_str_content[] = {")
|
2015-01-20 09:52:12 +00:00
|
|
|
for f, st in modules:
|
2015-05-29 22:38:44 +01:00
|
|
|
data = open(sys.argv[1] + "/" + f, "rb").read()
|
2016-05-13 13:12:01 +01:00
|
|
|
|
|
|
|
# We need to properly escape the script data to create a C string.
|
|
|
|
# When C parses hex characters of the form \x00 it keeps parsing the hex
|
|
|
|
# data until it encounters a non-hex character. Thus one must create
|
|
|
|
# strings of the form "data\x01" "abc" to properly encode this kind of
|
|
|
|
# data. We could just encode all characters as hex digits but it's nice
|
|
|
|
# to be able to read the resulting C code as ASCII when possible.
|
|
|
|
|
2020-02-27 04:36:53 +00:00
|
|
|
data = bytearray(data) # so Python2 extracts each byte as an integer
|
|
|
|
esc_dict = {ord("\n"): "\\n", ord("\r"): "\\r", ord('"'): '\\"', ord("\\"): "\\\\"}
|
2016-05-13 13:12:01 +01:00
|
|
|
chrs = ['"']
|
|
|
|
break_str = False
|
|
|
|
for c in data:
|
|
|
|
try:
|
|
|
|
chrs.append(esc_dict[c])
|
|
|
|
except KeyError:
|
|
|
|
if 32 <= c <= 126:
|
|
|
|
if break_str:
|
|
|
|
chrs.append('" "')
|
|
|
|
break_str = False
|
|
|
|
chrs.append(chr(c))
|
|
|
|
else:
|
2020-02-27 04:36:53 +00:00
|
|
|
chrs.append("\\x%02x" % c)
|
2016-05-13 13:12:01 +01:00
|
|
|
break_str = True
|
|
|
|
chrs.append('\\0"')
|
2020-02-27 04:36:53 +00:00
|
|
|
print("".join(chrs))
|
2016-05-13 13:12:01 +01:00
|
|
|
|
2020-09-10 11:22:49 +01:00
|
|
|
print('"\\0"};')
|