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 2007 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 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 ccptr = ccl = (CHR *)myalloc(CCLSIZE, sizeof (*ccl)); 247 pcptr = pchar = (CHR *)myalloc(pchlen, sizeof (*pchar)); 248 def = (CHR **)myalloc(DEFSIZE, sizeof (*def)); 249 subs = (CHR **)myalloc(DEFSIZE, sizeof (*subs)); 250 dp = dchar = (CHR *)myalloc(DEFCHAR, sizeof (*dchar)); 251 sname = (CHR **)myalloc(STARTSIZE, sizeof (*sname)); 252 /* XCU4: exclusive start array */ 253 exclusive = (int *)myalloc(STARTSIZE, sizeof (*exclusive)); 254 sp = schar = (CHR *)myalloc(STARTCHAR, sizeof (*schar)); 255 if (ccl == 0 || def == 0 || 256 pchar == 0 || subs == 0 || dchar == 0 || 257 sname == 0 || exclusive == 0 || schar == 0) 258 error("Too little core to begin"); 259 } 260 261 static void 262 free1core(void) 263 { 264 free(def); 265 free(subs); 266 free(dchar); 267 } 268 269 static void 270 get2core(void) 271 { 272 int i; 273 gotof = (int *)myalloc(nstates, sizeof (*gotof)); 274 nexts = (int *)myalloc(ntrans, sizeof (*nexts)); 275 nchar = (CHR *)myalloc(ntrans, sizeof (*nchar)); 276 state = (int **)myalloc(nstates, sizeof (*state)); 277 atable = (int *)myalloc(nstates, sizeof (*atable)); 278 sfall = (int *)myalloc(nstates, sizeof (*sfall)); 279 cpackflg = (Boolean *)myalloc(nstates, sizeof (*cpackflg)); 280 tmpstat = (CHR *)myalloc(tptr+1, sizeof (*tmpstat)); 281 foll = (int **)myalloc(tptr+1, sizeof (*foll)); 282 nxtpos = positions = (int *)myalloc(maxpos, sizeof (*positions)); 283 if (tmpstat == 0 || foll == 0 || positions == 0 || 284 gotof == 0 || nexts == 0 || nchar == 0 || 285 state == 0 || atable == 0 || sfall == 0 || cpackflg == 0) 286 error("Too little core for state generation"); 287 for (i = 0; i <= tptr; i++) 288 foll[i] = 0; 289 } 290 291 static void 292 free2core(void) 293 { 294 free(positions); 295 free(tmpstat); 296 free(foll); 297 free(name); 298 free(left); 299 free(right); 300 free(parent); 301 free(nullstr); 302 free(state); 303 free(sname); 304 /* XCU4: exclusive start array */ 305 free(exclusive); 306 free(schar); 307 free(ccl); 308 } 309 310 static void 311 get3core(void) 312 { 313 verify = (int *)myalloc(outsize, sizeof (*verify)); 314 advance = (int *)myalloc(outsize, sizeof (*advance)); 315 stoff = (int *)myalloc(stnum+2, sizeof (*stoff)); 316 if (verify == 0 || advance == 0 || stoff == 0) 317 error("Too little core for final packing"); 318 } 319 320 #ifdef DEBUG 321 static void 322 free3core(void) 323 { 324 free(advance); 325 free(verify); 326 free(stoff); 327 free(gotof); 328 free(nexts); 329 free(nchar); 330 free(atable); 331 free(sfall); 332 free(cpackflg); 333 } 334 #endif 335 336 BYTE * 337 myalloc(int a, int b) 338 { 339 BYTE *i; 340 i = calloc(a, b); 341 if (i == 0) 342 warning("calloc returns a 0"); 343 return (i); 344 } 345 346 void 347 yyerror(char *s) 348 { 349 (void) fprintf(stderr, 350 "\"%s\":line %d: Error: %s\n", sargv[optind], yyline, s); 351 } 352