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 }