make-frozen.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. #
  20. from __future__ import print_function
  21. import sys
  22. import os
  23. def module_name(f):
  24. return f
  25. modules = []
  26. root = sys.argv[1].rstrip("/")
  27. root_len = len(root)
  28. for dirpath, dirnames, filenames in os.walk(root):
  29. for f in filenames:
  30. fullpath = dirpath + "/" + f
  31. st = os.stat(fullpath)
  32. modules.append((fullpath[root_len + 1:], st))
  33. print("#include <stdint.h>")
  34. print("const char mp_frozen_str_names[] = {")
  35. for f, st in modules:
  36. m = module_name(f)
  37. print('"%s\\0"' % m)
  38. print('"\\0"};')
  39. print("const uint32_t mp_frozen_str_sizes[] = {")
  40. for f, st in modules:
  41. print("%d," % st.st_size)
  42. print("};")
  43. print("const char mp_frozen_str_content[] = {")
  44. for f, st in modules:
  45. data = open(sys.argv[1] + "/" + f, "rb").read()
  46. # We need to properly escape the script data to create a C string.
  47. # When C parses hex characters of the form \x00 it keeps parsing the hex
  48. # data until it encounters a non-hex character. Thus one must create
  49. # strings of the form "data\x01" "abc" to properly encode this kind of
  50. # data. We could just encode all characters as hex digits but it's nice
  51. # to be able to read the resulting C code as ASCII when possible.
  52. data = bytearray(data) # so Python2 extracts each byte as an integer
  53. esc_dict = {ord('\n'): '\\n', ord('\r'): '\\r', ord('"'): '\\"', ord('\\'): '\\\\'}
  54. chrs = ['"']
  55. break_str = False
  56. for c in data:
  57. try:
  58. chrs.append(esc_dict[c])
  59. except KeyError:
  60. if 32 <= c <= 126:
  61. if break_str:
  62. chrs.append('" "')
  63. break_str = False
  64. chrs.append(chr(c))
  65. else:
  66. chrs.append('\\x%02x' % c)
  67. break_str = True
  68. chrs.append('\\0"')
  69. print(''.join(chrs))
  70. print("};")