1226031Sstas#!/usr/local/bin/python 2226031Sstas# -*- coding: iso-8859-1 -*- 3226031Sstas 4226031Sstas# $Id$ 5226031Sstas 6226031Sstas# Copyright (c) 2004 Kungliga Tekniska H��gskolan 7226031Sstas# (Royal Institute of Technology, Stockholm, Sweden). 8226031Sstas# All rights reserved. 9226031Sstas# 10226031Sstas# Redistribution and use in source and binary forms, with or without 11226031Sstas# modification, are permitted provided that the following conditions 12226031Sstas# are met: 13226031Sstas# 14226031Sstas# 1. Redistributions of source code must retain the above copyright 15226031Sstas# notice, this list of conditions and the following disclaimer. 16226031Sstas# 17226031Sstas# 2. Redistributions in binary form must reproduce the above copyright 18226031Sstas# notice, this list of conditions and the following disclaimer in the 19226031Sstas# documentation and/or other materials provided with the distribution. 20226031Sstas# 21226031Sstas# 3. Neither the name of the Institute nor the names of its contributors 22226031Sstas# may be used to endorse or promote products derived from this software 23226031Sstas# without specific prior written permission. 24226031Sstas# 25226031Sstas# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 26226031Sstas# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27226031Sstas# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28226031Sstas# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 29226031Sstas# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30226031Sstas# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31226031Sstas# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32226031Sstas# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33226031Sstas# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34226031Sstas# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35226031Sstas# SUCH DAMAGE. 36226031Sstas 37226031Sstasimport re 38226031Sstasimport string 39226031Sstasimport sys 40226031Sstas 41226031Sstasimport generate 42226031Sstasimport UnicodeData 43226031Sstasimport util 44226031Sstas 45226031Sstasif len(sys.argv) != 4: 46226031Sstas print "usage: %s UnicodeData.txt" 47226031Sstas " CompositionExclusions-3.2.0.txt out-dir" % sys.argv[0] 48226031Sstas sys.exit(1) 49226031Sstas 50226031Sstasud = UnicodeData.read(sys.argv[1]) 51226031Sstas 52226031Sstasdef sortedKeys(d): 53226031Sstas """Return a sorted list of the keys of a dict""" 54226031Sstas keys = d.keys() 55226031Sstas keys.sort() 56226031Sstas return keys 57226031Sstas 58226031Sstastrans = dict([(k, [re.sub('<[a-zA-Z]+>', '', v[4]), v[0]]) 59226031Sstas for k,v in ud.items() if v[4]]) 60226031Sstas 61226031SstasmaxLength = 0 62226031Sstasfor v in trans.values(): 63226031Sstas maxLength = max(maxLength, len(v[0].split())) 64226031Sstas 65226031Sstasnormalize_h = generate.Header('%s/normalize_table.h' % sys.argv[3]) 66226031Sstasnormalize_c = generate.Implementation('%s/normalize_table.c' % sys.argv[3]) 67226031Sstas 68226031Sstasnormalize_h.file.write( 69226031Sstas''' 70226031Sstas#include <krb5-types.h> 71226031Sstas 72226031Sstas#define MAX_LENGTH_CANON %u 73226031Sstas 74226031Sstasstruct translation { 75226031Sstas uint32_t key; 76226031Sstas unsigned short val_len; 77226031Sstas unsigned short val_offset; 78226031Sstas}; 79226031Sstas 80226031Sstasextern const struct translation _wind_normalize_table[]; 81226031Sstas 82226031Sstasextern const uint32_t _wind_normalize_val_table[]; 83226031Sstas 84226031Sstasextern const size_t _wind_normalize_table_size; 85226031Sstas 86226031Sstasstruct canon_node { 87226031Sstas uint32_t val; 88226031Sstas unsigned char next_start; 89226031Sstas unsigned char next_end; 90226031Sstas unsigned short next_offset; 91226031Sstas}; 92226031Sstas 93226031Sstasextern const struct canon_node _wind_canon_table[]; 94226031Sstas 95226031Sstasextern const unsigned short _wind_canon_next_table[]; 96226031Sstas''' % maxLength) 97226031Sstas 98226031Sstasnormalize_c.file.write( 99226031Sstas''' 100226031Sstas#include <stdlib.h> 101226031Sstas#include "normalize_table.h" 102226031Sstas 103226031Sstasconst struct translation _wind_normalize_table[] = { 104226031Sstas''') 105226031Sstas 106226031SstasnormalizeValTable = [] 107226031Sstas 108226031Sstasfor k in sortedKeys(trans) : 109226031Sstas v = trans[k] 110226031Sstas (key, value, description) = k, v[0], v[1] 111226031Sstas vec = [int(x, 0x10) for x in value.split()]; 112226031Sstas offset = util.subList(normalizeValTable, vec) 113226031Sstas if not offset: 114226031Sstas offset = len(normalizeValTable) 115226031Sstas normalizeValTable.extend(vec) # [("0x%s" % i) for i in vec]) 116226031Sstas normalize_c.file.write(" {0x%x, %u, %u}, /* %s */\n" 117226031Sstas % (key, len(vec), offset, description)) 118226031Sstas 119226031Sstasnormalize_c.file.write( 120226031Sstas'''}; 121226031Sstas 122226031Sstas''') 123226031Sstas 124226031Sstasnormalize_c.file.write( 125226031Sstas "const size_t _wind_normalize_table_size = %u;\n\n" % len(trans)) 126226031Sstas 127226031Sstasnormalize_c.file.write("const uint32_t _wind_normalize_val_table[] = {\n") 128226031Sstas 129226031Sstasfor v in normalizeValTable: 130226031Sstas normalize_c.file.write(" 0x%x,\n" % v) 131226031Sstas 132226031Sstasnormalize_c.file.write("};\n\n"); 133226031Sstas 134226031Sstasexclusions = UnicodeData.read(sys.argv[2]) 135226031Sstas 136226031Sstasinv = dict([(''.join(["%05x" % int(x, 0x10) for x in v[4].split(' ')]), 137226031Sstas [k, v[0]]) 138226031Sstas for k,v in ud.items() 139226031Sstas if v[4] and not re.search('<[a-zA-Z]+> *', v[4]) and not exclusions.has_key(k)]) 140226031Sstas 141226031Sstastable = 0 142226031Sstas 143226031Sstastables = {} 144226031Sstas 145226031Sstasdef createTable(): 146226031Sstas """add a new table""" 147226031Sstas global table, tables 148226031Sstas ret = table 149226031Sstas table += 1 150226031Sstas tables[ret] = [0] + [None] * 16 151226031Sstas return ret 152226031Sstas 153226031Sstasdef add(table, k, v): 154226031Sstas """add an entry (k, v) to table (recursively)""" 155226031Sstas if len(k) == 0: 156226031Sstas table[0] = v[0] 157226031Sstas else: 158226031Sstas i = int(k[0], 0x10) + 1 159226031Sstas if table[i] == None: 160226031Sstas table[i] = createTable() 161226031Sstas add(tables[table[i]], k[1:], v) 162226031Sstas 163226031Sstastop = createTable() 164226031Sstas 165226031Sstasfor k,v in inv.items(): 166226031Sstas add(tables[top], k, v) 167226031Sstas 168226031Sstasnext_table = [] 169226031SstastableToNext = {} 170226031SstastableEnd = {} 171226031SstastableStart = {} 172226031Sstas 173226031Sstasfor k in sortedKeys(tables) : 174226031Sstas t = tables[k] 175226031Sstas tableToNext[k] = len(next_table) 176226031Sstas l = t[1:] 177226031Sstas start = 0 178226031Sstas while start < 16 and l[start] == None: 179226031Sstas start += 1 180226031Sstas end = 16 181226031Sstas while end > start and l[end - 1] == None: 182226031Sstas end -= 1 183226031Sstas tableStart[k] = start 184226031Sstas tableEnd[k] = end 185226031Sstas n = [] 186226031Sstas for i in range(start, end): 187226031Sstas x = l[i] 188226031Sstas if x: 189226031Sstas n.append(x) 190226031Sstas else: 191226031Sstas n.append(0) 192226031Sstas next_table.extend(n) 193226031Sstas 194226031Sstasnormalize_c.file.write("const struct canon_node _wind_canon_table[] = {\n") 195226031Sstas 196226031Sstasfor k in sortedKeys(tables) : 197226031Sstas t = tables[k] 198226031Sstas normalize_c.file.write(" {0x%x, %u, %u, %u},\n" % 199226031Sstas (t[0], tableStart[k], tableEnd[k], tableToNext[k])) 200226031Sstas 201226031Sstasnormalize_c.file.write("};\n\n") 202226031Sstas 203226031Sstasnormalize_c.file.write("const unsigned short _wind_canon_next_table[] = {\n") 204226031Sstas 205226031Sstasfor k in next_table: 206226031Sstas normalize_c.file.write(" %u,\n" % k) 207226031Sstas 208226031Sstasnormalize_c.file.write("};\n\n") 209226031Sstas 210226031Sstasnormalize_h.close() 211226031Sstasnormalize_c.close() 212