1#!/usr/bin/python2 2 3# Copyright 2016 The Chromium Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7import binascii 8import optparse 9import sys 10 11parser = optparse.OptionParser() 12parser.add_option("--mac", 13 help="generate assembly file for Mac/iOS (default: False)", 14 action="store_true", default=False) 15parser.add_option("--win32", 16 help="generate assembly file for 32bit Windows (default: False)", 17 action="store_true", default=False) 18parser.add_option("--win64", 19 help="generate assembly file for 64bit Windows (default: False)", 20 action="store_true", default=False) 21parser.set_usage("""make_data_assembly icu_data [assembly_file] [--mac] [--win] [--win-on-linux] 22 icu_data: ICU data file to generate assembly from. 23 assembly_file: Output file converted from icu_data file.""") 24(options, args) = parser.parse_args() 25 26if len(args) < 1: 27 parser.error("ICU data file is not given.") 28 29input_file = args[0] 30n = input_file.find(".dat") 31if n == -1: 32 sys.exit("%s is not an ICU .dat file." % input_file) 33 34if len(args) < 2: 35 output_file = input_file[0:n] + "_dat.S" 36else: 37 output_file = args[1] 38 39if input_file.find("l.dat") == -1: 40 if input_file.find("b.dat") == -1: 41 sys.exit("%s has no endianness marker." % input_file) 42 else: 43 step = 1 44else: 45 step = -1 46 47input_data = open(input_file, 'rb').read() 48n = input_data.find(b'icudt') 49if n == -1: 50 sys.exit("Cannot find a version number in %s." % input_file) 51 52version_number = input_data[n + 5:n + 7].decode("ascii") 53 54output = open(output_file, 'w') 55 56if options.mac: 57 output.write(".globl _icudt%s_dat\n" 58 "#ifdef U_HIDE_DATA_SYMBOL\n" 59 "\t.private_extern _icudt%s_dat\n" 60 "#endif\n" 61 "\t.data\n" 62 "\t.const\n" 63 "\t.align 4\n" 64 "_icudt%s_dat:\n" %tuple([version_number] * 3)) 65elif options.win32: 66 output.write(".globl _icudt%s_dat\n" 67 "\t.section .rdata\n" 68 "\t.balign 16\n" 69 "_icudt%s_dat:\n" % tuple([version_number] * 2)) 70elif options.win64: 71 output.write(".globl icudt%s_dat\n" 72 "\t.section .rdata\n" 73 "\t.balign 16\n" 74 "icudt%s_dat:\n" % tuple([version_number] * 2)) 75else: 76 output.write(".globl icudt%s_dat\n" 77 "\t.section .note.GNU-stack,\"\",%%progbits\n" 78 "\t.section .rodata\n" 79 "\t.balign 16\n" 80 "#ifdef U_HIDE_DATA_SYMBOL\n" 81 "\t.hidden icudt%s_dat\n" 82 "#endif\n" 83 "\t.type icudt%s_dat,%%object\n" 84 "icudt%s_dat:\n" % tuple([version_number] * 4)) 85 86split = [binascii.hexlify(input_data[i:i + 4][::step]).decode('ascii').upper().lstrip('0') 87 for i in range(0, len(input_data), 4)] 88 89for i in range(len(split)): 90 if (len(split[i]) == 0): 91 value = '0' 92 elif (len(split[i]) == 1): 93 if not any((c in '123456789') for c in split[i]): 94 value = '0x0' + split[i] 95 else: 96 value = split[i] 97 elif (len(split[i]) % 2 == 1): 98 value = '0x0' + split[i] 99 else: 100 value = '0x' + split[i] 101 102 if (i % 32 == 0): 103 output.write("\n.long ") 104 else: 105 output.write(",") 106 output.write(value) 107 108output.write("\n") 109output.close() 110