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 * 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 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