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