Changeset 9ce911d in mainline for tools/mkarray.py


Ignore:
Timestamp:
2017-06-02T20:06:13Z (7 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f98434b8
Parents:
7367c31
Message:

improve binary data packer

  • optional deflate compression
  • performance improvements
  • generate an assembly source, a header file and a C source with metadata (all there files are stored in an uncompressed ZIP archive first to workaround the inability of GNU Make to express a dependency rule with multiple targets)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/mkarray.py

    r7367c31 r9ce911d  
    2828#
    2929"""
    30 C structure creator
     30Binary inline data packer
    3131"""
    3232
    3333import sys
    3434import os
    35 import struct
     35import zlib
     36import zipfile
     37import binascii
    3638
    3739def usage(prname):
    3840        "Print usage syntax"
    39         print("%s <DESTINATION> <LABEL> <AS_PROLOG> [SOURCE ...]" % prname)
     41        print("%s [--deflate] <DESTINATION> <LABEL> <AS_PROLOG> [SOURCE ...]" % prname)
     42
     43def arg_check():
     44        if (len(sys.argv) < 4):
     45                usage(sys.argv[0])
     46                sys.exit()
     47
     48def deflate(data):
     49        "Compress using deflate algorithm (without any headers)"
     50        return zlib.compress(data, 9)[2:-4]
     51
     52def chunks(string, length):
     53        "Produce string chunks"
     54        for start in range(0, len(string), length):
     55                yield string[start:start + length]
    4056
    4157def main():
    42         if (len(sys.argv) < 4):
    43                 usage(sys.argv[0])
    44                 return
     58        arg_check()
     59       
     60        if sys.argv[1] == "--deflate":
     61                sys.argv.pop(1)
     62                arg_check()
     63                compress = True
     64        else:
     65                compress = False
    4566       
    4667        dest = sys.argv[1]
     
    4970       
    5071        header_ctx = []
     72        desc_ctx = []
     73        size_ctx = []
    5174        data_ctx = []
     75       
     76        src_cnt = 0
    5277       
    5378        for src in sys.argv[4:]:
    5479                basename = os.path.basename(src)
     80                plainname = os.path.splitext(basename)[0]
    5581                symbol = basename.replace(".", "_")
    5682               
     
    6187                src_in.close()
    6288               
    63                 data_rec = "\t.byte "
     89                length = len(src_data)
    6490               
    65                 fmt = 'B'
    66                 item_size = struct.calcsize(fmt)
    67                 offset = 0
    68                 cnt = 0
     91                if compress:
     92                        src_data = deflate(src_data)
    6993               
    70                 while (len(src_data[offset:]) >= item_size):
    71                         byte = struct.unpack_from(fmt, src_data, offset)
    72                        
    73                         if (offset > 0):
    74                                 if ((cnt % 15) == 0):
    75                                         data_rec += "\n\t.byte "
    76                                 else:
    77                                         data_rec += ", "
    78                        
    79                         data_rec += "0x%x" % byte
    80                         offset += item_size
    81                         cnt += 1
     94                if sys.version_info < (3,):
     95                        src_data = bytearray(src_data)
    8296               
    83                 data_rec += "\n"
     97                length_out = len(src_data)
    8498               
    85                 header_ctx.append("extern uint64_t %s_size;" % symbol)
    8699                header_ctx.append("extern uint8_t %s[];" % symbol)
    87                
    88                 data_ctx.append(".globl %s_size" % symbol)
    89                 data_ctx.append(".balign 8");
    90                 data_ctx.append(".size %s_size, 8" % symbol)
    91                 data_ctx.append("%s_size:" % symbol)
    92                 data_ctx.append("\t.quad %u\n" % offset)
     100                header_ctx.append("extern size_t %s_size;" % symbol)
    93101               
    94102                data_ctx.append(".globl %s" % symbol)
    95103                data_ctx.append(".balign 8")
    96                 data_ctx.append(".size %s, %u" % (symbol, offset))
     104                data_ctx.append(".size %s, %u" % (symbol, length_out))
    97105                data_ctx.append("%s:" % symbol)
    98                 data_ctx.append(data_rec)
     106                data_ctx.append("\t.byte 0x" + ', 0x'.join(chunks(binascii.b2a_hex(src_data), 2)) + "\n")
     107               
     108                desc_field = []
     109                desc_field.append("\t{")
     110                desc_field.append("\t\t.name = \"%s\"," % plainname)
     111                desc_field.append("\t\t.addr = (void *) %s," % symbol)
     112                desc_field.append("\t\t.size = %u," % length_out)
     113                desc_field.append("\t\t.inflated = %u" % length)
     114                desc_field.append("\t}")
     115               
     116                desc_ctx.append("\n".join(desc_field))
     117               
     118                size_ctx.append("size_t %s_size = %u;" % (symbol, length_out))
     119               
     120                src_cnt += 1
    99121       
    100         header = open("%s.h" % dest, "w")
     122        archive = zipfile.ZipFile("%s.zip" % dest, "w", zipfile.ZIP_STORED)
    101123       
    102         header.write('/***************************************\n')
    103         header.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
    104         header.write(' * Generated by: tools/mkarray.py      *\n')
    105         header.write(' ***************************************/\n\n')
    106         header.write("#ifndef %s_H_\n" % label)
    107         header.write("#define %s_H_\n\n" % label)
    108         header.write("#include <stddef.h>\n")
    109         header.write("#include <stdint.h>\n\n")
    110         header.write("\n".join(header_ctx))
    111         header.write("\n\n")
    112         header.write("#endif\n")
     124        data = ''
     125        data += '/***************************************\n'
     126        data += ' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n'
     127        data += ' * Generated by: tools/mkarray.py      *\n'
     128        data += ' ***************************************/\n\n'
     129        data += "#ifndef %sS_H_\n" % label.upper()
     130        data += "#define %sS_H_\n\n" % label.upper()
     131        data += "#include <stddef.h>\n"
     132        data += "#include <stdint.h>\n\n"
     133        data += "#define %sS  %u\n\n" % (label.upper(), src_cnt)
     134        data += "typedef struct {\n"
     135        data += "\tconst char *name;\n"
     136        data += "\tvoid *addr;\n"
     137        data += "\tsize_t size;\n"
     138        data += "\tsize_t inflated;\n"
     139        data += "} %s_t;\n\n" % label
     140        data += "extern %s_t %ss[];\n\n" % (label, label)
     141        data += "\n".join(header_ctx)
     142        data += "\n\n"
     143        data += "#endif\n"
     144        archive.writestr("%s.h" % dest, data)
    113145       
    114         header.close()
     146        data = ''
     147        data += '/***************************************\n'
     148        data += ' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n'
     149        data += ' * Generated by: tools/mkarray.py      *\n'
     150        data += ' ***************************************/\n\n'
     151        data += as_prolog
     152        data += '.data\n\n'
     153        data += "\n".join(data_ctx)
     154        data += "\n"
     155        archive.writestr("%s.s" % dest, data)
    115156       
    116         data = open("%s.s" % dest, "w")
     157        data = ''
     158        data += '/***************************************\n'
     159        data += ' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n'
     160        data += ' * Generated by: tools/mkarray.py      *\n'
     161        data += ' ***************************************/\n\n'
     162        data += "#include \"%s.h\"\n\n" % dest
     163        data += "%s_t %ss[] = {\n" % (label, label)
     164        data += ",\n".join(desc_ctx)
     165        data += "\n"
     166        data += "};\n\n"
     167        data += "\n".join(size_ctx)
     168        data += "\n"
     169        archive.writestr("%s_desc.c" % dest, data)
    117170       
    118         data.write('/***************************************\n')
    119         data.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
    120         data.write(' * Generated by: tools/mkarray.py      *\n')
    121         data.write(' ***************************************/\n\n')
    122         data.write(as_prolog)
    123         data.write('.data\n\n')
    124         data.write("\n".join(data_ctx))
    125        
    126         data.close()
     171        archive.close()
    127172
    128173if __name__ == '__main__':
Note: See TracChangeset for help on using the changeset viewer.