xref: /illumos-gate/usr/src/cmd/sgs/lex/common/main.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 2008 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 	(void) 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 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
247 	ccptr =	ccl = (CHR *)myalloc(CCLSIZE, sizeof (*ccl));
248 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
249 	pcptr = pchar = (CHR *)myalloc(pchlen, sizeof (*pchar));
250 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
251 	def = (CHR **)myalloc(DEFSIZE, sizeof (*def));
252 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
253 	subs = (CHR **)myalloc(DEFSIZE, sizeof (*subs));
254 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
255 	dp = dchar = (CHR *)myalloc(DEFCHAR, sizeof (*dchar));
256 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
257 	sname = (CHR **)myalloc(STARTSIZE, sizeof (*sname));
258 	/* XCU4: exclusive start array */
259 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
260 	exclusive = (int *)myalloc(STARTSIZE, sizeof (*exclusive));
261 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
262 	sp = schar = (CHR *)myalloc(STARTCHAR, sizeof (*schar));
263 	if (ccl == 0 || def == 0 ||
264 	    pchar == 0 || subs == 0 || dchar == 0 ||
265 	    sname == 0 || exclusive == 0 || schar == 0)
266 		error("Too little core to begin");
267 }
268 
269 static void
270 free1core(void)
271 {
272 	free(def);
273 	free(subs);
274 	free(dchar);
275 }
276 
277 static void
278 get2core(void)
279 {
280 	int i;
281 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
282 	gotof = (int *)myalloc(nstates, sizeof (*gotof));
283 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
284 	nexts = (int *)myalloc(ntrans, sizeof (*nexts));
285 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
286 	nchar = (CHR *)myalloc(ntrans, sizeof (*nchar));
287 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
288 	state = (int **)myalloc(nstates, sizeof (*state));
289 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
290 	atable = (int *)myalloc(nstates, sizeof (*atable));
291 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
292 	sfall = (int *)myalloc(nstates, sizeof (*sfall));
293 	cpackflg = (Boolean *)myalloc(nstates, sizeof (*cpackflg));
294 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
295 	tmpstat = (CHR *)myalloc(tptr+1, sizeof (*tmpstat));
296 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
297 	foll = (int **)myalloc(tptr+1, sizeof (*foll));
298 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
299 	nxtpos = positions = (int *)myalloc(maxpos, sizeof (*positions));
300 	if (tmpstat == 0 || foll == 0 || positions == 0 ||
301 	    gotof == 0 || nexts == 0 || nchar == 0 ||
302 	    state == 0 || atable == 0 || sfall == 0 || cpackflg == 0)
303 		error("Too little core for state generation");
304 	for (i = 0; i <= tptr; i++)
305 		foll[i] = 0;
306 }
307 
308 static void
309 free2core(void)
310 {
311 	free(positions);
312 	free(tmpstat);
313 	free(foll);
314 	free(name);
315 	free(left);
316 	free(right);
317 	free(parent);
318 	free(nullstr);
319 	free(state);
320 	free(sname);
321 	/* XCU4: exclusive start array */
322 	free(exclusive);
323 	free(schar);
324 	free(ccl);
325 }
326 
327 static void
328 get3core(void)
329 {
330 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
331 	verify = (int *)myalloc(outsize, sizeof (*verify));
332 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
333 	advance = (int *)myalloc(outsize, sizeof (*advance));
334 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
335 	stoff = (int *)myalloc(stnum+2, sizeof (*stoff));
336 	if (verify == 0 || advance == 0 || stoff == 0)
337 		error("Too little core for final packing");
338 }
339 
340 #ifdef DEBUG
341 static void
342 free3core(void)
343 {
344 	free(advance);
345 	free(verify);
346 	free(stoff);
347 	free(gotof);
348 	free(nexts);
349 	free(nchar);
350 	free(atable);
351 	free(sfall);
352 	free(cpackflg);
353 }
354 #endif
355 
356 BYTE *
357 myalloc(int a, int b)
358 {
359 	BYTE *i;
360 	i = calloc(a,  b);
361 	if (i == 0)
362 		warning("calloc returns a 0");
363 	return (i);
364 }
365 
366 void
367 yyerror(char *s)
368 {
369 	(void) fprintf(stderr,
370 	    "\"%s\":line %d: Error: %s\n", sargv[optind], yyline, s);
371 }
372