source: trunk/src/xml_chars.py @ 386

Last change on this file since 386 was 220, checked in by cameron, 11 years ago

Generator program to produce namechars.h

File size: 9.3 KB
Line 
1#    xml_chars.py
2#    Copyright (c) 2008, Robert D. Cameron.
3#    Licensed to the public under the Open Software License 3.0.
4#    Licensed to International Characters, Inc., under the Academic
5#    Free License 3.0.
6
7#    Characters legal in XML names for both XML 1.0 and XML 1.1.
8#    See http://www.w3.org/TR/ and http://www.w3.org/TR/xml11/
9
10import re
11
12BaseChar = ['#x0041-#x005A', '#x0061-#x007A', '#x00C0-#x00D6',
13                '#x00D8-#x00F6', '#x00F8-#x00FF', '#x0100-#x0131', '#x0134-#x013E',
14                '#x0141-#x0148', '#x014A-#x017E', '#x0180-#x01C3', '#x01CD-#x01F0',
15                '#x01F4-#x01F5', '#x01FA-#x0217', '#x0250-#x02A8', '#x02BB-#x02C1',
16                '#x0386', '#x0388-#x038A', '#x038C', '#x038E-#x03A1',
17                '#x03A3-#x03CE', '#x03D0-#x03D6', '#x03DA', '#x03DC',
18                '#x03DE', '#x03E0', '#x03E2-#x03F3', '#x0401-#x040C',
19                '#x040E-#x044F', '#x0451-#x045C', '#x045E-#x0481', '#x0490-#x04C4',
20                '#x04C7-#x04C8', '#x04CB-#x04CC', '#x04D0-#x04EB', '#x04EE-#x04F5',
21                '#x04F8-#x04F9', '#x0531-#x0556', '#x0559', '#x0561-#x0586',
22                '#x05D0-#x05EA', '#x05F0-#x05F2', '#x0621-#x063A', '#x0641-#x064A',
23                '#x0671-#x06B7', '#x06BA-#x06BE', '#x06C0-#x06CE', '#x06D0-#x06D3',
24                '#x06D5', '#x06E5-#x06E6', '#x0905-#x0939', '#x093D',
25                '#x0958-#x0961', '#x0985-#x098C', '#x098F-#x0990', '#x0993-#x09A8',
26                '#x09AA-#x09B0', '#x09B2', '#x09B6-#x09B9', '#x09DC-#x09DD',
27                '#x09DF-#x09E1', '#x09F0-#x09F1', '#x0A05-#x0A0A', '#x0A0F-#x0A10',
28                '#x0A13-#x0A28', '#x0A2A-#x0A30', '#x0A32-#x0A33', '#x0A35-#x0A36',
29                '#x0A38-#x0A39', '#x0A59-#x0A5C', '#x0A5E', '#x0A72-#x0A74',
30                '#x0A85-#x0A8B', '#x0A8D', '#x0A8F-#x0A91', '#x0A93-#x0AA8',
31                '#x0AAA-#x0AB0', '#x0AB2-#x0AB3', '#x0AB5-#x0AB9', '#x0ABD',
32                '#x0AE0', '#x0B05-#x0B0C', '#x0B0F-#x0B10', '#x0B13-#x0B28',
33                '#x0B2A-#x0B30', '#x0B32-#x0B33', '#x0B36-#x0B39', '#x0B3D',
34                '#x0B5C-#x0B5D', '#x0B5F-#x0B61', '#x0B85-#x0B8A', '#x0B8E-#x0B90',
35                '#x0B92-#x0B95', '#x0B99-#x0B9A', '#x0B9C', '#x0B9E-#x0B9F',
36                '#x0BA3-#x0BA4', '#x0BA8-#x0BAA', '#x0BAE-#x0BB5', '#x0BB7-#x0BB9',
37                '#x0C05-#x0C0C', '#x0C0E-#x0C10', '#x0C12-#x0C28', '#x0C2A-#x0C33',
38                '#x0C35-#x0C39', '#x0C60-#x0C61', '#x0C85-#x0C8C', '#x0C8E-#x0C90',
39                '#x0C92-#x0CA8', '#x0CAA-#x0CB3', '#x0CB5-#x0CB9', '#x0CDE',
40                '#x0CE0-#x0CE1', '#x0D05-#x0D0C', '#x0D0E-#x0D10', '#x0D12-#x0D28',
41                '#x0D2A-#x0D39', '#x0D60-#x0D61', '#x0E01-#x0E2E', '#x0E30',
42                '#x0E32-#x0E33', '#x0E40-#x0E45', '#x0E81-#x0E82', '#x0E84',
43                '#x0E87-#x0E88', '#x0E8A', '#x0E8D', '#x0E94-#x0E97',
44                '#x0E99-#x0E9F', '#x0EA1-#x0EA3', '#x0EA5', '#x0EA7',
45                '#x0EAA-#x0EAB', '#x0EAD-#x0EAE', '#x0EB0', '#x0EB2-#x0EB3',
46                '#x0EBD', '#x0EC0-#x0EC4', '#x0F40-#x0F47', '#x0F49-#x0F69',
47                '#x10A0-#x10C5', '#x10D0-#x10F6', '#x1100', '#x1102-#x1103',
48                '#x1105-#x1107', '#x1109', '#x110B-#x110C', '#x110E-#x1112',
49                '#x113C', '#x113E', '#x1140', '#x114C', '#x114E', '#x1150',
50                '#x1154-#x1155', '#x1159', '#x115F-#x1161', '#x1163',
51                '#x1165', '#x1167', '#x1169', '#x116D-#x116E', '#x1172-#x1173',
52                '#x1175', '#x119E', '#x11A8', '#x11AB', '#x11AE-#x11AF',
53                '#x11B7-#x11B8', '#x11BA', '#x11BC-#x11C2', '#x11EB',
54                '#x11F0', '#x11F9', '#x1E00-#x1E9B', '#x1EA0-#x1EF9',
55                '#x1F00-#x1F15', '#x1F18-#x1F1D', '#x1F20-#x1F45', '#x1F48-#x1F4D',
56                '#x1F50-#x1F57', '#x1F59', '#x1F5B', '#x1F5D', '#x1F5F-#x1F7D',
57                '#x1F80-#x1FB4', '#x1FB6-#x1FBC', '#x1FBE', '#x1FC2-#x1FC4',
58                '#x1FC6-#x1FCC', '#x1FD0-#x1FD3', '#x1FD6-#x1FDB', '#x1FE0-#x1FEC',
59                '#x1FF2-#x1FF4', '#x1FF6-#x1FFC', '#x2126', '#x212A-#x212B',
60                '#x212E', '#x2180-#x2182', '#x3041-#x3094', '#x30A1-#x30FA',
61                '#x3105-#x312C', '#xAC00-#xD7A3']
62
63Ideographic = ['#x4E00-#x9FA5', '#x3007', '#x3021-#x3029']
64
65CombiningCh = ['#x0300-#x0345', '#x0360-#x0361', '#x0483-#x0486',
66                '#x0591-#x05A1', '#x05A3-#x05B9', '#x05BB-#x05BD', '#x05BF',
67                '#x05C1-#x05C2', '#x05C4', '#x064B-#x0652', '#x0670',
68                '#x06D6-#x06DC', '#x06DD-#x06DF', '#x06E0-#x06E4', '#x06E7-#x06E8',
69                '#x06EA-#x06ED', '#x0901-#x0903', '#x093C', '#x093E-#x094C',
70                '#x094D', '#x0951-#x0954', '#x0962-#x0963', '#x0981-#x0983',
71                '#x09BC', '#x09BE', '#x09BF', '#x09C0-#x09C4', '#x09C7-#x09C8',
72                '#x09CB-#x09CD', '#x09D7', '#x09E2-#x09E3', '#x0A02',
73                '#x0A3C', '#x0A3E', '#x0A3F', '#x0A40-#x0A42', '#x0A47-#x0A48',
74                '#x0A4B-#x0A4D', '#x0A70-#x0A71', '#x0A81-#x0A83', '#x0ABC',
75                '#x0ABE-#x0AC5', '#x0AC7-#x0AC9', '#x0ACB-#x0ACD', '#x0B01-#x0B03',
76                '#x0B3C', '#x0B3E-#x0B43', '#x0B47-#x0B48', '#x0B4B-#x0B4D',
77                '#x0B56-#x0B57', '#x0B82-#x0B83', '#x0BBE-#x0BC2', '#x0BC6-#x0BC8',
78                '#x0BCA-#x0BCD', '#x0BD7', '#x0C01-#x0C03', '#x0C3E-#x0C44',
79                '#x0C46-#x0C48', '#x0C4A-#x0C4D', '#x0C55-#x0C56', '#x0C82-#x0C83',
80                '#x0CBE-#x0CC4', '#x0CC6-#x0CC8', '#x0CCA-#x0CCD', '#x0CD5-#x0CD6',
81                '#x0D02-#x0D03', '#x0D3E-#x0D43', '#x0D46-#x0D48', '#x0D4A-#x0D4D',
82                '#x0D57', '#x0E31', '#x0E34-#x0E3A', '#x0E47-#x0E4E',
83                '#x0EB1', '#x0EB4-#x0EB9', '#x0EBB-#x0EBC', '#x0EC8-#x0ECD',
84                '#x0F18-#x0F19', '#x0F35', '#x0F37', '#x0F39', '#x0F3E',
85                '#x0F3F', '#x0F71-#x0F84', '#x0F86-#x0F8B', '#x0F90-#x0F95',
86                '#x0F97', '#x0F99-#x0FAD', '#x0FB1-#x0FB7', '#x0FB9',
87                '#x20D0-#x20DC', '#x20E1', '#x302A-#x302F', '#x3099',
88                '#x309A']
89
90Digit = ['#x0030-#x0039', '#x0660-#x0669', '#x06F0-#x06F9',
91                '#x0966-#x096F', '#x09E6-#x09EF', '#x0A66-#x0A6F', '#x0AE6-#x0AEF',
92                '#x0B66-#x0B6F', '#x0BE7-#x0BEF', '#x0C66-#x0C6F', '#x0CE6-#x0CEF',
93                '#x0D66-#x0D6F', '#x0E50-#x0E59', '#x0ED0-#x0ED9', '#x0F20-#x0F29']
94
95Extender = ['#x00B7', '#x02D0', '#x02D1', '#x0387', '#x0640',
96                '#x0E46', '#x0EC6', '#x3005', '#x3031-#x3035', '#x309D-#x309E',
97                '#x30FC-#x30FE']
98
99NameStrt = ['#x003A', '#x005F'] + BaseChar + Ideographic
100NameChar = NameStrt + ['#x002D', '#x002E'] + Digit + Extender + CombiningCh
101
102XML11_NameStrt = ['#x003A', '#x005F', '#x0041-#x005A', '#x0061-#x007A', '#x00C0-#x00D6',
103                        '#x00D8-#x00F6', '#x00F8-#x02FF', '#x0370-#x037D', '#x037F-#x1FFF', '#x200C-#x200D',
104                        '#x2070-#x218F', '#x2C00-#x2FEF', '#x3001-#xD7FF', '#xF900-#xFDCF', '#xFDF0-#xFFFD', '#x10000-#xEFFFF']
105                       
106XML11_NameChar = XML11_NameStrt + ['#x002D', '#x002E', '#x0030-#x0039', '#x00B7', '#x0300-#x036F', '#x203F-#x2040']
107
108range_pattern = re.compile("#x([0-9A-Fa-f]+)-#x([0-9A-Fa-f]+)")
109def range_from_rangespec(s):
110        m = range_pattern.match(s)
111        if m != None:
112                return (int(m.group(1), 16), int(m.group(2), 16))
113        else:   
114                val = int(s[2:], 16)
115                return (val, val)
116       
117def charclass_ranges(CharClass):
118        return [range_from_rangespec(s) for s in CharClass]
119
120def charclass_map(CharClass):
121        map = {}
122        for s in CharClass:
123                r = range_from_rangespec(s)
124                for c in range(r[0], r[1]+1):
125                        map[c] = 1
126        return map
127
128
129def charclass_bitstring(map, lo_limit, hi_limit):
130        bits = ''
131        for x in range(lo_limit, hi_limit+1):
132                if map.has_key(x): bits += '1'
133                else: bits += '0'
134        return bits
135
136
137def bitstring2hexstring(bitstr):
138        h = ""
139        for q in range(0, len(bitstr)/4):
140                l = 4*q
141                if bitstr[l:l+4] == "0000": h += '0'
142                elif bitstr[l:l+4] == "0001": h += '1'
143                elif bitstr[l:l+4] == "0010": h += '2'
144                elif bitstr[l:l+4] == "0011": h += '3'
145                elif bitstr[l:l+4] == "0100": h += '4'
146                elif bitstr[l:l+4] == "0101": h += '5'
147                elif bitstr[l:l+4] == "0110": h += '6'
148                elif bitstr[l:l+4] == "0111": h += '7'
149                elif bitstr[l:l+4] == "1000": h += '8'
150                elif bitstr[l:l+4] == "1001": h += '9'
151                elif bitstr[l:l+4] == "1010": h += 'A'
152                elif bitstr[l:l+4] == "1011": h += 'B'
153                elif bitstr[l:l+4] == "1100": h += 'C'
154                elif bitstr[l:l+4] == "1101": h += 'D'
155                elif bitstr[l:l+4] == "1110": h += 'E'
156                elif bitstr[l:l+4] == "1111": h += 'F'
157        return h
158               
159def make_C_bit_map(name, map, lo_codepoint, hi_codepoint):
160        c_str = "uint8_t " + name + "[] = {\n    "
161        codepoint = lo_codepoint
162        groups_on_line = 0
163        while (codepoint <= hi_codepoint):
164                bits = charclass_bitstring(map, codepoint, codepoint+7)
165                c_str += "0x" + bitstring2hexstring(bits)
166                groups_on_line += 1
167                codepoint += 8
168                if (codepoint <= hi_codepoint):
169                        if (groups_on_line < 8): c_str += ', '
170                        else:
171                                c_str += ',\n    '
172                                groups_on_line = 0
173        c_str += "};\n\n"
174        return c_str
175       
176namechars_header = r"""/* namechars.h - Bitset maps for name characters.
177    Copyright (c) 2008, Robert D. Cameron.
178    Licensed to the public under the Open Software License 3.0.
179    Licensed to International Characters, Inc., under the Academic
180    Free License 3.0.
181   
182    This is a generated file using xml_chars.py.  Do not edit.
183   
184    The XML10 maps apply to XML 1.0 4th edition and prior.
185    The XML11 maps apply to XML 1.1 and the proposed XML 1.0 5th edition.
186
187*/
188#ifndef NAMECHARS_H
189#define NAMECHARS_H
190
191#ifndef _MSC_VER
192#include <stdint.h>
193#endif
194#ifdef _MSC_VER
195#include "../../lib/stdint.h"
196#endif
197
198"""
199
200def gen_NS_bitmaps(filename):
201        ncm = charclass_map(NameChar)
202        nsm = charclass_map(NameStrt)
203        f = open(filename, "w")
204        f.write(namechars_header)
205        f.write(make_C_bit_map('NameStrt_XML10_0000_11FF', nsm, 0, 0x11FF))
206        f.write(make_C_bit_map('NameStrt_XML10_1E00_1FFF', nsm, 0x1E00, 0x1FFF))
207        f.write(make_C_bit_map('NameStrt_XML10_2000_21FF', nsm, 0x2000, 0x21FF))
208        f.write(make_C_bit_map('NameStrt_XML10_3000_31FF', nsm, 0x3000, 0x31FF))
209        f.write(make_C_bit_map('NameChar_XML10_0000_11FF', ncm, 0, 0x11FF))
210        f.write(make_C_bit_map('NameChar_XML10_2000_21FF', ncm, 0x2000, 0x21FF))
211        f.write(make_C_bit_map('NameChar_XML10_3000_31FF', ncm, 0x3000, 0x31FF))
212       
213        ncm11 = charclass_map(XML11_NameChar)
214        nsm11 = charclass_map(XML11_NameStrt)
215        f.write(make_C_bit_map('NameStrt_XML11_0000_03FF', nsm11, 0, 0x03FF))
216        f.write(make_C_bit_map('NameChar_XML11_0000_03FF', ncm11, 0, 0x03FF))
217        f.write("#endif\n");
218        f.close()
219
220if __name__ == "__main__":
221        gen_NS_bitmaps("namechars.h")
222
Note: See TracBrowser for help on using the repository browser.