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