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