xref: /titanic_52/usr/src/cmd/egrep/egrep.y (revision 41599e9fdccb44cc5f17828ab04b3147cefcc4e0)
17c478bd9Sstevel@tonic-gate %{
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate  * CDDL HEADER START
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
67c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
77c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
87c478bd9Sstevel@tonic-gate  * with the License.
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
117c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
127c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
137c478bd9Sstevel@tonic-gate  * and limitations under the License.
147c478bd9Sstevel@tonic-gate  *
157c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
167c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
177c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
187c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
197c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
207c478bd9Sstevel@tonic-gate  *
217c478bd9Sstevel@tonic-gate  * CDDL HEADER END
227c478bd9Sstevel@tonic-gate  */
237c478bd9Sstevel@tonic-gate %}
247c478bd9Sstevel@tonic-gate /*
257c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
267c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
307c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate /*	Copyright (c) 1987, 1988 Microsoft Corporation	*/
337c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
347c478bd9Sstevel@tonic-gate 
35*41599e9fSDamian Bogel /*
36*41599e9fSDamian Bogel  * Copyright 2013 Damian Bogel. All rights reserved.
37*41599e9fSDamian Bogel  */
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate /*
407c478bd9Sstevel@tonic-gate  * egrep -- print lines containing (or not containing) a regular expression
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  *	status returns:
437c478bd9Sstevel@tonic-gate  *		0 - ok, and some matches
447c478bd9Sstevel@tonic-gate  *		1 - ok, but no matches
457c478bd9Sstevel@tonic-gate  *		2 - some error; matches irrelevant
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate %token CHAR MCHAR DOT MDOT CCL NCCL MCCL NMCCL OR CAT STAR PLUS QUEST
487c478bd9Sstevel@tonic-gate %left OR
497c478bd9Sstevel@tonic-gate %left CHAR MCHAR DOT CCL NCCL MCCL NMCCL '('
507c478bd9Sstevel@tonic-gate %left CAT
517c478bd9Sstevel@tonic-gate %left STAR PLUS QUEST
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate %{
547c478bd9Sstevel@tonic-gate #include <stdio.h>
557c478bd9Sstevel@tonic-gate #include <ctype.h>
567c478bd9Sstevel@tonic-gate #include <memory.h>
577c478bd9Sstevel@tonic-gate #include <wchar.h>
587c478bd9Sstevel@tonic-gate #include <wctype.h>
597c478bd9Sstevel@tonic-gate #include <widec.h>
607c478bd9Sstevel@tonic-gate #include <stdlib.h>
617c478bd9Sstevel@tonic-gate #include <limits.h>
627c478bd9Sstevel@tonic-gate #include <locale.h>
637c478bd9Sstevel@tonic-gate 
64*41599e9fSDamian Bogel #define STDIN_FILENAME gettext("(standard input)")
65*41599e9fSDamian Bogel 
667c478bd9Sstevel@tonic-gate #define BLKSIZE 512	/* size of reported disk blocks */
677c478bd9Sstevel@tonic-gate #define EBUFSIZ 8192
687c478bd9Sstevel@tonic-gate #define MAXLIN 350
697c478bd9Sstevel@tonic-gate #define NCHARS 256
707c478bd9Sstevel@tonic-gate #define MAXPOS 4000
717c478bd9Sstevel@tonic-gate #define NSTATES 64
727c478bd9Sstevel@tonic-gate #define FINAL -1
737c478bd9Sstevel@tonic-gate #define RIGHT '\n'	/* serves as record separator and as $ */
747c478bd9Sstevel@tonic-gate #define LEFT '\n'	/* beginning of line */
757c478bd9Sstevel@tonic-gate int gotofn[NSTATES][NCHARS];
767c478bd9Sstevel@tonic-gate int state[NSTATES];
777c478bd9Sstevel@tonic-gate int out[NSTATES];
787c478bd9Sstevel@tonic-gate int line  = 1;
797c478bd9Sstevel@tonic-gate int *name;
807c478bd9Sstevel@tonic-gate int *left;
817c478bd9Sstevel@tonic-gate int *right;
827c478bd9Sstevel@tonic-gate int *parent;
837c478bd9Sstevel@tonic-gate int *foll;
847c478bd9Sstevel@tonic-gate int *positions;
857c478bd9Sstevel@tonic-gate char *chars;
867c478bd9Sstevel@tonic-gate wchar_t *lower;
877c478bd9Sstevel@tonic-gate wchar_t *upper;
887c478bd9Sstevel@tonic-gate int maxlin, maxclin, maxwclin, maxpos;
897c478bd9Sstevel@tonic-gate int nxtpos = 0;
907c478bd9Sstevel@tonic-gate int inxtpos;
917c478bd9Sstevel@tonic-gate int nxtchar = 0;
927c478bd9Sstevel@tonic-gate int *tmpstat;
937c478bd9Sstevel@tonic-gate int *initstat;
947c478bd9Sstevel@tonic-gate int istat;
957c478bd9Sstevel@tonic-gate int nstate = 1;
967c478bd9Sstevel@tonic-gate int xstate;
977c478bd9Sstevel@tonic-gate int count;
987c478bd9Sstevel@tonic-gate int icount;
997c478bd9Sstevel@tonic-gate char *input;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate wchar_t lyylval;
1037c478bd9Sstevel@tonic-gate wchar_t nextch();
1047c478bd9Sstevel@tonic-gate wchar_t maxmin();
1057c478bd9Sstevel@tonic-gate int compare();
1067c478bd9Sstevel@tonic-gate void overflo();
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate char reinit = 0;
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate long long lnum;
1117c478bd9Sstevel@tonic-gate int	bflag;
1127c478bd9Sstevel@tonic-gate int	cflag;
1137c478bd9Sstevel@tonic-gate int	eflag;
1147c478bd9Sstevel@tonic-gate int	fflag;
115*41599e9fSDamian Bogel int	Hflag;
1167c478bd9Sstevel@tonic-gate int	hflag;
1177c478bd9Sstevel@tonic-gate int	iflag;
1187c478bd9Sstevel@tonic-gate int	lflag;
1197c478bd9Sstevel@tonic-gate int	nflag;
120*41599e9fSDamian Bogel int	qflag;
1217c478bd9Sstevel@tonic-gate int	vflag;
1227c478bd9Sstevel@tonic-gate int	nfile;
1237c478bd9Sstevel@tonic-gate long long blkno;
1247c478bd9Sstevel@tonic-gate long long tln;
1257c478bd9Sstevel@tonic-gate int	nsucc;
1267c478bd9Sstevel@tonic-gate int	badbotch;
1277c478bd9Sstevel@tonic-gate extern 	char *optarg;
1287c478bd9Sstevel@tonic-gate extern 	int optind;
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate int	f;
1317c478bd9Sstevel@tonic-gate FILE	*expfile;
1327c478bd9Sstevel@tonic-gate %}
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate %%
1357c478bd9Sstevel@tonic-gate s:	t
1367c478bd9Sstevel@tonic-gate 		{
1377c478bd9Sstevel@tonic-gate 		  unary(FINAL, $1);
1387c478bd9Sstevel@tonic-gate 		  line--;
1397c478bd9Sstevel@tonic-gate 		}
1407c478bd9Sstevel@tonic-gate 	;
1417c478bd9Sstevel@tonic-gate t:	b r
1427c478bd9Sstevel@tonic-gate 		{ $$ = node(CAT, $1, $2); }
1437c478bd9Sstevel@tonic-gate 	| OR b r OR
1447c478bd9Sstevel@tonic-gate 		{ $$ = node(CAT, $2, $3); }
1457c478bd9Sstevel@tonic-gate 	| OR b r
1467c478bd9Sstevel@tonic-gate 		{ $$ = node(CAT, $2, $3); }
1477c478bd9Sstevel@tonic-gate 	| b r OR
1487c478bd9Sstevel@tonic-gate 		{ $$ = node(CAT, $1, $2); }
1497c478bd9Sstevel@tonic-gate 	;
1507c478bd9Sstevel@tonic-gate b:
1517c478bd9Sstevel@tonic-gate 		{ /* if(multibyte)
1527c478bd9Sstevel@tonic-gate 			$$ = mdotenter();
1537c478bd9Sstevel@tonic-gate 		  else */
1547c478bd9Sstevel@tonic-gate 			$$ = enter(DOT);
1557c478bd9Sstevel@tonic-gate 		  $$ = unary(STAR, $$);
1567c478bd9Sstevel@tonic-gate 		}
1577c478bd9Sstevel@tonic-gate 	;
1587c478bd9Sstevel@tonic-gate r:	CHAR
1597c478bd9Sstevel@tonic-gate 		{ $$ = iflag && isalpha($1) ?
1607c478bd9Sstevel@tonic-gate 		node(OR, enter(tolower($1)), enter(toupper($1))) : enter($1); }
1617c478bd9Sstevel@tonic-gate 	| MCHAR
1627c478bd9Sstevel@tonic-gate 		{ $$ = (iflag && iswalpha(lyylval)) ?
1637c478bd9Sstevel@tonic-gate 		node(OR, mchar(towlower(lyylval)), mchar(towupper(lyylval))) :
1647c478bd9Sstevel@tonic-gate 		mchar(lyylval); }
1657c478bd9Sstevel@tonic-gate 	| DOT
1667c478bd9Sstevel@tonic-gate 		{ if(multibyte)
1677c478bd9Sstevel@tonic-gate 			$$ = mdotenter();
1687c478bd9Sstevel@tonic-gate 		  else
1697c478bd9Sstevel@tonic-gate 			$$ = enter(DOT);
1707c478bd9Sstevel@tonic-gate 		}
1717c478bd9Sstevel@tonic-gate 	| CCL
1727c478bd9Sstevel@tonic-gate 		{ $$ = cclenter(CCL); }
1737c478bd9Sstevel@tonic-gate 	| NCCL
1747c478bd9Sstevel@tonic-gate 		{ $$ = cclenter(NCCL); }
1757c478bd9Sstevel@tonic-gate 	| MCCL
1767c478bd9Sstevel@tonic-gate 		{ $$ = ccl(CCL); }
1777c478bd9Sstevel@tonic-gate 	| NMCCL
1787c478bd9Sstevel@tonic-gate 		{ $$ = ccl(NCCL); }
1797c478bd9Sstevel@tonic-gate 	;
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate r:	r OR r
1827c478bd9Sstevel@tonic-gate 		{ $$ = node(OR, $1, $3); }
1837c478bd9Sstevel@tonic-gate 	| r r %prec CAT
1847c478bd9Sstevel@tonic-gate 		{ $$ = node(CAT, $1, $2); }
1857c478bd9Sstevel@tonic-gate 	| r STAR
1867c478bd9Sstevel@tonic-gate 		{ $$ = unary(STAR, $1); }
1877c478bd9Sstevel@tonic-gate 	| r PLUS
1887c478bd9Sstevel@tonic-gate 		{ $$ = unary(PLUS, $1); }
1897c478bd9Sstevel@tonic-gate 	| r QUEST
1907c478bd9Sstevel@tonic-gate 		{ $$ = unary(QUEST, $1); }
1917c478bd9Sstevel@tonic-gate 	| '(' r ')'
1927c478bd9Sstevel@tonic-gate 		{ $$ = $2; }
1937c478bd9Sstevel@tonic-gate 	| error
1947c478bd9Sstevel@tonic-gate 	;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate %%
1977c478bd9Sstevel@tonic-gate void	add(int *, int);
1987c478bd9Sstevel@tonic-gate void	clearg(void);
1997c478bd9Sstevel@tonic-gate void	execute(char *);
2007c478bd9Sstevel@tonic-gate void	follow(int);
2017c478bd9Sstevel@tonic-gate int	mgetc(void);
2027c478bd9Sstevel@tonic-gate void	synerror(void);
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate void
2067c478bd9Sstevel@tonic-gate yyerror(char *s)
2077c478bd9Sstevel@tonic-gate {
2087c478bd9Sstevel@tonic-gate 	fprintf(stderr, "egrep: %s\n", s);
2097c478bd9Sstevel@tonic-gate 	exit(2);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate int
2137c478bd9Sstevel@tonic-gate yylex(void)
2147c478bd9Sstevel@tonic-gate {
2157c478bd9Sstevel@tonic-gate 	extern int yylval;
2167c478bd9Sstevel@tonic-gate 	int cclcnt, x, ccount, oldccount;
2177c478bd9Sstevel@tonic-gate 	wchar_t c, lc;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	c = nextch();
2207c478bd9Sstevel@tonic-gate 	switch(c) {
2217c478bd9Sstevel@tonic-gate 		case '^':
2227c478bd9Sstevel@tonic-gate 			yylval = LEFT;
2237c478bd9Sstevel@tonic-gate 			return(CHAR);
2247c478bd9Sstevel@tonic-gate 		case '$':
2257c478bd9Sstevel@tonic-gate 			c = RIGHT;
2267c478bd9Sstevel@tonic-gate 			goto defchar;
2277c478bd9Sstevel@tonic-gate 		case '|': return (OR);
2287c478bd9Sstevel@tonic-gate 		case '*': return (STAR);
2297c478bd9Sstevel@tonic-gate 		case '+': return (PLUS);
2307c478bd9Sstevel@tonic-gate 		case '?': return (QUEST);
2317c478bd9Sstevel@tonic-gate 		case '(': return (c);
2327c478bd9Sstevel@tonic-gate 		case ')': return (c);
2337c478bd9Sstevel@tonic-gate 		case '.': return(DOT);
2347c478bd9Sstevel@tonic-gate 		case '\0': return (0);
2357c478bd9Sstevel@tonic-gate 		case RIGHT: return (OR);
2367c478bd9Sstevel@tonic-gate 		case '[':
2377c478bd9Sstevel@tonic-gate 			x = (multibyte ? MCCL : CCL);
2387c478bd9Sstevel@tonic-gate 			cclcnt = 0;
2397c478bd9Sstevel@tonic-gate 			count = nxtchar++;
2407c478bd9Sstevel@tonic-gate 			if ((c = nextch()) == '^') {
2417c478bd9Sstevel@tonic-gate 				x = (multibyte ? NMCCL : NCCL);
2427c478bd9Sstevel@tonic-gate 				c = nextch();
2437c478bd9Sstevel@tonic-gate 			}
2447c478bd9Sstevel@tonic-gate 			lc = 0;
2457c478bd9Sstevel@tonic-gate 			do {
2467c478bd9Sstevel@tonic-gate 				if (iflag && iswalpha(c))
2477c478bd9Sstevel@tonic-gate 					c = towlower(c);
2487c478bd9Sstevel@tonic-gate 				if (c == '\0') synerror();
2497c478bd9Sstevel@tonic-gate 				if (c == '-' && cclcnt > 0 && lc != 0) {
2507c478bd9Sstevel@tonic-gate 					if ((c = nextch()) != 0) {
2517c478bd9Sstevel@tonic-gate 						if(c == ']') {
2527c478bd9Sstevel@tonic-gate 							chars[nxtchar++] = '-';
2537c478bd9Sstevel@tonic-gate 							cclcnt++;
2547c478bd9Sstevel@tonic-gate 							break;
2557c478bd9Sstevel@tonic-gate 						}
2567c478bd9Sstevel@tonic-gate 						if (iflag && iswalpha(c))
2577c478bd9Sstevel@tonic-gate 							c = towlower(c);
2587c478bd9Sstevel@tonic-gate 						if (!multibyte ||
2597c478bd9Sstevel@tonic-gate 						(c & WCHAR_CSMASK) == (lc & WCHAR_CSMASK) &&
2607c478bd9Sstevel@tonic-gate 						lc < c &&
2617c478bd9Sstevel@tonic-gate 						!iswcntrl(c) && !iswcntrl(lc)) {
2627c478bd9Sstevel@tonic-gate 							if (nxtchar >= maxclin)
2637c478bd9Sstevel@tonic-gate 								if (allocchars() == 0)
2647c478bd9Sstevel@tonic-gate 									overflo();
2657c478bd9Sstevel@tonic-gate 							chars[nxtchar++] = '-';
2667c478bd9Sstevel@tonic-gate 							cclcnt++;
2677c478bd9Sstevel@tonic-gate 						}
2687c478bd9Sstevel@tonic-gate 					}
2697c478bd9Sstevel@tonic-gate 				}
2707c478bd9Sstevel@tonic-gate 				ccount = oldccount = nxtchar;
2717c478bd9Sstevel@tonic-gate 				if(ccount + MB_LEN_MAX >= maxclin)
2727c478bd9Sstevel@tonic-gate 					if(allocchars() == 0)
2737c478bd9Sstevel@tonic-gate 						overflo();
2747c478bd9Sstevel@tonic-gate 				ccount += wctomb(&chars[ccount], c);
2757c478bd9Sstevel@tonic-gate 				cclcnt += ccount - oldccount;
2767c478bd9Sstevel@tonic-gate 				nxtchar += ccount - oldccount;
2777c478bd9Sstevel@tonic-gate 				lc = c;
2787c478bd9Sstevel@tonic-gate 			} while ((c = nextch()) != ']');
2797c478bd9Sstevel@tonic-gate 			chars[count] = cclcnt;
2807c478bd9Sstevel@tonic-gate 			return(x);
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 		case '\\':
2837c478bd9Sstevel@tonic-gate 			if ((c = nextch()) == '\0') synerror();
2847c478bd9Sstevel@tonic-gate 		defchar:
2857c478bd9Sstevel@tonic-gate 		default:
2867c478bd9Sstevel@tonic-gate 			if (c <= 0177) {
2877c478bd9Sstevel@tonic-gate 				yylval = c;
2887c478bd9Sstevel@tonic-gate 				return (CHAR);
2897c478bd9Sstevel@tonic-gate 			} else {
2907c478bd9Sstevel@tonic-gate 				lyylval = c;
2917c478bd9Sstevel@tonic-gate 				return (MCHAR);
2927c478bd9Sstevel@tonic-gate 			}
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate wchar_t
2977c478bd9Sstevel@tonic-gate nextch(void)
2987c478bd9Sstevel@tonic-gate {
2997c478bd9Sstevel@tonic-gate 	wchar_t lc;
3007c478bd9Sstevel@tonic-gate 	char multic[MB_LEN_MAX];
3017c478bd9Sstevel@tonic-gate 	int length, d;
3027c478bd9Sstevel@tonic-gate 	if (fflag) {
3037c478bd9Sstevel@tonic-gate 		if ((length = _mbftowc(multic, &lc, mgetc, &d)) < 0)
3047c478bd9Sstevel@tonic-gate 			synerror();
3057c478bd9Sstevel@tonic-gate 		if(length == 0)
3067c478bd9Sstevel@tonic-gate 			lc = '\0';
3077c478bd9Sstevel@tonic-gate 	}
3087c478bd9Sstevel@tonic-gate 	else  {
3097c478bd9Sstevel@tonic-gate 		if((length = mbtowc(&lc, input, MB_LEN_MAX)) == -1)
3107c478bd9Sstevel@tonic-gate 			synerror();
3117c478bd9Sstevel@tonic-gate 		if(length == 0)
3127c478bd9Sstevel@tonic-gate 			return(0);
3137c478bd9Sstevel@tonic-gate 		input += length;
3147c478bd9Sstevel@tonic-gate 	}
3157c478bd9Sstevel@tonic-gate 	return(lc);
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate int
3197c478bd9Sstevel@tonic-gate mgetc(void)
3207c478bd9Sstevel@tonic-gate {
3217c478bd9Sstevel@tonic-gate 	return(getc(expfile));
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate void
3257c478bd9Sstevel@tonic-gate synerror(void)
3267c478bd9Sstevel@tonic-gate {
3277c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("egrep: syntax error\n"));
3287c478bd9Sstevel@tonic-gate 	exit(2);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate int
3327c478bd9Sstevel@tonic-gate enter(int x)
3337c478bd9Sstevel@tonic-gate {
3347c478bd9Sstevel@tonic-gate 	if(line >= maxlin)
3357c478bd9Sstevel@tonic-gate 		if(alloctree() == 0)
3367c478bd9Sstevel@tonic-gate 			overflo();
3377c478bd9Sstevel@tonic-gate 	name[line] = x;
3387c478bd9Sstevel@tonic-gate 	left[line] = 0;
3397c478bd9Sstevel@tonic-gate 	right[line] = 0;
3407c478bd9Sstevel@tonic-gate 	return(line++);
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate int
3447c478bd9Sstevel@tonic-gate cclenter(int x)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate 	int linno;
3477c478bd9Sstevel@tonic-gate 	linno = enter(x);
3487c478bd9Sstevel@tonic-gate 	right[linno] = count;
3497c478bd9Sstevel@tonic-gate 	return (linno);
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate int
3537c478bd9Sstevel@tonic-gate node(int x, int l, int r)
3547c478bd9Sstevel@tonic-gate {
3557c478bd9Sstevel@tonic-gate 	if(line >= maxlin)
3567c478bd9Sstevel@tonic-gate 		if(alloctree() == 0)
3577c478bd9Sstevel@tonic-gate 			overflo();
3587c478bd9Sstevel@tonic-gate 	name[line] = x;
3597c478bd9Sstevel@tonic-gate 	left[line] = l;
3607c478bd9Sstevel@tonic-gate 	right[line] = r;
3617c478bd9Sstevel@tonic-gate 	parent[l] = line;
3627c478bd9Sstevel@tonic-gate 	parent[r] = line;
3637c478bd9Sstevel@tonic-gate 	return(line++);
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate int
3677c478bd9Sstevel@tonic-gate unary(int x, int d)
3687c478bd9Sstevel@tonic-gate {
3697c478bd9Sstevel@tonic-gate 	if(line >= maxlin)
3707c478bd9Sstevel@tonic-gate 		if(alloctree() == 0)
3717c478bd9Sstevel@tonic-gate 			overflo();
3727c478bd9Sstevel@tonic-gate 	name[line] = x;
3737c478bd9Sstevel@tonic-gate 	left[line] = d;
3747c478bd9Sstevel@tonic-gate 	right[line] = 0;
3757c478bd9Sstevel@tonic-gate 	parent[d] = line;
3767c478bd9Sstevel@tonic-gate 	return(line++);
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate int
3807c478bd9Sstevel@tonic-gate allocchars(void)
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate 	maxclin += MAXLIN;
3837c478bd9Sstevel@tonic-gate 	if((chars = realloc(chars, maxclin)) == (char *)0)
3847c478bd9Sstevel@tonic-gate 		return 0;
3857c478bd9Sstevel@tonic-gate 	return 1;
3867c478bd9Sstevel@tonic-gate }
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate int
3897c478bd9Sstevel@tonic-gate alloctree(void)
3907c478bd9Sstevel@tonic-gate {
3917c478bd9Sstevel@tonic-gate 	maxlin += MAXLIN;
3927c478bd9Sstevel@tonic-gate 	if((name = (int *)realloc(name, maxlin*sizeof(int))) == (int *)0)
3937c478bd9Sstevel@tonic-gate 		return 0;
3947c478bd9Sstevel@tonic-gate 	if((left = (int *)realloc(left, maxlin*sizeof(int))) == (int *)0)
3957c478bd9Sstevel@tonic-gate 		return 0;
3967c478bd9Sstevel@tonic-gate 	if((right = (int *)realloc(right, maxlin*sizeof(int))) == (int *)0)
3977c478bd9Sstevel@tonic-gate 		return 0;
3987c478bd9Sstevel@tonic-gate 	if((parent = (int *)realloc(parent, maxlin*sizeof(int))) == (int *)0)
3997c478bd9Sstevel@tonic-gate 		return 0;
4007c478bd9Sstevel@tonic-gate 	if((foll = (int *)realloc(foll, maxlin*sizeof(int))) == (int *)0)
4017c478bd9Sstevel@tonic-gate 		return 0;
4027c478bd9Sstevel@tonic-gate 	if((tmpstat = (int *)realloc(tmpstat, maxlin*sizeof(int))) == (int *)0)
4037c478bd9Sstevel@tonic-gate 		return 0;
4047c478bd9Sstevel@tonic-gate 	if((initstat = (int *)realloc(initstat, maxlin*sizeof(int))) == (int *)0)
4057c478bd9Sstevel@tonic-gate 		return 0;
4067c478bd9Sstevel@tonic-gate 	return 1;
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate void
4107c478bd9Sstevel@tonic-gate overflo(void)
4117c478bd9Sstevel@tonic-gate {
4127c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("egrep: regular expression too long\n"));
4137c478bd9Sstevel@tonic-gate 	exit(2);
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate void
4177c478bd9Sstevel@tonic-gate cfoll(int v)
4187c478bd9Sstevel@tonic-gate {
4197c478bd9Sstevel@tonic-gate 	int i;
4207c478bd9Sstevel@tonic-gate 	if (left[v] == 0) {
4217c478bd9Sstevel@tonic-gate 		count = 0;
4227c478bd9Sstevel@tonic-gate 		for (i=1; i<=line; i++) tmpstat[i] = 0;
4237c478bd9Sstevel@tonic-gate 		follow(v);
4247c478bd9Sstevel@tonic-gate 		add(foll, v);
4257c478bd9Sstevel@tonic-gate 	}
4267c478bd9Sstevel@tonic-gate 	else if (right[v] == 0) cfoll(left[v]);
4277c478bd9Sstevel@tonic-gate 	else {
4287c478bd9Sstevel@tonic-gate 		cfoll(left[v]);
4297c478bd9Sstevel@tonic-gate 		cfoll(right[v]);
4307c478bd9Sstevel@tonic-gate 	}
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate void
4347c478bd9Sstevel@tonic-gate cgotofn(void)
4357c478bd9Sstevel@tonic-gate {
4367c478bd9Sstevel@tonic-gate 	int i;
4377c478bd9Sstevel@tonic-gate 	count = 0;
4387c478bd9Sstevel@tonic-gate 	inxtpos = nxtpos;
4397c478bd9Sstevel@tonic-gate 	for (i=3; i<=line; i++) tmpstat[i] = 0;
4407c478bd9Sstevel@tonic-gate 	if (cstate(line-1)==0) {
4417c478bd9Sstevel@tonic-gate 		tmpstat[line] = 1;
4427c478bd9Sstevel@tonic-gate 		count++;
4437c478bd9Sstevel@tonic-gate 		out[1] = 1;
4447c478bd9Sstevel@tonic-gate 	}
4457c478bd9Sstevel@tonic-gate 	for (i=3; i<=line; i++) initstat[i] = tmpstat[i];
4467c478bd9Sstevel@tonic-gate 	count--;		/*leave out position 1 */
4477c478bd9Sstevel@tonic-gate 	icount = count;
4487c478bd9Sstevel@tonic-gate 	tmpstat[1] = 0;
4497c478bd9Sstevel@tonic-gate 	add(state, 1);
4507c478bd9Sstevel@tonic-gate 	istat = nxtst(1, LEFT);
4517c478bd9Sstevel@tonic-gate }
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate int
4547c478bd9Sstevel@tonic-gate nxtst(int s, int c)
4557c478bd9Sstevel@tonic-gate {
4567c478bd9Sstevel@tonic-gate 	int i, num, k;
4577c478bd9Sstevel@tonic-gate 	int pos, curpos, number, newpos;
4587c478bd9Sstevel@tonic-gate 	num = positions[state[s]];
4597c478bd9Sstevel@tonic-gate 	count = icount;
4607c478bd9Sstevel@tonic-gate 	for (i=3; i<=line; i++) tmpstat[i] = initstat[i];
4617c478bd9Sstevel@tonic-gate 	pos = state[s] + 1;
4627c478bd9Sstevel@tonic-gate 	for (i=0; i<num; i++) {
4637c478bd9Sstevel@tonic-gate 		curpos = positions[pos];
4647c478bd9Sstevel@tonic-gate 		k = name[curpos];
4657c478bd9Sstevel@tonic-gate 		if (k >= 0)
4667c478bd9Sstevel@tonic-gate 			if (
4677c478bd9Sstevel@tonic-gate 				(k == c)
4687c478bd9Sstevel@tonic-gate 				|| (k == DOT && dot(c))
4697c478bd9Sstevel@tonic-gate 				|| (k == MDOT && mdot(c))
4707c478bd9Sstevel@tonic-gate 				|| (k == CCL && dot(c) && member(c, right[curpos], 1))
4717c478bd9Sstevel@tonic-gate 				|| (k == NCCL && dot(c) && member(c, right[curpos], 0))
4727c478bd9Sstevel@tonic-gate 				|| (k == MCCL && mdot(c) && member(c, right[curpos], 1))
4737c478bd9Sstevel@tonic-gate 			) {
4747c478bd9Sstevel@tonic-gate 				number = positions[foll[curpos]];
4757c478bd9Sstevel@tonic-gate 				newpos = foll[curpos] + 1;
4767c478bd9Sstevel@tonic-gate 				for (k=0; k<number; k++) {
4777c478bd9Sstevel@tonic-gate 					if (tmpstat[positions[newpos]] != 1) {
4787c478bd9Sstevel@tonic-gate 						tmpstat[positions[newpos]] = 1;
4797c478bd9Sstevel@tonic-gate 						count++;
4807c478bd9Sstevel@tonic-gate 					}
4817c478bd9Sstevel@tonic-gate 					newpos++;
4827c478bd9Sstevel@tonic-gate 				}
4837c478bd9Sstevel@tonic-gate 			}
4847c478bd9Sstevel@tonic-gate 		pos++;
4857c478bd9Sstevel@tonic-gate 	}
4867c478bd9Sstevel@tonic-gate 	if (notin(nstate)) {
4877c478bd9Sstevel@tonic-gate 		if (++nstate >= NSTATES) {
4887c478bd9Sstevel@tonic-gate 			for (i=1; i<NSTATES; i++)
4897c478bd9Sstevel@tonic-gate 				out[i] = 0;
4907c478bd9Sstevel@tonic-gate 			for (i=1; i<NSTATES; i++)
4917c478bd9Sstevel@tonic-gate 				for (k=0; k<NCHARS; k++)
4927c478bd9Sstevel@tonic-gate 					gotofn[i][k] = 0;
4937c478bd9Sstevel@tonic-gate 			nstate = 1;
4947c478bd9Sstevel@tonic-gate 			nxtpos = inxtpos;
4957c478bd9Sstevel@tonic-gate 			reinit = 1;
4967c478bd9Sstevel@tonic-gate 			add(state, nstate);
4977c478bd9Sstevel@tonic-gate 			if (tmpstat[line] == 1) out[nstate] = 1;
4987c478bd9Sstevel@tonic-gate 			return nstate;
4997c478bd9Sstevel@tonic-gate 		}
5007c478bd9Sstevel@tonic-gate 		add(state, nstate);
5017c478bd9Sstevel@tonic-gate 		if (tmpstat[line] == 1) out[nstate] = 1;
5027c478bd9Sstevel@tonic-gate 		gotofn[s][c] = nstate;
5037c478bd9Sstevel@tonic-gate 		return nstate;
5047c478bd9Sstevel@tonic-gate 	}
5057c478bd9Sstevel@tonic-gate 	else {
5067c478bd9Sstevel@tonic-gate 		gotofn[s][c] = xstate;
5077c478bd9Sstevel@tonic-gate 		return xstate;
5087c478bd9Sstevel@tonic-gate 	}
5097c478bd9Sstevel@tonic-gate }
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate int
5137c478bd9Sstevel@tonic-gate cstate(int v)
5147c478bd9Sstevel@tonic-gate {
5157c478bd9Sstevel@tonic-gate 	int b;
5167c478bd9Sstevel@tonic-gate 	if (left[v] == 0) {
5177c478bd9Sstevel@tonic-gate 		if (tmpstat[v] != 1) {
5187c478bd9Sstevel@tonic-gate 			tmpstat[v] = 1;
5197c478bd9Sstevel@tonic-gate 			count++;
5207c478bd9Sstevel@tonic-gate 		}
5217c478bd9Sstevel@tonic-gate 		return(1);
5227c478bd9Sstevel@tonic-gate 	}
5237c478bd9Sstevel@tonic-gate 	else if (right[v] == 0) {
5247c478bd9Sstevel@tonic-gate 		if (cstate(left[v]) == 0) return (0);
5257c478bd9Sstevel@tonic-gate 		else if (name[v] == PLUS) return (1);
5267c478bd9Sstevel@tonic-gate 		else return (0);
5277c478bd9Sstevel@tonic-gate 	}
5287c478bd9Sstevel@tonic-gate 	else if (name[v] == CAT) {
5297c478bd9Sstevel@tonic-gate 		if (cstate(left[v]) == 0 && cstate(right[v]) == 0) return (0);
5307c478bd9Sstevel@tonic-gate 		else return (1);
5317c478bd9Sstevel@tonic-gate 	}
5327c478bd9Sstevel@tonic-gate 	else { /* name[v] == OR */
5337c478bd9Sstevel@tonic-gate 		b = cstate(right[v]);
5347c478bd9Sstevel@tonic-gate 		if (cstate(left[v]) == 0 || b == 0) return (0);
5357c478bd9Sstevel@tonic-gate 		else return (1);
5367c478bd9Sstevel@tonic-gate 	}
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate int
5417c478bd9Sstevel@tonic-gate dot(int c)
5427c478bd9Sstevel@tonic-gate {
5437c478bd9Sstevel@tonic-gate 	if(multibyte && c >= 0200 && (!iscntrl(c) || c == SS2 && eucw2 || c == SS3 && eucw3))
5447c478bd9Sstevel@tonic-gate 		return(0);
5457c478bd9Sstevel@tonic-gate 	if(c == RIGHT || c == LEFT)
5467c478bd9Sstevel@tonic-gate 		return(0);
5477c478bd9Sstevel@tonic-gate 	return(1);
5487c478bd9Sstevel@tonic-gate }
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate int
5517c478bd9Sstevel@tonic-gate mdot(int c)
5527c478bd9Sstevel@tonic-gate {
5537c478bd9Sstevel@tonic-gate 	if(c >= 0200 && !iscntrl(c))
5547c478bd9Sstevel@tonic-gate 		return(1);
5557c478bd9Sstevel@tonic-gate 	return(0);
5567c478bd9Sstevel@tonic-gate }
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate int
5597c478bd9Sstevel@tonic-gate member(int symb, int set, int torf)
5607c478bd9Sstevel@tonic-gate {
5617c478bd9Sstevel@tonic-gate 	int i, num, pos, c, lc;
5627c478bd9Sstevel@tonic-gate 	if(symb == RIGHT || symb == LEFT)
5637c478bd9Sstevel@tonic-gate 		return(0);
5647c478bd9Sstevel@tonic-gate 	num = chars[set];
5657c478bd9Sstevel@tonic-gate 	pos = set + 1;
5667c478bd9Sstevel@tonic-gate 	lc = 0;
5677c478bd9Sstevel@tonic-gate 	if(iflag)
5687c478bd9Sstevel@tonic-gate 		symb = tolower(symb);
5697c478bd9Sstevel@tonic-gate 	for (i=0; i<num; i++) {
5707c478bd9Sstevel@tonic-gate 		c = (unsigned char)chars[pos++];
5717c478bd9Sstevel@tonic-gate 		if(c == '-' && lc != 0 && ++i < num) {
5727c478bd9Sstevel@tonic-gate 			c = (unsigned char)chars[pos++];
5737c478bd9Sstevel@tonic-gate 			if(lc <= symb && symb <= c)
5747c478bd9Sstevel@tonic-gate 				return(torf);
5757c478bd9Sstevel@tonic-gate 		}
5767c478bd9Sstevel@tonic-gate 		if (symb == c)
5777c478bd9Sstevel@tonic-gate 			return (torf);
5787c478bd9Sstevel@tonic-gate 		lc = c;
5797c478bd9Sstevel@tonic-gate 	}
5807c478bd9Sstevel@tonic-gate 	return(!torf);
5817c478bd9Sstevel@tonic-gate }
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate int
5847c478bd9Sstevel@tonic-gate notin(int n)
5857c478bd9Sstevel@tonic-gate {
5867c478bd9Sstevel@tonic-gate 	int i, j, pos;
5877c478bd9Sstevel@tonic-gate 	for (i=1; i<=n; i++) {
5887c478bd9Sstevel@tonic-gate 		if (positions[state[i]] == count) {
5897c478bd9Sstevel@tonic-gate 			pos = state[i] + 1;
5907c478bd9Sstevel@tonic-gate 			for (j=0; j < count; j++)
5917c478bd9Sstevel@tonic-gate 				if (tmpstat[positions[pos++]] != 1) goto nxt;
5927c478bd9Sstevel@tonic-gate 			xstate = i;
5937c478bd9Sstevel@tonic-gate 			return (0);
5947c478bd9Sstevel@tonic-gate 		}
5957c478bd9Sstevel@tonic-gate 		nxt: ;
5967c478bd9Sstevel@tonic-gate 	}
5977c478bd9Sstevel@tonic-gate 	return (1);
5987c478bd9Sstevel@tonic-gate }
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate void
6017c478bd9Sstevel@tonic-gate add(int *array, int n)
6027c478bd9Sstevel@tonic-gate {
6037c478bd9Sstevel@tonic-gate 	int i;
6047c478bd9Sstevel@tonic-gate 	if (nxtpos + count >= maxpos) {
6057c478bd9Sstevel@tonic-gate 		maxpos += MAXPOS + count;
6067c478bd9Sstevel@tonic-gate 		if((positions = (int *)realloc(positions, maxpos *sizeof(int))) == (int *)0)
6077c478bd9Sstevel@tonic-gate 			overflo();
6087c478bd9Sstevel@tonic-gate 	}
6097c478bd9Sstevel@tonic-gate 	array[n] = nxtpos;
6107c478bd9Sstevel@tonic-gate 	positions[nxtpos++] = count;
6117c478bd9Sstevel@tonic-gate 	for (i=3; i <= line; i++) {
6127c478bd9Sstevel@tonic-gate 		if (tmpstat[i] == 1) {
6137c478bd9Sstevel@tonic-gate 			positions[nxtpos++] = i;
6147c478bd9Sstevel@tonic-gate 		}
6157c478bd9Sstevel@tonic-gate 	}
6167c478bd9Sstevel@tonic-gate }
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate void
6197c478bd9Sstevel@tonic-gate follow(int v)
6207c478bd9Sstevel@tonic-gate {
6217c478bd9Sstevel@tonic-gate 	int p;
6227c478bd9Sstevel@tonic-gate 	if (v == line) return;
6237c478bd9Sstevel@tonic-gate 	p = parent[v];
6247c478bd9Sstevel@tonic-gate 	switch(name[p]) {
6257c478bd9Sstevel@tonic-gate 		case STAR:
6267c478bd9Sstevel@tonic-gate 		case PLUS:	cstate(v);
6277c478bd9Sstevel@tonic-gate 				follow(p);
6287c478bd9Sstevel@tonic-gate 				return;
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate 		case OR:
6317c478bd9Sstevel@tonic-gate 		case QUEST:	follow(p);
6327c478bd9Sstevel@tonic-gate 				return;
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 		case CAT:	if (v == left[p]) {
6357c478bd9Sstevel@tonic-gate 					if (cstate(right[p]) == 0) {
6367c478bd9Sstevel@tonic-gate 						follow(p);
6377c478bd9Sstevel@tonic-gate 						return;
6387c478bd9Sstevel@tonic-gate 					}
6397c478bd9Sstevel@tonic-gate 				}
6407c478bd9Sstevel@tonic-gate 				else follow(p);
6417c478bd9Sstevel@tonic-gate 				return;
6427c478bd9Sstevel@tonic-gate 		case FINAL:	if (tmpstat[line] != 1) {
6437c478bd9Sstevel@tonic-gate 					tmpstat[line] = 1;
6447c478bd9Sstevel@tonic-gate 					count++;
6457c478bd9Sstevel@tonic-gate 				}
6467c478bd9Sstevel@tonic-gate 				return;
6477c478bd9Sstevel@tonic-gate 	}
6487c478bd9Sstevel@tonic-gate }
6497c478bd9Sstevel@tonic-gate 
650*41599e9fSDamian Bogel #define USAGE "[ -bchHilnsqv ] [ -e exp ] [ -f file ] [ strings ] [ file ] ..."
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate int
6537c478bd9Sstevel@tonic-gate main(int argc, char **argv)
6547c478bd9Sstevel@tonic-gate {
6557c478bd9Sstevel@tonic-gate 	char c;
6567c478bd9Sstevel@tonic-gate 	char nl = '\n';
6577c478bd9Sstevel@tonic-gate 	int errflag = 0;
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate 	(void)setlocale(LC_ALL, "");
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)		/* Should be defined by cc -D */
6627c478bd9Sstevel@tonic-gate 	#define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't. */
6637c478bd9Sstevel@tonic-gate #endif
6647c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
6657c478bd9Sstevel@tonic-gate 
666*41599e9fSDamian Bogel 	while((c = getopt(argc, argv, "ybcie:f:Hhlnvsq")) != -1)
6677c478bd9Sstevel@tonic-gate 		switch(c) {
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 		case 'b':
6707c478bd9Sstevel@tonic-gate 			bflag++;
6717c478bd9Sstevel@tonic-gate 			continue;
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 		case 'c':
6747c478bd9Sstevel@tonic-gate 			cflag++;
6757c478bd9Sstevel@tonic-gate 			continue;
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 		case 'e':
6787c478bd9Sstevel@tonic-gate 			eflag++;
6797c478bd9Sstevel@tonic-gate 			input = optarg;
6807c478bd9Sstevel@tonic-gate 			continue;
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate 		case 'f':
6837c478bd9Sstevel@tonic-gate 			fflag++;
6847c478bd9Sstevel@tonic-gate 			expfile = fopen(optarg, "r");
6857c478bd9Sstevel@tonic-gate 			if(expfile == NULL) {
6867c478bd9Sstevel@tonic-gate 				fprintf(stderr,
6877c478bd9Sstevel@tonic-gate 				  gettext("egrep: can't open %s\n"), optarg);
6887c478bd9Sstevel@tonic-gate 				exit(2);
6897c478bd9Sstevel@tonic-gate 			}
6907c478bd9Sstevel@tonic-gate 			continue;
6917c478bd9Sstevel@tonic-gate 
692*41599e9fSDamian Bogel 		case 'H':
693*41599e9fSDamian Bogel 			if (!lflag) /* H is excluded by l as in GNU grep */
694*41599e9fSDamian Bogel 				Hflag++;
695*41599e9fSDamian Bogel 			hflag = 0; /* H excludes h */
696*41599e9fSDamian Bogel 			continue;
697*41599e9fSDamian Bogel 
6987c478bd9Sstevel@tonic-gate 		case 'h':
6997c478bd9Sstevel@tonic-gate 			hflag++;
700*41599e9fSDamian Bogel 			Hflag = 0; /* h excludes H */
7017c478bd9Sstevel@tonic-gate 			continue;
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 		case 'y':
7047c478bd9Sstevel@tonic-gate 		case 'i':
7057c478bd9Sstevel@tonic-gate 			iflag++;
7067c478bd9Sstevel@tonic-gate 			continue;
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate 		case 'l':
7097c478bd9Sstevel@tonic-gate 			lflag++;
710*41599e9fSDamian Bogel 			Hflag = 0; /* l excludes H */
7117c478bd9Sstevel@tonic-gate 			continue;
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate 		case 'n':
7147c478bd9Sstevel@tonic-gate 			nflag++;
7157c478bd9Sstevel@tonic-gate 			continue;
7167c478bd9Sstevel@tonic-gate 
717*41599e9fSDamian Bogel 		case 'q':
718*41599e9fSDamian Bogel 		case 's': /* Solaris: legacy option */
719*41599e9fSDamian Bogel 			qflag++;
7207c478bd9Sstevel@tonic-gate 			continue;
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate 		case 'v':
7237c478bd9Sstevel@tonic-gate 			vflag++;
7247c478bd9Sstevel@tonic-gate 			continue;
7257c478bd9Sstevel@tonic-gate 
7267c478bd9Sstevel@tonic-gate 		case '?':
7277c478bd9Sstevel@tonic-gate 			errflag++;
7287c478bd9Sstevel@tonic-gate 		}
7297c478bd9Sstevel@tonic-gate 	if (errflag || ((argc <= 0) && !fflag && !eflag)) {
7307c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("usage: egrep %s\n"), gettext(USAGE));
7317c478bd9Sstevel@tonic-gate 		exit(2);
7327c478bd9Sstevel@tonic-gate 	}
7337c478bd9Sstevel@tonic-gate 	if(!eflag && !fflag) {
7347c478bd9Sstevel@tonic-gate 		input = argv[optind];
7357c478bd9Sstevel@tonic-gate 		optind++;
7367c478bd9Sstevel@tonic-gate 	}
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 	argc -= optind;
7397c478bd9Sstevel@tonic-gate 	argv = &argv[optind];
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 	/* allocate initial space for arrays */
7427c478bd9Sstevel@tonic-gate 	if((name = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
7437c478bd9Sstevel@tonic-gate 		overflo();
7447c478bd9Sstevel@tonic-gate 	if((left = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
7457c478bd9Sstevel@tonic-gate 		overflo();
7467c478bd9Sstevel@tonic-gate 	if((right = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
7477c478bd9Sstevel@tonic-gate 		overflo();
7487c478bd9Sstevel@tonic-gate 	if((parent = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
7497c478bd9Sstevel@tonic-gate 		overflo();
7507c478bd9Sstevel@tonic-gate 	if((foll = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
7517c478bd9Sstevel@tonic-gate 		overflo();
7527c478bd9Sstevel@tonic-gate 	if((tmpstat = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
7537c478bd9Sstevel@tonic-gate 		overflo();
7547c478bd9Sstevel@tonic-gate 	if((initstat = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
7557c478bd9Sstevel@tonic-gate 		overflo();
7567c478bd9Sstevel@tonic-gate 	if((chars = (char *)malloc(MAXLIN)) == (char *)0)
7577c478bd9Sstevel@tonic-gate 		overflo();
7587c478bd9Sstevel@tonic-gate 	if((lower = (wchar_t *)malloc(MAXLIN*sizeof(wchar_t))) == (wchar_t *)0)
7597c478bd9Sstevel@tonic-gate 		overflo();
7607c478bd9Sstevel@tonic-gate 	if((upper = (wchar_t *)malloc(MAXLIN*sizeof(wchar_t))) == (wchar_t *)0)
7617c478bd9Sstevel@tonic-gate 		overflo();
7627c478bd9Sstevel@tonic-gate 	if((positions = (int *)malloc(MAXPOS*sizeof(int))) == (int *)0)
7637c478bd9Sstevel@tonic-gate 		overflo();
7647c478bd9Sstevel@tonic-gate 	maxlin = MAXLIN;
7657c478bd9Sstevel@tonic-gate 	maxclin = MAXLIN;
7667c478bd9Sstevel@tonic-gate 	maxwclin = MAXLIN;
7677c478bd9Sstevel@tonic-gate 	maxpos = MAXPOS;
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate 	yyparse();
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 	cfoll(line-1);
7727c478bd9Sstevel@tonic-gate 	cgotofn();
7737c478bd9Sstevel@tonic-gate 	nfile = argc;
7747c478bd9Sstevel@tonic-gate 	if (argc<=0) {
7757c478bd9Sstevel@tonic-gate 		execute(0);
7767c478bd9Sstevel@tonic-gate 	}
7777c478bd9Sstevel@tonic-gate 	else while (--argc >= 0) {
7787c478bd9Sstevel@tonic-gate 		if (reinit == 1) clearg();
7797c478bd9Sstevel@tonic-gate 		execute(*argv++);
7807c478bd9Sstevel@tonic-gate 	}
7817c478bd9Sstevel@tonic-gate 	return (badbotch ? 2 : nsucc==0);
7827c478bd9Sstevel@tonic-gate }
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate void
7857c478bd9Sstevel@tonic-gate execute(char *file)
7867c478bd9Sstevel@tonic-gate {
7877c478bd9Sstevel@tonic-gate 	char *p;
7887c478bd9Sstevel@tonic-gate 	int cstat;
7897c478bd9Sstevel@tonic-gate 	wchar_t c;
7907c478bd9Sstevel@tonic-gate 	int t;
7917c478bd9Sstevel@tonic-gate 	long count;
7927c478bd9Sstevel@tonic-gate 	long count1, count2;
7937c478bd9Sstevel@tonic-gate 	long nchars;
7947c478bd9Sstevel@tonic-gate 	int succ;
7957c478bd9Sstevel@tonic-gate 	char *ptr, *ptrend, *lastptr;
7967c478bd9Sstevel@tonic-gate 	char *buf;
7977c478bd9Sstevel@tonic-gate 	long lBufSiz;
7987c478bd9Sstevel@tonic-gate 	FILE *f;
7997c478bd9Sstevel@tonic-gate 	int nlflag;
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate 	lBufSiz = EBUFSIZ;
8027c478bd9Sstevel@tonic-gate 	if ((buf = malloc (lBufSiz + EBUFSIZ)) == NULL) {
8037c478bd9Sstevel@tonic-gate 		exit (2); /* out of memory - BAIL */
8047c478bd9Sstevel@tonic-gate 	}
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 	if (file) {
8077c478bd9Sstevel@tonic-gate 		if ((f = fopen(file, "r")) == NULL) {
8087c478bd9Sstevel@tonic-gate 			fprintf(stderr,
8097c478bd9Sstevel@tonic-gate 				gettext("egrep: can't open %s\n"), file);
8107c478bd9Sstevel@tonic-gate 			badbotch=1;
8117c478bd9Sstevel@tonic-gate 			return;
8127c478bd9Sstevel@tonic-gate 		}
8137c478bd9Sstevel@tonic-gate 	} else {
8147c478bd9Sstevel@tonic-gate 		f = stdin;
815*41599e9fSDamian Bogel 		file = STDIN_FILENAME;
8167c478bd9Sstevel@tonic-gate 	}
8177c478bd9Sstevel@tonic-gate 	lnum = 1;
8187c478bd9Sstevel@tonic-gate 	tln = 0;
8197c478bd9Sstevel@tonic-gate 	if((count = read(fileno(f), buf, EBUFSIZ)) <= 0) {
8207c478bd9Sstevel@tonic-gate 		fclose(f);
8217c478bd9Sstevel@tonic-gate 
822*41599e9fSDamian Bogel 		if (cflag && !qflag) {
823*41599e9fSDamian Bogel 			if (Hflag || (nfile > 1 && !hflag))
8247c478bd9Sstevel@tonic-gate 				fprintf(stdout, "%s:", file);
8257c478bd9Sstevel@tonic-gate 			fprintf(stdout, "%lld\n", tln);
8267c478bd9Sstevel@tonic-gate 		}
8277c478bd9Sstevel@tonic-gate 		return;
8287c478bd9Sstevel@tonic-gate 	}
8297c478bd9Sstevel@tonic-gate 
8307c478bd9Sstevel@tonic-gate 	blkno = count;
8317c478bd9Sstevel@tonic-gate 	ptr = buf;
8327c478bd9Sstevel@tonic-gate 	for(;;) {
8337c478bd9Sstevel@tonic-gate 		if((ptrend = memchr(ptr, '\n', buf + count - ptr)) == NULL) {
8347c478bd9Sstevel@tonic-gate 			/*
8357c478bd9Sstevel@tonic-gate 				move the unused partial record to the head of the buffer
8367c478bd9Sstevel@tonic-gate 			*/
8377c478bd9Sstevel@tonic-gate 			if (ptr > buf) {
8387c478bd9Sstevel@tonic-gate 				count = buf + count - ptr;
8397c478bd9Sstevel@tonic-gate 				memmove (buf, ptr, count);
8407c478bd9Sstevel@tonic-gate 				ptr = buf;
8417c478bd9Sstevel@tonic-gate 			}
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate 			/*
8447c478bd9Sstevel@tonic-gate 				Get a bigger buffer if this one is full
8457c478bd9Sstevel@tonic-gate 			*/
8467c478bd9Sstevel@tonic-gate 			if(count > lBufSiz) {
8477c478bd9Sstevel@tonic-gate 				/*
8487c478bd9Sstevel@tonic-gate 					expand the buffer
8497c478bd9Sstevel@tonic-gate 				*/
8507c478bd9Sstevel@tonic-gate 				lBufSiz += EBUFSIZ;
8517c478bd9Sstevel@tonic-gate 				if ((buf = realloc (buf, lBufSiz + EBUFSIZ)) == NULL) {
8527c478bd9Sstevel@tonic-gate 					exit (2); /* out of memory - BAIL */
8537c478bd9Sstevel@tonic-gate 				}
8547c478bd9Sstevel@tonic-gate 
8557c478bd9Sstevel@tonic-gate 				ptr = buf;
8567c478bd9Sstevel@tonic-gate 			}
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 			p = buf + count;
8597c478bd9Sstevel@tonic-gate 			if((count1 = read(fileno(f), p, EBUFSIZ)) > 0) {
8607c478bd9Sstevel@tonic-gate 				count += count1;
8617c478bd9Sstevel@tonic-gate 				blkno += count1;
8627c478bd9Sstevel@tonic-gate 				continue;
8637c478bd9Sstevel@tonic-gate 			}
8647c478bd9Sstevel@tonic-gate 			ptrend = ptr + count;
8657c478bd9Sstevel@tonic-gate 			nlflag = 0;
8667c478bd9Sstevel@tonic-gate 		} else
8677c478bd9Sstevel@tonic-gate 			nlflag = 1;
8687c478bd9Sstevel@tonic-gate 		*ptrend = '\n';
8697c478bd9Sstevel@tonic-gate 		p = ptr;
8707c478bd9Sstevel@tonic-gate 		lastptr = ptr;
8717c478bd9Sstevel@tonic-gate 		cstat = istat;
8727c478bd9Sstevel@tonic-gate 		succ = 0;
8737c478bd9Sstevel@tonic-gate 		for(;;) {
8747c478bd9Sstevel@tonic-gate 			if(out[cstat]) {
8757c478bd9Sstevel@tonic-gate 				if(multibyte && p > ptr) {
8767c478bd9Sstevel@tonic-gate 					wchar_t wchar;
8777c478bd9Sstevel@tonic-gate 					int length;
8787c478bd9Sstevel@tonic-gate 					char *endptr = p;
8797c478bd9Sstevel@tonic-gate 					p = lastptr;
8807c478bd9Sstevel@tonic-gate 					while(p < endptr) {
8817c478bd9Sstevel@tonic-gate 						length = mbtowc(&wchar, p, MB_LEN_MAX);
8827c478bd9Sstevel@tonic-gate 						if(length <= 1)
8837c478bd9Sstevel@tonic-gate 							p++;
8847c478bd9Sstevel@tonic-gate 						else
8857c478bd9Sstevel@tonic-gate 							p += length;
8867c478bd9Sstevel@tonic-gate 					}
8877c478bd9Sstevel@tonic-gate 					if(p == endptr) {
8887c478bd9Sstevel@tonic-gate 						succ = !vflag;
8897c478bd9Sstevel@tonic-gate 						break;
8907c478bd9Sstevel@tonic-gate 					}
8917c478bd9Sstevel@tonic-gate 					cstat = 1;
8927c478bd9Sstevel@tonic-gate 					length = mbtowc(&wchar, lastptr, MB_LEN_MAX);
8937c478bd9Sstevel@tonic-gate 					if(length <= 1)
8947c478bd9Sstevel@tonic-gate 						lastptr++;
8957c478bd9Sstevel@tonic-gate 					else
8967c478bd9Sstevel@tonic-gate 						lastptr += length;
8977c478bd9Sstevel@tonic-gate 					p = lastptr;
8987c478bd9Sstevel@tonic-gate 					continue;
8997c478bd9Sstevel@tonic-gate 				}
9007c478bd9Sstevel@tonic-gate 				succ = !vflag;
9017c478bd9Sstevel@tonic-gate 				break;
9027c478bd9Sstevel@tonic-gate 			}
9037c478bd9Sstevel@tonic-gate 			c = (unsigned char)*p++;
9047c478bd9Sstevel@tonic-gate 			if ((t = gotofn[cstat][c]) == 0)
9057c478bd9Sstevel@tonic-gate 				cstat = nxtst(cstat, c);
9067c478bd9Sstevel@tonic-gate 			else
9077c478bd9Sstevel@tonic-gate 				cstat = t;
9087c478bd9Sstevel@tonic-gate 			if(c == RIGHT) {
9097c478bd9Sstevel@tonic-gate 				if(out[cstat]) {
9107c478bd9Sstevel@tonic-gate 					succ = !vflag;
9117c478bd9Sstevel@tonic-gate 					break;
9127c478bd9Sstevel@tonic-gate 				}
9137c478bd9Sstevel@tonic-gate 				succ = vflag;
9147c478bd9Sstevel@tonic-gate 				break;
9157c478bd9Sstevel@tonic-gate 			}
9167c478bd9Sstevel@tonic-gate 		}
9177c478bd9Sstevel@tonic-gate 		if (succ) {
9187c478bd9Sstevel@tonic-gate 			nsucc = 1;
919*41599e9fSDamian Bogel 			if (lflag || qflag) {
920*41599e9fSDamian Bogel 				if (!qflag)
921*41599e9fSDamian Bogel 					(void) printf("%s\n", file);
9227c478bd9Sstevel@tonic-gate 				fclose(f);
9237c478bd9Sstevel@tonic-gate 				return;
9247c478bd9Sstevel@tonic-gate 			}
925*41599e9fSDamian Bogel 			if (cflag) {
926*41599e9fSDamian Bogel 				tln++;
927*41599e9fSDamian Bogel 			} else {
928*41599e9fSDamian Bogel 				if (Hflag || (nfile > 1 && !hflag))
929*41599e9fSDamian Bogel 					printf("%s:", file);
9307c478bd9Sstevel@tonic-gate 				if (bflag) {
9317c478bd9Sstevel@tonic-gate 					nchars = blkno - (buf + count - ptrend) - 2;
9327c478bd9Sstevel@tonic-gate 					if(nlflag)
9337c478bd9Sstevel@tonic-gate 						nchars++;
9347c478bd9Sstevel@tonic-gate 					printf("%lld:", nchars/BLKSIZE);
9357c478bd9Sstevel@tonic-gate 				}
9367c478bd9Sstevel@tonic-gate 				if (nflag)
9377c478bd9Sstevel@tonic-gate 					printf("%lld:", lnum);
9387c478bd9Sstevel@tonic-gate 				if(nlflag)
9397c478bd9Sstevel@tonic-gate 					nchars = ptrend - ptr + 1;
9407c478bd9Sstevel@tonic-gate 				else
9417c478bd9Sstevel@tonic-gate 					nchars = ptrend - ptr;
9427c478bd9Sstevel@tonic-gate 				fwrite(ptr, (size_t)1, (size_t)nchars, stdout);
9437c478bd9Sstevel@tonic-gate 			}
9447c478bd9Sstevel@tonic-gate 		}
9457c478bd9Sstevel@tonic-gate 		if(!nlflag)
9467c478bd9Sstevel@tonic-gate 			break;
9477c478bd9Sstevel@tonic-gate 		ptr = ptrend + 1;
9487c478bd9Sstevel@tonic-gate 		if(ptr >= buf + count) {
9497c478bd9Sstevel@tonic-gate 			ptr = buf;
9507c478bd9Sstevel@tonic-gate 			if((count = read(fileno(f), buf, EBUFSIZ)) <= 0)
9517c478bd9Sstevel@tonic-gate 				break;
9527c478bd9Sstevel@tonic-gate 			blkno += count;
9537c478bd9Sstevel@tonic-gate 		}
9547c478bd9Sstevel@tonic-gate 		lnum++;
9557c478bd9Sstevel@tonic-gate 		if (reinit == 1)
9567c478bd9Sstevel@tonic-gate 			clearg();
9577c478bd9Sstevel@tonic-gate 	}
9587c478bd9Sstevel@tonic-gate 	fclose(f);
959*41599e9fSDamian Bogel 	if (cflag && !qflag) {
960*41599e9fSDamian Bogel 		if (Hflag || (nfile > 1 && !hflag))
961*41599e9fSDamian Bogel 			printf("%s:", file);
9627c478bd9Sstevel@tonic-gate 		printf("%lld\n", tln);
9637c478bd9Sstevel@tonic-gate 	}
9647c478bd9Sstevel@tonic-gate }
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate void
9677c478bd9Sstevel@tonic-gate clearg(void)
9687c478bd9Sstevel@tonic-gate {
9697c478bd9Sstevel@tonic-gate 	int i, k;
9707c478bd9Sstevel@tonic-gate 	for (i=1; i<=nstate; i++)
9717c478bd9Sstevel@tonic-gate 		out[i] = 0;
9727c478bd9Sstevel@tonic-gate 	for (i=1; i<=nstate; i++)
9737c478bd9Sstevel@tonic-gate 		for (k=0; k<NCHARS; k++)
9747c478bd9Sstevel@tonic-gate 			gotofn[i][k] = 0;
9757c478bd9Sstevel@tonic-gate 	nstate = 1;
9767c478bd9Sstevel@tonic-gate 	nxtpos = inxtpos;
9777c478bd9Sstevel@tonic-gate 	reinit = 0;
9787c478bd9Sstevel@tonic-gate 	count = 0;
9797c478bd9Sstevel@tonic-gate 	for (i=3; i<=line; i++) tmpstat[i] = 0;
9807c478bd9Sstevel@tonic-gate 	if (cstate(line-1)==0) {
9817c478bd9Sstevel@tonic-gate 		tmpstat[line] = 1;
9827c478bd9Sstevel@tonic-gate 		count++;
9837c478bd9Sstevel@tonic-gate 		out[1] = 1;
9847c478bd9Sstevel@tonic-gate 	}
9857c478bd9Sstevel@tonic-gate 	for (i=3; i<=line; i++) initstat[i] = tmpstat[i];
9867c478bd9Sstevel@tonic-gate 	count--;		/*leave out position 1 */
9877c478bd9Sstevel@tonic-gate 	icount = count;
9887c478bd9Sstevel@tonic-gate 	tmpstat[1] = 0;
9897c478bd9Sstevel@tonic-gate 	add(state, 1);
9907c478bd9Sstevel@tonic-gate 	istat = nxtst(1, LEFT);
9917c478bd9Sstevel@tonic-gate }
9927c478bd9Sstevel@tonic-gate 
9937c478bd9Sstevel@tonic-gate int
9947c478bd9Sstevel@tonic-gate mdotenter(void)
9957c478bd9Sstevel@tonic-gate {
9967c478bd9Sstevel@tonic-gate 	int i, x1, x2;
9977c478bd9Sstevel@tonic-gate 	x1 = enter(DOT);
9987c478bd9Sstevel@tonic-gate 	x2 = enter(MDOT);
9997c478bd9Sstevel@tonic-gate 	for(i = 1; i < (int) eucw1; i++)
10007c478bd9Sstevel@tonic-gate 		x2 = node(CAT, x2, enter(MDOT));
10017c478bd9Sstevel@tonic-gate 	x1 = node(OR, x1, x2);
10027c478bd9Sstevel@tonic-gate 	if(eucw2) {
10037c478bd9Sstevel@tonic-gate 		x2 = enter('\216');
10047c478bd9Sstevel@tonic-gate 		for(i = 1; i <= (int) eucw2; i++)
10057c478bd9Sstevel@tonic-gate 			x2 = node(CAT, x2, enter(MDOT));
10067c478bd9Sstevel@tonic-gate 		x1 = node(OR, x1, x2);
10077c478bd9Sstevel@tonic-gate 	}
10087c478bd9Sstevel@tonic-gate 	if(eucw3) {
10097c478bd9Sstevel@tonic-gate 		x2 = enter('\217');
10107c478bd9Sstevel@tonic-gate 		for(i = 1; i <= (int) eucw3; i++)
10117c478bd9Sstevel@tonic-gate 			x2 = node(CAT, x2, enter(MDOT));
10127c478bd9Sstevel@tonic-gate 		x1 = node(OR, x1, x2);
10137c478bd9Sstevel@tonic-gate 	}
10147c478bd9Sstevel@tonic-gate 	return(x1);
10157c478bd9Sstevel@tonic-gate }
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate int
10187c478bd9Sstevel@tonic-gate mchar(wchar_t c)
10197c478bd9Sstevel@tonic-gate {
10207c478bd9Sstevel@tonic-gate 	char multichar[MB_LEN_MAX+1];
10217c478bd9Sstevel@tonic-gate 	char *p;
10227c478bd9Sstevel@tonic-gate 	int x1, lc, length;
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate 	length = wctomb(multichar, c);
10257c478bd9Sstevel@tonic-gate 	p = multichar;
10267c478bd9Sstevel@tonic-gate 	*(p + length) = '\0';
10277c478bd9Sstevel@tonic-gate 	x1 = enter((unsigned char)*p++);
10287c478bd9Sstevel@tonic-gate 	while(lc = (unsigned char)*p++)
10297c478bd9Sstevel@tonic-gate 		x1 = node(CAT, x1, enter(lc));
10307c478bd9Sstevel@tonic-gate 	return(x1);
10317c478bd9Sstevel@tonic-gate }
10327c478bd9Sstevel@tonic-gate 
10337c478bd9Sstevel@tonic-gate int
10347c478bd9Sstevel@tonic-gate ccl(int type)
10357c478bd9Sstevel@tonic-gate {
10367c478bd9Sstevel@tonic-gate 	wchar_t c, lc;
10377c478bd9Sstevel@tonic-gate 	char multic1[MB_LEN_MAX];
10387c478bd9Sstevel@tonic-gate 	char multic2[MB_LEN_MAX];
10397c478bd9Sstevel@tonic-gate 	int x1, x2, length, current, last, cclcnt;
10407c478bd9Sstevel@tonic-gate 	x2 = 0;
10417c478bd9Sstevel@tonic-gate 	current = 0;
10427c478bd9Sstevel@tonic-gate 	last = genrange(type);
10437c478bd9Sstevel@tonic-gate 	nxtchar = count + 1;
10447c478bd9Sstevel@tonic-gate 	cclcnt = 0;
10457c478bd9Sstevel@tonic-gate 	/* create usual character class for single byte characters */
10467c478bd9Sstevel@tonic-gate 	while(current <= last && (isascii(c = lower[current]) || c <= 0377 && iscntrl(c))) {
10477c478bd9Sstevel@tonic-gate 		cclcnt++;
10487c478bd9Sstevel@tonic-gate 		chars[nxtchar++] = c;
10497c478bd9Sstevel@tonic-gate 		if(lower[current] != upper[current]) {
10507c478bd9Sstevel@tonic-gate 			chars[nxtchar++] = '-';
10517c478bd9Sstevel@tonic-gate 			chars[nxtchar++] = upper[current];
10527c478bd9Sstevel@tonic-gate 			cclcnt += 2;
10537c478bd9Sstevel@tonic-gate 		}
10547c478bd9Sstevel@tonic-gate 		current++;
10557c478bd9Sstevel@tonic-gate 	}
10567c478bd9Sstevel@tonic-gate 
10577c478bd9Sstevel@tonic-gate 	if(cclcnt)
10587c478bd9Sstevel@tonic-gate 		chars[count] = cclcnt;
10597c478bd9Sstevel@tonic-gate 	else
10607c478bd9Sstevel@tonic-gate 		nxtchar = count;
10617c478bd9Sstevel@tonic-gate 	if(current > 0)
10627c478bd9Sstevel@tonic-gate 		/* single byte part of character class */
10637c478bd9Sstevel@tonic-gate 		x2 = cclenter(type);
10647c478bd9Sstevel@tonic-gate 	else if(type == NCCL)
10657c478bd9Sstevel@tonic-gate 		/* all single byte characters match */
10667c478bd9Sstevel@tonic-gate 		x2 = enter(DOT);
10677c478bd9Sstevel@tonic-gate 	while(current <= last) {
10687c478bd9Sstevel@tonic-gate 		if(upper[current] == lower[current])
10697c478bd9Sstevel@tonic-gate 			x1 = mchar(lower[current]);
10707c478bd9Sstevel@tonic-gate 		else {
10717c478bd9Sstevel@tonic-gate 			length = wctomb(multic1, lower[current]);
10727c478bd9Sstevel@tonic-gate 			wctomb(multic2, upper[current]);
10737c478bd9Sstevel@tonic-gate 			x1 = range((unsigned char *)multic1,
10747c478bd9Sstevel@tonic-gate 			    (unsigned char *)multic2, length);
10757c478bd9Sstevel@tonic-gate 		}
10767c478bd9Sstevel@tonic-gate 		if(x2)
10777c478bd9Sstevel@tonic-gate 			x2 = node(OR, x2, x1);
10787c478bd9Sstevel@tonic-gate 		else
10797c478bd9Sstevel@tonic-gate 			x2 = x1;
10807c478bd9Sstevel@tonic-gate 		current++;
10817c478bd9Sstevel@tonic-gate 	}
10827c478bd9Sstevel@tonic-gate 	return x2;
10837c478bd9Sstevel@tonic-gate }
10847c478bd9Sstevel@tonic-gate 
10857c478bd9Sstevel@tonic-gate int
10867c478bd9Sstevel@tonic-gate range(unsigned char *p1, unsigned char *p2, int length)
10877c478bd9Sstevel@tonic-gate {
10887c478bd9Sstevel@tonic-gate 	char multic[MB_LEN_MAX+1];
10897c478bd9Sstevel@tonic-gate 	char *p;
10907c478bd9Sstevel@tonic-gate 	int i, x1, x2;
10917c478bd9Sstevel@tonic-gate 	if(length == 1)
10927c478bd9Sstevel@tonic-gate 		return(classenter(*p1, *p2));
10937c478bd9Sstevel@tonic-gate 	if(p1[0] == p2[0])
10947c478bd9Sstevel@tonic-gate 		return(node(CAT, enter(p1[0]), range(p1+1, p2+1, length - 1)));
10957c478bd9Sstevel@tonic-gate 	p = multic;
10967c478bd9Sstevel@tonic-gate 	for(i = 1; i < length; i++)
10977c478bd9Sstevel@tonic-gate 		*p++ = 0377;
10987c478bd9Sstevel@tonic-gate 	x1 = node(CAT, enter(p1[0]),
10997c478bd9Sstevel@tonic-gate 	    range(p1+1, (unsigned char *)multic, length - 1));
11007c478bd9Sstevel@tonic-gate 	if((unsigned char)(p1[0] + 1) < p2[0]) {
11017c478bd9Sstevel@tonic-gate 		x2 = classenter(p1[0] + 1, p2[0] - 1);
11027c478bd9Sstevel@tonic-gate 		for(i = 1; i < length; i++)
11037c478bd9Sstevel@tonic-gate 			x2 = node(CAT, x2, enter(MDOT));
11047c478bd9Sstevel@tonic-gate 		x1 = node(OR, x1, x2);
11057c478bd9Sstevel@tonic-gate 	}
11067c478bd9Sstevel@tonic-gate 	p = multic;
11077c478bd9Sstevel@tonic-gate 	for(i = 1; i < length; i++)
11087c478bd9Sstevel@tonic-gate 		*p++ = 0200;
11097c478bd9Sstevel@tonic-gate 	x2 = node(CAT, enter(p2[0]),
11107c478bd9Sstevel@tonic-gate 	    range((unsigned char *)multic, p2+1, length - 1));
11117c478bd9Sstevel@tonic-gate 	return node(OR, x1, x2);
11127c478bd9Sstevel@tonic-gate }
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate int
11157c478bd9Sstevel@tonic-gate classenter(int x1, int x2)
11167c478bd9Sstevel@tonic-gate {
11177c478bd9Sstevel@tonic-gate 	static int max, min;
11187c478bd9Sstevel@tonic-gate 	if(!max) {
11197c478bd9Sstevel@tonic-gate 		int i;
11207c478bd9Sstevel@tonic-gate 		for(i = 0200; i <= 0377; i++)
11217c478bd9Sstevel@tonic-gate 			if(!iscntrl(i))
11227c478bd9Sstevel@tonic-gate 				break;
11237c478bd9Sstevel@tonic-gate 		min = i;
11247c478bd9Sstevel@tonic-gate 		for(i = 0377; i >= 0200; i--)
11257c478bd9Sstevel@tonic-gate 			if(!iscntrl(i))
11267c478bd9Sstevel@tonic-gate 				break;
11277c478bd9Sstevel@tonic-gate 		max = i;
11287c478bd9Sstevel@tonic-gate 	}
11297c478bd9Sstevel@tonic-gate 	if(x1 <= min && x2 >= max)
11307c478bd9Sstevel@tonic-gate 		return enter(MDOT);
11317c478bd9Sstevel@tonic-gate 	if(nxtchar + 4 >= maxclin)
11327c478bd9Sstevel@tonic-gate 		if(allocchars() == 0)
11337c478bd9Sstevel@tonic-gate 			overflo();
11347c478bd9Sstevel@tonic-gate 	count = nxtchar++;
11357c478bd9Sstevel@tonic-gate 	chars[nxtchar++] = x1;
11367c478bd9Sstevel@tonic-gate 	chars[nxtchar++] = '-';
11377c478bd9Sstevel@tonic-gate 	chars[nxtchar++] = x2;
11387c478bd9Sstevel@tonic-gate 	chars[count] = 3;
11397c478bd9Sstevel@tonic-gate 	return cclenter(MCCL);
11407c478bd9Sstevel@tonic-gate }
11417c478bd9Sstevel@tonic-gate 
11427c478bd9Sstevel@tonic-gate int
11437c478bd9Sstevel@tonic-gate genrange(int type)
11447c478bd9Sstevel@tonic-gate {
11457c478bd9Sstevel@tonic-gate 	char *p, *endp;
11467c478bd9Sstevel@tonic-gate 	int current, nel, i, last, length;
11477c478bd9Sstevel@tonic-gate 	wchar_t c, lc;
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate 	current = 0;
11507c478bd9Sstevel@tonic-gate 	p = &chars[count+1];
11517c478bd9Sstevel@tonic-gate 	endp = &chars[count+1] + chars[count];
11527c478bd9Sstevel@tonic-gate 	lc = 0;
11537c478bd9Sstevel@tonic-gate 
11547c478bd9Sstevel@tonic-gate 	/* convert character class into union of ranges */
11557c478bd9Sstevel@tonic-gate 	while(p < endp) {
11567c478bd9Sstevel@tonic-gate 		length = mbtowc(&c, p, MB_LEN_MAX);
11577c478bd9Sstevel@tonic-gate 		p += length;
11587c478bd9Sstevel@tonic-gate 		if(c == '-' && lc != 0) {
11597c478bd9Sstevel@tonic-gate 			length = mbtowc(&c, p, MB_LEN_MAX);
11607c478bd9Sstevel@tonic-gate 			upper[current-1] = c;
11617c478bd9Sstevel@tonic-gate 			p += length;
11627c478bd9Sstevel@tonic-gate 		} else {
11637c478bd9Sstevel@tonic-gate 			lower[current] = c;
11647c478bd9Sstevel@tonic-gate 			upper[current++] = c;
11657c478bd9Sstevel@tonic-gate 		}
11667c478bd9Sstevel@tonic-gate 		lc = c;
11677c478bd9Sstevel@tonic-gate 	}
11687c478bd9Sstevel@tonic-gate 	nel = current;
11697c478bd9Sstevel@tonic-gate 	/* sort lower and upper bounds of ranges */
11707c478bd9Sstevel@tonic-gate 	qsort((char *)lower, nel, sizeof(wchar_t), compare);
11717c478bd9Sstevel@tonic-gate 	qsort((char *)upper, nel, sizeof(wchar_t), compare);
11727c478bd9Sstevel@tonic-gate 	last = current - 1;
11737c478bd9Sstevel@tonic-gate 	current = 0;
11747c478bd9Sstevel@tonic-gate 	/* combine overlapping or adjacent ranges */
11757c478bd9Sstevel@tonic-gate 	for(i = 0; i < last; i++)
11767c478bd9Sstevel@tonic-gate 		if(upper[i] >= lower[i+1] - 1)
11777c478bd9Sstevel@tonic-gate 			upper[current] = upper[i+1];
11787c478bd9Sstevel@tonic-gate 		else {
11797c478bd9Sstevel@tonic-gate 			lower[++current] = lower[i+1];
11807c478bd9Sstevel@tonic-gate 			upper[current] = upper[i+1];
11817c478bd9Sstevel@tonic-gate 		}
11827c478bd9Sstevel@tonic-gate 	if(type == NCCL) {
11837c478bd9Sstevel@tonic-gate 		/* find complement of character class */
11847c478bd9Sstevel@tonic-gate 		int j, next;
11857c478bd9Sstevel@tonic-gate 		i = 0;
11867c478bd9Sstevel@tonic-gate 		while(i <= current && isascii(c=lower[i]) || c <= 0377 && iscntrl(c))
11877c478bd9Sstevel@tonic-gate 			i++;
11887c478bd9Sstevel@tonic-gate 		if(i > current) {
11897c478bd9Sstevel@tonic-gate 			/* match all multibyte characters */
11907c478bd9Sstevel@tonic-gate 			if(eucw2) {
11917c478bd9Sstevel@tonic-gate 				lower[i] = maxmin(WCHAR_CS2, 0);
11927c478bd9Sstevel@tonic-gate 				upper[i++] = maxmin(WCHAR_CS2, 1);
11937c478bd9Sstevel@tonic-gate 			}
11947c478bd9Sstevel@tonic-gate 			if(eucw3) {
11957c478bd9Sstevel@tonic-gate 				lower[i] = maxmin(WCHAR_CS3, 0);
11967c478bd9Sstevel@tonic-gate 				upper[i++] = maxmin(WCHAR_CS3, 1);
11977c478bd9Sstevel@tonic-gate 			}
11987c478bd9Sstevel@tonic-gate 			lower[i] = maxmin(WCHAR_CS1, 0);
11997c478bd9Sstevel@tonic-gate 			upper[i++] = maxmin(WCHAR_CS1, 1);
12007c478bd9Sstevel@tonic-gate 			return i - 1;
12017c478bd9Sstevel@tonic-gate 		}
12027c478bd9Sstevel@tonic-gate 		next = current + 1;
12037c478bd9Sstevel@tonic-gate 		if(next + current + 2 >= maxwclin) {
12047c478bd9Sstevel@tonic-gate 			maxwclin += MAXLIN + next + current + 2;
12057c478bd9Sstevel@tonic-gate 			if((lower = (wchar_t *)realloc(lower, maxwclin *sizeof(wchar_t))) == (wchar_t *)0 ||
12067c478bd9Sstevel@tonic-gate 			   (upper = (wchar_t *)realloc(upper, maxwclin * sizeof(wchar_t))) == (wchar_t *)0)
12077c478bd9Sstevel@tonic-gate 				overflo();
12087c478bd9Sstevel@tonic-gate 		}
12097c478bd9Sstevel@tonic-gate 		if(eucw2 && lower[i] > maxmin(WCHAR_CS2, 0)) {
12107c478bd9Sstevel@tonic-gate 			lower[next] = maxmin(WCHAR_CS2, 0);
12117c478bd9Sstevel@tonic-gate 			if((lower[i] & WCHAR_CSMASK) != WCHAR_CS2) {
12127c478bd9Sstevel@tonic-gate 				upper[next++] = maxmin(WCHAR_CS2, 1);
12137c478bd9Sstevel@tonic-gate 				if((lower[i] & WCHAR_CSMASK) == WCHAR_CS1 && eucw3) {
12147c478bd9Sstevel@tonic-gate 					lower[next] = maxmin(WCHAR_CS3, 0);
12157c478bd9Sstevel@tonic-gate 					upper[next++] = maxmin(WCHAR_CS3, 1);
12167c478bd9Sstevel@tonic-gate 				}
12177c478bd9Sstevel@tonic-gate 				if(lower[i] > maxmin(lower[i] & WCHAR_CSMASK, 0)) {
12187c478bd9Sstevel@tonic-gate 					lower[next] = maxmin(lower[i] & WCHAR_CSMASK, 0);
12197c478bd9Sstevel@tonic-gate 					upper[next++] = lower[i] - 1;
12207c478bd9Sstevel@tonic-gate 				}
12217c478bd9Sstevel@tonic-gate 			} else
12227c478bd9Sstevel@tonic-gate 				upper[next++] = lower[i] - 1;
12237c478bd9Sstevel@tonic-gate 		} else if(lower[i] > maxmin(lower[i] & WCHAR_CSMASK, 0)) {
12247c478bd9Sstevel@tonic-gate 			lower[next] = maxmin(lower[i] & WCHAR_CSMASK, 0);
12257c478bd9Sstevel@tonic-gate 			upper[next++] = lower[i] - 1;
12267c478bd9Sstevel@tonic-gate 		}
12277c478bd9Sstevel@tonic-gate 		for(j = i; j < current; j++) {
12287c478bd9Sstevel@tonic-gate 			if(upper[j] < maxmin(upper[j] & WCHAR_CSMASK, 1)) {
12297c478bd9Sstevel@tonic-gate 				lower[next] = upper[j] + 1;
12307c478bd9Sstevel@tonic-gate 				if((upper[j] & WCHAR_CSMASK) != (lower[j+1] & WCHAR_CSMASK)) {
12317c478bd9Sstevel@tonic-gate 					upper[next++] = maxmin(upper[j] & WCHAR_CSMASK, 1);
12327c478bd9Sstevel@tonic-gate 					if(eucw3 && (upper[j] & WCHAR_CSMASK) == WCHAR_CS2 && (lower[j+1] & WCHAR_CSMASK) == WCHAR_CS1) {
12337c478bd9Sstevel@tonic-gate 						lower[next] = maxmin(WCHAR_CS3, 0);
12347c478bd9Sstevel@tonic-gate 						upper[next++] = maxmin(WCHAR_CS3, 1);
12357c478bd9Sstevel@tonic-gate 					}
12367c478bd9Sstevel@tonic-gate 					if(lower[j+1] > maxmin(lower[j+1] & WCHAR_CSMASK, 0)) {
12377c478bd9Sstevel@tonic-gate 						lower[next] = maxmin(lower[j+1] & WCHAR_CSMASK, 0);
12387c478bd9Sstevel@tonic-gate 						upper[next++] = lower[j+1] - 1;
12397c478bd9Sstevel@tonic-gate 					}
12407c478bd9Sstevel@tonic-gate 				} else
12417c478bd9Sstevel@tonic-gate 					upper[next++] = lower[j+1] - 1;
12427c478bd9Sstevel@tonic-gate 			} else if(lower[j+1] > maxmin(lower[j+1], 0)) {
12437c478bd9Sstevel@tonic-gate 				lower[next] = maxmin(lower[j+1], 0);
12447c478bd9Sstevel@tonic-gate 				upper[next++] = lower[j+1] - 1;
12457c478bd9Sstevel@tonic-gate 			}
12467c478bd9Sstevel@tonic-gate 		}
12477c478bd9Sstevel@tonic-gate 		if(upper[current] < maxmin(upper[current] & WCHAR_CSMASK, 1)) {
12487c478bd9Sstevel@tonic-gate 			lower[next] = upper[current] + 1;
12497c478bd9Sstevel@tonic-gate 			upper[next++] = maxmin(upper[current] & WCHAR_CSMASK, 1);
12507c478bd9Sstevel@tonic-gate 		}
12517c478bd9Sstevel@tonic-gate 		if((upper[current] & WCHAR_CSMASK) != WCHAR_CS1) {
12527c478bd9Sstevel@tonic-gate 			if((upper[current] & WCHAR_CSMASK) == WCHAR_CS2 && eucw3) {
12537c478bd9Sstevel@tonic-gate 				lower[next] = maxmin(WCHAR_CS3, 0);
12547c478bd9Sstevel@tonic-gate 				upper[next++] = maxmin(WCHAR_CS3, 1);
12557c478bd9Sstevel@tonic-gate 			}
12567c478bd9Sstevel@tonic-gate 			lower[next] = maxmin(WCHAR_CS1, 0);
12577c478bd9Sstevel@tonic-gate 			upper[next++] = maxmin(WCHAR_CS1, 1);
12587c478bd9Sstevel@tonic-gate 		}
12597c478bd9Sstevel@tonic-gate 		for(j = current + 1; j < next; j++) {
12607c478bd9Sstevel@tonic-gate 			lower[i] = lower[j];
12617c478bd9Sstevel@tonic-gate 			upper[i++] = upper[j];
12627c478bd9Sstevel@tonic-gate 		}
12637c478bd9Sstevel@tonic-gate 		current = i - 1;
12647c478bd9Sstevel@tonic-gate 	}
12657c478bd9Sstevel@tonic-gate 	return(current);
12667c478bd9Sstevel@tonic-gate }
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate int
12697c478bd9Sstevel@tonic-gate compare(wchar_t *c, wchar_t *d)
12707c478bd9Sstevel@tonic-gate {
12717c478bd9Sstevel@tonic-gate 	if(*c < *d)
12727c478bd9Sstevel@tonic-gate 		return -1;
12737c478bd9Sstevel@tonic-gate 	if(*c == *d)
12747c478bd9Sstevel@tonic-gate 		return 0;
12757c478bd9Sstevel@tonic-gate 	return 1;
12767c478bd9Sstevel@tonic-gate }
12777c478bd9Sstevel@tonic-gate 
12787c478bd9Sstevel@tonic-gate wchar_t
12797c478bd9Sstevel@tonic-gate maxmin(wchar_t c, int flag)
12807c478bd9Sstevel@tonic-gate {
12817c478bd9Sstevel@tonic-gate 	static wchar_t minmax1[2], minmax2[2], minmax3[2];
12827c478bd9Sstevel@tonic-gate 
12837c478bd9Sstevel@tonic-gate 	if(!minmax1[0]) {
12847c478bd9Sstevel@tonic-gate 		/* compute min and max process codes for all code sets */
12857c478bd9Sstevel@tonic-gate 		int length, i;
12867c478bd9Sstevel@tonic-gate 		char multic[MB_LEN_MAX], minmax[2];
12877c478bd9Sstevel@tonic-gate 		for(i = 0377; i >= 0200; i--)
12887c478bd9Sstevel@tonic-gate 			if(!iscntrl(i))
12897c478bd9Sstevel@tonic-gate 				break;
12907c478bd9Sstevel@tonic-gate 		minmax[1] = i;
12917c478bd9Sstevel@tonic-gate 		for(i = 0240; i <= 0377; i++)
12927c478bd9Sstevel@tonic-gate 			if(!iscntrl(i))
12937c478bd9Sstevel@tonic-gate 				break;
12947c478bd9Sstevel@tonic-gate 		minmax[0] = i;
12957c478bd9Sstevel@tonic-gate 		for(i = 0; i <= 1; i++) {
12967c478bd9Sstevel@tonic-gate 			length = MB_LEN_MAX;
12977c478bd9Sstevel@tonic-gate 			while(length--)
12987c478bd9Sstevel@tonic-gate 				multic[length] = minmax[i];
12997c478bd9Sstevel@tonic-gate 			mbtowc(&minmax1[i], multic, MB_LEN_MAX);
13007c478bd9Sstevel@tonic-gate 			if(eucw2) {
13017c478bd9Sstevel@tonic-gate 				multic[0] = SS2;
13027c478bd9Sstevel@tonic-gate 				mbtowc(&minmax2[i], multic, MB_LEN_MAX);
13037c478bd9Sstevel@tonic-gate 			}
13047c478bd9Sstevel@tonic-gate 			if(eucw3) {
13057c478bd9Sstevel@tonic-gate 				multic[0] = SS3;
13067c478bd9Sstevel@tonic-gate 				mbtowc(&minmax3[i], multic, MB_LEN_MAX);
13077c478bd9Sstevel@tonic-gate 			}
13087c478bd9Sstevel@tonic-gate 		}
13097c478bd9Sstevel@tonic-gate 	}
13107c478bd9Sstevel@tonic-gate 	switch(c) {
13117c478bd9Sstevel@tonic-gate 		case WCHAR_CS1: return minmax1[flag];
13127c478bd9Sstevel@tonic-gate 		case WCHAR_CS2: return minmax2[flag];
13137c478bd9Sstevel@tonic-gate 		case WCHAR_CS3: return minmax3[flag];
13147c478bd9Sstevel@tonic-gate 	}
13157c478bd9Sstevel@tonic-gate 
13167c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
13177c478bd9Sstevel@tonic-gate 	return (0);
13187c478bd9Sstevel@tonic-gate }
1319