xref: /illumos-gate/usr/src/cmd/sgs/lex/common/main.c (revision 287247a826fa2ab8d01f6c8f276d405eb08420f8)
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 (c) 2014 Gary Mills
23  *
24  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 /* Copyright (c) 1988 AT&T */
29 /* All Rights Reserved */
30 
31 /* Copyright 1976, Bell Telephone Laboratories, Inc. */
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 *apath = NULL;
55 	char *ypath;
56 	Boolean eoption = 0, woption = 0;
57 
58 	sargv = argv;
59 	sargc = argc;
60 	(void) setlocale(LC_ALL, "");
61 #ifdef DEBUG
62 	while ((c = getopt(argc, argv, "dyctvnewVQ:Y:")) != EOF) {
63 #else
64 	while ((c = getopt(argc, argv, "ctvnewVQ:Y:")) != EOF) {
65 #endif
66 		switch (c) {
67 #ifdef DEBUG
68 			case 'd':
69 				debug++;
70 				break;
71 			case 'y':
72 				yydebug = TRUE;
73 				break;
74 #endif
75 			case 'V':
76 				(void) fprintf(stderr, "lex: %s %s\n",
77 				    (const char *)SGU_PKG,
78 				    (const char *)SGU_REL);
79 				break;
80 			case 'Q':
81 				v_stmp = optarg;
82 				if (*v_stmp != 'y' && *v_stmp != 'n')
83 					error(
84 					"lex: -Q should be followed by [y/n]");
85 				break;
86 			case 'Y':
87 				apath = (char *)malloc(strlen(optarg) +
88 				    sizeof ("/nceucform") + 1);
89 				if (apath == NULL)
90 					error("No available memory "
91 					    "for directory name.");
92 				else
93 					apath = strcpy(apath, optarg);
94 				break;
95 			case 'c':
96 				ratfor = FALSE;
97 				break;
98 			case 't':
99 				fout = stdout;
100 				break;
101 			case 'v':
102 				report = 1;
103 				break;
104 			case 'n':
105 				report = 0;
106 				break;
107 			case 'w':
108 			case 'W':
109 				woption = 1;
110 				handleeuc = 1;
111 				widecio = 1;
112 				break;
113 			case 'e':
114 			case 'E':
115 				eoption = 1;
116 				handleeuc = 1;
117 				widecio = 0;
118 				break;
119 			default:
120 				(void) fprintf(stderr,
121 				"Usage: lex [-ewctvnV] [-Y directory] "
122 				"[-Q(y/n)] [file]\n");
123 				exit(1);
124 		}
125 	}
126 	if (woption && eoption) {
127 		error(
128 		"You may not specify both -w and -e simultaneously.");
129 	}
130 	no_input = argc - optind;
131 	if (no_input) {
132 		/* XCU4: recognize "-" file operand for stdin */
133 		if (strcmp(argv[optind], "-") == 0)
134 			fin = stdin;
135 		else {
136 			fin = fopen(argv[optind], "r");
137 			if (fin == NULL)
138 				error(
139 				"Can't open input file -- %s", argv[optind]);
140 		}
141 	} else
142 		fin = stdin;
143 
144 	/* may be gotten: def, subs, sname, schar, ccl, dchar */
145 	(void) gch();
146 
147 	/* may be gotten: name, left, right, nullstr, parent */
148 	get1core();
149 
150 	scopy(L_INITIAL, sp);
151 	sname[0] = sp;
152 	sp += slength(L_INITIAL) + 1;
153 	sname[1] = 0;
154 
155 	/* XCU4: %x exclusive start */
156 	exclusive[0] = 0;
157 
158 	if (!handleeuc) {
159 		/*
160 		 * Set ZCH and ncg to their default values
161 		 * as they may be needed to handle %t directive.
162 		 */
163 		ZCH = ncg = NCH; /* ncg behaves as constant in this mode. */
164 	}
165 
166 	/* may be disposed of: def, subs, dchar */
167 	if (yyparse())
168 		exit(1);	/* error return code */
169 
170 	if (handleeuc) {
171 		ncg = ncgidtbl * 2;
172 		ZCH = ncg;
173 		if (ncg >= MAXNCG)
174 			error(
175 			"Too complex rules -- requires too many char groups.");
176 		sortcgidtbl();
177 	}
178 	repbycgid(); /* Call this even in ASCII compat. mode. */
179 
180 	/*
181 	 * maybe get:
182 	 *		tmpstat, foll, positions, gotof, nexts,
183 	 *		nchar, state, atable, sfall, cpackflg
184 	 */
185 	free1core();
186 	get2core();
187 	ptail();
188 	mkmatch();
189 #ifdef DEBUG
190 	if (debug)
191 		pccl();
192 #endif
193 	sect  = ENDSECTION;
194 	if (tptr > 0)
195 		cfoll(tptr-1);
196 #ifdef DEBUG
197 	if (debug)
198 		pfoll();
199 #endif
200 	cgoto();
201 #ifdef DEBUG
202 	if (debug) {
203 		(void) printf("Print %d states:\n", stnum + 1);
204 		for (i = 0; i <= stnum; i++)
205 			stprt(i);
206 	}
207 #endif
208 	/*
209 	 * may be disposed of:
210 	 *		positions, tmpstat, foll, state, name,
211 	 *		left, right, parent, ccl, schar, sname
212 	 * maybe get:	 verify, advance, stoff
213 	 */
214 	free2core();
215 	get3core();
216 	layout();
217 	/*
218 	 * may be disposed of:
219 	 *		verify, advance, stoff, nexts, nchar,
220 	 *		gotof, atable, ccpackflg, sfall
221 	 */
222 
223 #ifdef DEBUG
224 	free3core();
225 #endif
226 
227 	if (handleeuc) {
228 		if (ratfor)
229 			error("Ratfor is not supported by -w or -e option.");
230 		ypath = EUCNAME;
231 	}
232 	else
233 		ypath = ratfor ? RATNAME : CNAME;
234 
235 	if (apath != NULL)
236 		ypath = strcat(apath, strrchr(ypath, '/'));
237 	fother = fopen(ypath, "r");
238 	if (fother == NULL)
239 		error("Lex driver missing, file %s", ypath);
240 	while ((i = getc(fother)) != EOF)
241 		(void) putc((char)i, fout);
242 	(void) fclose(fother);
243 	(void) fclose(fout);
244 	free(apath);
245 	if (report == 1)
246 		statistics();
247 	(void) fclose(stdout);
248 	(void) fclose(stderr);
249 	return (0);	/* success return code */
250 }
251 
252 static void
253 get1core(void)
254 {
255 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
256 	ccptr =	ccl = (CHR *)myalloc(CCLSIZE, sizeof (*ccl));
257 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
258 	pcptr = pchar = (CHR *)myalloc(pchlen, sizeof (*pchar));
259 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
260 	def = (CHR **)myalloc(DEFSIZE, sizeof (*def));
261 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
262 	subs = (CHR **)myalloc(DEFSIZE, sizeof (*subs));
263 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
264 	dp = dchar = (CHR *)myalloc(DEFCHAR, sizeof (*dchar));
265 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
266 	sname = (CHR **)myalloc(STARTSIZE, sizeof (*sname));
267 	/* XCU4: exclusive start array */
268 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
269 	exclusive = (int *)myalloc(STARTSIZE, sizeof (*exclusive));
270 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
271 	sp = schar = (CHR *)myalloc(STARTCHAR, sizeof (*schar));
272 	if (ccl == 0 || def == 0 ||
273 	    pchar == 0 || subs == 0 || dchar == 0 ||
274 	    sname == 0 || exclusive == 0 || schar == 0)
275 		error("Too little core to begin");
276 }
277 
278 static void
279 free1core(void)
280 {
281 	free(def);
282 	free(subs);
283 	free(dchar);
284 }
285 
286 static void
287 get2core(void)
288 {
289 	int i;
290 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
291 	gotof = (int *)myalloc(nstates, sizeof (*gotof));
292 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
293 	nexts = (int *)myalloc(ntrans, sizeof (*nexts));
294 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
295 	nchar = (CHR *)myalloc(ntrans, sizeof (*nchar));
296 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
297 	state = (int **)myalloc(nstates, sizeof (*state));
298 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
299 	atable = (int *)myalloc(nstates, sizeof (*atable));
300 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
301 	sfall = (int *)myalloc(nstates, sizeof (*sfall));
302 	cpackflg = (Boolean *)myalloc(nstates, sizeof (*cpackflg));
303 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
304 	tmpstat = (CHR *)myalloc(tptr+1, sizeof (*tmpstat));
305 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
306 	foll = (int **)myalloc(tptr+1, sizeof (*foll));
307 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
308 	nxtpos = positions = (int *)myalloc(maxpos, sizeof (*positions));
309 	if (tmpstat == 0 || foll == 0 || positions == 0 ||
310 	    gotof == 0 || nexts == 0 || nchar == 0 ||
311 	    state == 0 || atable == 0 || sfall == 0 || cpackflg == 0)
312 		error("Too little core for state generation");
313 	for (i = 0; i <= tptr; i++)
314 		foll[i] = 0;
315 }
316 
317 static void
318 free2core(void)
319 {
320 	free(positions);
321 	free(tmpstat);
322 	free(foll);
323 	free(name);
324 	free(left);
325 	free(right);
326 	free(parent);
327 	free(nullstr);
328 	free(state);
329 	free(sname);
330 	/* XCU4: exclusive start array */
331 	free(exclusive);
332 	free(schar);
333 	free(ccl);
334 }
335 
336 static void
337 get3core(void)
338 {
339 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
340 	verify = (int *)myalloc(outsize, sizeof (*verify));
341 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
342 	advance = (int *)myalloc(outsize, sizeof (*advance));
343 	/*LINTED: E_BAD_PTR_CAST_ALIGN*/
344 	stoff = (int *)myalloc(stnum+2, sizeof (*stoff));
345 	if (verify == 0 || advance == 0 || stoff == 0)
346 		error("Too little core for final packing");
347 }
348 
349 #ifdef DEBUG
350 static void
351 free3core(void)
352 {
353 	free(advance);
354 	free(verify);
355 	free(stoff);
356 	free(gotof);
357 	free(nexts);
358 	free(nchar);
359 	free(atable);
360 	free(sfall);
361 	free(cpackflg);
362 }
363 #endif
364 
365 BYTE *
366 myalloc(int a, int b)
367 {
368 	BYTE *i;
369 	i = calloc(a,  b);
370 	if (i == 0)
371 		warning("calloc returns a 0");
372 	return (i);
373 }
374 
375 void
376 yyerror(char *s)
377 {
378 	(void) fprintf(stderr,
379 	    "\"%s\":line %d: Error: %s\n", sargv[optind], yyline, s);
380 }
381