1#!/usr/bin/env python 2# 3# Create frozen modules structure for MicroPython. 4# 5# Usage: 6# 7# Have a directory with modules to be frozen (only modules, not packages 8# supported so far): 9# 10# frozen/foo.py 11# frozen/bar.py 12# 13# Run script, passing path to the directory above: 14# 15# ./make-frozen.py frozen > frozen.c 16# 17# Include frozen.c in your build, having defined MICROPY_MODULE_FROZEN_STR in 18# config. 19# 20from __future__ import print_function 21import sys 22import os 23 24 25def module_name(f): 26 return f 27 28 29modules = [] 30 31if len(sys.argv) > 1: 32 root = sys.argv[1].rstrip("/") 33 root_len = len(root) 34 35 for dirpath, dirnames, filenames in os.walk(root): 36 for f in filenames: 37 fullpath = dirpath + "/" + f 38 st = os.stat(fullpath) 39 modules.append((fullpath[root_len + 1 :], st)) 40 41print("#include <stdint.h>") 42print("const char mp_frozen_str_names[] = {") 43for f, st in modules: 44 m = module_name(f) 45 print('"%s\\0"' % m) 46print('"\\0"};') 47 48print("const uint32_t mp_frozen_str_sizes[] = {") 49 50for f, st in modules: 51 print("%d," % st.st_size) 52 53print("0};") 54 55print("const char mp_frozen_str_content[] = {") 56for f, st in modules: 57 data = open(sys.argv[1] + "/" + f, "rb").read() 58 59 # We need to properly escape the script data to create a C string. 60 # When C parses hex characters of the form \x00 it keeps parsing the hex 61 # data until it encounters a non-hex character. Thus one must create 62 # strings of the form "data\x01" "abc" to properly encode this kind of 63 # data. We could just encode all characters as hex digits but it's nice 64 # to be able to read the resulting C code as ASCII when possible. 65 66 data = bytearray(data) # so Python2 extracts each byte as an integer 67 esc_dict = {ord("\n"): "\\n", ord("\r"): "\\r", ord('"'): '\\"', ord("\\"): "\\\\"} 68 chrs = ['"'] 69 break_str = False 70 for c in data: 71 try: 72 chrs.append(esc_dict[c]) 73 except KeyError: 74 if 32 <= c <= 126: 75 if break_str: 76 chrs.append('" "') 77 break_str = False 78 chrs.append(chr(c)) 79 else: 80 chrs.append("\\x%02x" % c) 81 break_str = True 82 chrs.append('\\0"') 83 print("".join(chrs)) 84 85print('"\\0"};') 86