xref: /aosp_15_r20/external/libxml2/os400/iconv/bldcsndfa/bldcsndfa.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /**
2*7c568831SAndroid Build Coastguard Worker ***     Build a deterministic finite automaton to associate CCSIDs with
3*7c568831SAndroid Build Coastguard Worker ***             character set names.
4*7c568831SAndroid Build Coastguard Worker ***
5*7c568831SAndroid Build Coastguard Worker ***     Compile on OS/400 with options SYSIFCOPT(*IFSIO).
6*7c568831SAndroid Build Coastguard Worker ***
7*7c568831SAndroid Build Coastguard Worker ***     See Copyright for the status of this software.
8*7c568831SAndroid Build Coastguard Worker ***
9*7c568831SAndroid Build Coastguard Worker ***     Author: Patrick Monnerat <[email protected]>, DATASPHERE S.A.
10*7c568831SAndroid Build Coastguard Worker **/
11*7c568831SAndroid Build Coastguard Worker 
12*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
13*7c568831SAndroid Build Coastguard Worker #include <errno.h>
14*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
15*7c568831SAndroid Build Coastguard Worker #include <string.h>
16*7c568831SAndroid Build Coastguard Worker #include <fcntl.h>
17*7c568831SAndroid Build Coastguard Worker #include <ctype.h>
18*7c568831SAndroid Build Coastguard Worker 
19*7c568831SAndroid Build Coastguard Worker #include <iconv.h>
20*7c568831SAndroid Build Coastguard Worker 
21*7c568831SAndroid Build Coastguard Worker 
22*7c568831SAndroid Build Coastguard Worker #ifdef OLDXML
23*7c568831SAndroid Build Coastguard Worker #include "xml.h"
24*7c568831SAndroid Build Coastguard Worker #else
25*7c568831SAndroid Build Coastguard Worker #include <libxml/hash.h>
26*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
27*7c568831SAndroid Build Coastguard Worker #include <libxml/xpath.h>
28*7c568831SAndroid Build Coastguard Worker #include <libxml/xpathInternals.h>
29*7c568831SAndroid Build Coastguard Worker #endif
30*7c568831SAndroid Build Coastguard Worker 
31*7c568831SAndroid Build Coastguard Worker 
32*7c568831SAndroid Build Coastguard Worker #ifdef __OS400__
33*7c568831SAndroid Build Coastguard Worker #define iconv_open_error(cd)            ((cd).return_value == -1)
34*7c568831SAndroid Build Coastguard Worker #define set_iconv_open_error(cd)        ((cd).return_value = -1)
35*7c568831SAndroid Build Coastguard Worker #else
36*7c568831SAndroid Build Coastguard Worker #define iconv_open_error(cd)            ((cd) == (iconv_t) -1)
37*7c568831SAndroid Build Coastguard Worker #define set_iconv_open_error(cd)        ((cd) = (iconv_t) -1)
38*7c568831SAndroid Build Coastguard Worker #endif
39*7c568831SAndroid Build Coastguard Worker 
40*7c568831SAndroid Build Coastguard Worker 
41*7c568831SAndroid Build Coastguard Worker #define C_SOURCE_CCSID          500
42*7c568831SAndroid Build Coastguard Worker #define C_UTF8_CCSID            1208
43*7c568831SAndroid Build Coastguard Worker 
44*7c568831SAndroid Build Coastguard Worker 
45*7c568831SAndroid Build Coastguard Worker #define UTF8_SPACE      0x20
46*7c568831SAndroid Build Coastguard Worker #define UTF8_HT         0x09
47*7c568831SAndroid Build Coastguard Worker #define UTF8_0          0x30
48*7c568831SAndroid Build Coastguard Worker #define UTF8_9          0x39
49*7c568831SAndroid Build Coastguard Worker #define UTF8_A          0x41
50*7c568831SAndroid Build Coastguard Worker #define UTF8_Z          0x5A
51*7c568831SAndroid Build Coastguard Worker #define UTF8_a          0x61
52*7c568831SAndroid Build Coastguard Worker #define UTF8_z          0x7A
53*7c568831SAndroid Build Coastguard Worker 
54*7c568831SAndroid Build Coastguard Worker 
55*7c568831SAndroid Build Coastguard Worker #define GRANULE         128             /* Memory allocation granule. */
56*7c568831SAndroid Build Coastguard Worker 
57*7c568831SAndroid Build Coastguard Worker #define EPSILON         0x100           /* Token for empty transition. */
58*7c568831SAndroid Build Coastguard Worker 
59*7c568831SAndroid Build Coastguard Worker 
60*7c568831SAndroid Build Coastguard Worker #ifndef OFFSETOF
61*7c568831SAndroid Build Coastguard Worker #define OFFSETOF(t, f)  ((unsigned int) ((char *) &((t *) 0)->f - (char *) 0))
62*7c568831SAndroid Build Coastguard Worker #endif
63*7c568831SAndroid Build Coastguard Worker 
64*7c568831SAndroid Build Coastguard Worker #ifndef OFFSETBY
65*7c568831SAndroid Build Coastguard Worker #define OFFSETBY(t, p, o)       ((t *) ((char *) (p) + (unsigned int) (o)))
66*7c568831SAndroid Build Coastguard Worker #endif
67*7c568831SAndroid Build Coastguard Worker 
68*7c568831SAndroid Build Coastguard Worker 
69*7c568831SAndroid Build Coastguard Worker typedef struct t_transition     t_transition;   /* NFA/DFA transition. */
70*7c568831SAndroid Build Coastguard Worker typedef struct t_state          t_state;        /* NFA/DFA state node. */
71*7c568831SAndroid Build Coastguard Worker typedef struct t_symlist        t_symlist;      /* Symbol (i.e.: name) list. */
72*7c568831SAndroid Build Coastguard Worker typedef struct t_chset          t_chset;        /* Character set. */
73*7c568831SAndroid Build Coastguard Worker typedef struct t_stategroup     t_stategroup;   /* Optimization group. */
74*7c568831SAndroid Build Coastguard Worker typedef unsigned char           utf8char;       /* UTF-8 character byte. */
75*7c568831SAndroid Build Coastguard Worker typedef unsigned char           byte;           /* Untyped data byte. */
76*7c568831SAndroid Build Coastguard Worker 
77*7c568831SAndroid Build Coastguard Worker 
78*7c568831SAndroid Build Coastguard Worker typedef struct {                        /* Set of pointers. */
79*7c568831SAndroid Build Coastguard Worker         unsigned int    p_size;         /* Current allocated size. */
80*7c568831SAndroid Build Coastguard Worker         unsigned int    p_card;         /* Current element count. */
81*7c568831SAndroid Build Coastguard Worker         void *          p_set[1];       /* Element array. */
82*7c568831SAndroid Build Coastguard Worker }               t_powerset;
83*7c568831SAndroid Build Coastguard Worker 
84*7c568831SAndroid Build Coastguard Worker 
85*7c568831SAndroid Build Coastguard Worker struct t_transition {
86*7c568831SAndroid Build Coastguard Worker         t_transition *  t_forwprev;     /* Head of forward transition list. */
87*7c568831SAndroid Build Coastguard Worker         t_transition *  t_forwnext;     /* Tail of forward transition list. */
88*7c568831SAndroid Build Coastguard Worker         t_transition *  t_backprev;     /* Head of backward transition list. */
89*7c568831SAndroid Build Coastguard Worker         t_transition *  t_backnext;     /* Tail of backward transition list. */
90*7c568831SAndroid Build Coastguard Worker         t_state *       t_from;         /* Incoming state. */
91*7c568831SAndroid Build Coastguard Worker         t_state *       t_to;           /* Destination state. */
92*7c568831SAndroid Build Coastguard Worker         unsigned short  t_token;        /* Transition token. */
93*7c568831SAndroid Build Coastguard Worker         unsigned int    t_index;        /* Transition array index. */
94*7c568831SAndroid Build Coastguard Worker };
95*7c568831SAndroid Build Coastguard Worker 
96*7c568831SAndroid Build Coastguard Worker 
97*7c568831SAndroid Build Coastguard Worker struct t_state {
98*7c568831SAndroid Build Coastguard Worker         t_state *       s_next;         /* Next state (for DFA construction). */
99*7c568831SAndroid Build Coastguard Worker         t_state *       s_stack;        /* Unprocessed DFA states stack. */
100*7c568831SAndroid Build Coastguard Worker         t_transition *  s_forward;      /* Forward transitions. */
101*7c568831SAndroid Build Coastguard Worker         t_transition *  s_backward;     /* Backward transitions. */
102*7c568831SAndroid Build Coastguard Worker         t_chset *       s_final;        /* Recognized character set. */
103*7c568831SAndroid Build Coastguard Worker         t_powerset *    s_nfastates;    /* Corresponding NFA states. */
104*7c568831SAndroid Build Coastguard Worker         unsigned int    s_index;        /* State index. */
105*7c568831SAndroid Build Coastguard Worker };
106*7c568831SAndroid Build Coastguard Worker 
107*7c568831SAndroid Build Coastguard Worker 
108*7c568831SAndroid Build Coastguard Worker struct t_symlist {
109*7c568831SAndroid Build Coastguard Worker         t_symlist *     l_next;         /* Next name in list. */
110*7c568831SAndroid Build Coastguard Worker         utf8char        l_symbol[1];    /* Name bytes. */
111*7c568831SAndroid Build Coastguard Worker };
112*7c568831SAndroid Build Coastguard Worker 
113*7c568831SAndroid Build Coastguard Worker 
114*7c568831SAndroid Build Coastguard Worker struct t_chset {
115*7c568831SAndroid Build Coastguard Worker         t_chset *       c_next;         /* Next character set. */
116*7c568831SAndroid Build Coastguard Worker         t_symlist *     c_names;        /* Character set name list. */
117*7c568831SAndroid Build Coastguard Worker         iconv_t         c_fromUTF8;     /* Conversion from UTF-8. */
118*7c568831SAndroid Build Coastguard Worker         unsigned int    c_ccsid;        /* IBM character set code. */
119*7c568831SAndroid Build Coastguard Worker         unsigned int    c_mibenum;      /* IANA character code. */
120*7c568831SAndroid Build Coastguard Worker };
121*7c568831SAndroid Build Coastguard Worker 
122*7c568831SAndroid Build Coastguard Worker 
123*7c568831SAndroid Build Coastguard Worker struct t_stategroup {
124*7c568831SAndroid Build Coastguard Worker         t_stategroup *  g_next;         /* Next group. */
125*7c568831SAndroid Build Coastguard Worker         t_state *       g_member;       /* Group member (s_stack) list. */
126*7c568831SAndroid Build Coastguard Worker         unsigned int    g_id;           /* Group ident. */
127*7c568831SAndroid Build Coastguard Worker };
128*7c568831SAndroid Build Coastguard Worker 
129*7c568831SAndroid Build Coastguard Worker 
130*7c568831SAndroid Build Coastguard Worker 
131*7c568831SAndroid Build Coastguard Worker t_chset *       chset_list;             /* Character set list. */
132*7c568831SAndroid Build Coastguard Worker t_state *       initial_state;          /* Initial NFA state. */
133*7c568831SAndroid Build Coastguard Worker iconv_t         job2utf8;               /* Job CCSID to UTF-8 conversion. */
134*7c568831SAndroid Build Coastguard Worker iconv_t         utf82job;               /* UTF-8 to job CCSID conversion. */
135*7c568831SAndroid Build Coastguard Worker t_state *       dfa_states;             /* List of DFA states. */
136*7c568831SAndroid Build Coastguard Worker unsigned int    groupid;                /* Group ident counter. */
137*7c568831SAndroid Build Coastguard Worker 
138*7c568831SAndroid Build Coastguard Worker 
139*7c568831SAndroid Build Coastguard Worker /**
140*7c568831SAndroid Build Coastguard Worker ***     UTF-8 strings.
141*7c568831SAndroid Build Coastguard Worker **/
142*7c568831SAndroid Build Coastguard Worker 
143*7c568831SAndroid Build Coastguard Worker #pragma convert(819)
144*7c568831SAndroid Build Coastguard Worker 
145*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_MIBenum[] = "MIBenum";
146*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_mibenum[] = "mibenum";
147*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_ibm_[] = "ibm-";
148*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_IBMCCSID[] = "IBMCCSID";
149*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_iana_[] = "iana-";
150*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_Name[] = "Name";
151*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_Pref_MIME_Name[] = "Preferred MIME Name";
152*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_Aliases[] = "Aliases";
153*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_html[] = "html";
154*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_htmluri[] = "http://www.w3.org/1999/xhtml";
155*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_A[] = "A";
156*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_C[] = "C";
157*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_M[] = "M";
158*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_N[] = "N";
159*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_P[] = "P";
160*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_T[] = "T";
161*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_ccsid[] = "ccsid";
162*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_EBCDIC[] = "EBCDIC";
163*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_ASCII[] = "ASCII";
164*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_assocnodes[] = "/ccsid_mibenum/assoc[@ccsid]";
165*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_aliastext[] =
166*7c568831SAndroid Build Coastguard Worker                                 "/ccsid_mibenum/assoc[@ccsid=$C]/alias/text()";
167*7c568831SAndroid Build Coastguard Worker #ifdef OLDXML
168*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_tablerows[] =
169*7c568831SAndroid Build Coastguard Worker                         "//table[@id='table-character-sets-1']/*/tr";
170*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_headerpos[] =
171*7c568831SAndroid Build Coastguard Worker                 "count(th[text()=$T]/preceding-sibling::th)+1";
172*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_getmibenum[] = "number(td[$M])";
173*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_getprefname[] = "string(td[$P])";
174*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_getname[] = "string(td[$N])";
175*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_getaliases[] = "td[$A]/text()";
176*7c568831SAndroid Build Coastguard Worker #else
177*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_tablerows[] =
178*7c568831SAndroid Build Coastguard Worker                         "//html:table[@id='table-character-sets-1']/*/html:tr";
179*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_headerpos[] =
180*7c568831SAndroid Build Coastguard Worker                 "count(html:th[text()=$T]/preceding-sibling::html:th)+1";
181*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_getmibenum[] = "number(html:td[$M])";
182*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_getprefname[] = "string(html:td[$P])";
183*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_getname[] = "string(html:td[$N])";
184*7c568831SAndroid Build Coastguard Worker static const utf8char   utf8_getaliases[] = "html:td[$A]/text()";
185*7c568831SAndroid Build Coastguard Worker #endif
186*7c568831SAndroid Build Coastguard Worker 
187*7c568831SAndroid Build Coastguard Worker #pragma convert(0)
188*7c568831SAndroid Build Coastguard Worker 
189*7c568831SAndroid Build Coastguard Worker 
190*7c568831SAndroid Build Coastguard Worker /**
191*7c568831SAndroid Build Coastguard Worker ***     UTF-8 character length table.
192*7c568831SAndroid Build Coastguard Worker ***
193*7c568831SAndroid Build Coastguard Worker ***     Index is first character byte, value is the character byte count.
194*7c568831SAndroid Build Coastguard Worker **/
195*7c568831SAndroid Build Coastguard Worker 
196*7c568831SAndroid Build Coastguard Worker static signed char      utf8_chlen[] = {
197*7c568831SAndroid Build Coastguard Worker /* 00-07 */     1,      1,      1,      1,      1,      1,      1,      1,
198*7c568831SAndroid Build Coastguard Worker /* 08-0F */     1,      1,      1,      1,      1,      1,      1,      1,
199*7c568831SAndroid Build Coastguard Worker /* 10-17 */     1,      1,      1,      1,      1,      1,      1,      1,
200*7c568831SAndroid Build Coastguard Worker /* 18-1F */     1,      1,      1,      1,      1,      1,      1,      1,
201*7c568831SAndroid Build Coastguard Worker /* 20-27 */     1,      1,      1,      1,      1,      1,      1,      1,
202*7c568831SAndroid Build Coastguard Worker /* 28-2F */     1,      1,      1,      1,      1,      1,      1,      1,
203*7c568831SAndroid Build Coastguard Worker /* 30-37 */     1,      1,      1,      1,      1,      1,      1,      1,
204*7c568831SAndroid Build Coastguard Worker /* 38-3F */     1,      1,      1,      1,      1,      1,      1,      1,
205*7c568831SAndroid Build Coastguard Worker /* 40-47 */     1,      1,      1,      1,      1,      1,      1,      1,
206*7c568831SAndroid Build Coastguard Worker /* 48-4F */     1,      1,      1,      1,      1,      1,      1,      1,
207*7c568831SAndroid Build Coastguard Worker /* 50-57 */     1,      1,      1,      1,      1,      1,      1,      1,
208*7c568831SAndroid Build Coastguard Worker /* 58-5F */     1,      1,      1,      1,      1,      1,      1,      1,
209*7c568831SAndroid Build Coastguard Worker /* 60-67 */     1,      1,      1,      1,      1,      1,      1,      1,
210*7c568831SAndroid Build Coastguard Worker /* 68-6F */     1,      1,      1,      1,      1,      1,      1,      1,
211*7c568831SAndroid Build Coastguard Worker /* 70-77 */     1,      1,      1,      1,      1,      1,      1,      1,
212*7c568831SAndroid Build Coastguard Worker /* 78-7F */     1,      1,      1,      1,      1,      1,      1,      1,
213*7c568831SAndroid Build Coastguard Worker /* 80-87 */     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
214*7c568831SAndroid Build Coastguard Worker /* 88-8F */     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
215*7c568831SAndroid Build Coastguard Worker /* 90-97 */     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
216*7c568831SAndroid Build Coastguard Worker /* 98-9F */     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
217*7c568831SAndroid Build Coastguard Worker /* A0-A7 */     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
218*7c568831SAndroid Build Coastguard Worker /* A8-AF */     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
219*7c568831SAndroid Build Coastguard Worker /* B0-B7 */     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
220*7c568831SAndroid Build Coastguard Worker /* B8-BF */     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
221*7c568831SAndroid Build Coastguard Worker /* C0-C7 */     2,      2,      2,      2,      2,      2,      2,      2,
222*7c568831SAndroid Build Coastguard Worker /* C8-CF */     2,      2,      2,      2,      2,      2,      2,      2,
223*7c568831SAndroid Build Coastguard Worker /* D0-D7 */     2,      2,      2,      2,      2,      2,      2,      2,
224*7c568831SAndroid Build Coastguard Worker /* D8-DF */     2,      2,      2,      2,      2,      2,      2,      2,
225*7c568831SAndroid Build Coastguard Worker /* E0-E7 */     3,      3,      3,      3,      3,      3,      3,      3,
226*7c568831SAndroid Build Coastguard Worker /* E8-EF */     3,      3,      3,      3,      3,      3,      3,      3,
227*7c568831SAndroid Build Coastguard Worker /* F0-F7 */     4,      4,      4,      4,      4,      4,      4,      4,
228*7c568831SAndroid Build Coastguard Worker /* F8-FF */     5,      5,      5,      5,      6,      6,      -1,     -1
229*7c568831SAndroid Build Coastguard Worker };
230*7c568831SAndroid Build Coastguard Worker 
231*7c568831SAndroid Build Coastguard Worker 
232*7c568831SAndroid Build Coastguard Worker 
233*7c568831SAndroid Build Coastguard Worker void
chknull(void * p)234*7c568831SAndroid Build Coastguard Worker chknull(void * p)
235*7c568831SAndroid Build Coastguard Worker 
236*7c568831SAndroid Build Coastguard Worker {
237*7c568831SAndroid Build Coastguard Worker         if (p)
238*7c568831SAndroid Build Coastguard Worker                 return;
239*7c568831SAndroid Build Coastguard Worker 
240*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "Not enough memory\n");
241*7c568831SAndroid Build Coastguard Worker         exit(1);
242*7c568831SAndroid Build Coastguard Worker }
243*7c568831SAndroid Build Coastguard Worker 
244*7c568831SAndroid Build Coastguard Worker 
245*7c568831SAndroid Build Coastguard Worker void
makecode(char * buf,unsigned int ccsid)246*7c568831SAndroid Build Coastguard Worker makecode(char * buf, unsigned int ccsid)
247*7c568831SAndroid Build Coastguard Worker 
248*7c568831SAndroid Build Coastguard Worker {
249*7c568831SAndroid Build Coastguard Worker         ccsid &= 0xFFFF;
250*7c568831SAndroid Build Coastguard Worker         memset(buf, 0, 32);
251*7c568831SAndroid Build Coastguard Worker         sprintf(buf, "IBMCCSID%05u0000000", ccsid);
252*7c568831SAndroid Build Coastguard Worker }
253*7c568831SAndroid Build Coastguard Worker 
254*7c568831SAndroid Build Coastguard Worker 
255*7c568831SAndroid Build Coastguard Worker iconv_t
iconv_open_ccsid(unsigned int ccsidout,unsigned int ccsidin,unsigned int nullflag)256*7c568831SAndroid Build Coastguard Worker iconv_open_ccsid(unsigned int ccsidout,
257*7c568831SAndroid Build Coastguard Worker                                 unsigned int ccsidin, unsigned int nullflag)
258*7c568831SAndroid Build Coastguard Worker 
259*7c568831SAndroid Build Coastguard Worker {
260*7c568831SAndroid Build Coastguard Worker         char fromcode[33];
261*7c568831SAndroid Build Coastguard Worker         char tocode[33];
262*7c568831SAndroid Build Coastguard Worker 
263*7c568831SAndroid Build Coastguard Worker         makecode(fromcode, ccsidin);
264*7c568831SAndroid Build Coastguard Worker         makecode(tocode, ccsidout);
265*7c568831SAndroid Build Coastguard Worker         memset(tocode + 13, 0, sizeof tocode - 13);
266*7c568831SAndroid Build Coastguard Worker 
267*7c568831SAndroid Build Coastguard Worker         if (nullflag)
268*7c568831SAndroid Build Coastguard Worker                 fromcode[18] = '1';
269*7c568831SAndroid Build Coastguard Worker 
270*7c568831SAndroid Build Coastguard Worker         return iconv_open(tocode, fromcode);
271*7c568831SAndroid Build Coastguard Worker }
272*7c568831SAndroid Build Coastguard Worker 
273*7c568831SAndroid Build Coastguard Worker 
274*7c568831SAndroid Build Coastguard Worker unsigned int
getnum(char ** cpp)275*7c568831SAndroid Build Coastguard Worker getnum(char * * cpp)
276*7c568831SAndroid Build Coastguard Worker 
277*7c568831SAndroid Build Coastguard Worker {
278*7c568831SAndroid Build Coastguard Worker         unsigned int n;
279*7c568831SAndroid Build Coastguard Worker         char * cp;
280*7c568831SAndroid Build Coastguard Worker 
281*7c568831SAndroid Build Coastguard Worker         cp = *cpp;
282*7c568831SAndroid Build Coastguard Worker         n = 0;
283*7c568831SAndroid Build Coastguard Worker 
284*7c568831SAndroid Build Coastguard Worker         while (isdigit(*cp))
285*7c568831SAndroid Build Coastguard Worker                 n = 10 * n + *cp++ - '0';
286*7c568831SAndroid Build Coastguard Worker 
287*7c568831SAndroid Build Coastguard Worker         *cpp = cp;
288*7c568831SAndroid Build Coastguard Worker         return n;
289*7c568831SAndroid Build Coastguard Worker }
290*7c568831SAndroid Build Coastguard Worker 
291*7c568831SAndroid Build Coastguard Worker 
292*7c568831SAndroid Build Coastguard Worker const utf8char *
hashBinaryKey(const byte * bytes,unsigned int len)293*7c568831SAndroid Build Coastguard Worker hashBinaryKey(const byte * bytes, unsigned int len)
294*7c568831SAndroid Build Coastguard Worker 
295*7c568831SAndroid Build Coastguard Worker {
296*7c568831SAndroid Build Coastguard Worker         const byte * bp;
297*7c568831SAndroid Build Coastguard Worker         utf8char * key;
298*7c568831SAndroid Build Coastguard Worker         utf8char * cp;
299*7c568831SAndroid Build Coastguard Worker         unsigned int n;
300*7c568831SAndroid Build Coastguard Worker         unsigned int n4;
301*7c568831SAndroid Build Coastguard Worker         unsigned int i;
302*7c568831SAndroid Build Coastguard Worker 
303*7c568831SAndroid Build Coastguard Worker         /**
304*7c568831SAndroid Build Coastguard Worker         ***     Encode binary data in character form to be used as hash
305*7c568831SAndroid Build Coastguard Worker         ***             table key.
306*7c568831SAndroid Build Coastguard Worker         **/
307*7c568831SAndroid Build Coastguard Worker 
308*7c568831SAndroid Build Coastguard Worker         n = (4 * len + 2) / 3;
309*7c568831SAndroid Build Coastguard Worker         key = (utf8char *) malloc(n + 1);
310*7c568831SAndroid Build Coastguard Worker         chknull(key);
311*7c568831SAndroid Build Coastguard Worker         bp = bytes;
312*7c568831SAndroid Build Coastguard Worker         cp = key;
313*7c568831SAndroid Build Coastguard Worker 
314*7c568831SAndroid Build Coastguard Worker         for (n4 = n >> 2; n4; n4--) {
315*7c568831SAndroid Build Coastguard Worker                 i = (bp[0] << 16) | (bp[1] << 8) | bp[2];
316*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + ((i >> 18) & 0x3F);
317*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + ((i >> 12) & 0x3F);
318*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + ((i >> 6) & 0x3F);
319*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + (i & 0x3F);
320*7c568831SAndroid Build Coastguard Worker                 bp += 3;
321*7c568831SAndroid Build Coastguard Worker                 }
322*7c568831SAndroid Build Coastguard Worker 
323*7c568831SAndroid Build Coastguard Worker         switch (n & 0x3) {
324*7c568831SAndroid Build Coastguard Worker 
325*7c568831SAndroid Build Coastguard Worker         case 2:
326*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + ((*bp >> 2) & 0x3F);
327*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + ((*bp << 4) & 0x3F);
328*7c568831SAndroid Build Coastguard Worker                 break;
329*7c568831SAndroid Build Coastguard Worker 
330*7c568831SAndroid Build Coastguard Worker         case 3:
331*7c568831SAndroid Build Coastguard Worker                 i = (bp[0] << 8) | bp[1];
332*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + ((i >> 10) & 0x3F);
333*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + ((i >> 4) & 0x3F);
334*7c568831SAndroid Build Coastguard Worker                 *cp++ = 0x21 + ((i << 2) & 0x3F);
335*7c568831SAndroid Build Coastguard Worker                 break;
336*7c568831SAndroid Build Coastguard Worker                 }
337*7c568831SAndroid Build Coastguard Worker 
338*7c568831SAndroid Build Coastguard Worker         *cp = '\0';
339*7c568831SAndroid Build Coastguard Worker         return key;
340*7c568831SAndroid Build Coastguard Worker }
341*7c568831SAndroid Build Coastguard Worker 
342*7c568831SAndroid Build Coastguard Worker 
343*7c568831SAndroid Build Coastguard Worker void *
hash_get(xmlHashTablePtr h,const void * binkey,unsigned int len)344*7c568831SAndroid Build Coastguard Worker hash_get(xmlHashTablePtr h, const void * binkey, unsigned int len)
345*7c568831SAndroid Build Coastguard Worker 
346*7c568831SAndroid Build Coastguard Worker {
347*7c568831SAndroid Build Coastguard Worker         const utf8char * key;
348*7c568831SAndroid Build Coastguard Worker         void * result;
349*7c568831SAndroid Build Coastguard Worker 
350*7c568831SAndroid Build Coastguard Worker         key = hashBinaryKey((const byte *) binkey, len);
351*7c568831SAndroid Build Coastguard Worker         result = xmlHashLookup(h, key);
352*7c568831SAndroid Build Coastguard Worker         free((char *) key);
353*7c568831SAndroid Build Coastguard Worker         return result;
354*7c568831SAndroid Build Coastguard Worker }
355*7c568831SAndroid Build Coastguard Worker 
356*7c568831SAndroid Build Coastguard Worker 
357*7c568831SAndroid Build Coastguard Worker int
hash_add(xmlHashTablePtr h,const void * binkey,unsigned int len,void * data)358*7c568831SAndroid Build Coastguard Worker hash_add(xmlHashTablePtr h, const void * binkey, unsigned int len, void * data)
359*7c568831SAndroid Build Coastguard Worker 
360*7c568831SAndroid Build Coastguard Worker {
361*7c568831SAndroid Build Coastguard Worker         const utf8char * key;
362*7c568831SAndroid Build Coastguard Worker         int result;
363*7c568831SAndroid Build Coastguard Worker 
364*7c568831SAndroid Build Coastguard Worker         key = hashBinaryKey((const byte *) binkey, len);
365*7c568831SAndroid Build Coastguard Worker         result = xmlHashAddEntry(h, key, data);
366*7c568831SAndroid Build Coastguard Worker         free((char *) key);
367*7c568831SAndroid Build Coastguard Worker         return result;
368*7c568831SAndroid Build Coastguard Worker }
369*7c568831SAndroid Build Coastguard Worker 
370*7c568831SAndroid Build Coastguard Worker 
371*7c568831SAndroid Build Coastguard Worker xmlDocPtr
loadXMLFile(const char * filename)372*7c568831SAndroid Build Coastguard Worker loadXMLFile(const char * filename)
373*7c568831SAndroid Build Coastguard Worker 
374*7c568831SAndroid Build Coastguard Worker {
375*7c568831SAndroid Build Coastguard Worker         struct stat sbuf;
376*7c568831SAndroid Build Coastguard Worker         byte * databuf;
377*7c568831SAndroid Build Coastguard Worker         int fd;
378*7c568831SAndroid Build Coastguard Worker         int i;
379*7c568831SAndroid Build Coastguard Worker         xmlDocPtr doc;
380*7c568831SAndroid Build Coastguard Worker 
381*7c568831SAndroid Build Coastguard Worker         if (stat(filename, &sbuf))
382*7c568831SAndroid Build Coastguard Worker                 return (xmlDocPtr) NULL;
383*7c568831SAndroid Build Coastguard Worker 
384*7c568831SAndroid Build Coastguard Worker         databuf = malloc(sbuf.st_size + 4);
385*7c568831SAndroid Build Coastguard Worker 
386*7c568831SAndroid Build Coastguard Worker         if (!databuf)
387*7c568831SAndroid Build Coastguard Worker                 return (xmlDocPtr) NULL;
388*7c568831SAndroid Build Coastguard Worker 
389*7c568831SAndroid Build Coastguard Worker         fd = open(filename, O_RDONLY
390*7c568831SAndroid Build Coastguard Worker #ifdef O_BINARY
391*7c568831SAndroid Build Coastguard Worker                                          | O_BINARY
392*7c568831SAndroid Build Coastguard Worker #endif
393*7c568831SAndroid Build Coastguard Worker                                                         );
394*7c568831SAndroid Build Coastguard Worker 
395*7c568831SAndroid Build Coastguard Worker         if (fd < 0) {
396*7c568831SAndroid Build Coastguard Worker                 free((char *) databuf);
397*7c568831SAndroid Build Coastguard Worker                 return (xmlDocPtr) NULL;
398*7c568831SAndroid Build Coastguard Worker                 }
399*7c568831SAndroid Build Coastguard Worker 
400*7c568831SAndroid Build Coastguard Worker         i = read(fd, (char *) databuf, sbuf.st_size);
401*7c568831SAndroid Build Coastguard Worker         close(fd);
402*7c568831SAndroid Build Coastguard Worker 
403*7c568831SAndroid Build Coastguard Worker         if (i != sbuf.st_size) {
404*7c568831SAndroid Build Coastguard Worker                 free((char *) databuf);
405*7c568831SAndroid Build Coastguard Worker                 return (xmlDocPtr) NULL;
406*7c568831SAndroid Build Coastguard Worker                 }
407*7c568831SAndroid Build Coastguard Worker 
408*7c568831SAndroid Build Coastguard Worker         databuf[i] = databuf[i + 1] = databuf[i + 2] = databuf[i + 3] = 0;
409*7c568831SAndroid Build Coastguard Worker         doc = xmlParseMemory((xmlChar *) databuf, i);
410*7c568831SAndroid Build Coastguard Worker         free((char *) databuf);
411*7c568831SAndroid Build Coastguard Worker         return doc;
412*7c568831SAndroid Build Coastguard Worker }
413*7c568831SAndroid Build Coastguard Worker 
414*7c568831SAndroid Build Coastguard Worker 
415*7c568831SAndroid Build Coastguard Worker int
match(char ** cpp,char * s)416*7c568831SAndroid Build Coastguard Worker match(char * * cpp, char * s)
417*7c568831SAndroid Build Coastguard Worker 
418*7c568831SAndroid Build Coastguard Worker {
419*7c568831SAndroid Build Coastguard Worker         char * cp;
420*7c568831SAndroid Build Coastguard Worker         int c1;
421*7c568831SAndroid Build Coastguard Worker         int c2;
422*7c568831SAndroid Build Coastguard Worker 
423*7c568831SAndroid Build Coastguard Worker         cp = *cpp;
424*7c568831SAndroid Build Coastguard Worker 
425*7c568831SAndroid Build Coastguard Worker         for (cp = *cpp; c2 = *s++; cp++) {
426*7c568831SAndroid Build Coastguard Worker                 c1 = *cp;
427*7c568831SAndroid Build Coastguard Worker 
428*7c568831SAndroid Build Coastguard Worker                 if (c1 != c2) {
429*7c568831SAndroid Build Coastguard Worker                         if (isupper(c1))
430*7c568831SAndroid Build Coastguard Worker                                 c1 = tolower(c1);
431*7c568831SAndroid Build Coastguard Worker 
432*7c568831SAndroid Build Coastguard Worker                         if (isupper(c2))
433*7c568831SAndroid Build Coastguard Worker                                 c2 = tolower(c2);
434*7c568831SAndroid Build Coastguard Worker                         }
435*7c568831SAndroid Build Coastguard Worker 
436*7c568831SAndroid Build Coastguard Worker                 if (c1 != c2)
437*7c568831SAndroid Build Coastguard Worker                         return 0;
438*7c568831SAndroid Build Coastguard Worker                 }
439*7c568831SAndroid Build Coastguard Worker 
440*7c568831SAndroid Build Coastguard Worker         c1 = *cp;
441*7c568831SAndroid Build Coastguard Worker 
442*7c568831SAndroid Build Coastguard Worker         while (c1 == ' ' || c1 == '\t')
443*7c568831SAndroid Build Coastguard Worker                 c1 = *++cp;
444*7c568831SAndroid Build Coastguard Worker 
445*7c568831SAndroid Build Coastguard Worker         *cpp = cp;
446*7c568831SAndroid Build Coastguard Worker         return 1;
447*7c568831SAndroid Build Coastguard Worker }
448*7c568831SAndroid Build Coastguard Worker 
449*7c568831SAndroid Build Coastguard Worker 
450*7c568831SAndroid Build Coastguard Worker t_state *
newstate(void)451*7c568831SAndroid Build Coastguard Worker newstate(void)
452*7c568831SAndroid Build Coastguard Worker 
453*7c568831SAndroid Build Coastguard Worker {
454*7c568831SAndroid Build Coastguard Worker         t_state * s;
455*7c568831SAndroid Build Coastguard Worker 
456*7c568831SAndroid Build Coastguard Worker         s = (t_state *) malloc(sizeof *s);
457*7c568831SAndroid Build Coastguard Worker         chknull(s);
458*7c568831SAndroid Build Coastguard Worker         memset((char *) s, 0, sizeof *s);
459*7c568831SAndroid Build Coastguard Worker         return s;
460*7c568831SAndroid Build Coastguard Worker }
461*7c568831SAndroid Build Coastguard Worker 
462*7c568831SAndroid Build Coastguard Worker 
463*7c568831SAndroid Build Coastguard Worker void
unlink_transition(t_transition * t)464*7c568831SAndroid Build Coastguard Worker unlink_transition(t_transition * t)
465*7c568831SAndroid Build Coastguard Worker 
466*7c568831SAndroid Build Coastguard Worker {
467*7c568831SAndroid Build Coastguard Worker         if (t->t_backnext)
468*7c568831SAndroid Build Coastguard Worker                 t->t_backnext->t_backprev = t->t_backprev;
469*7c568831SAndroid Build Coastguard Worker 
470*7c568831SAndroid Build Coastguard Worker         if (t->t_backprev)
471*7c568831SAndroid Build Coastguard Worker                 t->t_backprev->t_backnext = t->t_backnext;
472*7c568831SAndroid Build Coastguard Worker         else if (t->t_to)
473*7c568831SAndroid Build Coastguard Worker                 t->t_to->s_backward = t->t_backnext;
474*7c568831SAndroid Build Coastguard Worker 
475*7c568831SAndroid Build Coastguard Worker         if (t->t_forwnext)
476*7c568831SAndroid Build Coastguard Worker                 t->t_forwnext->t_forwprev = t->t_forwprev;
477*7c568831SAndroid Build Coastguard Worker 
478*7c568831SAndroid Build Coastguard Worker         if (t->t_forwprev)
479*7c568831SAndroid Build Coastguard Worker                 t->t_forwprev->t_forwnext = t->t_forwnext;
480*7c568831SAndroid Build Coastguard Worker         else if (t->t_from)
481*7c568831SAndroid Build Coastguard Worker                 t->t_from->s_forward = t->t_forwnext;
482*7c568831SAndroid Build Coastguard Worker 
483*7c568831SAndroid Build Coastguard Worker         t->t_backprev = (t_transition *) NULL;
484*7c568831SAndroid Build Coastguard Worker         t->t_backnext = (t_transition *) NULL;
485*7c568831SAndroid Build Coastguard Worker         t->t_forwprev = (t_transition *) NULL;
486*7c568831SAndroid Build Coastguard Worker         t->t_forwnext = (t_transition *) NULL;
487*7c568831SAndroid Build Coastguard Worker         t->t_from = (t_state *) NULL;
488*7c568831SAndroid Build Coastguard Worker         t->t_to = (t_state *) NULL;
489*7c568831SAndroid Build Coastguard Worker }
490*7c568831SAndroid Build Coastguard Worker 
491*7c568831SAndroid Build Coastguard Worker 
492*7c568831SAndroid Build Coastguard Worker void
link_transition(t_transition * t,t_state * from,t_state * to)493*7c568831SAndroid Build Coastguard Worker link_transition(t_transition * t, t_state * from, t_state * to)
494*7c568831SAndroid Build Coastguard Worker 
495*7c568831SAndroid Build Coastguard Worker {
496*7c568831SAndroid Build Coastguard Worker         if (!from)
497*7c568831SAndroid Build Coastguard Worker                 from = t->t_from;
498*7c568831SAndroid Build Coastguard Worker 
499*7c568831SAndroid Build Coastguard Worker         if (!to)
500*7c568831SAndroid Build Coastguard Worker                 to = t->t_to;
501*7c568831SAndroid Build Coastguard Worker 
502*7c568831SAndroid Build Coastguard Worker         unlink_transition(t);
503*7c568831SAndroid Build Coastguard Worker 
504*7c568831SAndroid Build Coastguard Worker         if ((t->t_from = from)) {
505*7c568831SAndroid Build Coastguard Worker                 if ((t->t_forwnext = from->s_forward))
506*7c568831SAndroid Build Coastguard Worker                         t->t_forwnext->t_forwprev = t;
507*7c568831SAndroid Build Coastguard Worker 
508*7c568831SAndroid Build Coastguard Worker                 from->s_forward = t;
509*7c568831SAndroid Build Coastguard Worker                 }
510*7c568831SAndroid Build Coastguard Worker 
511*7c568831SAndroid Build Coastguard Worker         if ((t->t_to = to)) {
512*7c568831SAndroid Build Coastguard Worker                 if ((t->t_backnext = to->s_backward))
513*7c568831SAndroid Build Coastguard Worker                         t->t_backnext->t_backprev = t;
514*7c568831SAndroid Build Coastguard Worker 
515*7c568831SAndroid Build Coastguard Worker                 to->s_backward = t;
516*7c568831SAndroid Build Coastguard Worker                 }
517*7c568831SAndroid Build Coastguard Worker }
518*7c568831SAndroid Build Coastguard Worker 
519*7c568831SAndroid Build Coastguard Worker 
520*7c568831SAndroid Build Coastguard Worker t_transition *
newtransition(unsigned int token,t_state * from,t_state * to)521*7c568831SAndroid Build Coastguard Worker newtransition(unsigned int token, t_state * from, t_state * to)
522*7c568831SAndroid Build Coastguard Worker 
523*7c568831SAndroid Build Coastguard Worker {
524*7c568831SAndroid Build Coastguard Worker         t_transition * t;
525*7c568831SAndroid Build Coastguard Worker 
526*7c568831SAndroid Build Coastguard Worker         t = (t_transition *) malloc(sizeof *t);
527*7c568831SAndroid Build Coastguard Worker         chknull(t);
528*7c568831SAndroid Build Coastguard Worker         memset((char *) t, 0, sizeof *t);
529*7c568831SAndroid Build Coastguard Worker         t->t_token = token;
530*7c568831SAndroid Build Coastguard Worker         link_transition(t, from, to);
531*7c568831SAndroid Build Coastguard Worker         return t;
532*7c568831SAndroid Build Coastguard Worker }
533*7c568831SAndroid Build Coastguard Worker 
534*7c568831SAndroid Build Coastguard Worker 
535*7c568831SAndroid Build Coastguard Worker t_transition *
uniquetransition(unsigned int token,t_state * from,t_state * to)536*7c568831SAndroid Build Coastguard Worker uniquetransition(unsigned int token, t_state * from, t_state * to)
537*7c568831SAndroid Build Coastguard Worker 
538*7c568831SAndroid Build Coastguard Worker {
539*7c568831SAndroid Build Coastguard Worker         t_transition * t;
540*7c568831SAndroid Build Coastguard Worker 
541*7c568831SAndroid Build Coastguard Worker         for (t = from->s_forward; t; t = t->t_forwnext)
542*7c568831SAndroid Build Coastguard Worker                 if (t->t_token == token && (t->t_to == to || !to))
543*7c568831SAndroid Build Coastguard Worker                         return t;
544*7c568831SAndroid Build Coastguard Worker 
545*7c568831SAndroid Build Coastguard Worker         return to? newtransition(token, from, to): (t_transition *) NULL;
546*7c568831SAndroid Build Coastguard Worker }
547*7c568831SAndroid Build Coastguard Worker 
548*7c568831SAndroid Build Coastguard Worker 
549*7c568831SAndroid Build Coastguard Worker int
set_position(t_powerset * s,void * e)550*7c568831SAndroid Build Coastguard Worker set_position(t_powerset * s, void * e)
551*7c568831SAndroid Build Coastguard Worker 
552*7c568831SAndroid Build Coastguard Worker {
553*7c568831SAndroid Build Coastguard Worker         unsigned int l;
554*7c568831SAndroid Build Coastguard Worker         unsigned int h;
555*7c568831SAndroid Build Coastguard Worker         unsigned int m;
556*7c568831SAndroid Build Coastguard Worker         int i;
557*7c568831SAndroid Build Coastguard Worker 
558*7c568831SAndroid Build Coastguard Worker         l = 0;
559*7c568831SAndroid Build Coastguard Worker         h = s->p_card;
560*7c568831SAndroid Build Coastguard Worker 
561*7c568831SAndroid Build Coastguard Worker         while (l < h) {
562*7c568831SAndroid Build Coastguard Worker                 m = (l + h) >> 1;
563*7c568831SAndroid Build Coastguard Worker 
564*7c568831SAndroid Build Coastguard Worker                 /**
565*7c568831SAndroid Build Coastguard Worker                 ***     If both pointers belong to different allocation arenas,
566*7c568831SAndroid Build Coastguard Worker                 ***             native comparison may find them neither
567*7c568831SAndroid Build Coastguard Worker                 ***             equal, nor greater, nor smaller.
568*7c568831SAndroid Build Coastguard Worker                 ***     We thus compare using memcmp() to get an orthogonal
569*7c568831SAndroid Build Coastguard Worker                 ***             result.
570*7c568831SAndroid Build Coastguard Worker                 **/
571*7c568831SAndroid Build Coastguard Worker 
572*7c568831SAndroid Build Coastguard Worker                 i = memcmp(&e, s->p_set + m, sizeof e);
573*7c568831SAndroid Build Coastguard Worker 
574*7c568831SAndroid Build Coastguard Worker                 if (i < 0)
575*7c568831SAndroid Build Coastguard Worker                         h = m;
576*7c568831SAndroid Build Coastguard Worker                 else if (!i)
577*7c568831SAndroid Build Coastguard Worker                         return m;
578*7c568831SAndroid Build Coastguard Worker                 else
579*7c568831SAndroid Build Coastguard Worker                         l = m + 1;
580*7c568831SAndroid Build Coastguard Worker                 }
581*7c568831SAndroid Build Coastguard Worker 
582*7c568831SAndroid Build Coastguard Worker         return l;
583*7c568831SAndroid Build Coastguard Worker }
584*7c568831SAndroid Build Coastguard Worker 
585*7c568831SAndroid Build Coastguard Worker 
586*7c568831SAndroid Build Coastguard Worker t_powerset *
set_include(t_powerset * s,void * e)587*7c568831SAndroid Build Coastguard Worker set_include(t_powerset * s, void * e)
588*7c568831SAndroid Build Coastguard Worker 
589*7c568831SAndroid Build Coastguard Worker {
590*7c568831SAndroid Build Coastguard Worker         unsigned int pos;
591*7c568831SAndroid Build Coastguard Worker         unsigned int n;
592*7c568831SAndroid Build Coastguard Worker 
593*7c568831SAndroid Build Coastguard Worker         if (!s) {
594*7c568831SAndroid Build Coastguard Worker                 s = (t_powerset *) malloc(sizeof *s +
595*7c568831SAndroid Build Coastguard Worker                     GRANULE * sizeof s->p_set);
596*7c568831SAndroid Build Coastguard Worker                 chknull(s);
597*7c568831SAndroid Build Coastguard Worker                 s->p_size = GRANULE;
598*7c568831SAndroid Build Coastguard Worker                 s->p_set[GRANULE] = (t_state *) NULL;
599*7c568831SAndroid Build Coastguard Worker                 s->p_set[0] = e;
600*7c568831SAndroid Build Coastguard Worker                 s->p_card = 1;
601*7c568831SAndroid Build Coastguard Worker                 return s;
602*7c568831SAndroid Build Coastguard Worker                 }
603*7c568831SAndroid Build Coastguard Worker 
604*7c568831SAndroid Build Coastguard Worker         pos = set_position(s, e);
605*7c568831SAndroid Build Coastguard Worker 
606*7c568831SAndroid Build Coastguard Worker         if (pos < s->p_card && s->p_set[pos] == e)
607*7c568831SAndroid Build Coastguard Worker                 return s;
608*7c568831SAndroid Build Coastguard Worker 
609*7c568831SAndroid Build Coastguard Worker         if (s->p_card >= s->p_size) {
610*7c568831SAndroid Build Coastguard Worker                 s->p_size += GRANULE;
611*7c568831SAndroid Build Coastguard Worker                 s = (t_powerset *) realloc(s,
612*7c568831SAndroid Build Coastguard Worker                     sizeof *s + s->p_size * sizeof s->p_set);
613*7c568831SAndroid Build Coastguard Worker                 chknull(s);
614*7c568831SAndroid Build Coastguard Worker                 s->p_set[s->p_size] = (t_state *) NULL;
615*7c568831SAndroid Build Coastguard Worker                 }
616*7c568831SAndroid Build Coastguard Worker 
617*7c568831SAndroid Build Coastguard Worker         n = s->p_card - pos;
618*7c568831SAndroid Build Coastguard Worker 
619*7c568831SAndroid Build Coastguard Worker         if (n)
620*7c568831SAndroid Build Coastguard Worker                 memmove((char *) (s->p_set + pos + 1),
621*7c568831SAndroid Build Coastguard Worker                     (char *) (s->p_set + pos), n * sizeof s->p_set[0]);
622*7c568831SAndroid Build Coastguard Worker 
623*7c568831SAndroid Build Coastguard Worker         s->p_set[pos] = e;
624*7c568831SAndroid Build Coastguard Worker         s->p_card++;
625*7c568831SAndroid Build Coastguard Worker         return s;
626*7c568831SAndroid Build Coastguard Worker }
627*7c568831SAndroid Build Coastguard Worker 
628*7c568831SAndroid Build Coastguard Worker 
629*7c568831SAndroid Build Coastguard Worker t_state *
nfatransition(t_state * to,byte token)630*7c568831SAndroid Build Coastguard Worker nfatransition(t_state * to, byte token)
631*7c568831SAndroid Build Coastguard Worker 
632*7c568831SAndroid Build Coastguard Worker {
633*7c568831SAndroid Build Coastguard Worker         t_state * from;
634*7c568831SAndroid Build Coastguard Worker 
635*7c568831SAndroid Build Coastguard Worker         from = newstate();
636*7c568831SAndroid Build Coastguard Worker         newtransition(token, from, to);
637*7c568831SAndroid Build Coastguard Worker         return from;
638*7c568831SAndroid Build Coastguard Worker }
639*7c568831SAndroid Build Coastguard Worker 
640*7c568831SAndroid Build Coastguard Worker 
641*7c568831SAndroid Build Coastguard Worker static t_state *        nfadevelop(t_state * from, t_state * final, iconv_t icc,
642*7c568831SAndroid Build Coastguard Worker                                 const utf8char * name, unsigned int len);
643*7c568831SAndroid Build Coastguard Worker 
644*7c568831SAndroid Build Coastguard Worker 
645*7c568831SAndroid Build Coastguard Worker void
nfaslice(t_state ** from,t_state ** to,iconv_t icc,const utf8char * chr,unsigned int chlen,const utf8char * name,unsigned int len,t_state * final)646*7c568831SAndroid Build Coastguard Worker nfaslice(t_state * * from, t_state * * to, iconv_t icc,
647*7c568831SAndroid Build Coastguard Worker                 const utf8char * chr, unsigned int chlen,
648*7c568831SAndroid Build Coastguard Worker                 const utf8char * name, unsigned int len, t_state * final)
649*7c568831SAndroid Build Coastguard Worker 
650*7c568831SAndroid Build Coastguard Worker {
651*7c568831SAndroid Build Coastguard Worker         char * srcp;
652*7c568831SAndroid Build Coastguard Worker         char * dstp;
653*7c568831SAndroid Build Coastguard Worker         size_t srcc;
654*7c568831SAndroid Build Coastguard Worker         size_t dstc;
655*7c568831SAndroid Build Coastguard Worker         unsigned int cnt;
656*7c568831SAndroid Build Coastguard Worker         t_state * f;
657*7c568831SAndroid Build Coastguard Worker         t_state * t;
658*7c568831SAndroid Build Coastguard Worker         t_transition * tp;
659*7c568831SAndroid Build Coastguard Worker         byte bytebuf[8];
660*7c568831SAndroid Build Coastguard Worker 
661*7c568831SAndroid Build Coastguard Worker         srcp = (char *) chr;
662*7c568831SAndroid Build Coastguard Worker         srcc = chlen;
663*7c568831SAndroid Build Coastguard Worker         dstp = (char *) bytebuf;
664*7c568831SAndroid Build Coastguard Worker         dstc = sizeof bytebuf;
665*7c568831SAndroid Build Coastguard Worker         iconv(icc, &srcp, &srcc, &dstp, &dstc);
666*7c568831SAndroid Build Coastguard Worker         dstp = (char *) bytebuf;
667*7c568831SAndroid Build Coastguard Worker         cnt = sizeof bytebuf - dstc;
668*7c568831SAndroid Build Coastguard Worker         t = *to;
669*7c568831SAndroid Build Coastguard Worker         f = *from;
670*7c568831SAndroid Build Coastguard Worker 
671*7c568831SAndroid Build Coastguard Worker         /**
672*7c568831SAndroid Build Coastguard Worker         ***     Check for end of string.
673*7c568831SAndroid Build Coastguard Worker         **/
674*7c568831SAndroid Build Coastguard Worker 
675*7c568831SAndroid Build Coastguard Worker         if (!len)
676*7c568831SAndroid Build Coastguard Worker                 if (t && t != final)
677*7c568831SAndroid Build Coastguard Worker                         uniquetransition(EPSILON, t, final);
678*7c568831SAndroid Build Coastguard Worker                 else
679*7c568831SAndroid Build Coastguard Worker                         t = final;
680*7c568831SAndroid Build Coastguard Worker 
681*7c568831SAndroid Build Coastguard Worker         if (f)
682*7c568831SAndroid Build Coastguard Worker                 while (cnt) {
683*7c568831SAndroid Build Coastguard Worker                         tp = uniquetransition(*dstp, f, (t_state *) NULL);
684*7c568831SAndroid Build Coastguard Worker 
685*7c568831SAndroid Build Coastguard Worker                         if (!tp)
686*7c568831SAndroid Build Coastguard Worker                                 break;
687*7c568831SAndroid Build Coastguard Worker 
688*7c568831SAndroid Build Coastguard Worker                         f = tp->t_to;
689*7c568831SAndroid Build Coastguard Worker                         dstp++;
690*7c568831SAndroid Build Coastguard Worker                         cnt--;
691*7c568831SAndroid Build Coastguard Worker                         }
692*7c568831SAndroid Build Coastguard Worker 
693*7c568831SAndroid Build Coastguard Worker         if (!cnt) {
694*7c568831SAndroid Build Coastguard Worker                 if (!t)
695*7c568831SAndroid Build Coastguard Worker                         t = nfadevelop(f, final, icc, name, len);
696*7c568831SAndroid Build Coastguard Worker 
697*7c568831SAndroid Build Coastguard Worker                 *to = t;
698*7c568831SAndroid Build Coastguard Worker                 return;
699*7c568831SAndroid Build Coastguard Worker                 }
700*7c568831SAndroid Build Coastguard Worker 
701*7c568831SAndroid Build Coastguard Worker         if (!t) {
702*7c568831SAndroid Build Coastguard Worker                 t = nfadevelop((t_state *) NULL, final, icc, name, len);
703*7c568831SAndroid Build Coastguard Worker                 *to = t;
704*7c568831SAndroid Build Coastguard Worker                 }
705*7c568831SAndroid Build Coastguard Worker 
706*7c568831SAndroid Build Coastguard Worker         if (!f)
707*7c568831SAndroid Build Coastguard Worker                 *from = f = newstate();
708*7c568831SAndroid Build Coastguard Worker 
709*7c568831SAndroid Build Coastguard Worker         while (cnt > 1)
710*7c568831SAndroid Build Coastguard Worker                 t = nfatransition(t, dstp[--cnt]);
711*7c568831SAndroid Build Coastguard Worker 
712*7c568831SAndroid Build Coastguard Worker         newtransition(*dstp, f, t);
713*7c568831SAndroid Build Coastguard Worker }
714*7c568831SAndroid Build Coastguard Worker 
715*7c568831SAndroid Build Coastguard Worker 
716*7c568831SAndroid Build Coastguard Worker t_state *
nfadevelop(t_state * from,t_state * final,iconv_t icc,const utf8char * name,unsigned int len)717*7c568831SAndroid Build Coastguard Worker nfadevelop(t_state * from, t_state * final, iconv_t icc,
718*7c568831SAndroid Build Coastguard Worker                                         const utf8char * name, unsigned int len)
719*7c568831SAndroid Build Coastguard Worker 
720*7c568831SAndroid Build Coastguard Worker {
721*7c568831SAndroid Build Coastguard Worker         int chlen;
722*7c568831SAndroid Build Coastguard Worker         int i;
723*7c568831SAndroid Build Coastguard Worker         t_state * to;
724*7c568831SAndroid Build Coastguard Worker         int uccnt;
725*7c568831SAndroid Build Coastguard Worker         int lccnt;
726*7c568831SAndroid Build Coastguard Worker         utf8char chr;
727*7c568831SAndroid Build Coastguard Worker 
728*7c568831SAndroid Build Coastguard Worker         chlen = utf8_chlen[*name];
729*7c568831SAndroid Build Coastguard Worker 
730*7c568831SAndroid Build Coastguard Worker         for (i = 1; i < chlen; i++)
731*7c568831SAndroid Build Coastguard Worker                 if ((name[i] & 0xC0) != 0x80)
732*7c568831SAndroid Build Coastguard Worker                         break;
733*7c568831SAndroid Build Coastguard Worker 
734*7c568831SAndroid Build Coastguard Worker         if (i != chlen) {
735*7c568831SAndroid Build Coastguard Worker                 fprintf(stderr,
736*7c568831SAndroid Build Coastguard Worker                     "Invalid UTF8 character in character set name\n");
737*7c568831SAndroid Build Coastguard Worker                 return (t_state *) NULL;
738*7c568831SAndroid Build Coastguard Worker                 }
739*7c568831SAndroid Build Coastguard Worker 
740*7c568831SAndroid Build Coastguard Worker         to = (t_state *) NULL;
741*7c568831SAndroid Build Coastguard Worker         nfaslice(&from, &to,
742*7c568831SAndroid Build Coastguard Worker             icc, name, chlen, name + chlen, len - chlen, final);
743*7c568831SAndroid Build Coastguard Worker 
744*7c568831SAndroid Build Coastguard Worker         if (*name >= UTF8_a && *name <= UTF8_z)
745*7c568831SAndroid Build Coastguard Worker                 chr = *name - UTF8_a + UTF8_A;
746*7c568831SAndroid Build Coastguard Worker         else if (*name >= UTF8_A && *name <= UTF8_Z)
747*7c568831SAndroid Build Coastguard Worker                 chr = *name - UTF8_A + UTF8_a;
748*7c568831SAndroid Build Coastguard Worker         else
749*7c568831SAndroid Build Coastguard Worker                 return from;
750*7c568831SAndroid Build Coastguard Worker 
751*7c568831SAndroid Build Coastguard Worker         nfaslice(&from, &to, icc, &chr, 1, name + chlen, len - chlen, final);
752*7c568831SAndroid Build Coastguard Worker         return from;
753*7c568831SAndroid Build Coastguard Worker }
754*7c568831SAndroid Build Coastguard Worker 
755*7c568831SAndroid Build Coastguard Worker 
756*7c568831SAndroid Build Coastguard Worker 
757*7c568831SAndroid Build Coastguard Worker void
nfaenter(const utf8char * name,int len,t_chset * charset)758*7c568831SAndroid Build Coastguard Worker nfaenter(const utf8char * name, int len, t_chset * charset)
759*7c568831SAndroid Build Coastguard Worker 
760*7c568831SAndroid Build Coastguard Worker {
761*7c568831SAndroid Build Coastguard Worker         t_chset * s;
762*7c568831SAndroid Build Coastguard Worker         t_state * final;
763*7c568831SAndroid Build Coastguard Worker         t_state * sp;
764*7c568831SAndroid Build Coastguard Worker         t_symlist * lp;
765*7c568831SAndroid Build Coastguard Worker 
766*7c568831SAndroid Build Coastguard Worker         /**
767*7c568831SAndroid Build Coastguard Worker         ***     Enter case-insensitive `name' in NFA in all known
768*7c568831SAndroid Build Coastguard Worker         ***             character codes.
769*7c568831SAndroid Build Coastguard Worker         ***     Redundant shift state changes as well as shift state
770*7c568831SAndroid Build Coastguard Worker         ***             differences between uppercase and lowercase are
771*7c568831SAndroid Build Coastguard Worker         ***             not handled.
772*7c568831SAndroid Build Coastguard Worker         **/
773*7c568831SAndroid Build Coastguard Worker 
774*7c568831SAndroid Build Coastguard Worker         if (len < 0)
775*7c568831SAndroid Build Coastguard Worker                 len = strlen(name) + 1;
776*7c568831SAndroid Build Coastguard Worker 
777*7c568831SAndroid Build Coastguard Worker         for (lp = charset->c_names; lp; lp = lp->l_next)
778*7c568831SAndroid Build Coastguard Worker                 if (!memcmp(name, lp->l_symbol, len))
779*7c568831SAndroid Build Coastguard Worker                         return;         /* Already entered. */
780*7c568831SAndroid Build Coastguard Worker 
781*7c568831SAndroid Build Coastguard Worker         lp = (t_symlist *) malloc(sizeof *lp + len);
782*7c568831SAndroid Build Coastguard Worker         chknull(lp);
783*7c568831SAndroid Build Coastguard Worker         memcpy(lp->l_symbol, name, len);
784*7c568831SAndroid Build Coastguard Worker         lp->l_symbol[len] = '\0';
785*7c568831SAndroid Build Coastguard Worker         lp->l_next = charset->c_names;
786*7c568831SAndroid Build Coastguard Worker         charset->c_names = lp;
787*7c568831SAndroid Build Coastguard Worker         final = newstate();
788*7c568831SAndroid Build Coastguard Worker         final->s_final = charset;
789*7c568831SAndroid Build Coastguard Worker 
790*7c568831SAndroid Build Coastguard Worker         for (s = chset_list; s; s = s->c_next)
791*7c568831SAndroid Build Coastguard Worker                 if (!iconv_open_error(s->c_fromUTF8))
792*7c568831SAndroid Build Coastguard Worker                         sp = nfadevelop(initial_state, final,
793*7c568831SAndroid Build Coastguard Worker                             s->c_fromUTF8, name, len);
794*7c568831SAndroid Build Coastguard Worker }
795*7c568831SAndroid Build Coastguard Worker 
796*7c568831SAndroid Build Coastguard Worker 
797*7c568831SAndroid Build Coastguard Worker unsigned int
utf8_utostr(utf8char * s,unsigned int v)798*7c568831SAndroid Build Coastguard Worker utf8_utostr(utf8char * s, unsigned int v)
799*7c568831SAndroid Build Coastguard Worker 
800*7c568831SAndroid Build Coastguard Worker {
801*7c568831SAndroid Build Coastguard Worker         unsigned int d;
802*7c568831SAndroid Build Coastguard Worker         unsigned int i;
803*7c568831SAndroid Build Coastguard Worker 
804*7c568831SAndroid Build Coastguard Worker         d = v / 10;
805*7c568831SAndroid Build Coastguard Worker         v -= d * 10;
806*7c568831SAndroid Build Coastguard Worker         i = d? utf8_utostr(s, d): 0;
807*7c568831SAndroid Build Coastguard Worker         s[i++] = v + UTF8_0;
808*7c568831SAndroid Build Coastguard Worker         s[i] = '\0';
809*7c568831SAndroid Build Coastguard Worker         return i;
810*7c568831SAndroid Build Coastguard Worker }
811*7c568831SAndroid Build Coastguard Worker 
812*7c568831SAndroid Build Coastguard Worker 
813*7c568831SAndroid Build Coastguard Worker unsigned int
utf8_utostrpad(utf8char * s,unsigned int v,int digits)814*7c568831SAndroid Build Coastguard Worker utf8_utostrpad(utf8char * s, unsigned int v, int digits)
815*7c568831SAndroid Build Coastguard Worker 
816*7c568831SAndroid Build Coastguard Worker {
817*7c568831SAndroid Build Coastguard Worker         unsigned int i = utf8_utostr(s, v);
818*7c568831SAndroid Build Coastguard Worker         utf8char pad = UTF8_SPACE;
819*7c568831SAndroid Build Coastguard Worker 
820*7c568831SAndroid Build Coastguard Worker         if (digits < 0) {
821*7c568831SAndroid Build Coastguard Worker                 pad = UTF8_0;
822*7c568831SAndroid Build Coastguard Worker                 digits = -digits;
823*7c568831SAndroid Build Coastguard Worker                 }
824*7c568831SAndroid Build Coastguard Worker 
825*7c568831SAndroid Build Coastguard Worker         if (i >= digits)
826*7c568831SAndroid Build Coastguard Worker                 return i;
827*7c568831SAndroid Build Coastguard Worker 
828*7c568831SAndroid Build Coastguard Worker         memmove(s + digits - i, s, i + 1);
829*7c568831SAndroid Build Coastguard Worker         memset(s, pad, digits - i);
830*7c568831SAndroid Build Coastguard Worker         return digits;
831*7c568831SAndroid Build Coastguard Worker }
832*7c568831SAndroid Build Coastguard Worker 
833*7c568831SAndroid Build Coastguard Worker 
834*7c568831SAndroid Build Coastguard Worker unsigned int
utf8_strtou(const utf8char * s)835*7c568831SAndroid Build Coastguard Worker utf8_strtou(const utf8char * s)
836*7c568831SAndroid Build Coastguard Worker 
837*7c568831SAndroid Build Coastguard Worker {
838*7c568831SAndroid Build Coastguard Worker         unsigned int v;
839*7c568831SAndroid Build Coastguard Worker 
840*7c568831SAndroid Build Coastguard Worker         while (*s == UTF8_SPACE || *s == UTF8_HT)
841*7c568831SAndroid Build Coastguard Worker                 s++;
842*7c568831SAndroid Build Coastguard Worker 
843*7c568831SAndroid Build Coastguard Worker         for (v = 0; *s >= UTF8_0 && *s <= UTF8_9;)
844*7c568831SAndroid Build Coastguard Worker                 v = 10 * v + *s++ - UTF8_0;
845*7c568831SAndroid Build Coastguard Worker 
846*7c568831SAndroid Build Coastguard Worker         return v;
847*7c568831SAndroid Build Coastguard Worker }
848*7c568831SAndroid Build Coastguard Worker 
849*7c568831SAndroid Build Coastguard Worker 
850*7c568831SAndroid Build Coastguard Worker unsigned int
getNumAttr(xmlNodePtr node,const xmlChar * name)851*7c568831SAndroid Build Coastguard Worker getNumAttr(xmlNodePtr node, const xmlChar * name)
852*7c568831SAndroid Build Coastguard Worker 
853*7c568831SAndroid Build Coastguard Worker {
854*7c568831SAndroid Build Coastguard Worker         const xmlChar * s;
855*7c568831SAndroid Build Coastguard Worker         unsigned int val;
856*7c568831SAndroid Build Coastguard Worker 
857*7c568831SAndroid Build Coastguard Worker         s = xmlGetProp(node, name);
858*7c568831SAndroid Build Coastguard Worker 
859*7c568831SAndroid Build Coastguard Worker         if (!s)
860*7c568831SAndroid Build Coastguard Worker                 return 0;
861*7c568831SAndroid Build Coastguard Worker 
862*7c568831SAndroid Build Coastguard Worker         val = utf8_strtou(s);
863*7c568831SAndroid Build Coastguard Worker         xmlFree((xmlChar *) s);
864*7c568831SAndroid Build Coastguard Worker         return val;
865*7c568831SAndroid Build Coastguard Worker }
866*7c568831SAndroid Build Coastguard Worker 
867*7c568831SAndroid Build Coastguard Worker 
868*7c568831SAndroid Build Coastguard Worker void
read_assocs(const char * filename)869*7c568831SAndroid Build Coastguard Worker read_assocs(const char * filename)
870*7c568831SAndroid Build Coastguard Worker 
871*7c568831SAndroid Build Coastguard Worker {
872*7c568831SAndroid Build Coastguard Worker         xmlDocPtr doc;
873*7c568831SAndroid Build Coastguard Worker         xmlXPathContextPtr ctxt;
874*7c568831SAndroid Build Coastguard Worker         xmlXPathObjectPtr obj;
875*7c568831SAndroid Build Coastguard Worker         xmlNodePtr node;
876*7c568831SAndroid Build Coastguard Worker         t_chset * sp;
877*7c568831SAndroid Build Coastguard Worker         int i;
878*7c568831SAndroid Build Coastguard Worker         unsigned int ccsid;
879*7c568831SAndroid Build Coastguard Worker         unsigned int mibenum;
880*7c568831SAndroid Build Coastguard Worker         utf8char symbuf[32];
881*7c568831SAndroid Build Coastguard Worker 
882*7c568831SAndroid Build Coastguard Worker         doc = loadXMLFile(filename);
883*7c568831SAndroid Build Coastguard Worker 
884*7c568831SAndroid Build Coastguard Worker         if (!doc) {
885*7c568831SAndroid Build Coastguard Worker                 fprintf(stderr, "Cannot load file %s\n", filename);
886*7c568831SAndroid Build Coastguard Worker                 exit(1);
887*7c568831SAndroid Build Coastguard Worker                 }
888*7c568831SAndroid Build Coastguard Worker 
889*7c568831SAndroid Build Coastguard Worker         ctxt = xmlXPathNewContext(doc);
890*7c568831SAndroid Build Coastguard Worker         obj = xmlXPathEval(utf8_assocnodes, ctxt);
891*7c568831SAndroid Build Coastguard Worker 
892*7c568831SAndroid Build Coastguard Worker         if (!obj || obj->type != XPATH_NODESET || !obj->nodesetval ||
893*7c568831SAndroid Build Coastguard Worker             !obj->nodesetval->nodeTab || !obj->nodesetval->nodeNr) {
894*7c568831SAndroid Build Coastguard Worker                 fprintf(stderr, "No association found in %s\n", filename);
895*7c568831SAndroid Build Coastguard Worker                 exit(1);
896*7c568831SAndroid Build Coastguard Worker                 }
897*7c568831SAndroid Build Coastguard Worker 
898*7c568831SAndroid Build Coastguard Worker         for (i = 0; i < obj->nodesetval->nodeNr; i++) {
899*7c568831SAndroid Build Coastguard Worker                 node = obj->nodesetval->nodeTab[i];
900*7c568831SAndroid Build Coastguard Worker                 ccsid = getNumAttr(node, utf8_ccsid);
901*7c568831SAndroid Build Coastguard Worker                 mibenum = getNumAttr(node, utf8_mibenum);
902*7c568831SAndroid Build Coastguard Worker 
903*7c568831SAndroid Build Coastguard Worker                 /**
904*7c568831SAndroid Build Coastguard Worker                 ***     Check for duplicate.
905*7c568831SAndroid Build Coastguard Worker                 **/
906*7c568831SAndroid Build Coastguard Worker 
907*7c568831SAndroid Build Coastguard Worker                 for (sp = chset_list; sp; sp = sp->c_next)
908*7c568831SAndroid Build Coastguard Worker                         if (ccsid && ccsid == sp->c_ccsid ||
909*7c568831SAndroid Build Coastguard Worker                             mibenum && mibenum == sp->c_mibenum) {
910*7c568831SAndroid Build Coastguard Worker                                 fprintf(stderr, "Duplicate character set: ");
911*7c568831SAndroid Build Coastguard Worker                                 fprintf(stderr, "CCSID = %u/%u, ",
912*7c568831SAndroid Build Coastguard Worker                                     ccsid, sp->c_ccsid);
913*7c568831SAndroid Build Coastguard Worker                                 fprintf(stderr, "MIBenum = %u/%u\n",
914*7c568831SAndroid Build Coastguard Worker                                     mibenum, sp->c_mibenum);
915*7c568831SAndroid Build Coastguard Worker                                 break;
916*7c568831SAndroid Build Coastguard Worker                                 }
917*7c568831SAndroid Build Coastguard Worker 
918*7c568831SAndroid Build Coastguard Worker                 if (sp)
919*7c568831SAndroid Build Coastguard Worker                         continue;
920*7c568831SAndroid Build Coastguard Worker 
921*7c568831SAndroid Build Coastguard Worker                 /**
922*7c568831SAndroid Build Coastguard Worker                 ***     Allocate the new character set.
923*7c568831SAndroid Build Coastguard Worker                 **/
924*7c568831SAndroid Build Coastguard Worker 
925*7c568831SAndroid Build Coastguard Worker                 sp = (t_chset *) malloc(sizeof *sp);
926*7c568831SAndroid Build Coastguard Worker                 chknull(sp);
927*7c568831SAndroid Build Coastguard Worker                 memset(sp, 0, sizeof *sp);
928*7c568831SAndroid Build Coastguard Worker 
929*7c568831SAndroid Build Coastguard Worker                 if (!ccsid)     /* Do not attempt with current job CCSID. */
930*7c568831SAndroid Build Coastguard Worker                         set_iconv_open_error(sp->c_fromUTF8);
931*7c568831SAndroid Build Coastguard Worker                 else {
932*7c568831SAndroid Build Coastguard Worker                         sp->c_fromUTF8 =
933*7c568831SAndroid Build Coastguard Worker                             iconv_open_ccsid(ccsid, C_UTF8_CCSID, 0);
934*7c568831SAndroid Build Coastguard Worker 
935*7c568831SAndroid Build Coastguard Worker                         if (iconv_open_error(sp->c_fromUTF8) == -1)
936*7c568831SAndroid Build Coastguard Worker                                 fprintf(stderr,
937*7c568831SAndroid Build Coastguard Worker                                     "Cannot convert into CCSID %u: ignored\n",
938*7c568831SAndroid Build Coastguard Worker                                     ccsid);
939*7c568831SAndroid Build Coastguard Worker                         }
940*7c568831SAndroid Build Coastguard Worker 
941*7c568831SAndroid Build Coastguard Worker                 sp->c_ccsid = ccsid;
942*7c568831SAndroid Build Coastguard Worker                 sp->c_mibenum = mibenum;
943*7c568831SAndroid Build Coastguard Worker                 sp->c_next = chset_list;
944*7c568831SAndroid Build Coastguard Worker                 chset_list = sp;
945*7c568831SAndroid Build Coastguard Worker                 }
946*7c568831SAndroid Build Coastguard Worker 
947*7c568831SAndroid Build Coastguard Worker         xmlXPathFreeObject(obj);
948*7c568831SAndroid Build Coastguard Worker 
949*7c568831SAndroid Build Coastguard Worker         /**
950*7c568831SAndroid Build Coastguard Worker         ***     Enter aliases.
951*7c568831SAndroid Build Coastguard Worker         **/
952*7c568831SAndroid Build Coastguard Worker 
953*7c568831SAndroid Build Coastguard Worker         for (sp = chset_list; sp; sp = sp->c_next) {
954*7c568831SAndroid Build Coastguard Worker                 strcpy(symbuf, utf8_ibm_);
955*7c568831SAndroid Build Coastguard Worker                 utf8_utostr(symbuf + 4, sp->c_ccsid);
956*7c568831SAndroid Build Coastguard Worker                 nfaenter(symbuf, -1, sp);
957*7c568831SAndroid Build Coastguard Worker                 strcpy(symbuf, utf8_IBMCCSID);
958*7c568831SAndroid Build Coastguard Worker                 utf8_utostrpad(symbuf + 8, sp->c_ccsid, -5);
959*7c568831SAndroid Build Coastguard Worker                 nfaenter(symbuf, 13, sp);       /* Not null-terminated. */
960*7c568831SAndroid Build Coastguard Worker 
961*7c568831SAndroid Build Coastguard Worker                 if (sp->c_mibenum) {
962*7c568831SAndroid Build Coastguard Worker                         strcpy(symbuf, utf8_iana_);
963*7c568831SAndroid Build Coastguard Worker                         utf8_utostr(symbuf + 5, sp->c_mibenum);
964*7c568831SAndroid Build Coastguard Worker                         nfaenter(symbuf, -1, sp);
965*7c568831SAndroid Build Coastguard Worker                         }
966*7c568831SAndroid Build Coastguard Worker 
967*7c568831SAndroid Build Coastguard Worker                 xmlXPathRegisterVariable(ctxt, utf8_C,
968*7c568831SAndroid Build Coastguard Worker                     xmlXPathNewFloat((double) sp->c_ccsid));
969*7c568831SAndroid Build Coastguard Worker                 obj = xmlXPathEval(utf8_aliastext, ctxt);
970*7c568831SAndroid Build Coastguard Worker 
971*7c568831SAndroid Build Coastguard Worker                 if (!obj || obj->type != XPATH_NODESET) {
972*7c568831SAndroid Build Coastguard Worker                         fprintf(stderr, "getAlias failed in %s\n", filename);
973*7c568831SAndroid Build Coastguard Worker                         exit(1);
974*7c568831SAndroid Build Coastguard Worker                         }
975*7c568831SAndroid Build Coastguard Worker 
976*7c568831SAndroid Build Coastguard Worker                 if (obj->nodesetval &&
977*7c568831SAndroid Build Coastguard Worker                     obj->nodesetval->nodeTab && obj->nodesetval->nodeNr) {
978*7c568831SAndroid Build Coastguard Worker                         for (i = 0; i < obj->nodesetval->nodeNr; i++) {
979*7c568831SAndroid Build Coastguard Worker                                 node = obj->nodesetval->nodeTab[i];
980*7c568831SAndroid Build Coastguard Worker                                 nfaenter(node->content, -1, sp);
981*7c568831SAndroid Build Coastguard Worker                                 }
982*7c568831SAndroid Build Coastguard Worker                         }
983*7c568831SAndroid Build Coastguard Worker 
984*7c568831SAndroid Build Coastguard Worker                 xmlXPathFreeObject(obj);
985*7c568831SAndroid Build Coastguard Worker                 }
986*7c568831SAndroid Build Coastguard Worker 
987*7c568831SAndroid Build Coastguard Worker         xmlXPathFreeContext(ctxt);
988*7c568831SAndroid Build Coastguard Worker         xmlFreeDoc(doc);
989*7c568831SAndroid Build Coastguard Worker }
990*7c568831SAndroid Build Coastguard Worker 
991*7c568831SAndroid Build Coastguard Worker 
992*7c568831SAndroid Build Coastguard Worker unsigned int
columnPosition(xmlXPathContextPtr ctxt,const xmlChar * header)993*7c568831SAndroid Build Coastguard Worker columnPosition(xmlXPathContextPtr ctxt, const xmlChar * header)
994*7c568831SAndroid Build Coastguard Worker 
995*7c568831SAndroid Build Coastguard Worker {
996*7c568831SAndroid Build Coastguard Worker         xmlXPathObjectPtr obj;
997*7c568831SAndroid Build Coastguard Worker         unsigned int res = 0;
998*7c568831SAndroid Build Coastguard Worker 
999*7c568831SAndroid Build Coastguard Worker         xmlXPathRegisterVariable(ctxt, utf8_T, xmlXPathNewString(header));
1000*7c568831SAndroid Build Coastguard Worker         obj = xmlXPathEval(utf8_headerpos, ctxt);
1001*7c568831SAndroid Build Coastguard Worker 
1002*7c568831SAndroid Build Coastguard Worker         if (obj) {
1003*7c568831SAndroid Build Coastguard Worker                 if (obj->type == XPATH_NUMBER)
1004*7c568831SAndroid Build Coastguard Worker                         res = (unsigned int) obj->floatval;
1005*7c568831SAndroid Build Coastguard Worker 
1006*7c568831SAndroid Build Coastguard Worker                 xmlXPathFreeObject(obj);
1007*7c568831SAndroid Build Coastguard Worker                 }
1008*7c568831SAndroid Build Coastguard Worker 
1009*7c568831SAndroid Build Coastguard Worker         return res;
1010*7c568831SAndroid Build Coastguard Worker }
1011*7c568831SAndroid Build Coastguard Worker 
1012*7c568831SAndroid Build Coastguard Worker 
1013*7c568831SAndroid Build Coastguard Worker void
read_iana(const char * filename)1014*7c568831SAndroid Build Coastguard Worker read_iana(const char * filename)
1015*7c568831SAndroid Build Coastguard Worker 
1016*7c568831SAndroid Build Coastguard Worker {
1017*7c568831SAndroid Build Coastguard Worker         xmlDocPtr doc;
1018*7c568831SAndroid Build Coastguard Worker         xmlXPathContextPtr ctxt;
1019*7c568831SAndroid Build Coastguard Worker         xmlXPathObjectPtr obj1;
1020*7c568831SAndroid Build Coastguard Worker         xmlXPathObjectPtr obj2;
1021*7c568831SAndroid Build Coastguard Worker         xmlNodePtr node;
1022*7c568831SAndroid Build Coastguard Worker         int prefnamecol;
1023*7c568831SAndroid Build Coastguard Worker         int namecol;
1024*7c568831SAndroid Build Coastguard Worker         int mibenumcol;
1025*7c568831SAndroid Build Coastguard Worker         int aliascol;
1026*7c568831SAndroid Build Coastguard Worker         int mibenum;
1027*7c568831SAndroid Build Coastguard Worker         t_chset * sp;
1028*7c568831SAndroid Build Coastguard Worker         int n;
1029*7c568831SAndroid Build Coastguard Worker         int i;
1030*7c568831SAndroid Build Coastguard Worker 
1031*7c568831SAndroid Build Coastguard Worker         doc = loadXMLFile(filename);
1032*7c568831SAndroid Build Coastguard Worker 
1033*7c568831SAndroid Build Coastguard Worker         if (!doc) {
1034*7c568831SAndroid Build Coastguard Worker                 fprintf(stderr, "Cannot load file %s\n", filename);
1035*7c568831SAndroid Build Coastguard Worker                 exit(1);
1036*7c568831SAndroid Build Coastguard Worker                 }
1037*7c568831SAndroid Build Coastguard Worker 
1038*7c568831SAndroid Build Coastguard Worker         ctxt = xmlXPathNewContext(doc);
1039*7c568831SAndroid Build Coastguard Worker 
1040*7c568831SAndroid Build Coastguard Worker #ifndef OLDXML
1041*7c568831SAndroid Build Coastguard Worker         xmlXPathRegisterNs(ctxt, utf8_html, utf8_htmluri);
1042*7c568831SAndroid Build Coastguard Worker #endif
1043*7c568831SAndroid Build Coastguard Worker 
1044*7c568831SAndroid Build Coastguard Worker         obj1 = xmlXPathEval(utf8_tablerows, ctxt);
1045*7c568831SAndroid Build Coastguard Worker 
1046*7c568831SAndroid Build Coastguard Worker         if (!obj1 || obj1->type != XPATH_NODESET || !obj1->nodesetval ||
1047*7c568831SAndroid Build Coastguard Worker             !obj1->nodesetval->nodeTab || obj1->nodesetval->nodeNr <= 1) {
1048*7c568831SAndroid Build Coastguard Worker                 fprintf(stderr, "No data in %s\n", filename);
1049*7c568831SAndroid Build Coastguard Worker                 exit(1);
1050*7c568831SAndroid Build Coastguard Worker                 }
1051*7c568831SAndroid Build Coastguard Worker 
1052*7c568831SAndroid Build Coastguard Worker         /**
1053*7c568831SAndroid Build Coastguard Worker         ***     Identify columns.
1054*7c568831SAndroid Build Coastguard Worker         **/
1055*7c568831SAndroid Build Coastguard Worker 
1056*7c568831SAndroid Build Coastguard Worker         xmlXPathSetContextNode(obj1->nodesetval->nodeTab[0], ctxt);
1057*7c568831SAndroid Build Coastguard Worker         prefnamecol = columnPosition(ctxt, utf8_Pref_MIME_Name);
1058*7c568831SAndroid Build Coastguard Worker         namecol = columnPosition(ctxt, utf8_Name);
1059*7c568831SAndroid Build Coastguard Worker         mibenumcol = columnPosition(ctxt, utf8_MIBenum);
1060*7c568831SAndroid Build Coastguard Worker         aliascol = columnPosition(ctxt, utf8_Aliases);
1061*7c568831SAndroid Build Coastguard Worker 
1062*7c568831SAndroid Build Coastguard Worker         if (!prefnamecol || !namecol || !mibenumcol || !aliascol) {
1063*7c568831SAndroid Build Coastguard Worker                 fprintf(stderr, "Key column(s) missing in %s\n", filename);
1064*7c568831SAndroid Build Coastguard Worker                 exit(1);
1065*7c568831SAndroid Build Coastguard Worker                 }
1066*7c568831SAndroid Build Coastguard Worker 
1067*7c568831SAndroid Build Coastguard Worker         xmlXPathRegisterVariable(ctxt, utf8_P,
1068*7c568831SAndroid Build Coastguard Worker             xmlXPathNewFloat((double) prefnamecol));
1069*7c568831SAndroid Build Coastguard Worker         xmlXPathRegisterVariable(ctxt, utf8_N,
1070*7c568831SAndroid Build Coastguard Worker             xmlXPathNewFloat((double) namecol));
1071*7c568831SAndroid Build Coastguard Worker         xmlXPathRegisterVariable(ctxt, utf8_M,
1072*7c568831SAndroid Build Coastguard Worker             xmlXPathNewFloat((double) mibenumcol));
1073*7c568831SAndroid Build Coastguard Worker         xmlXPathRegisterVariable(ctxt, utf8_A,
1074*7c568831SAndroid Build Coastguard Worker             xmlXPathNewFloat((double) aliascol));
1075*7c568831SAndroid Build Coastguard Worker 
1076*7c568831SAndroid Build Coastguard Worker         /**
1077*7c568831SAndroid Build Coastguard Worker         ***     Process each row.
1078*7c568831SAndroid Build Coastguard Worker         **/
1079*7c568831SAndroid Build Coastguard Worker 
1080*7c568831SAndroid Build Coastguard Worker         for (n = 1; n < obj1->nodesetval->nodeNr; n++) {
1081*7c568831SAndroid Build Coastguard Worker                 xmlXPathSetContextNode(obj1->nodesetval->nodeTab[n], ctxt);
1082*7c568831SAndroid Build Coastguard Worker 
1083*7c568831SAndroid Build Coastguard Worker                 /**
1084*7c568831SAndroid Build Coastguard Worker                 ***     Get the MIBenum from current row.
1085*7c568831SAndroid Build Coastguard Worker                 */
1086*7c568831SAndroid Build Coastguard Worker 
1087*7c568831SAndroid Build Coastguard Worker                 obj2 = xmlXPathEval(utf8_getmibenum, ctxt);
1088*7c568831SAndroid Build Coastguard Worker 
1089*7c568831SAndroid Build Coastguard Worker                 if (!obj2 || obj2->type != XPATH_NUMBER) {
1090*7c568831SAndroid Build Coastguard Worker                         fprintf(stderr, "get MIBenum failed at row %u\n", n);
1091*7c568831SAndroid Build Coastguard Worker                         exit(1);
1092*7c568831SAndroid Build Coastguard Worker                         }
1093*7c568831SAndroid Build Coastguard Worker 
1094*7c568831SAndroid Build Coastguard Worker                 if (xmlXPathIsNaN(obj2->floatval) ||
1095*7c568831SAndroid Build Coastguard Worker                     obj2->floatval < 1.0 || obj2->floatval > 65535.0 ||
1096*7c568831SAndroid Build Coastguard Worker                     ((unsigned int) obj2->floatval) != obj2->floatval) {
1097*7c568831SAndroid Build Coastguard Worker                         fprintf(stderr, "invalid MIBenum at row %u\n", n);
1098*7c568831SAndroid Build Coastguard Worker                         xmlXPathFreeObject(obj2);
1099*7c568831SAndroid Build Coastguard Worker                         continue;
1100*7c568831SAndroid Build Coastguard Worker                         }
1101*7c568831SAndroid Build Coastguard Worker 
1102*7c568831SAndroid Build Coastguard Worker                 mibenum = obj2->floatval;
1103*7c568831SAndroid Build Coastguard Worker                 xmlXPathFreeObject(obj2);
1104*7c568831SAndroid Build Coastguard Worker 
1105*7c568831SAndroid Build Coastguard Worker                 /**
1106*7c568831SAndroid Build Coastguard Worker                 ***     Search the associations for a corresponding CCSID.
1107*7c568831SAndroid Build Coastguard Worker                 **/
1108*7c568831SAndroid Build Coastguard Worker 
1109*7c568831SAndroid Build Coastguard Worker                 for (sp = chset_list; sp; sp = sp->c_next)
1110*7c568831SAndroid Build Coastguard Worker                         if (sp->c_mibenum == mibenum)
1111*7c568831SAndroid Build Coastguard Worker                                 break;
1112*7c568831SAndroid Build Coastguard Worker 
1113*7c568831SAndroid Build Coastguard Worker                 if (!sp)
1114*7c568831SAndroid Build Coastguard Worker                         continue;       /* No CCSID for this MIBenum. */
1115*7c568831SAndroid Build Coastguard Worker 
1116*7c568831SAndroid Build Coastguard Worker                 /**
1117*7c568831SAndroid Build Coastguard Worker                 ***     Process preferred MIME name.
1118*7c568831SAndroid Build Coastguard Worker                 **/
1119*7c568831SAndroid Build Coastguard Worker 
1120*7c568831SAndroid Build Coastguard Worker                 obj2 = xmlXPathEval(utf8_getprefname, ctxt);
1121*7c568831SAndroid Build Coastguard Worker 
1122*7c568831SAndroid Build Coastguard Worker                 if (!obj2 || obj2->type != XPATH_STRING) {
1123*7c568831SAndroid Build Coastguard Worker                         fprintf(stderr,
1124*7c568831SAndroid Build Coastguard Worker                             "get Preferred_MIME_Name failed at row %u\n", n);
1125*7c568831SAndroid Build Coastguard Worker                         exit(1);
1126*7c568831SAndroid Build Coastguard Worker                         }
1127*7c568831SAndroid Build Coastguard Worker 
1128*7c568831SAndroid Build Coastguard Worker                 if (obj2->stringval && obj2->stringval[0])
1129*7c568831SAndroid Build Coastguard Worker                         nfaenter(obj2->stringval, -1, sp);
1130*7c568831SAndroid Build Coastguard Worker 
1131*7c568831SAndroid Build Coastguard Worker                 xmlXPathFreeObject(obj2);
1132*7c568831SAndroid Build Coastguard Worker 
1133*7c568831SAndroid Build Coastguard Worker                 /**
1134*7c568831SAndroid Build Coastguard Worker                 ***     Process name.
1135*7c568831SAndroid Build Coastguard Worker                 **/
1136*7c568831SAndroid Build Coastguard Worker 
1137*7c568831SAndroid Build Coastguard Worker                 obj2 = xmlXPathEval(utf8_getname, ctxt);
1138*7c568831SAndroid Build Coastguard Worker 
1139*7c568831SAndroid Build Coastguard Worker                 if (!obj2 || obj2->type != XPATH_STRING) {
1140*7c568831SAndroid Build Coastguard Worker                         fprintf(stderr, "get name failed at row %u\n", n);
1141*7c568831SAndroid Build Coastguard Worker                         exit(1);
1142*7c568831SAndroid Build Coastguard Worker                         }
1143*7c568831SAndroid Build Coastguard Worker 
1144*7c568831SAndroid Build Coastguard Worker                 if (obj2->stringval && obj2->stringval[0])
1145*7c568831SAndroid Build Coastguard Worker                         nfaenter(obj2->stringval, -1, sp);
1146*7c568831SAndroid Build Coastguard Worker 
1147*7c568831SAndroid Build Coastguard Worker                 xmlXPathFreeObject(obj2);
1148*7c568831SAndroid Build Coastguard Worker 
1149*7c568831SAndroid Build Coastguard Worker                 /**
1150*7c568831SAndroid Build Coastguard Worker                 ***     Process aliases.
1151*7c568831SAndroid Build Coastguard Worker                 **/
1152*7c568831SAndroid Build Coastguard Worker 
1153*7c568831SAndroid Build Coastguard Worker                 obj2 = xmlXPathEval(utf8_getaliases, ctxt);
1154*7c568831SAndroid Build Coastguard Worker 
1155*7c568831SAndroid Build Coastguard Worker                 if (!obj2 || obj2->type != XPATH_NODESET) {
1156*7c568831SAndroid Build Coastguard Worker                         fprintf(stderr, "get aliases failed at row %u\n", n);
1157*7c568831SAndroid Build Coastguard Worker                         exit(1);
1158*7c568831SAndroid Build Coastguard Worker                         }
1159*7c568831SAndroid Build Coastguard Worker 
1160*7c568831SAndroid Build Coastguard Worker                 if (obj2->nodesetval && obj2->nodesetval->nodeTab)
1161*7c568831SAndroid Build Coastguard Worker                         for (i = 0; i < obj2->nodesetval->nodeNr; i++) {
1162*7c568831SAndroid Build Coastguard Worker                                 node = obj2->nodesetval->nodeTab[i];
1163*7c568831SAndroid Build Coastguard Worker 
1164*7c568831SAndroid Build Coastguard Worker                                 if (node && node->content && node->content[0])
1165*7c568831SAndroid Build Coastguard Worker                                         nfaenter(node->content, -1, sp);
1166*7c568831SAndroid Build Coastguard Worker                                 }
1167*7c568831SAndroid Build Coastguard Worker 
1168*7c568831SAndroid Build Coastguard Worker                 xmlXPathFreeObject(obj2);
1169*7c568831SAndroid Build Coastguard Worker                 }
1170*7c568831SAndroid Build Coastguard Worker 
1171*7c568831SAndroid Build Coastguard Worker         xmlXPathFreeObject(obj1);
1172*7c568831SAndroid Build Coastguard Worker         xmlXPathFreeContext(ctxt);
1173*7c568831SAndroid Build Coastguard Worker         xmlFreeDoc(doc);
1174*7c568831SAndroid Build Coastguard Worker }
1175*7c568831SAndroid Build Coastguard Worker 
1176*7c568831SAndroid Build Coastguard Worker 
1177*7c568831SAndroid Build Coastguard Worker t_powerset *    closureset(t_powerset * dst, t_powerset * src);
1178*7c568831SAndroid Build Coastguard Worker 
1179*7c568831SAndroid Build Coastguard Worker 
1180*7c568831SAndroid Build Coastguard Worker t_powerset *
closure(t_powerset * dst,t_state * src)1181*7c568831SAndroid Build Coastguard Worker closure(t_powerset * dst, t_state * src)
1182*7c568831SAndroid Build Coastguard Worker 
1183*7c568831SAndroid Build Coastguard Worker {
1184*7c568831SAndroid Build Coastguard Worker         t_transition * t;
1185*7c568831SAndroid Build Coastguard Worker         unsigned int oldcard;
1186*7c568831SAndroid Build Coastguard Worker 
1187*7c568831SAndroid Build Coastguard Worker         if (src->s_nfastates) {
1188*7c568831SAndroid Build Coastguard Worker                 /**
1189*7c568831SAndroid Build Coastguard Worker                 ***     Is a DFA state: return closure of set of equivalent
1190*7c568831SAndroid Build Coastguard Worker                 ***             NFA states.
1191*7c568831SAndroid Build Coastguard Worker                 **/
1192*7c568831SAndroid Build Coastguard Worker 
1193*7c568831SAndroid Build Coastguard Worker                 return closureset(dst, src->s_nfastates);
1194*7c568831SAndroid Build Coastguard Worker                 }
1195*7c568831SAndroid Build Coastguard Worker 
1196*7c568831SAndroid Build Coastguard Worker         /**
1197*7c568831SAndroid Build Coastguard Worker         ***     Compute closure of NFA state.
1198*7c568831SAndroid Build Coastguard Worker         **/
1199*7c568831SAndroid Build Coastguard Worker 
1200*7c568831SAndroid Build Coastguard Worker         dst = set_include(dst, src);
1201*7c568831SAndroid Build Coastguard Worker 
1202*7c568831SAndroid Build Coastguard Worker         for (t = src->s_forward; t; t = t->t_forwnext)
1203*7c568831SAndroid Build Coastguard Worker                 if (t->t_token == EPSILON) {
1204*7c568831SAndroid Build Coastguard Worker                         oldcard = dst->p_card;
1205*7c568831SAndroid Build Coastguard Worker                         dst = set_include(dst, t->t_to);
1206*7c568831SAndroid Build Coastguard Worker 
1207*7c568831SAndroid Build Coastguard Worker                         if (oldcard != dst->p_card)
1208*7c568831SAndroid Build Coastguard Worker                                 dst = closure(dst, t->t_to);
1209*7c568831SAndroid Build Coastguard Worker                         }
1210*7c568831SAndroid Build Coastguard Worker 
1211*7c568831SAndroid Build Coastguard Worker         return dst;
1212*7c568831SAndroid Build Coastguard Worker }
1213*7c568831SAndroid Build Coastguard Worker 
1214*7c568831SAndroid Build Coastguard Worker 
1215*7c568831SAndroid Build Coastguard Worker t_powerset *
closureset(t_powerset * dst,t_powerset * src)1216*7c568831SAndroid Build Coastguard Worker closureset(t_powerset * dst, t_powerset * src)
1217*7c568831SAndroid Build Coastguard Worker 
1218*7c568831SAndroid Build Coastguard Worker {
1219*7c568831SAndroid Build Coastguard Worker         unsigned int i;
1220*7c568831SAndroid Build Coastguard Worker 
1221*7c568831SAndroid Build Coastguard Worker         for (i = 0; i < src->p_card; i++)
1222*7c568831SAndroid Build Coastguard Worker                 dst = closure(dst, (t_state *) src->p_set[i]);
1223*7c568831SAndroid Build Coastguard Worker 
1224*7c568831SAndroid Build Coastguard Worker         return dst;
1225*7c568831SAndroid Build Coastguard Worker }
1226*7c568831SAndroid Build Coastguard Worker 
1227*7c568831SAndroid Build Coastguard Worker 
1228*7c568831SAndroid Build Coastguard Worker t_state *
get_dfa_state(t_state ** stack,t_powerset * nfastates,xmlHashTablePtr sethash)1229*7c568831SAndroid Build Coastguard Worker get_dfa_state(t_state * * stack,
1230*7c568831SAndroid Build Coastguard Worker                         t_powerset * nfastates, xmlHashTablePtr sethash)
1231*7c568831SAndroid Build Coastguard Worker 
1232*7c568831SAndroid Build Coastguard Worker {
1233*7c568831SAndroid Build Coastguard Worker         t_state * s;
1234*7c568831SAndroid Build Coastguard Worker 
1235*7c568831SAndroid Build Coastguard Worker         if (s = hash_get(sethash, nfastates->p_set,
1236*7c568831SAndroid Build Coastguard Worker             nfastates->p_card * sizeof nfastates->p_set[0])) {
1237*7c568831SAndroid Build Coastguard Worker                 /**
1238*7c568831SAndroid Build Coastguard Worker                 ***     DFA state already present.
1239*7c568831SAndroid Build Coastguard Worker                 ***     Release the NFA state set and return
1240*7c568831SAndroid Build Coastguard Worker                 ***             the address of the old DFA state.
1241*7c568831SAndroid Build Coastguard Worker                 **/
1242*7c568831SAndroid Build Coastguard Worker 
1243*7c568831SAndroid Build Coastguard Worker                 free((char *) nfastates);
1244*7c568831SAndroid Build Coastguard Worker                 return s;
1245*7c568831SAndroid Build Coastguard Worker                 }
1246*7c568831SAndroid Build Coastguard Worker 
1247*7c568831SAndroid Build Coastguard Worker         /**
1248*7c568831SAndroid Build Coastguard Worker         ***     Build the new state.
1249*7c568831SAndroid Build Coastguard Worker         **/
1250*7c568831SAndroid Build Coastguard Worker 
1251*7c568831SAndroid Build Coastguard Worker         s = newstate();
1252*7c568831SAndroid Build Coastguard Worker         s->s_nfastates = nfastates;
1253*7c568831SAndroid Build Coastguard Worker         s->s_next = dfa_states;
1254*7c568831SAndroid Build Coastguard Worker         dfa_states = s;
1255*7c568831SAndroid Build Coastguard Worker         s->s_stack = *stack;
1256*7c568831SAndroid Build Coastguard Worker         *stack = s;
1257*7c568831SAndroid Build Coastguard Worker 
1258*7c568831SAndroid Build Coastguard Worker         /**
1259*7c568831SAndroid Build Coastguard Worker         ***     Enter it in hash.
1260*7c568831SAndroid Build Coastguard Worker         **/
1261*7c568831SAndroid Build Coastguard Worker 
1262*7c568831SAndroid Build Coastguard Worker         if (hash_add(sethash, nfastates->p_set,
1263*7c568831SAndroid Build Coastguard Worker             nfastates->p_card * sizeof nfastates->p_set[0], s))
1264*7c568831SAndroid Build Coastguard Worker                 chknull(NULL);          /* Memory allocation error. */
1265*7c568831SAndroid Build Coastguard Worker 
1266*7c568831SAndroid Build Coastguard Worker         return s;
1267*7c568831SAndroid Build Coastguard Worker }
1268*7c568831SAndroid Build Coastguard Worker 
1269*7c568831SAndroid Build Coastguard Worker 
1270*7c568831SAndroid Build Coastguard Worker int
transcmp(const void * p1,const void * p2)1271*7c568831SAndroid Build Coastguard Worker transcmp(const void * p1, const void * p2)
1272*7c568831SAndroid Build Coastguard Worker 
1273*7c568831SAndroid Build Coastguard Worker {
1274*7c568831SAndroid Build Coastguard Worker         t_transition * t1;
1275*7c568831SAndroid Build Coastguard Worker         t_transition * t2;
1276*7c568831SAndroid Build Coastguard Worker 
1277*7c568831SAndroid Build Coastguard Worker         t1 = *(t_transition * *) p1;
1278*7c568831SAndroid Build Coastguard Worker         t2 = *(t_transition * *) p2;
1279*7c568831SAndroid Build Coastguard Worker         return ((int) t1->t_token) - ((int) t2->t_token);
1280*7c568831SAndroid Build Coastguard Worker }
1281*7c568831SAndroid Build Coastguard Worker 
1282*7c568831SAndroid Build Coastguard Worker 
1283*7c568831SAndroid Build Coastguard Worker void
builddfa(void)1284*7c568831SAndroid Build Coastguard Worker builddfa(void)
1285*7c568831SAndroid Build Coastguard Worker 
1286*7c568831SAndroid Build Coastguard Worker {
1287*7c568831SAndroid Build Coastguard Worker         t_powerset * transset;
1288*7c568831SAndroid Build Coastguard Worker         t_powerset * stateset;
1289*7c568831SAndroid Build Coastguard Worker         t_state * s;
1290*7c568831SAndroid Build Coastguard Worker         t_state * s2;
1291*7c568831SAndroid Build Coastguard Worker         unsigned int n;
1292*7c568831SAndroid Build Coastguard Worker         unsigned int i;
1293*7c568831SAndroid Build Coastguard Worker         unsigned int token;
1294*7c568831SAndroid Build Coastguard Worker         t_transition * t;
1295*7c568831SAndroid Build Coastguard Worker         t_state * stack;
1296*7c568831SAndroid Build Coastguard Worker         xmlHashTablePtr sethash;
1297*7c568831SAndroid Build Coastguard Worker         unsigned int nst;
1298*7c568831SAndroid Build Coastguard Worker 
1299*7c568831SAndroid Build Coastguard Worker         transset = set_include(NULL, NULL);
1300*7c568831SAndroid Build Coastguard Worker         chknull(transset);
1301*7c568831SAndroid Build Coastguard Worker         stateset = set_include(NULL, NULL);
1302*7c568831SAndroid Build Coastguard Worker         chknull(stateset);
1303*7c568831SAndroid Build Coastguard Worker         sethash = xmlHashCreate(1);
1304*7c568831SAndroid Build Coastguard Worker         chknull(sethash);
1305*7c568831SAndroid Build Coastguard Worker         dfa_states = (t_state *) NULL;
1306*7c568831SAndroid Build Coastguard Worker         stack = (t_state *) NULL;
1307*7c568831SAndroid Build Coastguard Worker         nst = 0;
1308*7c568831SAndroid Build Coastguard Worker 
1309*7c568831SAndroid Build Coastguard Worker         /**
1310*7c568831SAndroid Build Coastguard Worker         ***     Build the DFA initial state.
1311*7c568831SAndroid Build Coastguard Worker         **/
1312*7c568831SAndroid Build Coastguard Worker 
1313*7c568831SAndroid Build Coastguard Worker         get_dfa_state(&stack, closure(NULL, initial_state), sethash);
1314*7c568831SAndroid Build Coastguard Worker 
1315*7c568831SAndroid Build Coastguard Worker         /**
1316*7c568831SAndroid Build Coastguard Worker         ***     Build the other DFA states by looking at each
1317*7c568831SAndroid Build Coastguard Worker         ***             possible transition from stacked DFA states.
1318*7c568831SAndroid Build Coastguard Worker         **/
1319*7c568831SAndroid Build Coastguard Worker 
1320*7c568831SAndroid Build Coastguard Worker         do {
1321*7c568831SAndroid Build Coastguard Worker                 if (!(++nst % 100))
1322*7c568831SAndroid Build Coastguard Worker                         fprintf(stderr, "%u DFA states\n", nst);
1323*7c568831SAndroid Build Coastguard Worker 
1324*7c568831SAndroid Build Coastguard Worker                 s = stack;
1325*7c568831SAndroid Build Coastguard Worker                 stack = s->s_stack;
1326*7c568831SAndroid Build Coastguard Worker                 s->s_stack = (t_state *) NULL;
1327*7c568831SAndroid Build Coastguard Worker 
1328*7c568831SAndroid Build Coastguard Worker                 /**
1329*7c568831SAndroid Build Coastguard Worker                 ***     Build a set of all non-epsilon transitions from this
1330*7c568831SAndroid Build Coastguard Worker                 ***             state.
1331*7c568831SAndroid Build Coastguard Worker                 **/
1332*7c568831SAndroid Build Coastguard Worker 
1333*7c568831SAndroid Build Coastguard Worker                 transset->p_card = 0;
1334*7c568831SAndroid Build Coastguard Worker 
1335*7c568831SAndroid Build Coastguard Worker                 for (n = 0; n < s->s_nfastates->p_card; n++) {
1336*7c568831SAndroid Build Coastguard Worker                         s2 = s->s_nfastates->p_set[n];
1337*7c568831SAndroid Build Coastguard Worker 
1338*7c568831SAndroid Build Coastguard Worker                         for (t = s2->s_forward; t; t = t->t_forwnext)
1339*7c568831SAndroid Build Coastguard Worker                                 if (t->t_token != EPSILON) {
1340*7c568831SAndroid Build Coastguard Worker                                         transset = set_include(transset, t);
1341*7c568831SAndroid Build Coastguard Worker                                         chknull(transset);
1342*7c568831SAndroid Build Coastguard Worker                                         }
1343*7c568831SAndroid Build Coastguard Worker                         }
1344*7c568831SAndroid Build Coastguard Worker 
1345*7c568831SAndroid Build Coastguard Worker                 /**
1346*7c568831SAndroid Build Coastguard Worker                 ***     Sort transitions by token.
1347*7c568831SAndroid Build Coastguard Worker                 **/
1348*7c568831SAndroid Build Coastguard Worker 
1349*7c568831SAndroid Build Coastguard Worker                 qsort(transset->p_set, transset->p_card,
1350*7c568831SAndroid Build Coastguard Worker                     sizeof transset->p_set[0], transcmp);
1351*7c568831SAndroid Build Coastguard Worker 
1352*7c568831SAndroid Build Coastguard Worker                 /**
1353*7c568831SAndroid Build Coastguard Worker                 ***     Process all transitions, grouping them by token.
1354*7c568831SAndroid Build Coastguard Worker                 **/
1355*7c568831SAndroid Build Coastguard Worker 
1356*7c568831SAndroid Build Coastguard Worker                 stateset->p_card = 0;
1357*7c568831SAndroid Build Coastguard Worker                 token = EPSILON;
1358*7c568831SAndroid Build Coastguard Worker 
1359*7c568831SAndroid Build Coastguard Worker                 for (i = 0; i < transset->p_card; i++) {
1360*7c568831SAndroid Build Coastguard Worker                         t = transset->p_set[i];
1361*7c568831SAndroid Build Coastguard Worker 
1362*7c568831SAndroid Build Coastguard Worker                         if (token != t->t_token) {
1363*7c568831SAndroid Build Coastguard Worker                                 if (stateset->p_card) {
1364*7c568831SAndroid Build Coastguard Worker                                         /**
1365*7c568831SAndroid Build Coastguard Worker                                         ***     Get the equivalent DFA state
1366*7c568831SAndroid Build Coastguard Worker                                         ***             and create transition.
1367*7c568831SAndroid Build Coastguard Worker                                         **/
1368*7c568831SAndroid Build Coastguard Worker 
1369*7c568831SAndroid Build Coastguard Worker                                         newtransition(token, s,
1370*7c568831SAndroid Build Coastguard Worker                                             get_dfa_state(&stack,
1371*7c568831SAndroid Build Coastguard Worker                                             closureset(NULL, stateset),
1372*7c568831SAndroid Build Coastguard Worker                                             sethash));
1373*7c568831SAndroid Build Coastguard Worker                                         stateset->p_card = 0;
1374*7c568831SAndroid Build Coastguard Worker                                         }
1375*7c568831SAndroid Build Coastguard Worker 
1376*7c568831SAndroid Build Coastguard Worker                                 token = t->t_token;
1377*7c568831SAndroid Build Coastguard Worker                                 }
1378*7c568831SAndroid Build Coastguard Worker 
1379*7c568831SAndroid Build Coastguard Worker                         stateset = set_include(stateset, t->t_to);
1380*7c568831SAndroid Build Coastguard Worker                         }
1381*7c568831SAndroid Build Coastguard Worker 
1382*7c568831SAndroid Build Coastguard Worker                 if (stateset->p_card)
1383*7c568831SAndroid Build Coastguard Worker                         newtransition(token, s, get_dfa_state(&stack,
1384*7c568831SAndroid Build Coastguard Worker                             closureset(NULL, stateset), sethash));
1385*7c568831SAndroid Build Coastguard Worker         } while (stack);
1386*7c568831SAndroid Build Coastguard Worker 
1387*7c568831SAndroid Build Coastguard Worker         free((char *) transset);
1388*7c568831SAndroid Build Coastguard Worker         free((char *) stateset);
1389*7c568831SAndroid Build Coastguard Worker         xmlHashFree(sethash, NULL);
1390*7c568831SAndroid Build Coastguard Worker 
1391*7c568831SAndroid Build Coastguard Worker         /**
1392*7c568831SAndroid Build Coastguard Worker         ***     Reverse the state list to get the initial state first,
1393*7c568831SAndroid Build Coastguard Worker         ***             check for ambiguous prefixes, determine final states,
1394*7c568831SAndroid Build Coastguard Worker         ***             destroy NFA state sets.
1395*7c568831SAndroid Build Coastguard Worker         **/
1396*7c568831SAndroid Build Coastguard Worker 
1397*7c568831SAndroid Build Coastguard Worker         while (s = dfa_states) {
1398*7c568831SAndroid Build Coastguard Worker                 dfa_states = s->s_next;
1399*7c568831SAndroid Build Coastguard Worker                 s->s_next = stack;
1400*7c568831SAndroid Build Coastguard Worker                 stack = s;
1401*7c568831SAndroid Build Coastguard Worker                 stateset = s->s_nfastates;
1402*7c568831SAndroid Build Coastguard Worker                 s->s_nfastates = (t_powerset *) NULL;
1403*7c568831SAndroid Build Coastguard Worker 
1404*7c568831SAndroid Build Coastguard Worker                 for (n = 0; n < stateset->p_card; n++) {
1405*7c568831SAndroid Build Coastguard Worker                         s2 = (t_state *) stateset->p_set[n];
1406*7c568831SAndroid Build Coastguard Worker 
1407*7c568831SAndroid Build Coastguard Worker                         if (s2->s_final) {
1408*7c568831SAndroid Build Coastguard Worker                                 if (s->s_final && s->s_final != s2->s_final)
1409*7c568831SAndroid Build Coastguard Worker                                         fprintf(stderr,
1410*7c568831SAndroid Build Coastguard Worker                                             "Ambiguous name for CCSIDs %u/%u\n",
1411*7c568831SAndroid Build Coastguard Worker                                             s->s_final->c_ccsid,
1412*7c568831SAndroid Build Coastguard Worker                                             s2->s_final->c_ccsid);
1413*7c568831SAndroid Build Coastguard Worker 
1414*7c568831SAndroid Build Coastguard Worker                                 s->s_final = s2->s_final;
1415*7c568831SAndroid Build Coastguard Worker                                 }
1416*7c568831SAndroid Build Coastguard Worker                         }
1417*7c568831SAndroid Build Coastguard Worker 
1418*7c568831SAndroid Build Coastguard Worker                 free((char *) stateset);
1419*7c568831SAndroid Build Coastguard Worker                 }
1420*7c568831SAndroid Build Coastguard Worker 
1421*7c568831SAndroid Build Coastguard Worker         dfa_states = stack;
1422*7c568831SAndroid Build Coastguard Worker }
1423*7c568831SAndroid Build Coastguard Worker 
1424*7c568831SAndroid Build Coastguard Worker 
1425*7c568831SAndroid Build Coastguard Worker void
deletenfa(void)1426*7c568831SAndroid Build Coastguard Worker deletenfa(void)
1427*7c568831SAndroid Build Coastguard Worker 
1428*7c568831SAndroid Build Coastguard Worker {
1429*7c568831SAndroid Build Coastguard Worker         t_transition * t;
1430*7c568831SAndroid Build Coastguard Worker         t_state * s;
1431*7c568831SAndroid Build Coastguard Worker         t_state * u;
1432*7c568831SAndroid Build Coastguard Worker         t_state * stack;
1433*7c568831SAndroid Build Coastguard Worker 
1434*7c568831SAndroid Build Coastguard Worker         stack = initial_state;
1435*7c568831SAndroid Build Coastguard Worker         stack->s_stack = (t_state *) NULL;
1436*7c568831SAndroid Build Coastguard Worker 
1437*7c568831SAndroid Build Coastguard Worker         while ((s = stack)) {
1438*7c568831SAndroid Build Coastguard Worker                 stack = s->s_stack;
1439*7c568831SAndroid Build Coastguard Worker 
1440*7c568831SAndroid Build Coastguard Worker                 while ((t = s->s_forward)) {
1441*7c568831SAndroid Build Coastguard Worker                         u = t->t_to;
1442*7c568831SAndroid Build Coastguard Worker                         unlink_transition(t);
1443*7c568831SAndroid Build Coastguard Worker                         free((char *) t);
1444*7c568831SAndroid Build Coastguard Worker 
1445*7c568831SAndroid Build Coastguard Worker                         if (!u->s_backward) {
1446*7c568831SAndroid Build Coastguard Worker                                 u->s_stack = stack;
1447*7c568831SAndroid Build Coastguard Worker                                 stack = u;
1448*7c568831SAndroid Build Coastguard Worker                                 }
1449*7c568831SAndroid Build Coastguard Worker                         }
1450*7c568831SAndroid Build Coastguard Worker 
1451*7c568831SAndroid Build Coastguard Worker                 free((char *) s);
1452*7c568831SAndroid Build Coastguard Worker                 }
1453*7c568831SAndroid Build Coastguard Worker }
1454*7c568831SAndroid Build Coastguard Worker 
1455*7c568831SAndroid Build Coastguard Worker 
1456*7c568831SAndroid Build Coastguard Worker t_stategroup *
newgroup(void)1457*7c568831SAndroid Build Coastguard Worker newgroup(void)
1458*7c568831SAndroid Build Coastguard Worker 
1459*7c568831SAndroid Build Coastguard Worker {
1460*7c568831SAndroid Build Coastguard Worker         t_stategroup * g;
1461*7c568831SAndroid Build Coastguard Worker 
1462*7c568831SAndroid Build Coastguard Worker         g = (t_stategroup *) malloc(sizeof *g);
1463*7c568831SAndroid Build Coastguard Worker         chknull(g);
1464*7c568831SAndroid Build Coastguard Worker         memset((char *) g, 0, sizeof *g);
1465*7c568831SAndroid Build Coastguard Worker         g->g_id = groupid++;
1466*7c568831SAndroid Build Coastguard Worker         return g;
1467*7c568831SAndroid Build Coastguard Worker }
1468*7c568831SAndroid Build Coastguard Worker 
1469*7c568831SAndroid Build Coastguard Worker 
1470*7c568831SAndroid Build Coastguard Worker void
optimizedfa(void)1471*7c568831SAndroid Build Coastguard Worker optimizedfa(void)
1472*7c568831SAndroid Build Coastguard Worker 
1473*7c568831SAndroid Build Coastguard Worker {
1474*7c568831SAndroid Build Coastguard Worker         unsigned int i;
1475*7c568831SAndroid Build Coastguard Worker         xmlHashTablePtr h;
1476*7c568831SAndroid Build Coastguard Worker         t_state * s1;
1477*7c568831SAndroid Build Coastguard Worker         t_state * s2;
1478*7c568831SAndroid Build Coastguard Worker         t_state * finstates;
1479*7c568831SAndroid Build Coastguard Worker         t_state * * sp;
1480*7c568831SAndroid Build Coastguard Worker         t_stategroup * g1;
1481*7c568831SAndroid Build Coastguard Worker         t_stategroup * g2;
1482*7c568831SAndroid Build Coastguard Worker         t_stategroup * ghead;
1483*7c568831SAndroid Build Coastguard Worker         t_transition * t1;
1484*7c568831SAndroid Build Coastguard Worker         t_transition * t2;
1485*7c568831SAndroid Build Coastguard Worker         unsigned int done;
1486*7c568831SAndroid Build Coastguard Worker         unsigned int startgroup;
1487*7c568831SAndroid Build Coastguard Worker         unsigned int gtrans[1 << (8 * sizeof(unsigned char))];
1488*7c568831SAndroid Build Coastguard Worker 
1489*7c568831SAndroid Build Coastguard Worker         /**
1490*7c568831SAndroid Build Coastguard Worker         ***     Reduce DFA state count.
1491*7c568831SAndroid Build Coastguard Worker         **/
1492*7c568831SAndroid Build Coastguard Worker 
1493*7c568831SAndroid Build Coastguard Worker         groupid = 0;
1494*7c568831SAndroid Build Coastguard Worker         ghead = (t_stategroup *) NULL;
1495*7c568831SAndroid Build Coastguard Worker 
1496*7c568831SAndroid Build Coastguard Worker         /**
1497*7c568831SAndroid Build Coastguard Worker         ***     First split: non-final and each distinct final states.
1498*7c568831SAndroid Build Coastguard Worker         **/
1499*7c568831SAndroid Build Coastguard Worker 
1500*7c568831SAndroid Build Coastguard Worker         h = xmlHashCreate(4);
1501*7c568831SAndroid Build Coastguard Worker         chknull(h);
1502*7c568831SAndroid Build Coastguard Worker 
1503*7c568831SAndroid Build Coastguard Worker         for (s1 = dfa_states; s1; s1 = s1->s_next) {
1504*7c568831SAndroid Build Coastguard Worker                 if (!(g1 = hash_get(h, &s1->s_final, sizeof s1->s_final))) {
1505*7c568831SAndroid Build Coastguard Worker                         g1 = newgroup();
1506*7c568831SAndroid Build Coastguard Worker                         g1->g_next = ghead;
1507*7c568831SAndroid Build Coastguard Worker                         ghead = g1;
1508*7c568831SAndroid Build Coastguard Worker 
1509*7c568831SAndroid Build Coastguard Worker                         if (hash_add(h, &s1->s_final, sizeof s1->s_final, g1))
1510*7c568831SAndroid Build Coastguard Worker                                 chknull(NULL);  /* Memory allocation error. */
1511*7c568831SAndroid Build Coastguard Worker                         }
1512*7c568831SAndroid Build Coastguard Worker 
1513*7c568831SAndroid Build Coastguard Worker                 s1->s_index = g1->g_id;
1514*7c568831SAndroid Build Coastguard Worker                 s1->s_stack = g1->g_member;
1515*7c568831SAndroid Build Coastguard Worker                 g1->g_member = s1;
1516*7c568831SAndroid Build Coastguard Worker                 }
1517*7c568831SAndroid Build Coastguard Worker 
1518*7c568831SAndroid Build Coastguard Worker         xmlHashFree(h, NULL);
1519*7c568831SAndroid Build Coastguard Worker 
1520*7c568831SAndroid Build Coastguard Worker         /**
1521*7c568831SAndroid Build Coastguard Worker         ***     Subsequent splits: states that have the same forward
1522*7c568831SAndroid Build Coastguard Worker         ***             transition tokens to states in the same group.
1523*7c568831SAndroid Build Coastguard Worker         **/
1524*7c568831SAndroid Build Coastguard Worker 
1525*7c568831SAndroid Build Coastguard Worker         do {
1526*7c568831SAndroid Build Coastguard Worker                 done = 1;
1527*7c568831SAndroid Build Coastguard Worker 
1528*7c568831SAndroid Build Coastguard Worker                 for (g2 = ghead; g2; g2 = g2->g_next) {
1529*7c568831SAndroid Build Coastguard Worker                         s1 = g2->g_member;
1530*7c568831SAndroid Build Coastguard Worker 
1531*7c568831SAndroid Build Coastguard Worker                         if (!s1->s_stack)
1532*7c568831SAndroid Build Coastguard Worker                                 continue;
1533*7c568831SAndroid Build Coastguard Worker 
1534*7c568831SAndroid Build Coastguard Worker                         h = xmlHashCreate(1);
1535*7c568831SAndroid Build Coastguard Worker                         chknull(h);
1536*7c568831SAndroid Build Coastguard Worker 
1537*7c568831SAndroid Build Coastguard Worker                         /**
1538*7c568831SAndroid Build Coastguard Worker                         ***     Build the group transition map.
1539*7c568831SAndroid Build Coastguard Worker                         **/
1540*7c568831SAndroid Build Coastguard Worker 
1541*7c568831SAndroid Build Coastguard Worker                         memset((char *) gtrans, ~0, sizeof gtrans);
1542*7c568831SAndroid Build Coastguard Worker 
1543*7c568831SAndroid Build Coastguard Worker                         for (t1 = s1->s_forward; t1; t1 = t1->t_forwnext)
1544*7c568831SAndroid Build Coastguard Worker                                 gtrans[t1->t_token] = t1->t_to->s_index;
1545*7c568831SAndroid Build Coastguard Worker 
1546*7c568831SAndroid Build Coastguard Worker                         if (hash_add(h, gtrans, sizeof gtrans, g2))
1547*7c568831SAndroid Build Coastguard Worker                                 chknull(NULL);
1548*7c568831SAndroid Build Coastguard Worker 
1549*7c568831SAndroid Build Coastguard Worker                         /**
1550*7c568831SAndroid Build Coastguard Worker                         ***     Process other states in group.
1551*7c568831SAndroid Build Coastguard Worker                         **/
1552*7c568831SAndroid Build Coastguard Worker 
1553*7c568831SAndroid Build Coastguard Worker                         sp = &s1->s_stack;
1554*7c568831SAndroid Build Coastguard Worker                         s1 = *sp;
1555*7c568831SAndroid Build Coastguard Worker 
1556*7c568831SAndroid Build Coastguard Worker                         do {
1557*7c568831SAndroid Build Coastguard Worker                                 *sp = s1->s_stack;
1558*7c568831SAndroid Build Coastguard Worker 
1559*7c568831SAndroid Build Coastguard Worker                                 /**
1560*7c568831SAndroid Build Coastguard Worker                                 ***     Build the transition map.
1561*7c568831SAndroid Build Coastguard Worker                                 **/
1562*7c568831SAndroid Build Coastguard Worker 
1563*7c568831SAndroid Build Coastguard Worker                                 memset((char *) gtrans, ~0, sizeof gtrans);
1564*7c568831SAndroid Build Coastguard Worker 
1565*7c568831SAndroid Build Coastguard Worker                                 for (t1 = s1->s_forward;
1566*7c568831SAndroid Build Coastguard Worker                                     t1; t1 = t1->t_forwnext)
1567*7c568831SAndroid Build Coastguard Worker                                         gtrans[t1->t_token] = t1->t_to->s_index;
1568*7c568831SAndroid Build Coastguard Worker 
1569*7c568831SAndroid Build Coastguard Worker                                 g1 = hash_get(h, gtrans, sizeof gtrans);
1570*7c568831SAndroid Build Coastguard Worker 
1571*7c568831SAndroid Build Coastguard Worker                                 if (g1 == g2) {
1572*7c568831SAndroid Build Coastguard Worker                                         *sp = s1;
1573*7c568831SAndroid Build Coastguard Worker                                         sp = &s1->s_stack;
1574*7c568831SAndroid Build Coastguard Worker                                         }
1575*7c568831SAndroid Build Coastguard Worker                                 else {
1576*7c568831SAndroid Build Coastguard Worker                                         if (!g1) {
1577*7c568831SAndroid Build Coastguard Worker                                                 g1 = newgroup();
1578*7c568831SAndroid Build Coastguard Worker                                                 g1->g_next = ghead;
1579*7c568831SAndroid Build Coastguard Worker                                                 ghead = g1;
1580*7c568831SAndroid Build Coastguard Worker 
1581*7c568831SAndroid Build Coastguard Worker                                                 if (hash_add(h, gtrans,
1582*7c568831SAndroid Build Coastguard Worker                                                     sizeof gtrans, g1))
1583*7c568831SAndroid Build Coastguard Worker                                                         chknull(NULL);
1584*7c568831SAndroid Build Coastguard Worker                                                 }
1585*7c568831SAndroid Build Coastguard Worker 
1586*7c568831SAndroid Build Coastguard Worker                                         s1->s_index = g1->g_id;
1587*7c568831SAndroid Build Coastguard Worker                                         s1->s_stack = g1->g_member;
1588*7c568831SAndroid Build Coastguard Worker                                         g1->g_member = s1;
1589*7c568831SAndroid Build Coastguard Worker                                         done = 0;
1590*7c568831SAndroid Build Coastguard Worker                                         }
1591*7c568831SAndroid Build Coastguard Worker                         } while (s1 = *sp);
1592*7c568831SAndroid Build Coastguard Worker 
1593*7c568831SAndroid Build Coastguard Worker                         xmlHashFree(h, NULL);
1594*7c568831SAndroid Build Coastguard Worker                         }
1595*7c568831SAndroid Build Coastguard Worker         } while (!done);
1596*7c568831SAndroid Build Coastguard Worker 
1597*7c568831SAndroid Build Coastguard Worker         /**
1598*7c568831SAndroid Build Coastguard Worker         ***     Establish group leaders and remap transitions.
1599*7c568831SAndroid Build Coastguard Worker         **/
1600*7c568831SAndroid Build Coastguard Worker 
1601*7c568831SAndroid Build Coastguard Worker         startgroup = dfa_states->s_index;
1602*7c568831SAndroid Build Coastguard Worker 
1603*7c568831SAndroid Build Coastguard Worker         for (g1 = ghead; g1; g1 = g1->g_next)
1604*7c568831SAndroid Build Coastguard Worker                 for (s1 = g1->g_member->s_stack; s1; s1 = s1->s_stack)
1605*7c568831SAndroid Build Coastguard Worker                         for (t1 = s1->s_backward; t1; t1 = t2) {
1606*7c568831SAndroid Build Coastguard Worker                                 t2 = t1->t_backnext;
1607*7c568831SAndroid Build Coastguard Worker                                 link_transition(t1, NULL, g1->g_member);
1608*7c568831SAndroid Build Coastguard Worker                                 }
1609*7c568831SAndroid Build Coastguard Worker 
1610*7c568831SAndroid Build Coastguard Worker         /**
1611*7c568831SAndroid Build Coastguard Worker         ***     Remove redundant states and transitions.
1612*7c568831SAndroid Build Coastguard Worker         **/
1613*7c568831SAndroid Build Coastguard Worker 
1614*7c568831SAndroid Build Coastguard Worker         for (g1 = ghead; g1; g1 = g1->g_next) {
1615*7c568831SAndroid Build Coastguard Worker                 g1->g_member->s_next = (t_state *) NULL;
1616*7c568831SAndroid Build Coastguard Worker 
1617*7c568831SAndroid Build Coastguard Worker                 while ((s1 = g1->g_member->s_stack)) {
1618*7c568831SAndroid Build Coastguard Worker                         g1->g_member->s_stack = s1->s_stack;
1619*7c568831SAndroid Build Coastguard Worker 
1620*7c568831SAndroid Build Coastguard Worker                         for (t1 = s1->s_forward; t1; t1 = t2) {
1621*7c568831SAndroid Build Coastguard Worker                                 t2 = t1->t_forwnext;
1622*7c568831SAndroid Build Coastguard Worker                                 unlink_transition(t1);
1623*7c568831SAndroid Build Coastguard Worker                                 free((char *) t1);
1624*7c568831SAndroid Build Coastguard Worker                                 }
1625*7c568831SAndroid Build Coastguard Worker 
1626*7c568831SAndroid Build Coastguard Worker                         free((char *) s1);
1627*7c568831SAndroid Build Coastguard Worker                         }
1628*7c568831SAndroid Build Coastguard Worker                 }
1629*7c568831SAndroid Build Coastguard Worker 
1630*7c568831SAndroid Build Coastguard Worker         /**
1631*7c568831SAndroid Build Coastguard Worker         ***     Remove group support and relink DFA states.
1632*7c568831SAndroid Build Coastguard Worker         **/
1633*7c568831SAndroid Build Coastguard Worker 
1634*7c568831SAndroid Build Coastguard Worker         dfa_states = (t_state *) NULL;
1635*7c568831SAndroid Build Coastguard Worker         s2 = (t_state *) NULL;
1636*7c568831SAndroid Build Coastguard Worker         finstates = (t_state *) NULL;
1637*7c568831SAndroid Build Coastguard Worker 
1638*7c568831SAndroid Build Coastguard Worker         while (g1 = ghead) {
1639*7c568831SAndroid Build Coastguard Worker                 ghead = g1->g_next;
1640*7c568831SAndroid Build Coastguard Worker                 s1 = g1->g_member;
1641*7c568831SAndroid Build Coastguard Worker 
1642*7c568831SAndroid Build Coastguard Worker                 if (g1->g_id == startgroup)
1643*7c568831SAndroid Build Coastguard Worker                         dfa_states = s1;        /* Keep start state first. */
1644*7c568831SAndroid Build Coastguard Worker                 else if (s1->s_final) {         /* Then final states. */
1645*7c568831SAndroid Build Coastguard Worker                         s1->s_next = finstates;
1646*7c568831SAndroid Build Coastguard Worker                         finstates = s1;
1647*7c568831SAndroid Build Coastguard Worker                         }
1648*7c568831SAndroid Build Coastguard Worker                 else {                  /* Finish with non-final states. */
1649*7c568831SAndroid Build Coastguard Worker                         s1->s_next = s2;
1650*7c568831SAndroid Build Coastguard Worker                         s2 = s1;
1651*7c568831SAndroid Build Coastguard Worker                         }
1652*7c568831SAndroid Build Coastguard Worker 
1653*7c568831SAndroid Build Coastguard Worker                 free((char *) g1);
1654*7c568831SAndroid Build Coastguard Worker                 }
1655*7c568831SAndroid Build Coastguard Worker 
1656*7c568831SAndroid Build Coastguard Worker         for (dfa_states->s_next = finstates; finstates->s_next;)
1657*7c568831SAndroid Build Coastguard Worker                 finstates = finstates->s_next;
1658*7c568831SAndroid Build Coastguard Worker 
1659*7c568831SAndroid Build Coastguard Worker         finstates->s_next = s2;
1660*7c568831SAndroid Build Coastguard Worker }
1661*7c568831SAndroid Build Coastguard Worker 
1662*7c568831SAndroid Build Coastguard Worker 
1663*7c568831SAndroid Build Coastguard Worker const char *
inttype(unsigned long max)1664*7c568831SAndroid Build Coastguard Worker inttype(unsigned long max)
1665*7c568831SAndroid Build Coastguard Worker 
1666*7c568831SAndroid Build Coastguard Worker {
1667*7c568831SAndroid Build Coastguard Worker         int i;
1668*7c568831SAndroid Build Coastguard Worker 
1669*7c568831SAndroid Build Coastguard Worker         for (i = 0; max; i++)
1670*7c568831SAndroid Build Coastguard Worker                 max >>= 1;
1671*7c568831SAndroid Build Coastguard Worker 
1672*7c568831SAndroid Build Coastguard Worker         if (i > 8 * sizeof(unsigned int))
1673*7c568831SAndroid Build Coastguard Worker                 return "unsigned long";
1674*7c568831SAndroid Build Coastguard Worker 
1675*7c568831SAndroid Build Coastguard Worker         if (i > 8 * sizeof(unsigned short))
1676*7c568831SAndroid Build Coastguard Worker                 return "unsigned int";
1677*7c568831SAndroid Build Coastguard Worker 
1678*7c568831SAndroid Build Coastguard Worker         if (i > 8 * sizeof(unsigned char))
1679*7c568831SAndroid Build Coastguard Worker                 return "unsigned short";
1680*7c568831SAndroid Build Coastguard Worker 
1681*7c568831SAndroid Build Coastguard Worker         return "unsigned char";
1682*7c568831SAndroid Build Coastguard Worker }
1683*7c568831SAndroid Build Coastguard Worker 
1684*7c568831SAndroid Build Coastguard Worker 
listids(FILE * fp)1685*7c568831SAndroid Build Coastguard Worker listids(FILE * fp)
1686*7c568831SAndroid Build Coastguard Worker 
1687*7c568831SAndroid Build Coastguard Worker {
1688*7c568831SAndroid Build Coastguard Worker         unsigned int pos;
1689*7c568831SAndroid Build Coastguard Worker         t_chset * cp;
1690*7c568831SAndroid Build Coastguard Worker         t_symlist * lp;
1691*7c568831SAndroid Build Coastguard Worker         char * srcp;
1692*7c568831SAndroid Build Coastguard Worker         char * dstp;
1693*7c568831SAndroid Build Coastguard Worker         size_t srcc;
1694*7c568831SAndroid Build Coastguard Worker         size_t dstc;
1695*7c568831SAndroid Build Coastguard Worker         char buf[80];
1696*7c568831SAndroid Build Coastguard Worker 
1697*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "/**\n***     CCSID   For arg   Recognized name.\n");
1698*7c568831SAndroid Build Coastguard Worker         pos = 0;
1699*7c568831SAndroid Build Coastguard Worker 
1700*7c568831SAndroid Build Coastguard Worker         for (cp = chset_list; cp; cp = cp->c_next) {
1701*7c568831SAndroid Build Coastguard Worker                 if (pos) {
1702*7c568831SAndroid Build Coastguard Worker                         fprintf(fp, "\n");
1703*7c568831SAndroid Build Coastguard Worker                         pos = 0;
1704*7c568831SAndroid Build Coastguard Worker                         }
1705*7c568831SAndroid Build Coastguard Worker 
1706*7c568831SAndroid Build Coastguard Worker                 if (!cp->c_names)
1707*7c568831SAndroid Build Coastguard Worker                         continue;
1708*7c568831SAndroid Build Coastguard Worker 
1709*7c568831SAndroid Build Coastguard Worker                 pos = fprintf(fp, "***     %5u      %c     ", cp->c_ccsid,
1710*7c568831SAndroid Build Coastguard Worker                     iconv_open_error(cp->c_fromUTF8)? ' ': 'X');
1711*7c568831SAndroid Build Coastguard Worker 
1712*7c568831SAndroid Build Coastguard Worker                 for (lp = cp->c_names; lp; lp = lp->l_next) {
1713*7c568831SAndroid Build Coastguard Worker                         srcp = (char *) lp->l_symbol;
1714*7c568831SAndroid Build Coastguard Worker                         srcc = strlen(srcp);
1715*7c568831SAndroid Build Coastguard Worker                         dstp = buf;
1716*7c568831SAndroid Build Coastguard Worker                         dstc = sizeof buf;
1717*7c568831SAndroid Build Coastguard Worker                         iconv(utf82job, &srcp, &srcc, &dstp, &dstc);
1718*7c568831SAndroid Build Coastguard Worker                         srcc = dstp - buf;
1719*7c568831SAndroid Build Coastguard Worker 
1720*7c568831SAndroid Build Coastguard Worker                         if (pos + srcc > 79) {
1721*7c568831SAndroid Build Coastguard Worker                                 fprintf(fp, "\n***%22c", ' ');
1722*7c568831SAndroid Build Coastguard Worker                                 pos = 25;
1723*7c568831SAndroid Build Coastguard Worker                                 }
1724*7c568831SAndroid Build Coastguard Worker 
1725*7c568831SAndroid Build Coastguard Worker                         pos += fprintf(fp, " %.*s", srcc, buf);
1726*7c568831SAndroid Build Coastguard Worker                         }
1727*7c568831SAndroid Build Coastguard Worker                 }
1728*7c568831SAndroid Build Coastguard Worker 
1729*7c568831SAndroid Build Coastguard Worker         if (pos)
1730*7c568831SAndroid Build Coastguard Worker                 fprintf(fp, "\n");
1731*7c568831SAndroid Build Coastguard Worker 
1732*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "**/\n\n");
1733*7c568831SAndroid Build Coastguard Worker }
1734*7c568831SAndroid Build Coastguard Worker 
1735*7c568831SAndroid Build Coastguard Worker 
1736*7c568831SAndroid Build Coastguard Worker void
generate(FILE * fp)1737*7c568831SAndroid Build Coastguard Worker generate(FILE * fp)
1738*7c568831SAndroid Build Coastguard Worker 
1739*7c568831SAndroid Build Coastguard Worker {
1740*7c568831SAndroid Build Coastguard Worker         unsigned int nstates;
1741*7c568831SAndroid Build Coastguard Worker         unsigned int ntrans;
1742*7c568831SAndroid Build Coastguard Worker         unsigned int maxfinal;
1743*7c568831SAndroid Build Coastguard Worker         t_state * s;
1744*7c568831SAndroid Build Coastguard Worker         t_transition * t;
1745*7c568831SAndroid Build Coastguard Worker         unsigned int i;
1746*7c568831SAndroid Build Coastguard Worker         unsigned int pos;
1747*7c568831SAndroid Build Coastguard Worker         char * ns;
1748*7c568831SAndroid Build Coastguard Worker 
1749*7c568831SAndroid Build Coastguard Worker         /**
1750*7c568831SAndroid Build Coastguard Worker         ***     Assign indexes to states and transitions.
1751*7c568831SAndroid Build Coastguard Worker         **/
1752*7c568831SAndroid Build Coastguard Worker 
1753*7c568831SAndroid Build Coastguard Worker         nstates = 0;
1754*7c568831SAndroid Build Coastguard Worker         ntrans = 0;
1755*7c568831SAndroid Build Coastguard Worker         maxfinal = 0;
1756*7c568831SAndroid Build Coastguard Worker 
1757*7c568831SAndroid Build Coastguard Worker         for (s = dfa_states; s; s = s->s_next) {
1758*7c568831SAndroid Build Coastguard Worker                 s->s_index = nstates++;
1759*7c568831SAndroid Build Coastguard Worker 
1760*7c568831SAndroid Build Coastguard Worker                 if (s->s_final)
1761*7c568831SAndroid Build Coastguard Worker                         maxfinal = nstates;
1762*7c568831SAndroid Build Coastguard Worker 
1763*7c568831SAndroid Build Coastguard Worker                 for (t = s->s_forward; t; t = t->t_forwnext)
1764*7c568831SAndroid Build Coastguard Worker                         t->t_index = ntrans++;
1765*7c568831SAndroid Build Coastguard Worker                 }
1766*7c568831SAndroid Build Coastguard Worker 
1767*7c568831SAndroid Build Coastguard Worker         fprintf(fp,
1768*7c568831SAndroid Build Coastguard Worker             "/**\n***     %u states, %u finals, %u transitions.\n**/\n\n",
1769*7c568831SAndroid Build Coastguard Worker             nstates, maxfinal, ntrans);
1770*7c568831SAndroid Build Coastguard Worker         fprintf(stderr, "%u states, %u finals, %u transitions.\n",
1771*7c568831SAndroid Build Coastguard Worker             nstates, maxfinal, ntrans);
1772*7c568831SAndroid Build Coastguard Worker 
1773*7c568831SAndroid Build Coastguard Worker         /**
1774*7c568831SAndroid Build Coastguard Worker         ***     Generate types.
1775*7c568831SAndroid Build Coastguard Worker         **/
1776*7c568831SAndroid Build Coastguard Worker 
1777*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "typedef unsigned short          t_ccsid;\n");
1778*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "typedef %-23s t_staterange;\n", inttype(nstates));
1779*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "typedef %-23s t_transrange;\n\n", inttype(ntrans));
1780*7c568831SAndroid Build Coastguard Worker 
1781*7c568831SAndroid Build Coastguard Worker         /**
1782*7c568831SAndroid Build Coastguard Worker         ***     Generate first transition index for each state.
1783*7c568831SAndroid Build Coastguard Worker         **/
1784*7c568831SAndroid Build Coastguard Worker 
1785*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "static t_transrange     trans_array[] = {\n");
1786*7c568831SAndroid Build Coastguard Worker         pos = 0;
1787*7c568831SAndroid Build Coastguard Worker         ntrans = 0;
1788*7c568831SAndroid Build Coastguard Worker 
1789*7c568831SAndroid Build Coastguard Worker         for (s = dfa_states; s; s = s->s_next) {
1790*7c568831SAndroid Build Coastguard Worker                 pos += fprintf(fp, " %u,", ntrans);
1791*7c568831SAndroid Build Coastguard Worker 
1792*7c568831SAndroid Build Coastguard Worker                 if (pos > 72) {
1793*7c568831SAndroid Build Coastguard Worker                         fprintf(fp, "\n");
1794*7c568831SAndroid Build Coastguard Worker                         pos = 0;
1795*7c568831SAndroid Build Coastguard Worker                         }
1796*7c568831SAndroid Build Coastguard Worker 
1797*7c568831SAndroid Build Coastguard Worker                 for (t = s->s_forward; t; t = t->t_forwnext)
1798*7c568831SAndroid Build Coastguard Worker                         ntrans++;
1799*7c568831SAndroid Build Coastguard Worker                 }
1800*7c568831SAndroid Build Coastguard Worker 
1801*7c568831SAndroid Build Coastguard Worker         fprintf(fp, " %u\n};\n\n", ntrans);
1802*7c568831SAndroid Build Coastguard Worker 
1803*7c568831SAndroid Build Coastguard Worker         /**
1804*7c568831SAndroid Build Coastguard Worker         ***     Generate final state info.
1805*7c568831SAndroid Build Coastguard Worker         **/
1806*7c568831SAndroid Build Coastguard Worker 
1807*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "static t_ccsid          final_array[] = {\n");
1808*7c568831SAndroid Build Coastguard Worker         pos = 0;
1809*7c568831SAndroid Build Coastguard Worker         ns ="";
1810*7c568831SAndroid Build Coastguard Worker         i = 0;
1811*7c568831SAndroid Build Coastguard Worker 
1812*7c568831SAndroid Build Coastguard Worker         for (s = dfa_states; s && i++ < maxfinal; s = s->s_next) {
1813*7c568831SAndroid Build Coastguard Worker                 pos += fprintf(fp, "%s", ns);
1814*7c568831SAndroid Build Coastguard Worker                 ns = ",";
1815*7c568831SAndroid Build Coastguard Worker 
1816*7c568831SAndroid Build Coastguard Worker                 if (pos > 72) {
1817*7c568831SAndroid Build Coastguard Worker                         fprintf(fp, "\n");
1818*7c568831SAndroid Build Coastguard Worker                         pos = 0;
1819*7c568831SAndroid Build Coastguard Worker                         }
1820*7c568831SAndroid Build Coastguard Worker 
1821*7c568831SAndroid Build Coastguard Worker                 pos += fprintf(fp, " %u",
1822*7c568831SAndroid Build Coastguard Worker                     s->s_final? s->s_final->c_ccsid + 1: 0);
1823*7c568831SAndroid Build Coastguard Worker                 }
1824*7c568831SAndroid Build Coastguard Worker 
1825*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "\n};\n\n");
1826*7c568831SAndroid Build Coastguard Worker 
1827*7c568831SAndroid Build Coastguard Worker         /**
1828*7c568831SAndroid Build Coastguard Worker         ***     Generate goto table.
1829*7c568831SAndroid Build Coastguard Worker         **/
1830*7c568831SAndroid Build Coastguard Worker 
1831*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "static t_staterange     goto_array[] = {\n");
1832*7c568831SAndroid Build Coastguard Worker         pos = 0;
1833*7c568831SAndroid Build Coastguard Worker 
1834*7c568831SAndroid Build Coastguard Worker         for (s = dfa_states; s; s = s->s_next)
1835*7c568831SAndroid Build Coastguard Worker                 for (t = s->s_forward; t; t = t->t_forwnext) {
1836*7c568831SAndroid Build Coastguard Worker                         pos += fprintf(fp, " %u,", t->t_to->s_index);
1837*7c568831SAndroid Build Coastguard Worker 
1838*7c568831SAndroid Build Coastguard Worker                         if (pos > 72) {
1839*7c568831SAndroid Build Coastguard Worker                                 fprintf(fp, "\n");
1840*7c568831SAndroid Build Coastguard Worker                                 pos = 0;
1841*7c568831SAndroid Build Coastguard Worker                                 }
1842*7c568831SAndroid Build Coastguard Worker                         }
1843*7c568831SAndroid Build Coastguard Worker 
1844*7c568831SAndroid Build Coastguard Worker         fprintf(fp, " %u\n};\n\n", nstates);
1845*7c568831SAndroid Build Coastguard Worker 
1846*7c568831SAndroid Build Coastguard Worker         /**
1847*7c568831SAndroid Build Coastguard Worker         ***     Generate transition label table.
1848*7c568831SAndroid Build Coastguard Worker         **/
1849*7c568831SAndroid Build Coastguard Worker 
1850*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "static unsigned char    label_array[] = {\n");
1851*7c568831SAndroid Build Coastguard Worker         pos = 0;
1852*7c568831SAndroid Build Coastguard Worker         ns ="";
1853*7c568831SAndroid Build Coastguard Worker 
1854*7c568831SAndroid Build Coastguard Worker         for (s = dfa_states; s; s = s->s_next)
1855*7c568831SAndroid Build Coastguard Worker                 for (t = s->s_forward; t; t = t->t_forwnext) {
1856*7c568831SAndroid Build Coastguard Worker                         pos += fprintf(fp, "%s", ns);
1857*7c568831SAndroid Build Coastguard Worker                         ns = ",";
1858*7c568831SAndroid Build Coastguard Worker 
1859*7c568831SAndroid Build Coastguard Worker                         if (pos > 72) {
1860*7c568831SAndroid Build Coastguard Worker                                 fprintf(fp, "\n");
1861*7c568831SAndroid Build Coastguard Worker                                 pos = 0;
1862*7c568831SAndroid Build Coastguard Worker                                 }
1863*7c568831SAndroid Build Coastguard Worker 
1864*7c568831SAndroid Build Coastguard Worker                         pos += fprintf(fp, " 0x%02X", t->t_token);
1865*7c568831SAndroid Build Coastguard Worker                         }
1866*7c568831SAndroid Build Coastguard Worker 
1867*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "\n};\n", nstates);
1868*7c568831SAndroid Build Coastguard Worker }
1869*7c568831SAndroid Build Coastguard Worker 
1870*7c568831SAndroid Build Coastguard Worker 
main(argc,argv)1871*7c568831SAndroid Build Coastguard Worker main(argc, argv)
1872*7c568831SAndroid Build Coastguard Worker int argc;
1873*7c568831SAndroid Build Coastguard Worker char * * argv;
1874*7c568831SAndroid Build Coastguard Worker 
1875*7c568831SAndroid Build Coastguard Worker {
1876*7c568831SAndroid Build Coastguard Worker         FILE * fp;
1877*7c568831SAndroid Build Coastguard Worker         t_chset * csp;
1878*7c568831SAndroid Build Coastguard Worker         char symbuf[20];
1879*7c568831SAndroid Build Coastguard Worker 
1880*7c568831SAndroid Build Coastguard Worker         chset_list = (t_chset *) NULL;
1881*7c568831SAndroid Build Coastguard Worker         initial_state = newstate();
1882*7c568831SAndroid Build Coastguard Worker         job2utf8 = iconv_open_ccsid(C_UTF8_CCSID, C_SOURCE_CCSID, 0);
1883*7c568831SAndroid Build Coastguard Worker         utf82job = iconv_open_ccsid(C_SOURCE_CCSID, C_UTF8_CCSID, 0);
1884*7c568831SAndroid Build Coastguard Worker 
1885*7c568831SAndroid Build Coastguard Worker         if (argc != 4) {
1886*7c568831SAndroid Build Coastguard Worker                 fprintf(stderr, "Usage: %s <ccsid-mibenum file> ", *argv);
1887*7c568831SAndroid Build Coastguard Worker                 fprintf(stderr, "<iana-character-set file> <output file>\n");
1888*7c568831SAndroid Build Coastguard Worker                 exit(1);
1889*7c568831SAndroid Build Coastguard Worker                 }
1890*7c568831SAndroid Build Coastguard Worker 
1891*7c568831SAndroid Build Coastguard Worker         /**
1892*7c568831SAndroid Build Coastguard Worker         ***     Read CCSID/MIBenum associations. Define special names.
1893*7c568831SAndroid Build Coastguard Worker         **/
1894*7c568831SAndroid Build Coastguard Worker 
1895*7c568831SAndroid Build Coastguard Worker         read_assocs(argv[1]);
1896*7c568831SAndroid Build Coastguard Worker 
1897*7c568831SAndroid Build Coastguard Worker         /**
1898*7c568831SAndroid Build Coastguard Worker         ***     Read character set names and establish the case-independent
1899*7c568831SAndroid Build Coastguard Worker         ***             name DFA in all possible CCSIDs.
1900*7c568831SAndroid Build Coastguard Worker         **/
1901*7c568831SAndroid Build Coastguard Worker 
1902*7c568831SAndroid Build Coastguard Worker         read_iana(argv[2]);
1903*7c568831SAndroid Build Coastguard Worker 
1904*7c568831SAndroid Build Coastguard Worker         /**
1905*7c568831SAndroid Build Coastguard Worker         ***     Build DFA from NFA.
1906*7c568831SAndroid Build Coastguard Worker         **/
1907*7c568831SAndroid Build Coastguard Worker 
1908*7c568831SAndroid Build Coastguard Worker         builddfa();
1909*7c568831SAndroid Build Coastguard Worker 
1910*7c568831SAndroid Build Coastguard Worker         /**
1911*7c568831SAndroid Build Coastguard Worker         ***     Delete NFA.
1912*7c568831SAndroid Build Coastguard Worker         **/
1913*7c568831SAndroid Build Coastguard Worker 
1914*7c568831SAndroid Build Coastguard Worker         deletenfa();
1915*7c568831SAndroid Build Coastguard Worker 
1916*7c568831SAndroid Build Coastguard Worker         /**
1917*7c568831SAndroid Build Coastguard Worker         ***     Minimize the DFA state count.
1918*7c568831SAndroid Build Coastguard Worker         **/
1919*7c568831SAndroid Build Coastguard Worker 
1920*7c568831SAndroid Build Coastguard Worker         optimizedfa();
1921*7c568831SAndroid Build Coastguard Worker 
1922*7c568831SAndroid Build Coastguard Worker         /**
1923*7c568831SAndroid Build Coastguard Worker         ***     Generate the table.
1924*7c568831SAndroid Build Coastguard Worker         **/
1925*7c568831SAndroid Build Coastguard Worker 
1926*7c568831SAndroid Build Coastguard Worker         fp = fopen(argv[3], "w+");
1927*7c568831SAndroid Build Coastguard Worker 
1928*7c568831SAndroid Build Coastguard Worker         if (!fp) {
1929*7c568831SAndroid Build Coastguard Worker                 perror(argv[3]);
1930*7c568831SAndroid Build Coastguard Worker                 exit(1);
1931*7c568831SAndroid Build Coastguard Worker                 }
1932*7c568831SAndroid Build Coastguard Worker 
1933*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "/**\n");
1934*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "***     Character set names table.\n");
1935*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "***     Generated by program BLDCSNDFA from");
1936*7c568831SAndroid Build Coastguard Worker         fprintf(fp, " IANA character set assignment file\n");
1937*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "***          and CCSID/MIBenum equivalence file.\n");
1938*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "***     *** Do not edit by hand ***\n");
1939*7c568831SAndroid Build Coastguard Worker         fprintf(fp, "**/\n\n");
1940*7c568831SAndroid Build Coastguard Worker         listids(fp);
1941*7c568831SAndroid Build Coastguard Worker         generate(fp);
1942*7c568831SAndroid Build Coastguard Worker 
1943*7c568831SAndroid Build Coastguard Worker         if (ferror(fp)) {
1944*7c568831SAndroid Build Coastguard Worker                 perror(argv[3]);
1945*7c568831SAndroid Build Coastguard Worker                 fclose(fp);
1946*7c568831SAndroid Build Coastguard Worker                 exit(1);
1947*7c568831SAndroid Build Coastguard Worker                 }
1948*7c568831SAndroid Build Coastguard Worker 
1949*7c568831SAndroid Build Coastguard Worker         fclose(fp);
1950*7c568831SAndroid Build Coastguard Worker         iconv_close(job2utf8);
1951*7c568831SAndroid Build Coastguard Worker         iconv_close(utf82job);
1952*7c568831SAndroid Build Coastguard Worker         exit(0);
1953*7c568831SAndroid Build Coastguard Worker }
1954