xref: /titanic_52/usr/src/cmd/oawk/b.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include "awk.def"
34*7c478bd9Sstevel@tonic-gate #include "stdio.h"
35*7c478bd9Sstevel@tonic-gate #include "awk.h"
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate extern NODE *op2();
39*7c478bd9Sstevel@tonic-gate extern struct fa *cgotofn();
40*7c478bd9Sstevel@tonic-gate #define	MAXLIN 256
41*7c478bd9Sstevel@tonic-gate #define	NCHARS 128
42*7c478bd9Sstevel@tonic-gate #define	NSTATES 256
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate #define	type(v)	v->nobj
46*7c478bd9Sstevel@tonic-gate #define	left(v)	v->narg[0]
47*7c478bd9Sstevel@tonic-gate #define	right(v)	v->narg[1]
48*7c478bd9Sstevel@tonic-gate #define	parent(v)	v->nnext
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #define	LEAF	case CCL: case NCCL: case CHAR: case DOT:
52*7c478bd9Sstevel@tonic-gate #define	UNARY	case FINAL: case STAR: case PLUS: case QUEST:
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate /*
56*7c478bd9Sstevel@tonic-gate  * encoding in tree NODEs:
57*7c478bd9Sstevel@tonic-gate  * leaf (CCL, NCCL, CHAR, DOT): left is index,
58*7c478bd9Sstevel@tonic-gate  * right contains value or pointer to value
59*7c478bd9Sstevel@tonic-gate  * unary (FINAL, STAR, PLUS, QUEST): left is child, right is null
60*7c478bd9Sstevel@tonic-gate  * binary (CAT, OR): left and right are children
61*7c478bd9Sstevel@tonic-gate  * parent contains pointer to parent
62*7c478bd9Sstevel@tonic-gate  */
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate struct fa {
66*7c478bd9Sstevel@tonic-gate union {
67*7c478bd9Sstevel@tonic-gate 		ccl_chars_t s;
68*7c478bd9Sstevel@tonic-gate 		int h;
69*7c478bd9Sstevel@tonic-gate 	} cc;
70*7c478bd9Sstevel@tonic-gate #define	MLCMPLT(m1, l1, m2, l2) ((m1 != m2 &&\
71*7c478bd9Sstevel@tonic-gate 				(int)m1 < (int)m2) ||\
72*7c478bd9Sstevel@tonic-gate 				(m1 == m2 && (int)l1 < (int)l2))
73*7c478bd9Sstevel@tonic-gate #define	MLCMPLE(m1, l1, m2, l2) ((m1 != m2 &&\
74*7c478bd9Sstevel@tonic-gate 				(int)m1 <= (int)m2) ||\
75*7c478bd9Sstevel@tonic-gate 				(m1 == m2 && (int)l1 <= (int)l2))
76*7c478bd9Sstevel@tonic-gate #define	MLCMPGT(m1, l1, m2, l2) ((m1 != m2 &&\
77*7c478bd9Sstevel@tonic-gate 				(int)m1 > (int)m2) ||\
78*7c478bd9Sstevel@tonic-gate 				(m1 == m2 && (int)l1 > (int)l2))
79*7c478bd9Sstevel@tonic-gate #define	MAX_CODESET	3
80*7c478bd9Sstevel@tonic-gate 	struct fa *st;
81*7c478bd9Sstevel@tonic-gate };
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate int	*state[NSTATES];
85*7c478bd9Sstevel@tonic-gate int	*foll[MAXLIN];
86*7c478bd9Sstevel@tonic-gate int	setvec[MAXLIN];
87*7c478bd9Sstevel@tonic-gate NODE	*point[MAXLIN];
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate int	setcnt;
91*7c478bd9Sstevel@tonic-gate int	line;
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate static int	ccln_member();
95*7c478bd9Sstevel@tonic-gate static int	insert_table();
96*7c478bd9Sstevel@tonic-gate static int	delete_table();
97*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
98*7c478bd9Sstevel@tonic-gate #define	ddump_table(t, s)	dump_table(t, s)
99*7c478bd9Sstevel@tonic-gate #else
100*7c478bd9Sstevel@tonic-gate #define	ddump_table(t, s)
101*7c478bd9Sstevel@tonic-gate #endif
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate struct fa *
105*7c478bd9Sstevel@tonic-gate makedfa(p)	/* returns dfa for tree pointed to by p */
106*7c478bd9Sstevel@tonic-gate NODE *p;
107*7c478bd9Sstevel@tonic-gate {
108*7c478bd9Sstevel@tonic-gate 	NODE *p1;
109*7c478bd9Sstevel@tonic-gate 	struct fa *fap;
110*7c478bd9Sstevel@tonic-gate 	p1 = op2(CAT, op2(STAR, op2(DOT, (NODE *) 0,
111*7c478bd9Sstevel@tonic-gate 		(NODE *) 0), (NODE *) 0), p);
112*7c478bd9Sstevel@tonic-gate 		/* put DOT STAR in front of reg. exp. */
113*7c478bd9Sstevel@tonic-gate 	p1 = op2(FINAL, p1, (NODE *) 0);	/* install FINAL NODE */
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 	line = 0;
117*7c478bd9Sstevel@tonic-gate 	penter(p1);	/* enter parent pointers and leaf indices */
118*7c478bd9Sstevel@tonic-gate 	point[line] = p1;	/* FINAL NODE */
119*7c478bd9Sstevel@tonic-gate 	setvec[0] = 1;		/* for initial DOT STAR */
120*7c478bd9Sstevel@tonic-gate 	cfoll(p1);	/* set up follow sets */
121*7c478bd9Sstevel@tonic-gate 	fap = cgotofn();
122*7c478bd9Sstevel@tonic-gate 	freetr(p1);	/* add this when alloc works */
123*7c478bd9Sstevel@tonic-gate 	return (fap);
124*7c478bd9Sstevel@tonic-gate }
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate penter(p)	/* set up parent pointers and leaf indices */
128*7c478bd9Sstevel@tonic-gate NODE *p;
129*7c478bd9Sstevel@tonic-gate {
130*7c478bd9Sstevel@tonic-gate 	switch (type(p)) {
131*7c478bd9Sstevel@tonic-gate 		LEAF
132*7c478bd9Sstevel@tonic-gate 			left(p) = (NODE *)line;
133*7c478bd9Sstevel@tonic-gate 			point[line++] = p;
134*7c478bd9Sstevel@tonic-gate 			break;
135*7c478bd9Sstevel@tonic-gate 		UNARY
136*7c478bd9Sstevel@tonic-gate 			penter(left(p));
137*7c478bd9Sstevel@tonic-gate 			parent(left(p)) = p;
138*7c478bd9Sstevel@tonic-gate 			break;
139*7c478bd9Sstevel@tonic-gate 		case CAT:
140*7c478bd9Sstevel@tonic-gate 		case OR:
141*7c478bd9Sstevel@tonic-gate 			penter(left(p));
142*7c478bd9Sstevel@tonic-gate 			penter(right(p));
143*7c478bd9Sstevel@tonic-gate 			parent(left(p)) = p;
144*7c478bd9Sstevel@tonic-gate 			parent(right(p)) = p;
145*7c478bd9Sstevel@tonic-gate 			break;
146*7c478bd9Sstevel@tonic-gate 		default:
147*7c478bd9Sstevel@tonic-gate 			error(FATAL, "unknown type %d in penter\n", type(p));
148*7c478bd9Sstevel@tonic-gate 			break;
149*7c478bd9Sstevel@tonic-gate 	}
150*7c478bd9Sstevel@tonic-gate }
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate freetr(p)	/* free parse tree and follow sets */
154*7c478bd9Sstevel@tonic-gate NODE *p;
155*7c478bd9Sstevel@tonic-gate {
156*7c478bd9Sstevel@tonic-gate 	switch (type(p)) {
157*7c478bd9Sstevel@tonic-gate 		LEAF
158*7c478bd9Sstevel@tonic-gate 			xfree(foll[(int)left(p)]);
159*7c478bd9Sstevel@tonic-gate 			xfree(p);
160*7c478bd9Sstevel@tonic-gate 			break;
161*7c478bd9Sstevel@tonic-gate 		UNARY
162*7c478bd9Sstevel@tonic-gate 			freetr(left(p));
163*7c478bd9Sstevel@tonic-gate 			xfree(p);
164*7c478bd9Sstevel@tonic-gate 			break;
165*7c478bd9Sstevel@tonic-gate 		case CAT:
166*7c478bd9Sstevel@tonic-gate 		case OR:
167*7c478bd9Sstevel@tonic-gate 			freetr(left(p));
168*7c478bd9Sstevel@tonic-gate 			freetr(right(p));
169*7c478bd9Sstevel@tonic-gate 			xfree(p);
170*7c478bd9Sstevel@tonic-gate 			break;
171*7c478bd9Sstevel@tonic-gate 		default:
172*7c478bd9Sstevel@tonic-gate 			error(FATAL, "unknown type %d in freetr", type(p));
173*7c478bd9Sstevel@tonic-gate 			break;
174*7c478bd9Sstevel@tonic-gate 	}
175*7c478bd9Sstevel@tonic-gate }
176*7c478bd9Sstevel@tonic-gate ccl_chars_t *
177*7c478bd9Sstevel@tonic-gate cclenter(p)
178*7c478bd9Sstevel@tonic-gate register wchar_t *p;
179*7c478bd9Sstevel@tonic-gate {
180*7c478bd9Sstevel@tonic-gate 	register int		i, cn;
181*7c478bd9Sstevel@tonic-gate 	register wchar_t	c, pc;
182*7c478bd9Sstevel@tonic-gate 	register wchar_t	*op;
183*7c478bd9Sstevel@tonic-gate 	register ccl_chars_t	*new;
184*7c478bd9Sstevel@tonic-gate 	ccl_chars_t		chars[MAXLIN];
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 	op = p;
188*7c478bd9Sstevel@tonic-gate 	i = 0;
189*7c478bd9Sstevel@tonic-gate 	while ((c = *p++) != 0) {
190*7c478bd9Sstevel@tonic-gate 		if (c == '-' && i > 0)  {
191*7c478bd9Sstevel@tonic-gate 			if (*p != 0) {
192*7c478bd9Sstevel@tonic-gate 				/*
193*7c478bd9Sstevel@tonic-gate 				 * If there are not in same code set,  the
194*7c478bd9Sstevel@tonic-gate 				 * class should be ignore (make two independent
195*7c478bd9Sstevel@tonic-gate 				 * characters)!
196*7c478bd9Sstevel@tonic-gate 				 */
197*7c478bd9Sstevel@tonic-gate 				c = *p++;
198*7c478bd9Sstevel@tonic-gate 				cn = wcsetno(pc);
199*7c478bd9Sstevel@tonic-gate 				if (cn != wcsetno(c) || pc > c)
200*7c478bd9Sstevel@tonic-gate 					goto char_array;
201*7c478bd9Sstevel@tonic-gate 				i = insert_table(chars, i, cn, pc, cn, c);
202*7c478bd9Sstevel@tonic-gate 				continue;
203*7c478bd9Sstevel@tonic-gate 			}
204*7c478bd9Sstevel@tonic-gate 		}
205*7c478bd9Sstevel@tonic-gate char_array:
206*7c478bd9Sstevel@tonic-gate 		if (i >= MAXLIN)
207*7c478bd9Sstevel@tonic-gate 			overflo();
208*7c478bd9Sstevel@tonic-gate 		cn = wcsetno(c);
209*7c478bd9Sstevel@tonic-gate 		i = insert_table(chars, i, cn, c, cn, c);
210*7c478bd9Sstevel@tonic-gate 		pc = c;
211*7c478bd9Sstevel@tonic-gate 	}
212*7c478bd9Sstevel@tonic-gate 	dprintf("cclenter: in = |%ws|, ", op, NULL, NULL);
213*7c478bd9Sstevel@tonic-gate 	xfree(op);
214*7c478bd9Sstevel@tonic-gate 	i = (i + 1) * sizeof (ccl_chars_t);
215*7c478bd9Sstevel@tonic-gate 	if ((new = (ccl_chars_t *)malloc(i)) == NULL)
216*7c478bd9Sstevel@tonic-gate 		error(FATAL, "out of space in cclenter on %s", op);
217*7c478bd9Sstevel@tonic-gate 	(void) memcpy((char *)new, (char *)chars, i);
218*7c478bd9Sstevel@tonic-gate 	ddump_table(chars, i / 4);
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate 	return (new);
222*7c478bd9Sstevel@tonic-gate }
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate overflo()
226*7c478bd9Sstevel@tonic-gate {
227*7c478bd9Sstevel@tonic-gate 	error(FATAL, "regular expression too long\n");
228*7c478bd9Sstevel@tonic-gate }
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate 
231*7c478bd9Sstevel@tonic-gate cfoll(v)	/* enter follow set of each leaf of vertex v into foll[leaf] */
232*7c478bd9Sstevel@tonic-gate register NODE *v;
233*7c478bd9Sstevel@tonic-gate {
234*7c478bd9Sstevel@tonic-gate 	register i;
235*7c478bd9Sstevel@tonic-gate 	int prev;
236*7c478bd9Sstevel@tonic-gate 	int *add();
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate 	switch (type(v)) {
240*7c478bd9Sstevel@tonic-gate 		LEAF
241*7c478bd9Sstevel@tonic-gate 			setcnt = 0;
242*7c478bd9Sstevel@tonic-gate 			for (i = 1; i <= line; i++)
243*7c478bd9Sstevel@tonic-gate 				setvec[i] = 0;
244*7c478bd9Sstevel@tonic-gate 			follow(v);
245*7c478bd9Sstevel@tonic-gate 			foll[(int)left(v)] = add(setcnt);
246*7c478bd9Sstevel@tonic-gate 			break;
247*7c478bd9Sstevel@tonic-gate 		UNARY
248*7c478bd9Sstevel@tonic-gate 			cfoll(left(v));
249*7c478bd9Sstevel@tonic-gate 			break;
250*7c478bd9Sstevel@tonic-gate 		case CAT:
251*7c478bd9Sstevel@tonic-gate 		case OR:
252*7c478bd9Sstevel@tonic-gate 			cfoll(left(v));
253*7c478bd9Sstevel@tonic-gate 			cfoll(right(v));
254*7c478bd9Sstevel@tonic-gate 			break;
255*7c478bd9Sstevel@tonic-gate 		default:
256*7c478bd9Sstevel@tonic-gate 			error(FATAL, "unknown type %d in cfoll", type(v));
257*7c478bd9Sstevel@tonic-gate 	}
258*7c478bd9Sstevel@tonic-gate }
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate first(p)		/* collects initially active leaves of p into setvec */
262*7c478bd9Sstevel@tonic-gate register NODE *p;
263*7c478bd9Sstevel@tonic-gate 	/* returns 0 or 1 depending on whether p matches empty string */
264*7c478bd9Sstevel@tonic-gate {
265*7c478bd9Sstevel@tonic-gate 	register b;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 	switch (type(p)) {
269*7c478bd9Sstevel@tonic-gate 		LEAF
270*7c478bd9Sstevel@tonic-gate 			if (setvec[(int)left(p)] != 1) {
271*7c478bd9Sstevel@tonic-gate 				setvec[(int)left(p)] = 1;
272*7c478bd9Sstevel@tonic-gate 				setcnt++;
273*7c478bd9Sstevel@tonic-gate 			}
274*7c478bd9Sstevel@tonic-gate 			if (type(p) == CCL &&
275*7c478bd9Sstevel@tonic-gate 			(*(ccl_chars_t *)right(p)).cc_cs == (wchar_t)0x0)
276*7c478bd9Sstevel@tonic-gate 				return (0);		/* empty CCL */
277*7c478bd9Sstevel@tonic-gate 			else return (1);
278*7c478bd9Sstevel@tonic-gate 		case FINAL:
279*7c478bd9Sstevel@tonic-gate 		case PLUS:
280*7c478bd9Sstevel@tonic-gate 			if (first(left(p)) == 0)
281*7c478bd9Sstevel@tonic-gate 				return (0);
282*7c478bd9Sstevel@tonic-gate 			return (1);
283*7c478bd9Sstevel@tonic-gate 		case STAR:
284*7c478bd9Sstevel@tonic-gate 		case QUEST:
285*7c478bd9Sstevel@tonic-gate 			first(left(p));
286*7c478bd9Sstevel@tonic-gate 			return (0);
287*7c478bd9Sstevel@tonic-gate 		case CAT:
288*7c478bd9Sstevel@tonic-gate 			if (first(left(p)) == 0 && first(right(p)) == 0)
289*7c478bd9Sstevel@tonic-gate 				return (0);
290*7c478bd9Sstevel@tonic-gate 			return (1);
291*7c478bd9Sstevel@tonic-gate 		case OR:
292*7c478bd9Sstevel@tonic-gate 			b = first(right(p));
293*7c478bd9Sstevel@tonic-gate 			if (first(left(p)) == 0 || b == 0)
294*7c478bd9Sstevel@tonic-gate 				return (0);
295*7c478bd9Sstevel@tonic-gate 			return (1);
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 	error(FATAL, "unknown type %d in first\n", type(p));
298*7c478bd9Sstevel@tonic-gate 	return (-1);
299*7c478bd9Sstevel@tonic-gate }
300*7c478bd9Sstevel@tonic-gate 
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate follow(v)
303*7c478bd9Sstevel@tonic-gate NODE *v;		/* collects leaves that can follow v into setvec */
304*7c478bd9Sstevel@tonic-gate {
305*7c478bd9Sstevel@tonic-gate 	NODE *p;
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate 	if (type(v) == FINAL)
309*7c478bd9Sstevel@tonic-gate 		return;
310*7c478bd9Sstevel@tonic-gate 	p = parent(v);
311*7c478bd9Sstevel@tonic-gate 	switch (type(p)) {
312*7c478bd9Sstevel@tonic-gate 		case STAR:
313*7c478bd9Sstevel@tonic-gate 		case PLUS:	first(v);
314*7c478bd9Sstevel@tonic-gate 				follow(p);
315*7c478bd9Sstevel@tonic-gate 				return;
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 		case OR:
319*7c478bd9Sstevel@tonic-gate 		case QUEST:	follow(p);
320*7c478bd9Sstevel@tonic-gate 				return;
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 		case CAT:	if (v == left(p)) { /* v is left child of p */
324*7c478bd9Sstevel@tonic-gate 					if (first(right(p)) == 0) {
325*7c478bd9Sstevel@tonic-gate 						follow(p);
326*7c478bd9Sstevel@tonic-gate 						return;
327*7c478bd9Sstevel@tonic-gate 					}
328*7c478bd9Sstevel@tonic-gate 				} else		/* v is right child */
329*7c478bd9Sstevel@tonic-gate 					follow(p);
330*7c478bd9Sstevel@tonic-gate 				return;
331*7c478bd9Sstevel@tonic-gate 		case FINAL:	if (setvec[line] != 1) {
332*7c478bd9Sstevel@tonic-gate 					setvec[line] = 1;
333*7c478bd9Sstevel@tonic-gate 					setcnt++;
334*7c478bd9Sstevel@tonic-gate 				}
335*7c478bd9Sstevel@tonic-gate 				return;
336*7c478bd9Sstevel@tonic-gate 	}
337*7c478bd9Sstevel@tonic-gate }
338*7c478bd9Sstevel@tonic-gate 
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate /*
341*7c478bd9Sstevel@tonic-gate  * There are three type of functions for checking member ship.  Because I have
342*7c478bd9Sstevel@tonic-gate  * been changed structure of CCL tables.  And some CCL tables end up with NULLs
343*7c478bd9Sstevel@tonic-gate  * but someone has length and will includes NULLs in table as one of data.
344*7c478bd9Sstevel@tonic-gate  * Please note, CCL table which has a length data and data will include NULLs,
345*7c478bd9Sstevel@tonic-gate  * it only used within a this source file("b.c").
346*7c478bd9Sstevel@tonic-gate  */
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate ccl_member(ns, cs, ne, ce, s)	/* is cs thru ce in s? */
350*7c478bd9Sstevel@tonic-gate register int		ns;
351*7c478bd9Sstevel@tonic-gate register wchar_t	cs;
352*7c478bd9Sstevel@tonic-gate register int		ne;
353*7c478bd9Sstevel@tonic-gate register wchar_t	ce;
354*7c478bd9Sstevel@tonic-gate register ccl_chars_t	*s;
355*7c478bd9Sstevel@tonic-gate {
356*7c478bd9Sstevel@tonic-gate 	/*
357*7c478bd9Sstevel@tonic-gate 	 * The specified range(cs, ce) must be beside the range between
358*7c478bd9Sstevel@tonic-gate 	 * s->cc_start and s->cc_end to determine member.
359*7c478bd9Sstevel@tonic-gate 	 */
360*7c478bd9Sstevel@tonic-gate 	while (s->cc_cs || s->cc_ce) {
361*7c478bd9Sstevel@tonic-gate 		if (MLCMPLE(s->cc_ns, s->cc_cs, ns, cs) &&
362*7c478bd9Sstevel@tonic-gate 				MLCMPLE(ne, ce, s->cc_ne, s->cc_ce))
363*7c478bd9Sstevel@tonic-gate 			return (1);
364*7c478bd9Sstevel@tonic-gate 		s++;
365*7c478bd9Sstevel@tonic-gate 	}
366*7c478bd9Sstevel@tonic-gate 	return (0);
367*7c478bd9Sstevel@tonic-gate }
368*7c478bd9Sstevel@tonic-gate 
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate static
371*7c478bd9Sstevel@tonic-gate ccln_member(ns, cs, ne, ce, s, n)	/* is cs thru ce in s? */
372*7c478bd9Sstevel@tonic-gate register int ns;
373*7c478bd9Sstevel@tonic-gate register wchar_t cs;
374*7c478bd9Sstevel@tonic-gate register int ne;
375*7c478bd9Sstevel@tonic-gate register wchar_t ce;
376*7c478bd9Sstevel@tonic-gate register ccl_chars_t *s;
377*7c478bd9Sstevel@tonic-gate register int n;
378*7c478bd9Sstevel@tonic-gate {
379*7c478bd9Sstevel@tonic-gate 	/*
380*7c478bd9Sstevel@tonic-gate 	 * The specified range(cs, ce) must be beside the range between
381*7c478bd9Sstevel@tonic-gate 	 * s->cc_start and s->cc_end to determine member.
382*7c478bd9Sstevel@tonic-gate 	 */
383*7c478bd9Sstevel@tonic-gate 	while (n-- > 0) {
384*7c478bd9Sstevel@tonic-gate 		if (MLCMPLE(s->cc_ns, s->cc_cs, ns, cs) &&
385*7c478bd9Sstevel@tonic-gate 				MLCMPLE(ne, ce, s->cc_ne, s->cc_ce))
386*7c478bd9Sstevel@tonic-gate 			return (1);
387*7c478bd9Sstevel@tonic-gate 		s++;
388*7c478bd9Sstevel@tonic-gate 	}
389*7c478bd9Sstevel@tonic-gate 	return (0);
390*7c478bd9Sstevel@tonic-gate }
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate member(c, s)	/* is c in s? */
394*7c478bd9Sstevel@tonic-gate register wchar_t c, *s;
395*7c478bd9Sstevel@tonic-gate {
396*7c478bd9Sstevel@tonic-gate 	while (*s)
397*7c478bd9Sstevel@tonic-gate 		if (c == *s++)
398*7c478bd9Sstevel@tonic-gate 			return (1);
399*7c478bd9Sstevel@tonic-gate 	return (0);
400*7c478bd9Sstevel@tonic-gate }
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 
403*7c478bd9Sstevel@tonic-gate notin(array, n, prev)		/* is setvec in array[0] thru array[n]? */
404*7c478bd9Sstevel@tonic-gate int **array;
405*7c478bd9Sstevel@tonic-gate int *prev; {
406*7c478bd9Sstevel@tonic-gate 	register i, j;
407*7c478bd9Sstevel@tonic-gate 	int *ptr;
408*7c478bd9Sstevel@tonic-gate 	for (i = 0; i <= n; i++) {
409*7c478bd9Sstevel@tonic-gate 		ptr = array[i];
410*7c478bd9Sstevel@tonic-gate 		if (*ptr == setcnt) {
411*7c478bd9Sstevel@tonic-gate 			for (j = 0; j < setcnt; j++)
412*7c478bd9Sstevel@tonic-gate 				if (setvec[*(++ptr)] != 1) goto nxt;
413*7c478bd9Sstevel@tonic-gate 			*prev = i;
414*7c478bd9Sstevel@tonic-gate 			return (0);
415*7c478bd9Sstevel@tonic-gate 		}
416*7c478bd9Sstevel@tonic-gate 		nxt: /* dummy */;
417*7c478bd9Sstevel@tonic-gate 	}
418*7c478bd9Sstevel@tonic-gate 	return (1);
419*7c478bd9Sstevel@tonic-gate }
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate int *add(n) {		/* remember setvec */
423*7c478bd9Sstevel@tonic-gate 	int *ptr, *p;
424*7c478bd9Sstevel@tonic-gate 	register i;
425*7c478bd9Sstevel@tonic-gate 	if ((p = ptr = (int *)malloc((n+1)*sizeof (int))) == NULL)
426*7c478bd9Sstevel@tonic-gate 		overflo();
427*7c478bd9Sstevel@tonic-gate 	*ptr = n;
428*7c478bd9Sstevel@tonic-gate 	dprintf("add(%d)\n", n, NULL, NULL);
429*7c478bd9Sstevel@tonic-gate 	for (i = 1; i <= line; i++)
430*7c478bd9Sstevel@tonic-gate 		if (setvec[i] == 1) {
431*7c478bd9Sstevel@tonic-gate 			*(++ptr) = i;
432*7c478bd9Sstevel@tonic-gate 		dprintf("  ptr = %o, *ptr = %d, i = %d\n", ptr, *ptr, i);
433*7c478bd9Sstevel@tonic-gate 		}
434*7c478bd9Sstevel@tonic-gate 	dprintf("\n", NULL, NULL, NULL);
435*7c478bd9Sstevel@tonic-gate 	return (p);
436*7c478bd9Sstevel@tonic-gate }
437*7c478bd9Sstevel@tonic-gate 
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate struct fa *
440*7c478bd9Sstevel@tonic-gate cgotofn()
441*7c478bd9Sstevel@tonic-gate {
442*7c478bd9Sstevel@tonic-gate 	register i, k;
443*7c478bd9Sstevel@tonic-gate 	register int *ptr;
444*7c478bd9Sstevel@tonic-gate 	register int ns, ne;
445*7c478bd9Sstevel@tonic-gate 	register wchar_t cs, ce;
446*7c478bd9Sstevel@tonic-gate 	register ccl_chars_t *p;
447*7c478bd9Sstevel@tonic-gate 	register NODE *cp;
448*7c478bd9Sstevel@tonic-gate 	int j, n, s, ind, numtrans;
449*7c478bd9Sstevel@tonic-gate 	int finflg;
450*7c478bd9Sstevel@tonic-gate 	int curpos, num, prev;
451*7c478bd9Sstevel@tonic-gate 	struct fa *where[NSTATES];
452*7c478bd9Sstevel@tonic-gate 
453*7c478bd9Sstevel@tonic-gate 
454*7c478bd9Sstevel@tonic-gate 	struct {
455*7c478bd9Sstevel@tonic-gate 		ccl_chars_t	cc;
456*7c478bd9Sstevel@tonic-gate 		int		n;
457*7c478bd9Sstevel@tonic-gate 	} fatab[257];
458*7c478bd9Sstevel@tonic-gate 	register struct fa *pfa;
459*7c478bd9Sstevel@tonic-gate 
460*7c478bd9Sstevel@tonic-gate 
461*7c478bd9Sstevel@tonic-gate 	char index[MAXLIN];
462*7c478bd9Sstevel@tonic-gate 	char iposns[MAXLIN];
463*7c478bd9Sstevel@tonic-gate 	int sposns[MAXLIN];
464*7c478bd9Sstevel@tonic-gate 	int spmax, spinit;
465*7c478bd9Sstevel@tonic-gate 	ccl_chars_t symbol[NCHARS];
466*7c478bd9Sstevel@tonic-gate 	ccl_chars_t isyms[NCHARS];
467*7c478bd9Sstevel@tonic-gate 	ccl_chars_t ssyms[NCHARS];
468*7c478bd9Sstevel@tonic-gate 	int ssmax, symax, ismax, ssinit;
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate 
471*7c478bd9Sstevel@tonic-gate 	wchar_t hat;
472*7c478bd9Sstevel@tonic-gate 	int hatcn;
473*7c478bd9Sstevel@tonic-gate 
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate 	for (i = 0; i <= line; i++) index[i] = iposns[i] = setvec[i] = 0;
476*7c478bd9Sstevel@tonic-gate 	isyms[0].cc_cs = isyms[0].cc_ce = (wchar_t)0x0;
477*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NCHARS; i++)
478*7c478bd9Sstevel@tonic-gate 		isyms[i] = symbol[i] = ssyms[i] = isyms[0];
479*7c478bd9Sstevel@tonic-gate 	symax = 0;
480*7c478bd9Sstevel@tonic-gate 	setcnt = 0;
481*7c478bd9Sstevel@tonic-gate 	/* compute initial positions and symbols of state 0 */
482*7c478bd9Sstevel@tonic-gate 	ismax = 0;
483*7c478bd9Sstevel@tonic-gate 	ssmax = 0;
484*7c478bd9Sstevel@tonic-gate 	ptr = state[0] = foll[0];
485*7c478bd9Sstevel@tonic-gate 	spinit = *ptr;
486*7c478bd9Sstevel@tonic-gate 	hat = HAT;
487*7c478bd9Sstevel@tonic-gate 	hatcn = wcsetno(hat);
488*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < spinit; i++) {
489*7c478bd9Sstevel@tonic-gate 		curpos = *(++ptr);
490*7c478bd9Sstevel@tonic-gate 		sposns[i] = curpos;
491*7c478bd9Sstevel@tonic-gate 		iposns[curpos] = 1;
492*7c478bd9Sstevel@tonic-gate 		cp = point[curpos];
493*7c478bd9Sstevel@tonic-gate 		dprintf("i= %d, spinit = %d, curpos = %d\n", i, spinit, curpos);
494*7c478bd9Sstevel@tonic-gate 		switch (type(cp)) {
495*7c478bd9Sstevel@tonic-gate 			case CHAR:
496*7c478bd9Sstevel@tonic-gate 				k = (int)right(cp);
497*7c478bd9Sstevel@tonic-gate 				ns = wcsetno(k);
498*7c478bd9Sstevel@tonic-gate 				if (! ccln_member(ns, k, ns, k,
499*7c478bd9Sstevel@tonic-gate 							isyms, ismax)) {
500*7c478bd9Sstevel@tonic-gate 					ismax = insert_table(isyms, ismax,
501*7c478bd9Sstevel@tonic-gate 								ns, k, ns, k);
502*7c478bd9Sstevel@tonic-gate 				}
503*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_ns = ns;
504*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_cs = k;
505*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_ne = ns;
506*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax++].cc_ce = k;
507*7c478bd9Sstevel@tonic-gate 				break;
508*7c478bd9Sstevel@tonic-gate 			case DOT:
509*7c478bd9Sstevel@tonic-gate 				cs = WC_VERY_SMALL;
510*7c478bd9Sstevel@tonic-gate 				ns = 0;
511*7c478bd9Sstevel@tonic-gate 				ce = HAT - 1;
512*7c478bd9Sstevel@tonic-gate 				ne = hatcn;
513*7c478bd9Sstevel@tonic-gate 				if (! ccln_member(ns, cs, ne, ce,
514*7c478bd9Sstevel@tonic-gate 							isyms, ismax)) {
515*7c478bd9Sstevel@tonic-gate 					ismax = insert_table(isyms, ismax,
516*7c478bd9Sstevel@tonic-gate 								ns, cs, ne, ce);
517*7c478bd9Sstevel@tonic-gate 				}
518*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_cs = cs;
519*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_ns = ns;
520*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_ce = ce;
521*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax++].cc_ne = ne;
522*7c478bd9Sstevel@tonic-gate 				cs = HAT + 1;
523*7c478bd9Sstevel@tonic-gate 				ns = hatcn;
524*7c478bd9Sstevel@tonic-gate 				ce = WC_VERY_LARGE;
525*7c478bd9Sstevel@tonic-gate 				ne = MAX_CODESET;
526*7c478bd9Sstevel@tonic-gate 				if (! ccln_member(ns, cs, ne, ce,
527*7c478bd9Sstevel@tonic-gate 							isyms, ismax)) {
528*7c478bd9Sstevel@tonic-gate 					ismax = insert_table(isyms, ismax,
529*7c478bd9Sstevel@tonic-gate 								ns, cs, ne, ce);
530*7c478bd9Sstevel@tonic-gate 				}
531*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_cs = cs;
532*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_ns = ns;
533*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_ce = ce;
534*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax++].cc_ne = ne;
535*7c478bd9Sstevel@tonic-gate 				break;
536*7c478bd9Sstevel@tonic-gate 			case CCL:
537*7c478bd9Sstevel@tonic-gate 				cs = HAT;
538*7c478bd9Sstevel@tonic-gate 				ns = hatcn;
539*7c478bd9Sstevel@tonic-gate 				for (p = (ccl_chars_t *)right(cp);
540*7c478bd9Sstevel@tonic-gate 					p->cc_cs; p++) {
541*7c478bd9Sstevel@tonic-gate 					if ((p->cc_ns != ns ||\
542*7c478bd9Sstevel@tonic-gate 					p->cc_cs != cs) &&\
543*7c478bd9Sstevel@tonic-gate 				!ccln_member(p->cc_ns, p->cc_cs,
544*7c478bd9Sstevel@tonic-gate 				p->cc_ne, p->cc_ce, isyms, ismax)) {
545*7c478bd9Sstevel@tonic-gate 						ismax = insert_table(isyms,
546*7c478bd9Sstevel@tonic-gate 				ismax, p->cc_ns, p->cc_cs, p->cc_ne, p->cc_ce);
547*7c478bd9Sstevel@tonic-gate 					}
548*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax++] = *p;
549*7c478bd9Sstevel@tonic-gate 				}
550*7c478bd9Sstevel@tonic-gate 				break;
551*7c478bd9Sstevel@tonic-gate 			case NCCL:
552*7c478bd9Sstevel@tonic-gate 				ns = 0;
553*7c478bd9Sstevel@tonic-gate 				cs = WC_VERY_SMALL;
554*7c478bd9Sstevel@tonic-gate 				for (p = (ccl_chars_t *)right(cp);
555*7c478bd9Sstevel@tonic-gate 					p->cc_cs; p++) {
556*7c478bd9Sstevel@tonic-gate 					if ((ns != hatcn || p->cc_cs != HAT) &&
557*7c478bd9Sstevel@tonic-gate 						! ccln_member(ns, cs,
558*7c478bd9Sstevel@tonic-gate 							p->cc_ns, p->cc_cs-1,
559*7c478bd9Sstevel@tonic-gate 								isyms, ismax)) {
560*7c478bd9Sstevel@tonic-gate 						ismax = insert_table(isyms,
561*7c478bd9Sstevel@tonic-gate 								ismax,
562*7c478bd9Sstevel@tonic-gate 								ns, cs,
563*7c478bd9Sstevel@tonic-gate 								p->cc_ns,
564*7c478bd9Sstevel@tonic-gate 								p->cc_cs-1);
565*7c478bd9Sstevel@tonic-gate 					}
566*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ns = ns;
567*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_cs = cs;
568*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ne = p->cc_ns;
569*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax++].cc_ce = p->cc_cs-1;
570*7c478bd9Sstevel@tonic-gate 					if (p->cc_ce == (wchar_t)0x0) {
571*7c478bd9Sstevel@tonic-gate 						ns = p->cc_ns;
572*7c478bd9Sstevel@tonic-gate 						cs = p->cc_cs + 1;
573*7c478bd9Sstevel@tonic-gate 
574*7c478bd9Sstevel@tonic-gate 					} else {
575*7c478bd9Sstevel@tonic-gate 						ns = p->cc_ne;
576*7c478bd9Sstevel@tonic-gate 						cs = p->cc_ce + 1;
577*7c478bd9Sstevel@tonic-gate 					}
578*7c478bd9Sstevel@tonic-gate 				}
579*7c478bd9Sstevel@tonic-gate 				if ((ns != hatcn || cs != HAT) &&
580*7c478bd9Sstevel@tonic-gate 					! ccln_member(ns, cs,
581*7c478bd9Sstevel@tonic-gate 						MAX_CODESET, WC_VERY_LARGE,
582*7c478bd9Sstevel@tonic-gate 							isyms, ismax)) {
583*7c478bd9Sstevel@tonic-gate 					ismax = insert_table(isyms, ismax,
584*7c478bd9Sstevel@tonic-gate 							ns, cs, MAX_CODESET,
585*7c478bd9Sstevel@tonic-gate 							WC_VERY_LARGE);
586*7c478bd9Sstevel@tonic-gate 				}
587*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_ns = ns;
588*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_cs = cs;
589*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax].cc_ne = MAX_CODESET;
590*7c478bd9Sstevel@tonic-gate 				ssyms[ssmax++].cc_ce = WC_VERY_LARGE;
591*7c478bd9Sstevel@tonic-gate 				break;
592*7c478bd9Sstevel@tonic-gate 		}
593*7c478bd9Sstevel@tonic-gate 	}
594*7c478bd9Sstevel@tonic-gate 	ssinit = ssmax;
595*7c478bd9Sstevel@tonic-gate 	symax = 0;
596*7c478bd9Sstevel@tonic-gate 	n = 0;
597*7c478bd9Sstevel@tonic-gate 	for (s = 0; s <= n; s++)  {
598*7c478bd9Sstevel@tonic-gate 		dprintf("s = %d\n", s, NULL, NULL);
599*7c478bd9Sstevel@tonic-gate 		ind = 0;
600*7c478bd9Sstevel@tonic-gate 		numtrans = 0;
601*7c478bd9Sstevel@tonic-gate 		finflg = 0;
602*7c478bd9Sstevel@tonic-gate 		if (*(state[s] + *state[s]) == line) {		/* s final? */
603*7c478bd9Sstevel@tonic-gate 			finflg = 1;
604*7c478bd9Sstevel@tonic-gate 			goto tenter;
605*7c478bd9Sstevel@tonic-gate 		}
606*7c478bd9Sstevel@tonic-gate 		spmax = spinit;
607*7c478bd9Sstevel@tonic-gate 		ssmax = ssinit;
608*7c478bd9Sstevel@tonic-gate 		ptr = state[s];
609*7c478bd9Sstevel@tonic-gate 		num = *ptr;
610*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < num; i++) {
611*7c478bd9Sstevel@tonic-gate 			curpos = *(++ptr);
612*7c478bd9Sstevel@tonic-gate 			if (iposns[curpos] != 1 && index[curpos] != 1) {
613*7c478bd9Sstevel@tonic-gate 				index[curpos] = 1;
614*7c478bd9Sstevel@tonic-gate 				sposns[spmax++] = curpos;
615*7c478bd9Sstevel@tonic-gate 			}
616*7c478bd9Sstevel@tonic-gate 			cp = point[curpos];
617*7c478bd9Sstevel@tonic-gate 			switch (type(cp)) {
618*7c478bd9Sstevel@tonic-gate 				case CHAR:
619*7c478bd9Sstevel@tonic-gate 					k = (int)right(cp);
620*7c478bd9Sstevel@tonic-gate 					ns = wcsetno(k);
621*7c478bd9Sstevel@tonic-gate 					if (! ccln_member(ns, k, ns, k,
622*7c478bd9Sstevel@tonic-gate 							isyms, ismax) &&
623*7c478bd9Sstevel@tonic-gate 						! ccln_member(ns, k, ns, k,
624*7c478bd9Sstevel@tonic-gate 							symbol, symax)) {
625*7c478bd9Sstevel@tonic-gate 						symax = insert_table(symbol,
626*7c478bd9Sstevel@tonic-gate 									symax,
627*7c478bd9Sstevel@tonic-gate 									ns, k,
628*7c478bd9Sstevel@tonic-gate 									ns, k);
629*7c478bd9Sstevel@tonic-gate 					}
630*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ns = ns;
631*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_cs = k;
632*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ne = ns;
633*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax++].cc_ce = k;
634*7c478bd9Sstevel@tonic-gate 					break;
635*7c478bd9Sstevel@tonic-gate 				case DOT:
636*7c478bd9Sstevel@tonic-gate 					cs = WC_VERY_SMALL;
637*7c478bd9Sstevel@tonic-gate 					ns = 0;
638*7c478bd9Sstevel@tonic-gate 					ce = HAT - 1;
639*7c478bd9Sstevel@tonic-gate 					ne = hatcn;
640*7c478bd9Sstevel@tonic-gate 					if (! ccln_member(ns, cs, ne, ce,
641*7c478bd9Sstevel@tonic-gate 							isyms, ismax) &&
642*7c478bd9Sstevel@tonic-gate 						! ccln_member(ns, cs, ne, ce,
643*7c478bd9Sstevel@tonic-gate 							symbol, symax)) {
644*7c478bd9Sstevel@tonic-gate 						symax = insert_table(symbol,
645*7c478bd9Sstevel@tonic-gate 									symax,
646*7c478bd9Sstevel@tonic-gate 									ns, cs,
647*7c478bd9Sstevel@tonic-gate 									ne, ce);
648*7c478bd9Sstevel@tonic-gate 					}
649*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_cs = cs;
650*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ns = ns;
651*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ce = ce;
652*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax++].cc_ne = ne;
653*7c478bd9Sstevel@tonic-gate 					cs = HAT + 1;
654*7c478bd9Sstevel@tonic-gate 					ns = hatcn;
655*7c478bd9Sstevel@tonic-gate 					ce = WC_VERY_LARGE;
656*7c478bd9Sstevel@tonic-gate 					ne = MAX_CODESET;
657*7c478bd9Sstevel@tonic-gate 					if (! ccln_member(ns, cs, ne, ce,
658*7c478bd9Sstevel@tonic-gate 								isyms, ismax) &&
659*7c478bd9Sstevel@tonic-gate 						! ccln_member(ns, cs, ne, ce,
660*7c478bd9Sstevel@tonic-gate 							symbol, symax)) {
661*7c478bd9Sstevel@tonic-gate 						symax = insert_table(symbol,
662*7c478bd9Sstevel@tonic-gate 									symax,
663*7c478bd9Sstevel@tonic-gate 									ns, cs,
664*7c478bd9Sstevel@tonic-gate 									ne, ce);
665*7c478bd9Sstevel@tonic-gate 					}
666*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_cs = cs;
667*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ns = ns;
668*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ce = ce;
669*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax++].cc_ne = ne;
670*7c478bd9Sstevel@tonic-gate 					break;
671*7c478bd9Sstevel@tonic-gate 				case CCL:
672*7c478bd9Sstevel@tonic-gate 					cs = HAT;
673*7c478bd9Sstevel@tonic-gate 					ns = hatcn;
674*7c478bd9Sstevel@tonic-gate 					for (p = (ccl_chars_t *)right(cp);
675*7c478bd9Sstevel@tonic-gate 						p->cc_cs; p++) {
676*7c478bd9Sstevel@tonic-gate 						if ((p->cc_ns != ns ||
677*7c478bd9Sstevel@tonic-gate 							p->cc_cs != cs) &&
678*7c478bd9Sstevel@tonic-gate 							! ccln_member(p->cc_ns,
679*7c478bd9Sstevel@tonic-gate 							p->cc_cs, p->cc_ne,
680*7c478bd9Sstevel@tonic-gate 						p->cc_ce, isyms, ismax) &&
681*7c478bd9Sstevel@tonic-gate 						!ccln_member(p->cc_ns, p->cc_cs,
682*7c478bd9Sstevel@tonic-gate 						p->cc_ne, p->cc_ce, symbol,
683*7c478bd9Sstevel@tonic-gate 						symax)) {
684*7c478bd9Sstevel@tonic-gate 							symax = insert_table(
685*7c478bd9Sstevel@tonic-gate 						symbol, symax, p->cc_ns,
686*7c478bd9Sstevel@tonic-gate 						p->cc_cs, p->cc_ne, p->cc_ce);
687*7c478bd9Sstevel@tonic-gate 						}
688*7c478bd9Sstevel@tonic-gate 						ssyms[ssmax++] = *p;
689*7c478bd9Sstevel@tonic-gate 					}
690*7c478bd9Sstevel@tonic-gate 					break;
691*7c478bd9Sstevel@tonic-gate 				case NCCL:
692*7c478bd9Sstevel@tonic-gate 					ns = 0;
693*7c478bd9Sstevel@tonic-gate 					cs = WC_VERY_SMALL;
694*7c478bd9Sstevel@tonic-gate 		for (p = (ccl_chars_t *)right(cp); p->cc_cs; p++) {
695*7c478bd9Sstevel@tonic-gate 			if ((p->cc_ns != hatcn || p->cc_cs != HAT) &&
696*7c478bd9Sstevel@tonic-gate 					! ccln_member(ns, cs, p->cc_ns,
697*7c478bd9Sstevel@tonic-gate 					p->cc_cs-1, isyms, ismax) &&
698*7c478bd9Sstevel@tonic-gate 					! ccln_member(ns, cs, p->cc_ns,
699*7c478bd9Sstevel@tonic-gate 					p->cc_cs-1, symbol, symax)) {
700*7c478bd9Sstevel@tonic-gate 				symax = insert_table(symbol,
701*7c478bd9Sstevel@tonic-gate 					symax, ns, cs, p->cc_ns, p->cc_cs-1);
702*7c478bd9Sstevel@tonic-gate 						}
703*7c478bd9Sstevel@tonic-gate 						ssyms[ssmax].cc_ns = ns;
704*7c478bd9Sstevel@tonic-gate 						ssyms[ssmax].cc_cs = cs;
705*7c478bd9Sstevel@tonic-gate 						ssyms[ssmax].cc_ne = p->cc_ns;
706*7c478bd9Sstevel@tonic-gate 						ssyms[ssmax++].cc_ce
707*7c478bd9Sstevel@tonic-gate 								= p->cc_cs-1;
708*7c478bd9Sstevel@tonic-gate 						if (p->cc_ce == (wchar_t)0x0) {
709*7c478bd9Sstevel@tonic-gate 							ns = p->cc_ns;
710*7c478bd9Sstevel@tonic-gate 							cs = p->cc_cs + 1;
711*7c478bd9Sstevel@tonic-gate 
712*7c478bd9Sstevel@tonic-gate 						} else {
713*7c478bd9Sstevel@tonic-gate 							ns = p->cc_ne;
714*7c478bd9Sstevel@tonic-gate 							cs = p->cc_ce + 1;
715*7c478bd9Sstevel@tonic-gate 						}
716*7c478bd9Sstevel@tonic-gate 					}
717*7c478bd9Sstevel@tonic-gate 		if ((ns != hatcn || cs != HAT) && ! ccln_member(ns, cs,
718*7c478bd9Sstevel@tonic-gate 				MAX_CODESET, WC_VERY_LARGE, isyms, ismax) &&
719*7c478bd9Sstevel@tonic-gate 				! ccln_member(ns, cs, MAX_CODESET,
720*7c478bd9Sstevel@tonic-gate 					WC_VERY_LARGE, symbol, symax)) {
721*7c478bd9Sstevel@tonic-gate 			symax = insert_table(symbol, symax, ns, cs,
722*7c478bd9Sstevel@tonic-gate 								MAX_CODESET,
723*7c478bd9Sstevel@tonic-gate 								WC_VERY_LARGE);
724*7c478bd9Sstevel@tonic-gate 					}
725*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ns = ns;
726*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_cs = cs;
727*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax].cc_ne = MAX_CODESET;
728*7c478bd9Sstevel@tonic-gate 					ssyms[ssmax++].cc_ce = WC_VERY_LARGE;
729*7c478bd9Sstevel@tonic-gate 					break;
730*7c478bd9Sstevel@tonic-gate 			}
731*7c478bd9Sstevel@tonic-gate 		}
732*7c478bd9Sstevel@tonic-gate 		for (j = 0; j < ssmax; j++) {	/* nextstate(s, ssyms[j]) */
733*7c478bd9Sstevel@tonic-gate 			ns = ssyms[j].cc_ns;
734*7c478bd9Sstevel@tonic-gate 			cs = ssyms[j].cc_cs;
735*7c478bd9Sstevel@tonic-gate 			ne = ssyms[j].cc_ne;
736*7c478bd9Sstevel@tonic-gate 			ce = ssyms[j].cc_ce;
737*7c478bd9Sstevel@tonic-gate dprintf("j = %d, cs = %o, ce = %o\n", j, cs, ce);
738*7c478bd9Sstevel@tonic-gate 			symax = delete_table(symbol, symax, ns, cs, ne, ce);
739*7c478bd9Sstevel@tonic-gate 			setcnt = 0;
740*7c478bd9Sstevel@tonic-gate 			for (k = 0; k <= line; k++) setvec[k] = 0;
741*7c478bd9Sstevel@tonic-gate 			for (i = 0; i < spmax; i++) {
742*7c478bd9Sstevel@tonic-gate 				index[sposns[i]] = 0;
743*7c478bd9Sstevel@tonic-gate 				cp = point[sposns[i]];
744*7c478bd9Sstevel@tonic-gate 				if ((k = type(cp)) != FINAL) {
745*7c478bd9Sstevel@tonic-gate 					if (k == CHAR && ns == ne && cs == ce &&
746*7c478bd9Sstevel@tonic-gate 						cs == (int)right(cp) ||
747*7c478bd9Sstevel@tonic-gate 						k == DOT || k == CCL &&
748*7c478bd9Sstevel@tonic-gate 						ccl_member(ns, cs, ne, ce,
749*7c478bd9Sstevel@tonic-gate 						(ccl_chars_t *)right(cp)) ||
750*7c478bd9Sstevel@tonic-gate 						k == NCCL &&
751*7c478bd9Sstevel@tonic-gate 						!ccl_member(ns, cs, ne, ce,
752*7c478bd9Sstevel@tonic-gate 						(ccl_chars_t *)right(cp))) {
753*7c478bd9Sstevel@tonic-gate 						ptr = foll[sposns[i]];
754*7c478bd9Sstevel@tonic-gate 						num = *ptr;
755*7c478bd9Sstevel@tonic-gate 						for (k = 0; k < num; k++) {
756*7c478bd9Sstevel@tonic-gate 						if (setvec[*(++ptr)] != 1 &&
757*7c478bd9Sstevel@tonic-gate 							iposns[*ptr] != 1) {
758*7c478bd9Sstevel@tonic-gate 							setvec[*ptr] = 1;
759*7c478bd9Sstevel@tonic-gate 								setcnt++;
760*7c478bd9Sstevel@tonic-gate 							}
761*7c478bd9Sstevel@tonic-gate 						}
762*7c478bd9Sstevel@tonic-gate 					}
763*7c478bd9Sstevel@tonic-gate 				}
764*7c478bd9Sstevel@tonic-gate 			} /* end nextstate */
765*7c478bd9Sstevel@tonic-gate 			if (notin(state, n, &prev)) {
766*7c478bd9Sstevel@tonic-gate 				if (n >= NSTATES - 1) {
767*7c478bd9Sstevel@tonic-gate 		printf("cgotofn: notin; state = %d, n = %d\n", state, n, NULL);
768*7c478bd9Sstevel@tonic-gate 					overflo();
769*7c478bd9Sstevel@tonic-gate 				}
770*7c478bd9Sstevel@tonic-gate 				state[++n] = add(setcnt);
771*7c478bd9Sstevel@tonic-gate 				dprintf("	delta(%d,[%o,%o])",
772*7c478bd9Sstevel@tonic-gate 					s, cs, ce);
773*7c478bd9Sstevel@tonic-gate 				dprintf(" = %d, ind = %d\n", n, ind+1, NULL);
774*7c478bd9Sstevel@tonic-gate 				fatab[++ind].cc.cc_ns = ns;
775*7c478bd9Sstevel@tonic-gate 				fatab[ind].cc.cc_cs = cs;
776*7c478bd9Sstevel@tonic-gate 				fatab[ind].cc.cc_ne = ne;
777*7c478bd9Sstevel@tonic-gate 				fatab[ind].cc.cc_ce = ce;
778*7c478bd9Sstevel@tonic-gate 				fatab[ind].n = n;
779*7c478bd9Sstevel@tonic-gate 				numtrans++;
780*7c478bd9Sstevel@tonic-gate 			} else {
781*7c478bd9Sstevel@tonic-gate 				if (prev != 0) {
782*7c478bd9Sstevel@tonic-gate 					dprintf("	delta(%d,[%o,%o])",
783*7c478bd9Sstevel@tonic-gate 						s, cs, ce);
784*7c478bd9Sstevel@tonic-gate 					dprintf("= %d, ind = %d\n",
785*7c478bd9Sstevel@tonic-gate 						prev, ind+1, NULL);
786*7c478bd9Sstevel@tonic-gate 					fatab[++ind].cc.cc_ns = ns;
787*7c478bd9Sstevel@tonic-gate 					fatab[ind].cc.cc_cs = cs;
788*7c478bd9Sstevel@tonic-gate 					fatab[ind].cc.cc_ne = ne;
789*7c478bd9Sstevel@tonic-gate 					fatab[ind].cc.cc_ce = ce;
790*7c478bd9Sstevel@tonic-gate 					fatab[ind].n = prev;
791*7c478bd9Sstevel@tonic-gate 					numtrans++;
792*7c478bd9Sstevel@tonic-gate 				}
793*7c478bd9Sstevel@tonic-gate 			}
794*7c478bd9Sstevel@tonic-gate 		}
795*7c478bd9Sstevel@tonic-gate 	tenter:
796*7c478bd9Sstevel@tonic-gate 		if ((pfa = (struct fa *)malloc((numtrans + 1)
797*7c478bd9Sstevel@tonic-gate 						* sizeof (struct fa))) == NULL)
798*7c478bd9Sstevel@tonic-gate 			overflo();
799*7c478bd9Sstevel@tonic-gate 		where[s] = pfa;
800*7c478bd9Sstevel@tonic-gate 		if (finflg)
801*7c478bd9Sstevel@tonic-gate 			pfa->cc.h = -1;		/* s is a final state */
802*7c478bd9Sstevel@tonic-gate 		else
803*7c478bd9Sstevel@tonic-gate 			pfa->cc.h = numtrans;
804*7c478bd9Sstevel@tonic-gate 		pfa->st = 0;
805*7c478bd9Sstevel@tonic-gate 		for (i = 1, pfa += 1; i <= numtrans; i++, pfa++) {
806*7c478bd9Sstevel@tonic-gate 			pfa->cc.s = fatab[i].cc;
807*7c478bd9Sstevel@tonic-gate 			pfa->st = (struct fa *)fatab[i].n;
808*7c478bd9Sstevel@tonic-gate 		}
809*7c478bd9Sstevel@tonic-gate 	}
810*7c478bd9Sstevel@tonic-gate 	for (i = 0; i <= n; i++) {
811*7c478bd9Sstevel@tonic-gate 		if (i != 0)	/* state[0] is freed later in freetr() */
812*7c478bd9Sstevel@tonic-gate 			xfree(state[i]);	/* free state[i] */
813*7c478bd9Sstevel@tonic-gate 		pfa = where[i];
814*7c478bd9Sstevel@tonic-gate 		pfa->st = where[0];
815*7c478bd9Sstevel@tonic-gate 		dprintf("state %d: (%o)\n", i, pfa, NULL);
816*7c478bd9Sstevel@tonic-gate 		dprintf("	numtrans = %d,	default = %o\n",
817*7c478bd9Sstevel@tonic-gate 			pfa->cc.h, pfa->st, NULL);
818*7c478bd9Sstevel@tonic-gate 		for (k = 1; k <= pfa->cc.h; k++) {
819*7c478bd9Sstevel@tonic-gate 			(pfa+k)->st = where[(int)(pfa+k)->st];
820*7c478bd9Sstevel@tonic-gate 			dprintf("	char = [%o,%o],	nextstate = %o\n",
821*7c478bd9Sstevel@tonic-gate 				(pfa+k)->cc.s.cc_cs, (pfa+k)->cc.s.cc_ce,
822*7c478bd9Sstevel@tonic-gate 				(pfa+k)->st);
823*7c478bd9Sstevel@tonic-gate 		}
824*7c478bd9Sstevel@tonic-gate 	}
825*7c478bd9Sstevel@tonic-gate 	pfa = where[0];
826*7c478bd9Sstevel@tonic-gate 	if ((num = pfa->cc.h) < 0)
827*7c478bd9Sstevel@tonic-gate 		return (where[0]);
828*7c478bd9Sstevel@tonic-gate 	for (pfa += num; num; num--, pfa--)
829*7c478bd9Sstevel@tonic-gate 		if (pfa->cc.s.cc_ns == hatcn && pfa->cc.s.cc_cs == HAT) {
830*7c478bd9Sstevel@tonic-gate 			return (pfa->st);
831*7c478bd9Sstevel@tonic-gate 		}
832*7c478bd9Sstevel@tonic-gate 	return (where[0]);
833*7c478bd9Sstevel@tonic-gate }
834*7c478bd9Sstevel@tonic-gate 
835*7c478bd9Sstevel@tonic-gate 
836*7c478bd9Sstevel@tonic-gate /*
837*7c478bd9Sstevel@tonic-gate  * Insert CCL entry to CCL table with maintain optimized order.
838*7c478bd9Sstevel@tonic-gate  */
839*7c478bd9Sstevel@tonic-gate static int
840*7c478bd9Sstevel@tonic-gate insert_table(table_base, table_size, ns, cs, ne, ce)
841*7c478bd9Sstevel@tonic-gate ccl_chars_t		*table_base;
842*7c478bd9Sstevel@tonic-gate register int		table_size;
843*7c478bd9Sstevel@tonic-gate register int		ns, ne;
844*7c478bd9Sstevel@tonic-gate register wchar_t	cs, ce;
845*7c478bd9Sstevel@tonic-gate {
846*7c478bd9Sstevel@tonic-gate 	register int		i;
847*7c478bd9Sstevel@tonic-gate 	register int		tns, tne;
848*7c478bd9Sstevel@tonic-gate 	register wchar_t	tcs, tce;
849*7c478bd9Sstevel@tonic-gate 	register ccl_chars_t	*table;
850*7c478bd9Sstevel@tonic-gate 	register ccl_chars_t	*saved_table;
851*7c478bd9Sstevel@tonic-gate 	int			saved_i;
852*7c478bd9Sstevel@tonic-gate 
853*7c478bd9Sstevel@tonic-gate 
854*7c478bd9Sstevel@tonic-gate 
855*7c478bd9Sstevel@tonic-gate 
856*7c478bd9Sstevel@tonic-gate 	dprintf("Inserting {%o, %o} to table %o\n", cs, ce, table_base);
857*7c478bd9Sstevel@tonic-gate 	/*
858*7c478bd9Sstevel@tonic-gate 	 * Searching the table to find out where should put the new item.
859*7c478bd9Sstevel@tonic-gate 	 */
860*7c478bd9Sstevel@tonic-gate 	for (i = 0, table = table_base; i < table_size; i++, table++) {
861*7c478bd9Sstevel@tonic-gate 		tns = table->cc_ns;
862*7c478bd9Sstevel@tonic-gate 		tcs = table->cc_cs;
863*7c478bd9Sstevel@tonic-gate 		tne = table->cc_ne;
864*7c478bd9Sstevel@tonic-gate 		tce = table->cc_ce;
865*7c478bd9Sstevel@tonic-gate 		if (MLCMPLT(ne, ce, tns, (tcs - 1))) {
866*7c478bd9Sstevel@tonic-gate 			/*
867*7c478bd9Sstevel@tonic-gate 			 * Quick! insert to font of current table entries.
868*7c478bd9Sstevel@tonic-gate 			 */
869*7c478bd9Sstevel@tonic-gate qinsert:
870*7c478bd9Sstevel@tonic-gate 			table_size++;
871*7c478bd9Sstevel@tonic-gate 			for (; i < table_size; i++, table++) {
872*7c478bd9Sstevel@tonic-gate 				tns = table->cc_ns;
873*7c478bd9Sstevel@tonic-gate 				tcs = table->cc_cs;
874*7c478bd9Sstevel@tonic-gate 				tne = table->cc_ne;
875*7c478bd9Sstevel@tonic-gate 				tce = table->cc_ce;
876*7c478bd9Sstevel@tonic-gate 				table->cc_ns = ns;
877*7c478bd9Sstevel@tonic-gate 				table->cc_cs = cs;
878*7c478bd9Sstevel@tonic-gate 				table->cc_ne = ne;
879*7c478bd9Sstevel@tonic-gate 				table->cc_ce = ce;
880*7c478bd9Sstevel@tonic-gate 				ns = tns;
881*7c478bd9Sstevel@tonic-gate 				cs = tcs;
882*7c478bd9Sstevel@tonic-gate 				ne = tne;
883*7c478bd9Sstevel@tonic-gate 				ce = tce;
884*7c478bd9Sstevel@tonic-gate 			}
885*7c478bd9Sstevel@tonic-gate 			goto add_null;
886*7c478bd9Sstevel@tonic-gate 		} else if (MLCMPLE(tns, (tcs - 1), ns, cs) &&
887*7c478bd9Sstevel@tonic-gate 				MLCMPLE(ns, cs, tne, (tce + 1))) {
888*7c478bd9Sstevel@tonic-gate 			/*
889*7c478bd9Sstevel@tonic-gate 			 * Starting point is within the current entry.
890*7c478bd9Sstevel@tonic-gate 			 */
891*7c478bd9Sstevel@tonic-gate 			if (MLCMPGT(tns, tcs, ns, cs)) {
892*7c478bd9Sstevel@tonic-gate 				table->cc_ns = ns;
893*7c478bd9Sstevel@tonic-gate 				table->cc_cs = cs;
894*7c478bd9Sstevel@tonic-gate 			}
895*7c478bd9Sstevel@tonic-gate 			if (MLCMPLE(ne, ce, tne, tce)) {
896*7c478bd9Sstevel@tonic-gate 				return (table_size);
897*7c478bd9Sstevel@tonic-gate 			}
898*7c478bd9Sstevel@tonic-gate 			goto combine;
899*7c478bd9Sstevel@tonic-gate 		}
900*7c478bd9Sstevel@tonic-gate 	}
901*7c478bd9Sstevel@tonic-gate 
902*7c478bd9Sstevel@tonic-gate 
903*7c478bd9Sstevel@tonic-gate 	/*
904*7c478bd9Sstevel@tonic-gate 	 * Adding new one to end of table.
905*7c478bd9Sstevel@tonic-gate 	 */
906*7c478bd9Sstevel@tonic-gate 	table->cc_ns = ns;
907*7c478bd9Sstevel@tonic-gate 	table->cc_cs = cs;
908*7c478bd9Sstevel@tonic-gate 	table->cc_ne = ne;
909*7c478bd9Sstevel@tonic-gate 	table->cc_ce = ce;
910*7c478bd9Sstevel@tonic-gate 
911*7c478bd9Sstevel@tonic-gate 
912*7c478bd9Sstevel@tonic-gate 	table_size++;
913*7c478bd9Sstevel@tonic-gate 	goto add_null;
914*7c478bd9Sstevel@tonic-gate 
915*7c478bd9Sstevel@tonic-gate 
916*7c478bd9Sstevel@tonic-gate 
917*7c478bd9Sstevel@tonic-gate 
918*7c478bd9Sstevel@tonic-gate 	combine:
919*7c478bd9Sstevel@tonic-gate 	/*
920*7c478bd9Sstevel@tonic-gate 	 * Check and try to combine the new entry with rest of entries.
921*7c478bd9Sstevel@tonic-gate 	 */
922*7c478bd9Sstevel@tonic-gate 	if ((i + 1) >= table_size) {
923*7c478bd9Sstevel@tonic-gate 		table->cc_ne = ne;
924*7c478bd9Sstevel@tonic-gate 		table->cc_ce = ce;
925*7c478bd9Sstevel@tonic-gate 		return (table_size);
926*7c478bd9Sstevel@tonic-gate 	}
927*7c478bd9Sstevel@tonic-gate 
928*7c478bd9Sstevel@tonic-gate 
929*7c478bd9Sstevel@tonic-gate 	saved_table = table++;
930*7c478bd9Sstevel@tonic-gate 	saved_i = i++;
931*7c478bd9Sstevel@tonic-gate 
932*7c478bd9Sstevel@tonic-gate 
933*7c478bd9Sstevel@tonic-gate 	/*
934*7c478bd9Sstevel@tonic-gate 	 * Finding the spot where we should put the end point.
935*7c478bd9Sstevel@tonic-gate 	 */
936*7c478bd9Sstevel@tonic-gate 	for (; i < table_size; i++, table++) {
937*7c478bd9Sstevel@tonic-gate 		if (MLCMPLT(ne, ce, table->cc_ns, (table->cc_cs - 1))) {
938*7c478bd9Sstevel@tonic-gate 			break;
939*7c478bd9Sstevel@tonic-gate 		} else
940*7c478bd9Sstevel@tonic-gate 		if (MLCMPLE(table->cc_ns, (table->cc_cs - 1), ne, ce) &&
941*7c478bd9Sstevel@tonic-gate 			MLCMPLE(ne, ce, table->cc_ne, (table->cc_ce + 1))) {
942*7c478bd9Sstevel@tonic-gate 			/*
943*7c478bd9Sstevel@tonic-gate 			 * Tack with this table.
944*7c478bd9Sstevel@tonic-gate 			 */
945*7c478bd9Sstevel@tonic-gate 			if (MLCMPLT(ne, ce, table->cc_ne, table->cc_ce)) {
946*7c478bd9Sstevel@tonic-gate 				ne = table->cc_ne;
947*7c478bd9Sstevel@tonic-gate 				ce = table->cc_ce;
948*7c478bd9Sstevel@tonic-gate 			}
949*7c478bd9Sstevel@tonic-gate 			table++;
950*7c478bd9Sstevel@tonic-gate 			i++;
951*7c478bd9Sstevel@tonic-gate 			break;
952*7c478bd9Sstevel@tonic-gate 		}
953*7c478bd9Sstevel@tonic-gate 	}
954*7c478bd9Sstevel@tonic-gate 
955*7c478bd9Sstevel@tonic-gate 
956*7c478bd9Sstevel@tonic-gate 	saved_table->cc_ne = ne;
957*7c478bd9Sstevel@tonic-gate 	saved_table->cc_ce = ce;
958*7c478bd9Sstevel@tonic-gate 	saved_i = table_size - (i - saved_i - 1);
959*7c478bd9Sstevel@tonic-gate 
960*7c478bd9Sstevel@tonic-gate 
961*7c478bd9Sstevel@tonic-gate 	/*
962*7c478bd9Sstevel@tonic-gate 	 * Moving the rest of entries.
963*7c478bd9Sstevel@tonic-gate 	 */
964*7c478bd9Sstevel@tonic-gate 	for (; i < table_size; i++, table++)
965*7c478bd9Sstevel@tonic-gate 		*(++saved_table) = *table;
966*7c478bd9Sstevel@tonic-gate 	table_size = saved_i;
967*7c478bd9Sstevel@tonic-gate 
968*7c478bd9Sstevel@tonic-gate 
969*7c478bd9Sstevel@tonic-gate add_null:
970*7c478bd9Sstevel@tonic-gate 	table_base[table_size].cc_cs = (wchar_t)0x0;
971*7c478bd9Sstevel@tonic-gate 	table_base[table_size].cc_ce = (wchar_t)0x0;
972*7c478bd9Sstevel@tonic-gate 
973*7c478bd9Sstevel@tonic-gate 
974*7c478bd9Sstevel@tonic-gate 	return (table_size);
975*7c478bd9Sstevel@tonic-gate }
976*7c478bd9Sstevel@tonic-gate 
977*7c478bd9Sstevel@tonic-gate 
978*7c478bd9Sstevel@tonic-gate 
979*7c478bd9Sstevel@tonic-gate 
980*7c478bd9Sstevel@tonic-gate static int
981*7c478bd9Sstevel@tonic-gate delete_table(table_base, table_size, ns, cs, ne, ce)
982*7c478bd9Sstevel@tonic-gate ccl_chars_t		*table_base;
983*7c478bd9Sstevel@tonic-gate register int		table_size;
984*7c478bd9Sstevel@tonic-gate register int		ns, ne;
985*7c478bd9Sstevel@tonic-gate register wchar_t	cs, ce;
986*7c478bd9Sstevel@tonic-gate {
987*7c478bd9Sstevel@tonic-gate 	register int		i;
988*7c478bd9Sstevel@tonic-gate 	int			saved_i;
989*7c478bd9Sstevel@tonic-gate 	register ccl_chars_t	*table;
990*7c478bd9Sstevel@tonic-gate 	register ccl_chars_t	*saved_table;
991*7c478bd9Sstevel@tonic-gate 	register int		tns;
992*7c478bd9Sstevel@tonic-gate 	register wchar_t	tcs;
993*7c478bd9Sstevel@tonic-gate 	register int		tne;
994*7c478bd9Sstevel@tonic-gate 	register wchar_t	tce;
995*7c478bd9Sstevel@tonic-gate 
996*7c478bd9Sstevel@tonic-gate 
997*7c478bd9Sstevel@tonic-gate 
998*7c478bd9Sstevel@tonic-gate 
999*7c478bd9Sstevel@tonic-gate 	for (i = 0, table = table_base; i < table_size; i++, table++) {
1000*7c478bd9Sstevel@tonic-gate 		tns = table->cc_ns;
1001*7c478bd9Sstevel@tonic-gate 		tcs = table->cc_cs;
1002*7c478bd9Sstevel@tonic-gate 		tne = table->cc_ne;
1003*7c478bd9Sstevel@tonic-gate 		tce = table->cc_ce;
1004*7c478bd9Sstevel@tonic-gate 		if (MLCMPLT(ne, ce, tns, tcs))
1005*7c478bd9Sstevel@tonic-gate 			return (table_size);
1006*7c478bd9Sstevel@tonic-gate 		else if (MLCMPLT(ne, ce, tne, tce)) {
1007*7c478bd9Sstevel@tonic-gate 			if (MLCMPLE(ns, cs, tns, tcs)) {
1008*7c478bd9Sstevel@tonic-gate 				/*
1009*7c478bd9Sstevel@tonic-gate 				 * Shrink type 1.
1010*7c478bd9Sstevel@tonic-gate 				 */
1011*7c478bd9Sstevel@tonic-gate 				table->cc_ns = ne;
1012*7c478bd9Sstevel@tonic-gate 				table->cc_cs = ce + 1;
1013*7c478bd9Sstevel@tonic-gate 				return (table_size);
1014*7c478bd9Sstevel@tonic-gate 
1015*7c478bd9Sstevel@tonic-gate 			} else {
1016*7c478bd9Sstevel@tonic-gate 				/*
1017*7c478bd9Sstevel@tonic-gate 				 * Spliting !!
1018*7c478bd9Sstevel@tonic-gate 				 */
1019*7c478bd9Sstevel@tonic-gate 				table->cc_ns = ne;
1020*7c478bd9Sstevel@tonic-gate 				table->cc_cs = ce + 1;
1021*7c478bd9Sstevel@tonic-gate 				tne = ns;
1022*7c478bd9Sstevel@tonic-gate 				tce = cs - 1;
1023*7c478bd9Sstevel@tonic-gate 				table_size++;
1024*7c478bd9Sstevel@tonic-gate 				for (; i < table_size; i++, table++) {
1025*7c478bd9Sstevel@tonic-gate 					ns = table->cc_ns;
1026*7c478bd9Sstevel@tonic-gate 					cs = table->cc_cs;
1027*7c478bd9Sstevel@tonic-gate 					ne = table->cc_ne;
1028*7c478bd9Sstevel@tonic-gate 					ce = table->cc_ce;
1029*7c478bd9Sstevel@tonic-gate 					table->cc_ns = tns;
1030*7c478bd9Sstevel@tonic-gate 					table->cc_cs = tcs;
1031*7c478bd9Sstevel@tonic-gate 					table->cc_ne = tne;
1032*7c478bd9Sstevel@tonic-gate 					table->cc_ce = tce;
1033*7c478bd9Sstevel@tonic-gate 					tns = ns;
1034*7c478bd9Sstevel@tonic-gate 					tcs = cs;
1035*7c478bd9Sstevel@tonic-gate 					tne = ne;
1036*7c478bd9Sstevel@tonic-gate 					tce = ce;
1037*7c478bd9Sstevel@tonic-gate 				}
1038*7c478bd9Sstevel@tonic-gate 				return (table_size);
1039*7c478bd9Sstevel@tonic-gate 			}
1040*7c478bd9Sstevel@tonic-gate 
1041*7c478bd9Sstevel@tonic-gate 		} else if (MLCMPLE(ns, cs, tne, tce)) {
1042*7c478bd9Sstevel@tonic-gate 			if (MLCMPGT(ns, cs, tns, tcs)) {
1043*7c478bd9Sstevel@tonic-gate 				/*
1044*7c478bd9Sstevel@tonic-gate 				 * Shrink current table(type 2).
1045*7c478bd9Sstevel@tonic-gate 				 */
1046*7c478bd9Sstevel@tonic-gate 				table->cc_ne = ns;
1047*7c478bd9Sstevel@tonic-gate 				table->cc_ce = cs - 1;
1048*7c478bd9Sstevel@tonic-gate 				table++;
1049*7c478bd9Sstevel@tonic-gate 				i++;
1050*7c478bd9Sstevel@tonic-gate 			}
1051*7c478bd9Sstevel@tonic-gate 			/*
1052*7c478bd9Sstevel@tonic-gate 			 * Search for the end point.
1053*7c478bd9Sstevel@tonic-gate 			 */
1054*7c478bd9Sstevel@tonic-gate 			saved_i = i;
1055*7c478bd9Sstevel@tonic-gate 			saved_table = table;
1056*7c478bd9Sstevel@tonic-gate 			for (; i < table_size; i++, table++) {
1057*7c478bd9Sstevel@tonic-gate 				if (MLCMPLT(ne, ce,
1058*7c478bd9Sstevel@tonic-gate 						table->cc_ns, table->cc_cs)) {
1059*7c478bd9Sstevel@tonic-gate 					/*
1060*7c478bd9Sstevel@tonic-gate 					 * Easy point, no shrinks!
1061*7c478bd9Sstevel@tonic-gate 					 */
1062*7c478bd9Sstevel@tonic-gate 					break;
1063*7c478bd9Sstevel@tonic-gate 
1064*7c478bd9Sstevel@tonic-gate 				} else if (MLCMPGT(table->cc_ne, table->cc_ce,
1065*7c478bd9Sstevel@tonic-gate 						ne, ce)) {
1066*7c478bd9Sstevel@tonic-gate 					/*
1067*7c478bd9Sstevel@tonic-gate 					 * Shrinking...
1068*7c478bd9Sstevel@tonic-gate 					 */
1069*7c478bd9Sstevel@tonic-gate 					table->cc_ns = ne;
1070*7c478bd9Sstevel@tonic-gate 					table->cc_cs = ce + 1;
1071*7c478bd9Sstevel@tonic-gate 					break;
1072*7c478bd9Sstevel@tonic-gate 				}
1073*7c478bd9Sstevel@tonic-gate 
1074*7c478bd9Sstevel@tonic-gate 
1075*7c478bd9Sstevel@tonic-gate 			}
1076*7c478bd9Sstevel@tonic-gate 			/*
1077*7c478bd9Sstevel@tonic-gate 			 * Moving(removing) backword.
1078*7c478bd9Sstevel@tonic-gate 			 */
1079*7c478bd9Sstevel@tonic-gate 			saved_i = table_size - (i - saved_i);
1080*7c478bd9Sstevel@tonic-gate 			for (; i < table_size; i++)
1081*7c478bd9Sstevel@tonic-gate 				*saved_table++ = *table++;
1082*7c478bd9Sstevel@tonic-gate 			return (saved_i);
1083*7c478bd9Sstevel@tonic-gate 		}
1084*7c478bd9Sstevel@tonic-gate 	}
1085*7c478bd9Sstevel@tonic-gate 	return (table_size);
1086*7c478bd9Sstevel@tonic-gate }
1087*7c478bd9Sstevel@tonic-gate 
1088*7c478bd9Sstevel@tonic-gate 
1089*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
1090*7c478bd9Sstevel@tonic-gate dump_table(table, size)
1091*7c478bd9Sstevel@tonic-gate register ccl_chars_t	*table;
1092*7c478bd9Sstevel@tonic-gate register int		size;
1093*7c478bd9Sstevel@tonic-gate {
1094*7c478bd9Sstevel@tonic-gate 	register int	i;
1095*7c478bd9Sstevel@tonic-gate 
1096*7c478bd9Sstevel@tonic-gate 
1097*7c478bd9Sstevel@tonic-gate 
1098*7c478bd9Sstevel@tonic-gate 
1099*7c478bd9Sstevel@tonic-gate 	if (! dbg)
1100*7c478bd9Sstevel@tonic-gate 		return;
1101*7c478bd9Sstevel@tonic-gate 
1102*7c478bd9Sstevel@tonic-gate 
1103*7c478bd9Sstevel@tonic-gate 	printf("Duming table %o with size %d\n", table, size);
1104*7c478bd9Sstevel@tonic-gate 	size++;	/* To watch out NULL */
1105*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < size; i++, table++)
1106*7c478bd9Sstevel@tonic-gate 	{
1107*7c478bd9Sstevel@tonic-gate 		printf("{%3o, %3o}, ", table->cc_cs, table->cc_ce);
1108*7c478bd9Sstevel@tonic-gate 	}
1109*7c478bd9Sstevel@tonic-gate 	printf("\n");
1110*7c478bd9Sstevel@tonic-gate }
1111*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
1112*7c478bd9Sstevel@tonic-gate 
1113*7c478bd9Sstevel@tonic-gate 
1114*7c478bd9Sstevel@tonic-gate 
1115*7c478bd9Sstevel@tonic-gate 
1116*7c478bd9Sstevel@tonic-gate match(pfa, p)
1117*7c478bd9Sstevel@tonic-gate register struct fa *pfa;
1118*7c478bd9Sstevel@tonic-gate register wchar_t *p;
1119*7c478bd9Sstevel@tonic-gate {
1120*7c478bd9Sstevel@tonic-gate 	register count;
1121*7c478bd9Sstevel@tonic-gate 	register int n, ns, ne;
1122*7c478bd9Sstevel@tonic-gate 	register wchar_t c, cs, ce;
1123*7c478bd9Sstevel@tonic-gate 
1124*7c478bd9Sstevel@tonic-gate 
1125*7c478bd9Sstevel@tonic-gate 	if (p == 0)
1126*7c478bd9Sstevel@tonic-gate 		return (0);
1127*7c478bd9Sstevel@tonic-gate 	if (pfa->cc.h == 1) { /* fast test for first character, if possible */
1128*7c478bd9Sstevel@tonic-gate 		ns = (++pfa)->cc.s.cc_ns;
1129*7c478bd9Sstevel@tonic-gate 		cs = (pfa)->cc.s.cc_cs;
1130*7c478bd9Sstevel@tonic-gate 		ne = (pfa)->cc.s.cc_ne;
1131*7c478bd9Sstevel@tonic-gate 		ce = (pfa)->cc.s.cc_ce;
1132*7c478bd9Sstevel@tonic-gate 		do {
1133*7c478bd9Sstevel@tonic-gate 			c = *p;
1134*7c478bd9Sstevel@tonic-gate 			n = wcsetno(c);
1135*7c478bd9Sstevel@tonic-gate 			if (MLCMPLE(ns, cs, n, c) &&
1136*7c478bd9Sstevel@tonic-gate 				MLCMPLE(n, c, ne, ce)) {
1137*7c478bd9Sstevel@tonic-gate 				p++;
1138*7c478bd9Sstevel@tonic-gate 				pfa = pfa->st;
1139*7c478bd9Sstevel@tonic-gate 				goto adv;
1140*7c478bd9Sstevel@tonic-gate 			}
1141*7c478bd9Sstevel@tonic-gate 		} while (*p++ != 0);
1142*7c478bd9Sstevel@tonic-gate 		return (0);
1143*7c478bd9Sstevel@tonic-gate 	}
1144*7c478bd9Sstevel@tonic-gate 	adv: if ((count = pfa->cc.h) < 0)
1145*7c478bd9Sstevel@tonic-gate 		return (1);
1146*7c478bd9Sstevel@tonic-gate 	do {
1147*7c478bd9Sstevel@tonic-gate 		c = *p;
1148*7c478bd9Sstevel@tonic-gate 		n = wcsetno(c);
1149*7c478bd9Sstevel@tonic-gate 		for (pfa += count; count; count--, pfa--) {
1150*7c478bd9Sstevel@tonic-gate 			ns = (pfa)->cc.s.cc_ns;
1151*7c478bd9Sstevel@tonic-gate 			cs = (pfa)->cc.s.cc_cs;
1152*7c478bd9Sstevel@tonic-gate 			ne = (pfa)->cc.s.cc_ne;
1153*7c478bd9Sstevel@tonic-gate 			ce = (pfa)->cc.s.cc_ce;
1154*7c478bd9Sstevel@tonic-gate 			if (MLCMPLE(ns, cs, n, c) && MLCMPLE(n, c, ne, ce))
1155*7c478bd9Sstevel@tonic-gate 				break;
1156*7c478bd9Sstevel@tonic-gate 		}
1157*7c478bd9Sstevel@tonic-gate 		pfa = pfa->st;
1158*7c478bd9Sstevel@tonic-gate 		if ((count = pfa->cc.h) < 0)
1159*7c478bd9Sstevel@tonic-gate 			return (1);
1160*7c478bd9Sstevel@tonic-gate 	} while (*p++ != 0);
1161*7c478bd9Sstevel@tonic-gate 	return (0);
1162*7c478bd9Sstevel@tonic-gate }
1163