xref: /aosp_15_r20/external/cronet/third_party/libxml/src/genUnicode.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6777b538SAndroid Build Coastguard Worker#
3*6777b538SAndroid Build Coastguard Worker# Original script modified in November 2003 to take advantage of
4*6777b538SAndroid Build Coastguard Worker# the character-validation range routines, and updated to the
5*6777b538SAndroid Build Coastguard Worker# current Unicode information (Version 4.0.1)
6*6777b538SAndroid Build Coastguard Worker#
7*6777b538SAndroid Build Coastguard Worker# NOTE: there is an 'alias' facility for blocks which are not present in
8*6777b538SAndroid Build Coastguard Worker#	the current release, but are needed for ABI compatibility.  This
9*6777b538SAndroid Build Coastguard Worker#	must be accomplished MANUALLY!  Please see the comments below under
10*6777b538SAndroid Build Coastguard Worker#     'blockAliases'
11*6777b538SAndroid Build Coastguard Worker#
12*6777b538SAndroid Build Coastguard Workerimport sys
13*6777b538SAndroid Build Coastguard Workerimport string
14*6777b538SAndroid Build Coastguard Workerimport time
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Workerwebpage = "http://www.unicode.org/Public/4.0-Update1/UCD-4.0.1.html"
17*6777b538SAndroid Build Coastguard Workersources = "Blocks-4.0.1.txt UnicodeData-4.0.1.txt"
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Worker#
20*6777b538SAndroid Build Coastguard Worker# blockAliases is a small hack - it is used for mapping block names which
21*6777b538SAndroid Build Coastguard Worker# were were used in the 3.1 release, but are missing or changed in the current
22*6777b538SAndroid Build Coastguard Worker# release.  The format is "OldBlockName:NewBlockName1[,NewBlockName2[,...]]"
23*6777b538SAndroid Build Coastguard WorkerblockAliases = []
24*6777b538SAndroid Build Coastguard WorkerblockAliases.append("CombiningMarksforSymbols:CombiningDiacriticalMarksforSymbols")
25*6777b538SAndroid Build Coastguard WorkerblockAliases.append("Greek:GreekandCoptic")
26*6777b538SAndroid Build Coastguard WorkerblockAliases.append("PrivateUse:PrivateUseArea,SupplementaryPrivateUseArea-A," +
27*6777b538SAndroid Build Coastguard Worker	"SupplementaryPrivateUseArea-B")
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker# minTableSize gives the minimum number of ranges which must be present
30*6777b538SAndroid Build Coastguard Worker# before a range table is produced.  If there are less than this
31*6777b538SAndroid Build Coastguard Worker# number, inline comparisons are generated
32*6777b538SAndroid Build Coastguard WorkerminTableSize = 8
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard Worker(blockfile, catfile) = sources.split()
35*6777b538SAndroid Build Coastguard Worker
36*6777b538SAndroid Build Coastguard Worker
37*6777b538SAndroid Build Coastguard Worker#
38*6777b538SAndroid Build Coastguard Worker# Now process the "blocks" file, reducing it to a dictionary
39*6777b538SAndroid Build Coastguard Worker# indexed by blockname, containing a tuple with the applicable
40*6777b538SAndroid Build Coastguard Worker# block range
41*6777b538SAndroid Build Coastguard Worker#
42*6777b538SAndroid Build Coastguard WorkerBlockNames = {}
43*6777b538SAndroid Build Coastguard Workertry:
44*6777b538SAndroid Build Coastguard Worker    blocks = open(blockfile, "r")
45*6777b538SAndroid Build Coastguard Workerexcept:
46*6777b538SAndroid Build Coastguard Worker    print("Missing %s, aborting ..." % blockfile)
47*6777b538SAndroid Build Coastguard Worker    sys.exit(1)
48*6777b538SAndroid Build Coastguard Worker
49*6777b538SAndroid Build Coastguard Workerfor line in blocks.readlines():
50*6777b538SAndroid Build Coastguard Worker    if line[0] == '#':
51*6777b538SAndroid Build Coastguard Worker        continue
52*6777b538SAndroid Build Coastguard Worker    line = line.strip()
53*6777b538SAndroid Build Coastguard Worker    if line == '':
54*6777b538SAndroid Build Coastguard Worker        continue
55*6777b538SAndroid Build Coastguard Worker    try:
56*6777b538SAndroid Build Coastguard Worker        fields = line.split(';')
57*6777b538SAndroid Build Coastguard Worker        range = fields[0].strip()
58*6777b538SAndroid Build Coastguard Worker        (start, end) = range.split("..")
59*6777b538SAndroid Build Coastguard Worker        name = fields[1].strip()
60*6777b538SAndroid Build Coastguard Worker        name = name.replace(' ', '')
61*6777b538SAndroid Build Coastguard Worker    except:
62*6777b538SAndroid Build Coastguard Worker        print("Failed to process line: %s" % (line))
63*6777b538SAndroid Build Coastguard Worker        continue
64*6777b538SAndroid Build Coastguard Worker    start = "0x" + start
65*6777b538SAndroid Build Coastguard Worker    end = "0x" + end
66*6777b538SAndroid Build Coastguard Worker    try:
67*6777b538SAndroid Build Coastguard Worker        BlockNames[name].append((start, end))
68*6777b538SAndroid Build Coastguard Worker    except:
69*6777b538SAndroid Build Coastguard Worker        BlockNames[name] = [(start, end)]
70*6777b538SAndroid Build Coastguard Workerblocks.close()
71*6777b538SAndroid Build Coastguard Workerprint("Parsed %d blocks descriptions" % (len(BlockNames.keys())))
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Workerfor block in blockAliases:
74*6777b538SAndroid Build Coastguard Worker    alias = block.split(':')
75*6777b538SAndroid Build Coastguard Worker    alist = alias[1].split(',')
76*6777b538SAndroid Build Coastguard Worker    for comp in alist:
77*6777b538SAndroid Build Coastguard Worker        if comp in BlockNames:
78*6777b538SAndroid Build Coastguard Worker            if alias[0] not in BlockNames:
79*6777b538SAndroid Build Coastguard Worker                BlockNames[alias[0]] = []
80*6777b538SAndroid Build Coastguard Worker            for r in BlockNames[comp]:
81*6777b538SAndroid Build Coastguard Worker                BlockNames[alias[0]].append(r)
82*6777b538SAndroid Build Coastguard Worker        else:
83*6777b538SAndroid Build Coastguard Worker            print("Alias %s: %s not in Blocks" % (alias[0], comp))
84*6777b538SAndroid Build Coastguard Worker            continue
85*6777b538SAndroid Build Coastguard Worker
86*6777b538SAndroid Build Coastguard Worker#
87*6777b538SAndroid Build Coastguard Worker# Next process the Categories file. This is more complex, since
88*6777b538SAndroid Build Coastguard Worker# the file is in code sequence, and we need to invert it.  We use
89*6777b538SAndroid Build Coastguard Worker# a dictionary with index category-name, with each entry containing
90*6777b538SAndroid Build Coastguard Worker# all the ranges (codepoints) of that category.  Note that category
91*6777b538SAndroid Build Coastguard Worker# names comprise two parts - the general category, and the "subclass"
92*6777b538SAndroid Build Coastguard Worker# within that category.  Therefore, both "general category" (which is
93*6777b538SAndroid Build Coastguard Worker# the first character of the 2-character category-name) and the full
94*6777b538SAndroid Build Coastguard Worker# (2-character) name are entered into this dictionary.
95*6777b538SAndroid Build Coastguard Worker#
96*6777b538SAndroid Build Coastguard Workertry:
97*6777b538SAndroid Build Coastguard Worker    data = open(catfile, "r")
98*6777b538SAndroid Build Coastguard Workerexcept:
99*6777b538SAndroid Build Coastguard Worker    print("Missing %s, aborting ..." % catfile)
100*6777b538SAndroid Build Coastguard Worker    sys.exit(1)
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Workernbchar = 0;
103*6777b538SAndroid Build Coastguard WorkerCategories = {}
104*6777b538SAndroid Build Coastguard Workerfor line in data.readlines():
105*6777b538SAndroid Build Coastguard Worker    if line[0] == '#':
106*6777b538SAndroid Build Coastguard Worker        continue
107*6777b538SAndroid Build Coastguard Worker    line = line.strip()
108*6777b538SAndroid Build Coastguard Worker    if line == '':
109*6777b538SAndroid Build Coastguard Worker        continue
110*6777b538SAndroid Build Coastguard Worker    try:
111*6777b538SAndroid Build Coastguard Worker        fields = line.split(';')
112*6777b538SAndroid Build Coastguard Worker        point = fields[0].strip()
113*6777b538SAndroid Build Coastguard Worker        value = 0
114*6777b538SAndroid Build Coastguard Worker        while point != '':
115*6777b538SAndroid Build Coastguard Worker            value = value * 16
116*6777b538SAndroid Build Coastguard Worker            if point[0] >= '0' and point[0] <= '9':
117*6777b538SAndroid Build Coastguard Worker                value = value + ord(point[0]) - ord('0')
118*6777b538SAndroid Build Coastguard Worker            elif point[0] >= 'A' and point[0] <= 'F':
119*6777b538SAndroid Build Coastguard Worker                value = value + 10 + ord(point[0]) - ord('A')
120*6777b538SAndroid Build Coastguard Worker            elif point[0] >= 'a' and point[0] <= 'f':
121*6777b538SAndroid Build Coastguard Worker                value = value + 10 + ord(point[0]) - ord('a')
122*6777b538SAndroid Build Coastguard Worker            point = point[1:]
123*6777b538SAndroid Build Coastguard Worker        name = fields[2]
124*6777b538SAndroid Build Coastguard Worker    except:
125*6777b538SAndroid Build Coastguard Worker        print("Failed to process line: %s" % (line))
126*6777b538SAndroid Build Coastguard Worker        continue
127*6777b538SAndroid Build Coastguard Worker
128*6777b538SAndroid Build Coastguard Worker    nbchar = nbchar + 1
129*6777b538SAndroid Build Coastguard Worker    # update entry for "full name"
130*6777b538SAndroid Build Coastguard Worker    try:
131*6777b538SAndroid Build Coastguard Worker        Categories[name].append(value)
132*6777b538SAndroid Build Coastguard Worker    except:
133*6777b538SAndroid Build Coastguard Worker        try:
134*6777b538SAndroid Build Coastguard Worker            Categories[name] = [value]
135*6777b538SAndroid Build Coastguard Worker        except:
136*6777b538SAndroid Build Coastguard Worker            print("Failed to process line: %s" % (line))
137*6777b538SAndroid Build Coastguard Worker    # update "general category" name
138*6777b538SAndroid Build Coastguard Worker    try:
139*6777b538SAndroid Build Coastguard Worker        Categories[name[0]].append(value)
140*6777b538SAndroid Build Coastguard Worker    except:
141*6777b538SAndroid Build Coastguard Worker        try:
142*6777b538SAndroid Build Coastguard Worker            Categories[name[0]] = [value]
143*6777b538SAndroid Build Coastguard Worker        except:
144*6777b538SAndroid Build Coastguard Worker            print("Failed to process line: %s" % (line))
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard Workerblocks.close()
147*6777b538SAndroid Build Coastguard Workerprint("Parsed %d char generating %d categories" % (nbchar, len(Categories.keys())))
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker#
150*6777b538SAndroid Build Coastguard Worker# The data is now all read.  Time to process it into a more useful form.
151*6777b538SAndroid Build Coastguard Worker#
152*6777b538SAndroid Build Coastguard Worker# reduce the number list into ranges
153*6777b538SAndroid Build Coastguard Workerfor cat in Categories.keys():
154*6777b538SAndroid Build Coastguard Worker    list = Categories[cat]
155*6777b538SAndroid Build Coastguard Worker    start = -1
156*6777b538SAndroid Build Coastguard Worker    prev = -1
157*6777b538SAndroid Build Coastguard Worker    end = -1
158*6777b538SAndroid Build Coastguard Worker    ranges = []
159*6777b538SAndroid Build Coastguard Worker    for val in list:
160*6777b538SAndroid Build Coastguard Worker        if start == -1:
161*6777b538SAndroid Build Coastguard Worker            start = val
162*6777b538SAndroid Build Coastguard Worker            prev = val
163*6777b538SAndroid Build Coastguard Worker            continue
164*6777b538SAndroid Build Coastguard Worker        elif val == prev + 1:
165*6777b538SAndroid Build Coastguard Worker            prev = val
166*6777b538SAndroid Build Coastguard Worker            continue
167*6777b538SAndroid Build Coastguard Worker        elif prev == start:
168*6777b538SAndroid Build Coastguard Worker            ranges.append((prev, prev))
169*6777b538SAndroid Build Coastguard Worker            start = val
170*6777b538SAndroid Build Coastguard Worker            prev = val
171*6777b538SAndroid Build Coastguard Worker            continue
172*6777b538SAndroid Build Coastguard Worker        else:
173*6777b538SAndroid Build Coastguard Worker            ranges.append((start, prev))
174*6777b538SAndroid Build Coastguard Worker            start = val
175*6777b538SAndroid Build Coastguard Worker            prev = val
176*6777b538SAndroid Build Coastguard Worker            continue
177*6777b538SAndroid Build Coastguard Worker    if prev == start:
178*6777b538SAndroid Build Coastguard Worker        ranges.append((prev, prev))
179*6777b538SAndroid Build Coastguard Worker    else:
180*6777b538SAndroid Build Coastguard Worker        ranges.append((start, prev))
181*6777b538SAndroid Build Coastguard Worker    Categories[cat] = ranges
182*6777b538SAndroid Build Coastguard Worker
183*6777b538SAndroid Build Coastguard Worker#
184*6777b538SAndroid Build Coastguard Worker# Assure all data is in alphabetic order, since we will be doing binary
185*6777b538SAndroid Build Coastguard Worker# searches on the tables.
186*6777b538SAndroid Build Coastguard Worker#
187*6777b538SAndroid Build Coastguard Workerbkeys = sorted(BlockNames.keys())
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Workerckeys = sorted(Categories.keys())
190*6777b538SAndroid Build Coastguard Worker
191*6777b538SAndroid Build Coastguard Worker#
192*6777b538SAndroid Build Coastguard Worker# Generate the resulting files
193*6777b538SAndroid Build Coastguard Worker#
194*6777b538SAndroid Build Coastguard Workertry:
195*6777b538SAndroid Build Coastguard Worker    header = open("include/libxml/xmlunicode.h", "w")
196*6777b538SAndroid Build Coastguard Workerexcept:
197*6777b538SAndroid Build Coastguard Worker    print("Failed to open include/libxml/xmlunicode.h")
198*6777b538SAndroid Build Coastguard Worker    sys.exit(1)
199*6777b538SAndroid Build Coastguard Worker
200*6777b538SAndroid Build Coastguard Workertry:
201*6777b538SAndroid Build Coastguard Worker    output = open("xmlunicode.c", "w")
202*6777b538SAndroid Build Coastguard Workerexcept:
203*6777b538SAndroid Build Coastguard Worker    print("Failed to open xmlunicode.c")
204*6777b538SAndroid Build Coastguard Worker    sys.exit(1)
205*6777b538SAndroid Build Coastguard Worker
206*6777b538SAndroid Build Coastguard Workerdate = time.asctime(time.localtime(time.time()))
207*6777b538SAndroid Build Coastguard Worker
208*6777b538SAndroid Build Coastguard Workerheader.write(
209*6777b538SAndroid Build Coastguard Worker"""/*
210*6777b538SAndroid Build Coastguard Worker * Summary: Unicode character APIs
211*6777b538SAndroid Build Coastguard Worker * Description: API for the Unicode character APIs
212*6777b538SAndroid Build Coastguard Worker *
213*6777b538SAndroid Build Coastguard Worker * This file is automatically generated from the
214*6777b538SAndroid Build Coastguard Worker * UCS description files of the Unicode Character Database
215*6777b538SAndroid Build Coastguard Worker * %s
216*6777b538SAndroid Build Coastguard Worker * using the genUnicode.py Python script.
217*6777b538SAndroid Build Coastguard Worker *
218*6777b538SAndroid Build Coastguard Worker * Generation date: %s
219*6777b538SAndroid Build Coastguard Worker * Sources: %s
220*6777b538SAndroid Build Coastguard Worker * Author: Daniel Veillard
221*6777b538SAndroid Build Coastguard Worker */
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker#ifndef __XML_UNICODE_H__
224*6777b538SAndroid Build Coastguard Worker#define __XML_UNICODE_H__
225*6777b538SAndroid Build Coastguard Worker
226*6777b538SAndroid Build Coastguard Worker#include <libxml/xmlversion.h>
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard Worker#ifdef LIBXML_UNICODE_ENABLED
229*6777b538SAndroid Build Coastguard Worker
230*6777b538SAndroid Build Coastguard Worker#ifdef __cplusplus
231*6777b538SAndroid Build Coastguard Workerextern "C" {
232*6777b538SAndroid Build Coastguard Worker#endif
233*6777b538SAndroid Build Coastguard Worker
234*6777b538SAndroid Build Coastguard Worker""" % (webpage, date, sources));
235*6777b538SAndroid Build Coastguard Worker
236*6777b538SAndroid Build Coastguard Workeroutput.write(
237*6777b538SAndroid Build Coastguard Worker"""/*
238*6777b538SAndroid Build Coastguard Worker * xmlunicode.c: this module implements the Unicode character APIs
239*6777b538SAndroid Build Coastguard Worker *
240*6777b538SAndroid Build Coastguard Worker * This file is automatically generated from the
241*6777b538SAndroid Build Coastguard Worker * UCS description files of the Unicode Character Database
242*6777b538SAndroid Build Coastguard Worker * %s
243*6777b538SAndroid Build Coastguard Worker * using the genUnicode.py Python script.
244*6777b538SAndroid Build Coastguard Worker *
245*6777b538SAndroid Build Coastguard Worker * Generation date: %s
246*6777b538SAndroid Build Coastguard Worker * Sources: %s
247*6777b538SAndroid Build Coastguard Worker * Daniel Veillard <[email protected]>
248*6777b538SAndroid Build Coastguard Worker */
249*6777b538SAndroid Build Coastguard Worker
250*6777b538SAndroid Build Coastguard Worker#define IN_LIBXML
251*6777b538SAndroid Build Coastguard Worker#include "libxml.h"
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Worker#ifdef LIBXML_UNICODE_ENABLED
254*6777b538SAndroid Build Coastguard Worker
255*6777b538SAndroid Build Coastguard Worker#include <string.h>
256*6777b538SAndroid Build Coastguard Worker#include <libxml/xmlversion.h>
257*6777b538SAndroid Build Coastguard Worker#include <libxml/xmlunicode.h>
258*6777b538SAndroid Build Coastguard Worker#include <libxml/chvalid.h>
259*6777b538SAndroid Build Coastguard Worker
260*6777b538SAndroid Build Coastguard Workertypedef int (xmlIntFunc)(int);	/* just to keep one's mind untwisted */
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Workertypedef struct {
263*6777b538SAndroid Build Coastguard Worker    const char *rangename;
264*6777b538SAndroid Build Coastguard Worker    xmlIntFunc *func;
265*6777b538SAndroid Build Coastguard Worker} xmlUnicodeRange;
266*6777b538SAndroid Build Coastguard Worker
267*6777b538SAndroid Build Coastguard Workertypedef struct {
268*6777b538SAndroid Build Coastguard Worker    const xmlUnicodeRange *table;
269*6777b538SAndroid Build Coastguard Worker    int		    numentries;
270*6777b538SAndroid Build Coastguard Worker} xmlUnicodeNameTable;
271*6777b538SAndroid Build Coastguard Worker
272*6777b538SAndroid Build Coastguard Worker
273*6777b538SAndroid Build Coastguard Workerstatic xmlIntFunc *xmlUnicodeLookup(const xmlUnicodeNameTable *tptr, const char *tname);
274*6777b538SAndroid Build Coastguard Worker
275*6777b538SAndroid Build Coastguard Workerstatic const xmlUnicodeRange xmlUnicodeBlocks[] = {
276*6777b538SAndroid Build Coastguard Worker""" % (webpage, date, sources));
277*6777b538SAndroid Build Coastguard Worker
278*6777b538SAndroid Build Coastguard Workerflag = 0
279*6777b538SAndroid Build Coastguard Workerfor block in bkeys:
280*6777b538SAndroid Build Coastguard Worker    name = block.replace('-', '')
281*6777b538SAndroid Build Coastguard Worker    if flag:
282*6777b538SAndroid Build Coastguard Worker        output.write(',\n')
283*6777b538SAndroid Build Coastguard Worker    else:
284*6777b538SAndroid Build Coastguard Worker        flag = 1
285*6777b538SAndroid Build Coastguard Worker    output.write('  {"%s", xmlUCSIs%s}' % (block, name))
286*6777b538SAndroid Build Coastguard Workeroutput.write('};\n\n')
287*6777b538SAndroid Build Coastguard Worker
288*6777b538SAndroid Build Coastguard Workeroutput.write('static const xmlUnicodeRange xmlUnicodeCats[] = {\n')
289*6777b538SAndroid Build Coastguard Workerflag = 0;
290*6777b538SAndroid Build Coastguard Workerfor name in ckeys:
291*6777b538SAndroid Build Coastguard Worker    if flag:
292*6777b538SAndroid Build Coastguard Worker        output.write(',\n')
293*6777b538SAndroid Build Coastguard Worker    else:
294*6777b538SAndroid Build Coastguard Worker        flag = 1
295*6777b538SAndroid Build Coastguard Worker    output.write('  {"%s", xmlUCSIsCat%s}' % (name, name))
296*6777b538SAndroid Build Coastguard Workeroutput.write('};\n\n')
297*6777b538SAndroid Build Coastguard Worker
298*6777b538SAndroid Build Coastguard Worker#
299*6777b538SAndroid Build Coastguard Worker# For any categories with more than minTableSize ranges we generate
300*6777b538SAndroid Build Coastguard Worker# a range table suitable for xmlCharInRange
301*6777b538SAndroid Build Coastguard Worker#
302*6777b538SAndroid Build Coastguard Workerfor name in ckeys:
303*6777b538SAndroid Build Coastguard Worker  if len(Categories[name]) > minTableSize:
304*6777b538SAndroid Build Coastguard Worker    numshort = 0
305*6777b538SAndroid Build Coastguard Worker    numlong = 0
306*6777b538SAndroid Build Coastguard Worker    ranges = Categories[name]
307*6777b538SAndroid Build Coastguard Worker    sptr = "NULL"
308*6777b538SAndroid Build Coastguard Worker    lptr = "NULL"
309*6777b538SAndroid Build Coastguard Worker    for range in ranges:
310*6777b538SAndroid Build Coastguard Worker      (low, high) = range
311*6777b538SAndroid Build Coastguard Worker      if high < 0x10000:
312*6777b538SAndroid Build Coastguard Worker        if numshort == 0:
313*6777b538SAndroid Build Coastguard Worker          pline = "static const xmlChSRange xml%sS[] = {" % name
314*6777b538SAndroid Build Coastguard Worker          sptr = "xml%sS" % name
315*6777b538SAndroid Build Coastguard Worker        else:
316*6777b538SAndroid Build Coastguard Worker          pline += ","
317*6777b538SAndroid Build Coastguard Worker        numshort += 1
318*6777b538SAndroid Build Coastguard Worker      else:
319*6777b538SAndroid Build Coastguard Worker        if numlong == 0:
320*6777b538SAndroid Build Coastguard Worker          if numshort > 0:
321*6777b538SAndroid Build Coastguard Worker            output.write(pline + " };\n")
322*6777b538SAndroid Build Coastguard Worker          pline = "static const xmlChLRange xml%sL[] = {" % name
323*6777b538SAndroid Build Coastguard Worker          lptr = "xml%sL" % name
324*6777b538SAndroid Build Coastguard Worker        else:
325*6777b538SAndroid Build Coastguard Worker          pline += ","
326*6777b538SAndroid Build Coastguard Worker        numlong += 1
327*6777b538SAndroid Build Coastguard Worker      if len(pline) > 60:
328*6777b538SAndroid Build Coastguard Worker        output.write(pline + "\n")
329*6777b538SAndroid Build Coastguard Worker        pline = "    "
330*6777b538SAndroid Build Coastguard Worker      elif pline[-1:] == ",":
331*6777b538SAndroid Build Coastguard Worker        pline += " "
332*6777b538SAndroid Build Coastguard Worker      pline += "{%s, %s}" % (hex(low), hex(high))
333*6777b538SAndroid Build Coastguard Worker    output.write(pline + " };\nstatic const xmlChRangeGroup xml%sG = {%s,%s,%s,%s};\n\n"
334*6777b538SAndroid Build Coastguard Worker         % (name, numshort, numlong, sptr, lptr))
335*6777b538SAndroid Build Coastguard Worker
336*6777b538SAndroid Build Coastguard Worker
337*6777b538SAndroid Build Coastguard Workeroutput.write(
338*6777b538SAndroid Build Coastguard Worker"""static const xmlUnicodeNameTable xmlUnicodeBlockTbl = {xmlUnicodeBlocks, %s};
339*6777b538SAndroid Build Coastguard Workerstatic const xmlUnicodeNameTable xmlUnicodeCatTbl = {xmlUnicodeCats, %s};
340*6777b538SAndroid Build Coastguard Worker
341*6777b538SAndroid Build Coastguard Worker/**
342*6777b538SAndroid Build Coastguard Worker * xmlUnicodeLookup:
343*6777b538SAndroid Build Coastguard Worker * @tptr: pointer to the name table
344*6777b538SAndroid Build Coastguard Worker * @name: name to be found
345*6777b538SAndroid Build Coastguard Worker *
346*6777b538SAndroid Build Coastguard Worker * binary table lookup for user-supplied name
347*6777b538SAndroid Build Coastguard Worker *
348*6777b538SAndroid Build Coastguard Worker * Returns pointer to range function if found, otherwise NULL
349*6777b538SAndroid Build Coastguard Worker */
350*6777b538SAndroid Build Coastguard Workerstatic xmlIntFunc
351*6777b538SAndroid Build Coastguard Worker*xmlUnicodeLookup(const xmlUnicodeNameTable *tptr, const char *tname) {
352*6777b538SAndroid Build Coastguard Worker    int low, high, mid, cmp;
353*6777b538SAndroid Build Coastguard Worker    const xmlUnicodeRange *sptr;
354*6777b538SAndroid Build Coastguard Worker
355*6777b538SAndroid Build Coastguard Worker    if ((tptr == NULL) || (tname == NULL)) return(NULL);
356*6777b538SAndroid Build Coastguard Worker
357*6777b538SAndroid Build Coastguard Worker    low = 0;
358*6777b538SAndroid Build Coastguard Worker    high = tptr->numentries - 1;
359*6777b538SAndroid Build Coastguard Worker    sptr = tptr->table;
360*6777b538SAndroid Build Coastguard Worker    while (low <= high) {
361*6777b538SAndroid Build Coastguard Worker	mid = (low + high) / 2;
362*6777b538SAndroid Build Coastguard Worker	if ((cmp=strcmp(tname, sptr[mid].rangename)) == 0)
363*6777b538SAndroid Build Coastguard Worker	    return (sptr[mid].func);
364*6777b538SAndroid Build Coastguard Worker	if (cmp < 0)
365*6777b538SAndroid Build Coastguard Worker	    high = mid - 1;
366*6777b538SAndroid Build Coastguard Worker	else
367*6777b538SAndroid Build Coastguard Worker	    low = mid + 1;
368*6777b538SAndroid Build Coastguard Worker    }
369*6777b538SAndroid Build Coastguard Worker    return (NULL);
370*6777b538SAndroid Build Coastguard Worker}
371*6777b538SAndroid Build Coastguard Worker
372*6777b538SAndroid Build Coastguard Worker""" % (len(BlockNames), len(Categories)) )
373*6777b538SAndroid Build Coastguard Worker
374*6777b538SAndroid Build Coastguard Workerfor block in bkeys:
375*6777b538SAndroid Build Coastguard Worker    name = block.replace('-', '')
376*6777b538SAndroid Build Coastguard Worker    header.write("XMLPUBFUN int xmlUCSIs%s\t(int code);\n" % name)
377*6777b538SAndroid Build Coastguard Worker    output.write("/**\n * xmlUCSIs%s:\n * @code: UCS code point\n" % (name))
378*6777b538SAndroid Build Coastguard Worker    output.write(" *\n * Check whether the character is part of %s UCS Block\n"%
379*6777b538SAndroid Build Coastguard Worker                 (block))
380*6777b538SAndroid Build Coastguard Worker    output.write(" *\n * Returns 1 if true 0 otherwise\n */\n");
381*6777b538SAndroid Build Coastguard Worker    output.write("int\nxmlUCSIs%s(int code) {\n    return(" % name)
382*6777b538SAndroid Build Coastguard Worker    flag = 0
383*6777b538SAndroid Build Coastguard Worker    for (start, end) in BlockNames[block]:
384*6777b538SAndroid Build Coastguard Worker        if flag:
385*6777b538SAndroid Build Coastguard Worker            output.write(" ||\n           ")
386*6777b538SAndroid Build Coastguard Worker        else:
387*6777b538SAndroid Build Coastguard Worker            flag = 1
388*6777b538SAndroid Build Coastguard Worker        output.write("((code >= %s) && (code <= %s))" % (start, end))
389*6777b538SAndroid Build Coastguard Worker    output.write(");\n}\n\n")
390*6777b538SAndroid Build Coastguard Worker
391*6777b538SAndroid Build Coastguard Workerheader.write("\nXMLPUBFUN int xmlUCSIsBlock\t(int code, const char *block);\n\n")
392*6777b538SAndroid Build Coastguard Workeroutput.write(
393*6777b538SAndroid Build Coastguard Worker"""/**
394*6777b538SAndroid Build Coastguard Worker * xmlUCSIsBlock:
395*6777b538SAndroid Build Coastguard Worker * @code: UCS code point
396*6777b538SAndroid Build Coastguard Worker * @block: UCS block name
397*6777b538SAndroid Build Coastguard Worker *
398*6777b538SAndroid Build Coastguard Worker * Check whether the character is part of the UCS Block
399*6777b538SAndroid Build Coastguard Worker *
400*6777b538SAndroid Build Coastguard Worker * Returns 1 if true, 0 if false and -1 on unknown block
401*6777b538SAndroid Build Coastguard Worker */
402*6777b538SAndroid Build Coastguard Workerint
403*6777b538SAndroid Build Coastguard WorkerxmlUCSIsBlock(int code, const char *block) {
404*6777b538SAndroid Build Coastguard Worker    xmlIntFunc *func;
405*6777b538SAndroid Build Coastguard Worker
406*6777b538SAndroid Build Coastguard Worker    func = xmlUnicodeLookup(&xmlUnicodeBlockTbl, block);
407*6777b538SAndroid Build Coastguard Worker    if (func == NULL)
408*6777b538SAndroid Build Coastguard Worker	return (-1);
409*6777b538SAndroid Build Coastguard Worker    return (func(code));
410*6777b538SAndroid Build Coastguard Worker}
411*6777b538SAndroid Build Coastguard Worker
412*6777b538SAndroid Build Coastguard Worker""")
413*6777b538SAndroid Build Coastguard Worker
414*6777b538SAndroid Build Coastguard Workerfor name in ckeys:
415*6777b538SAndroid Build Coastguard Worker    ranges = Categories[name]
416*6777b538SAndroid Build Coastguard Worker    header.write("XMLPUBFUN int xmlUCSIsCat%s\t(int code);\n" % name)
417*6777b538SAndroid Build Coastguard Worker    output.write("/**\n * xmlUCSIsCat%s:\n * @code: UCS code point\n" % (name))
418*6777b538SAndroid Build Coastguard Worker    output.write(" *\n * Check whether the character is part of %s UCS Category\n"%
419*6777b538SAndroid Build Coastguard Worker                 (name))
420*6777b538SAndroid Build Coastguard Worker    output.write(" *\n * Returns 1 if true 0 otherwise\n */\n");
421*6777b538SAndroid Build Coastguard Worker    output.write("int\nxmlUCSIsCat%s(int code) {\n" % name)
422*6777b538SAndroid Build Coastguard Worker    if len(Categories[name]) > minTableSize:
423*6777b538SAndroid Build Coastguard Worker        output.write("    return(xmlCharInRange((unsigned int)code, &xml%sG)"
424*6777b538SAndroid Build Coastguard Worker            % name)
425*6777b538SAndroid Build Coastguard Worker    else:
426*6777b538SAndroid Build Coastguard Worker        start = 1
427*6777b538SAndroid Build Coastguard Worker        for range in ranges:
428*6777b538SAndroid Build Coastguard Worker            (begin, end) = range;
429*6777b538SAndroid Build Coastguard Worker            if start:
430*6777b538SAndroid Build Coastguard Worker                output.write("    return(");
431*6777b538SAndroid Build Coastguard Worker                start = 0
432*6777b538SAndroid Build Coastguard Worker            else:
433*6777b538SAndroid Build Coastguard Worker                output.write(" ||\n           ");
434*6777b538SAndroid Build Coastguard Worker            if (begin == end):
435*6777b538SAndroid Build Coastguard Worker                output.write("(code == %s)" % (hex(begin)))
436*6777b538SAndroid Build Coastguard Worker            else:
437*6777b538SAndroid Build Coastguard Worker                output.write("((code >= %s) && (code <= %s))" % (
438*6777b538SAndroid Build Coastguard Worker                         hex(begin), hex(end)))
439*6777b538SAndroid Build Coastguard Worker    output.write(");\n}\n\n")
440*6777b538SAndroid Build Coastguard Worker
441*6777b538SAndroid Build Coastguard Workerheader.write("\nXMLPUBFUN int xmlUCSIsCat\t(int code, const char *cat);\n")
442*6777b538SAndroid Build Coastguard Workeroutput.write(
443*6777b538SAndroid Build Coastguard Worker"""/**
444*6777b538SAndroid Build Coastguard Worker * xmlUCSIsCat:
445*6777b538SAndroid Build Coastguard Worker * @code: UCS code point
446*6777b538SAndroid Build Coastguard Worker * @cat: UCS Category name
447*6777b538SAndroid Build Coastguard Worker *
448*6777b538SAndroid Build Coastguard Worker * Check whether the character is part of the UCS Category
449*6777b538SAndroid Build Coastguard Worker *
450*6777b538SAndroid Build Coastguard Worker * Returns 1 if true, 0 if false and -1 on unknown category
451*6777b538SAndroid Build Coastguard Worker */
452*6777b538SAndroid Build Coastguard Workerint
453*6777b538SAndroid Build Coastguard WorkerxmlUCSIsCat(int code, const char *cat) {
454*6777b538SAndroid Build Coastguard Worker    xmlIntFunc *func;
455*6777b538SAndroid Build Coastguard Worker
456*6777b538SAndroid Build Coastguard Worker    func = xmlUnicodeLookup(&xmlUnicodeCatTbl, cat);
457*6777b538SAndroid Build Coastguard Worker    if (func == NULL)
458*6777b538SAndroid Build Coastguard Worker	return (-1);
459*6777b538SAndroid Build Coastguard Worker    return (func(code));
460*6777b538SAndroid Build Coastguard Worker}
461*6777b538SAndroid Build Coastguard Worker
462*6777b538SAndroid Build Coastguard Worker#endif /* LIBXML_UNICODE_ENABLED */
463*6777b538SAndroid Build Coastguard Worker""")
464*6777b538SAndroid Build Coastguard Worker
465*6777b538SAndroid Build Coastguard Workerheader.write("""
466*6777b538SAndroid Build Coastguard Worker#ifdef __cplusplus
467*6777b538SAndroid Build Coastguard Worker}
468*6777b538SAndroid Build Coastguard Worker#endif
469*6777b538SAndroid Build Coastguard Worker
470*6777b538SAndroid Build Coastguard Worker#endif /* LIBXML_UNICODE_ENABLED */
471*6777b538SAndroid Build Coastguard Worker
472*6777b538SAndroid Build Coastguard Worker#endif /* __XML_UNICODE_H__ */
473*6777b538SAndroid Build Coastguard Worker""");
474*6777b538SAndroid Build Coastguard Worker
475*6777b538SAndroid Build Coastguard Workerheader.close()
476*6777b538SAndroid Build Coastguard Workeroutput.close()
477