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