xref: /illumos-gate/usr/src/cmd/sgs/lex/common/main.c (revision d2ec54f7875f7e05edd56195adbeb593c947763f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
28 
29 /* Copyright 1976, Bell Telephone Laboratories, Inc. */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #include <string.h>
34 #include "once.h"
35 #include "sgs.h"
36 #include <locale.h>
37 #include <limits.h>
38 
39 static wchar_t  L_INITIAL[] = {'I', 'N', 'I', 'T', 'I', 'A', 'L', 0};
40 static void get1core(void);
41 static void free1core(void);
42 static void get2core(void);
43 static void free2core(void);
44 static void get3core(void);
45 #ifdef DEBUG
46 static void free3core(void);
47 #endif
48 
49 int
50 main(int argc, char **argv)
51 {
52 	int i;
53 	int c;
54 	char *path = NULL;
55 	Boolean eoption = 0, woption = 0;
56 
57 	sargv = argv;
58 	sargc = argc;
59 	setlocale(LC_ALL, "");
60 #ifdef DEBUG
61 	while ((c = getopt(argc, argv, "dyctvnewVQ:Y:")) != EOF) {
62 #else
63 	while ((c = getopt(argc, argv, "ctvnewVQ:Y:")) != EOF) {
64 #endif
65 		switch (c) {
66 #ifdef DEBUG
67 			case 'd':
68 				debug++;
69 				break;
70 			case 'y':
71 				yydebug = TRUE;
72 				break;
73 #endif
74 			case 'V':
75 				(void) fprintf(stderr, "lex: %s %s\n",
76 				    (const char *)SGU_PKG,
77 				    (const char *)SGU_REL);
78 				break;
79 			case 'Q':
80 				v_stmp = optarg;
81 				if (*v_stmp != 'y' && *v_stmp != 'n')
82 					error(
83 					"lex: -Q should be followed by [y/n]");
84 				break;
85 			case 'Y':
86 				path = (char *)malloc(strlen(optarg) +
87 				    sizeof ("/nceucform") + 1);
88 				path = strcpy(path, optarg);
89 				break;
90 			case 'c':
91 				ratfor = FALSE;
92 				break;
93 			case 't':
94 				fout = stdout;
95 				break;
96 			case 'v':
97 				report = 1;
98 				break;
99 			case 'n':
100 				report = 0;
101 				break;
102 			case 'w':
103 			case 'W':
104 				woption = 1;
105 				handleeuc = 1;
106 				widecio = 1;
107 				break;
108 			case 'e':
109 			case 'E':
110 				eoption = 1;
111 				handleeuc = 1;
112 				widecio = 0;
113 				break;
114 			default:
115 				(void) fprintf(stderr,
116 				"Usage: lex [-ewctvnVY] [-Q(y/n)] [file]\n");
117 				exit(1);
118 		}
119 	}
120 	if (woption && eoption) {
121 		error(
122 		"You may not specify both -w and -e simultaneously.");
123 	}
124 	no_input = argc - optind;
125 	if (no_input) {
126 		/* XCU4: recognize "-" file operand for stdin */
127 		if (strcmp(argv[optind], "-") == 0)
128 			fin = stdin;
129 		else {
130 			fin = fopen(argv[optind], "r");
131 			if (fin == NULL)
132 				error(
133 				"Can't open input file -- %s", argv[optind]);
134 		}
135 	} else
136 		fin = stdin;
137 
138 	/* may be gotten: def, subs, sname, schar, ccl, dchar */
139 	(void) gch();
140 
141 	/* may be gotten: name, left, right, nullstr, parent */
142 	get1core();
143 
144 	scopy(L_INITIAL, sp);
145 	sname[0] = sp;
146 	sp += slength(L_INITIAL) + 1;
147 	sname[1] = 0;
148 
149 	/* XCU4: %x exclusive start */
150 	exclusive[0] = 0;
151 
152 	if (!handleeuc) {
153 		/*
154 		 * Set ZCH and ncg to their default values
155 		 * as they may be needed to handle %t directive.
156 		 */
157 		ZCH = ncg = NCH; /* ncg behaves as constant in this mode. */
158 	}
159 
160 	/* may be disposed of: def, subs, dchar */
161 	if (yyparse())
162 		exit(1);	/* error return code */
163 
164 	if (handleeuc) {
165 		ncg = ncgidtbl * 2;
166 		ZCH = ncg;
167 		if (ncg >= MAXNCG)
168 			error(
169 			"Too complex rules -- requires too many char groups.");
170 		sortcgidtbl();
171 	}
172 	repbycgid(); /* Call this even in ASCII compat. mode. */
173 
174 	/*
175 	 * maybe get:
176 	 *		tmpstat, foll, positions, gotof, nexts,
177 	 *		nchar, state, atable, sfall, cpackflg
178 	 */
179 	free1core();
180 	get2core();
181 	ptail();
182 	mkmatch();
183 #ifdef DEBUG
184 	if (debug)
185 		pccl();
186 #endif
187 	sect  = ENDSECTION;
188 	if (tptr > 0)
189 		cfoll(tptr-1);
190 #ifdef DEBUG
191 	if (debug)
192 		pfoll();
193 #endif
194 	cgoto();
195 #ifdef DEBUG
196 	if (debug) {
197 		(void) printf("Print %d states:\n", stnum + 1);
198 		for (i = 0; i <= stnum; i++)
199 			stprt(i);
200 	}
201 #endif
202 	/*
203 	 * may be disposed of:
204 	 *		positions, tmpstat, foll, state, name,
205 	 *		left, right, parent, ccl, schar, sname
206 	 * maybe get:	 verify, advance, stoff
207 	 */
208 	free2core();
209 	get3core();
210 	layout();
211 	/*
212 	 * may be disposed of:
213 	 *		verify, advance, stoff, nexts, nchar,
214 	 *		gotof, atable, ccpackflg, sfall
215 	 */
216 
217 #ifdef DEBUG
218 	free3core();
219 #endif
220 
221 	if (handleeuc) {
222 		if (ratfor)
223 			error("Ratfor is not supported by -w or -e option.");
224 		path = EUCNAME;
225 	}
226 	else
227 		path = ratfor ? RATNAME : CNAME;
228 
229 	fother = fopen(path, "r");
230 	if (fother == NULL)
231 		error("Lex driver missing, file %s", path);
232 	while ((i = getc(fother)) != EOF)
233 		(void) putc((char)i, fout);
234 	(void) fclose(fother);
235 	(void) fclose(fout);
236 	if (report == 1)
237 		statistics();
238 	(void) fclose(stdout);
239 	(void) fclose(stderr);
240 	return (0);	/* success return code */
241 }
242 
243 static void
244 get1core(void)
245 {
246 	ccptr =	ccl = (CHR *)myalloc(CCLSIZE, sizeof (*ccl));
247 	pcptr = pchar = (CHR *)myalloc(pchlen, sizeof (*pchar));
248 	def = (CHR **)myalloc(DEFSIZE, sizeof (*def));
249 	subs = (CHR **)myalloc(DEFSIZE, sizeof (*subs));
250 	dp = dchar = (CHR *)myalloc(DEFCHAR, sizeof (*dchar));
251 	sname = (CHR **)myalloc(STARTSIZE, sizeof (*sname));
252 	/* XCU4: exclusive start array */
253 	exclusive = (int *)myalloc(STARTSIZE, sizeof (*exclusive));
254 	sp = schar = (CHR *)myalloc(STARTCHAR, sizeof (*schar));
255 	if (ccl == 0 || def == 0 ||
256 	    pchar == 0 || subs == 0 || dchar == 0 ||
257 	    sname == 0 || exclusive == 0 || schar == 0)
258 		error("Too little core to begin");
259 }
260 
261 static void
262 free1core(void)
263 {
264 	free(def);
265 	free(subs);
266 	free(dchar);
267 }
268 
269 static void
270 get2core(void)
271 {
272 	int i;
273 	gotof = (int *)myalloc(nstates, sizeof (*gotof));
274 	nexts = (int *)myalloc(ntrans, sizeof (*nexts));
275 	nchar = (CHR *)myalloc(ntrans, sizeof (*nchar));
276 	state = (int **)myalloc(nstates, sizeof (*state));
277 	atable = (int *)myalloc(nstates, sizeof (*atable));
278 	sfall = (int *)myalloc(nstates, sizeof (*sfall));
279 	cpackflg = (Boolean *)myalloc(nstates, sizeof (*cpackflg));
280 	tmpstat = (CHR *)myalloc(tptr+1, sizeof (*tmpstat));
281 	foll = (int **)myalloc(tptr+1, sizeof (*foll));
282 	nxtpos = positions = (int *)myalloc(maxpos, sizeof (*positions));
283 	if (tmpstat == 0 || foll == 0 || positions == 0 ||
284 	    gotof == 0 || nexts == 0 || nchar == 0 ||
285 	    state == 0 || atable == 0 || sfall == 0 || cpackflg == 0)
286 		error("Too little core for state generation");
287 	for (i = 0; i <= tptr; i++)
288 		foll[i] = 0;
289 }
290 
291 static void
292 free2core(void)
293 {
294 	free(positions);
295 	free(tmpstat);
296 	free(foll);
297 	free(name);
298 	free(left);
299 	free(right);
300 	free(parent);
301 	free(nullstr);
302 	free(state);
303 	free(sname);
304 	/* XCU4: exclusive start array */
305 	free(exclusive);
306 	free(schar);
307 	free(ccl);
308 }
309 
310 static void
311 get3core(void)
312 {
313 	verify = (int *)myalloc(outsize, sizeof (*verify));
314 	advance = (int *)myalloc(outsize, sizeof (*advance));
315 	stoff = (int *)myalloc(stnum+2, sizeof (*stoff));
316 	if (verify == 0 || advance == 0 || stoff == 0)
317 		error("Too little core for final packing");
318 }
319 
320 #ifdef DEBUG
321 static void
322 free3core(void)
323 {
324 	free(advance);
325 	free(verify);
326 	free(stoff);
327 	free(gotof);
328 	free(nexts);
329 	free(nchar);
330 	free(atable);
331 	free(sfall);
332 	free(cpackflg);
333 }
334 #endif
335 
336 BYTE *
337 myalloc(int a, int b)
338 {
339 	BYTE *i;
340 	i = calloc(a,  b);
341 	if (i == 0)
342 		warning("calloc returns a 0");
343 	return (i);
344 }
345 
346 void
347 yyerror(char *s)
348 {
349 	(void) fprintf(stderr,
350 	    "\"%s\":line %d: Error: %s\n", sargv[optind], yyline, s);
351 }
352