1#!/usr/bin/env python
2#
3# Takes a directory of files and zips them up (as uncompressed files).
4# This then gets converted into a C data structure which can be read
5# like a filesystem at runtime.
6#
7# This is somewhat like frozen modules in python, but allows arbitrary files
8# to be used.
9
10from __future__ import print_function
11
12import argparse
13import os
14import subprocess
15import sys
16import types
17
18def create_zip(zip_filename, zip_dir):
19    abs_zip_filename = os.path.abspath(zip_filename)
20    save_cwd = os.getcwd()
21    os.chdir(zip_dir)
22    if os.path.exists(abs_zip_filename):
23        os.remove(abs_zip_filename)
24    subprocess.check_call(['zip', '-0', '-r', '-D', abs_zip_filename, '.'])
25    os.chdir(save_cwd)
26
27def create_c_from_file(c_filename, zip_filename):
28    with open(zip_filename, 'rb') as zip_file:
29        with open(c_filename, 'wb') as c_file:
30            print('#include <stdint.h>', file=c_file)
31            print('', file=c_file)
32            print('const uint8_t memzip_data[] = {', file=c_file)
33            while True:
34                buf = zip_file.read(16)
35                if not buf:
36                    break
37                print('   ', end='', file=c_file)
38                for byte in buf:
39                    if type(byte) is types.StringType:
40                        print(' 0x{:02x},'.format(ord(byte)), end='', file=c_file)
41                    else:
42                        print(' 0x{:02x},'.format(byte), end='', file=c_file)
43                print('', file=c_file)
44            print('};', file=c_file)
45
46def main():
47    parser = argparse.ArgumentParser(
48        prog='make-memzip.py',
49        usage='%(prog)s [options] [command]',
50        description='Generates a C source memzip file.'
51    )
52    parser.add_argument(
53        '-z', '--zip-file',
54        dest='zip_filename',
55        help='Specifies the name of the created zip file.',
56        default='memzip_files.zip'
57    )
58    parser.add_argument(
59        '-c', '--c-file',
60        dest='c_filename',
61        help='Specifies the name of the created C source file.',
62        default='memzip_files.c'
63    )
64    parser.add_argument(
65        dest='source_dir',
66        default='memzip_files'
67    )
68    args = parser.parse_args(sys.argv[1:])
69
70    print('args.zip_filename =', args.zip_filename)
71    print('args.c_filename =', args.c_filename)
72    print('args.source_dir =', args.source_dir)
73
74    create_zip(args.zip_filename, args.source_dir)
75    create_c_from_file(args.c_filename, args.zip_filename)
76
77if __name__ == "__main__":
78    main()
79
80