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