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 (c) 2014 Gary Mills
  23  *
  24  * Copyright 2008 Sun Microsystems, Inc.  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 #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 *apath = NULL;
  55         char *ypath;
  56         Boolean eoption = 0, woption = 0;
  57 
  58         sargv = argv;
  59         sargc = argc;
  60         (void) setlocale(LC_ALL, "");
  61 #ifdef DEBUG
  62         while ((c = getopt(argc, argv, "dyctvnewVQ:Y:")) != EOF) {
  63 #else
  64         while ((c = getopt(argc, argv, "ctvnewVQ:Y:")) != EOF) {
  65 #endif
  66                 switch (c) {
  67 #ifdef DEBUG
  68                         case 'd':
  69                                 debug++;
  70                                 break;
  71                         case 'y':
  72                                 yydebug = TRUE;
  73                                 break;
  74 #endif
  75                         case 'V':
  76                                 (void) fprintf(stderr, "lex: %s %s\n",
  77                                     (const char *)SGU_PKG,
  78                                     (const char *)SGU_REL);
  79                                 break;
  80                         case 'Q':
  81                                 v_stmp = optarg;
  82                                 if (*v_stmp != 'y' && *v_stmp != 'n')
  83                                         error(
  84                                         "lex: -Q should be followed by [y/n]");
  85                                 break;
  86                         case 'Y':
  87                                 apath = (char *)malloc(strlen(optarg) +
  88                                     sizeof ("/nceucform") + 1);
  89                                 if (apath == NULL)
  90                                         error("No available memory "
  91                                             "for directory name.");
  92                                 else
  93                                         apath = strcpy(apath, optarg);
  94                                 break;
  95                         case 'c':
  96                                 ratfor = FALSE;
  97                                 break;
  98                         case 't':
  99                                 fout = stdout;
 100                                 break;
 101                         case 'v':
 102                                 report = 1;
 103                                 break;
 104                         case 'n':
 105                                 report = 0;
 106                                 break;
 107                         case 'w':
 108                         case 'W':
 109                                 woption = 1;
 110                                 handleeuc = 1;
 111                                 widecio = 1;
 112                                 break;
 113                         case 'e':
 114                         case 'E':
 115                                 eoption = 1;
 116                                 handleeuc = 1;
 117                                 widecio = 0;
 118                                 break;
 119                         default:
 120                                 (void) fprintf(stderr,
 121                                 "Usage: lex [-ewctvnV] [-Y directory] "
 122                                 "[-Q(y/n)] [file]\n");
 123                                 exit(1);
 124                 }
 125         }
 126         if (woption && eoption) {
 127                 error(
 128                 "You may not specify both -w and -e simultaneously.");
 129         }
 130         no_input = argc - optind;
 131         if (no_input) {
 132                 /* XCU4: recognize "-" file operand for stdin */
 133                 if (strcmp(argv[optind], "-") == 0)
 134                         fin = stdin;
 135                 else {
 136                         fin = fopen(argv[optind], "r");
 137                         if (fin == NULL)
 138                                 error(
 139                                 "Can't open input file -- %s", argv[optind]);
 140                 }
 141         } else
 142                 fin = stdin;
 143 
 144         /* may be gotten: def, subs, sname, schar, ccl, dchar */
 145         (void) gch();
 146 
 147         /* may be gotten: name, left, right, nullstr, parent */
 148         get1core();
 149 
 150         scopy(L_INITIAL, sp);
 151         sname[0] = sp;
 152         sp += slength(L_INITIAL) + 1;
 153         sname[1] = 0;
 154 
 155         /* XCU4: %x exclusive start */
 156         exclusive[0] = 0;
 157 
 158         if (!handleeuc) {
 159                 /*
 160                  * Set ZCH and ncg to their default values
 161                  * as they may be needed to handle %t directive.
 162                  */
 163                 ZCH = ncg = NCH; /* ncg behaves as constant in this mode. */
 164         }
 165 
 166         /* may be disposed of: def, subs, dchar */
 167         if (yyparse())
 168                 exit(1);        /* error return code */
 169 
 170         if (handleeuc) {
 171                 ncg = ncgidtbl * 2;
 172                 ZCH = ncg;
 173                 if (ncg >= MAXNCG)
 174                         error(
 175                         "Too complex rules -- requires too many char groups.");
 176                 sortcgidtbl();
 177         }
 178         repbycgid(); /* Call this even in ASCII compat. mode. */
 179 
 180         /*
 181          * maybe get:
 182          *              tmpstat, foll, positions, gotof, nexts,
 183          *              nchar, state, atable, sfall, cpackflg
 184          */
 185         free1core();
 186         get2core();
 187         ptail();
 188         mkmatch();
 189 #ifdef DEBUG
 190         if (debug)
 191                 pccl();
 192 #endif
 193         sect  = ENDSECTION;
 194         if (tptr > 0)
 195                 cfoll(tptr-1);
 196 #ifdef DEBUG
 197         if (debug)
 198                 pfoll();
 199 #endif
 200         cgoto();
 201 #ifdef DEBUG
 202         if (debug) {
 203                 (void) printf("Print %d states:\n", stnum + 1);
 204                 for (i = 0; i <= stnum; i++)
 205                         stprt(i);
 206         }
 207 #endif
 208         /*
 209          * may be disposed of:
 210          *              positions, tmpstat, foll, state, name,
 211          *              left, right, parent, ccl, schar, sname
 212          * maybe get:    verify, advance, stoff
 213          */
 214         free2core();
 215         get3core();
 216         layout();
 217         /*
 218          * may be disposed of:
 219          *              verify, advance, stoff, nexts, nchar,
 220          *              gotof, atable, ccpackflg, sfall
 221          */
 222 
 223 #ifdef DEBUG
 224         free3core();
 225 #endif
 226 
 227         if (handleeuc) {
 228                 if (ratfor)
 229                         error("Ratfor is not supported by -w or -e option.");
 230                 ypath = EUCNAME;
 231         }
 232         else
 233                 ypath = ratfor ? RATNAME : CNAME;
 234 
 235         if (apath != NULL)
 236                 ypath = strcat(apath, strrchr(ypath, '/'));
 237         fother = fopen(ypath, "r");
 238         if (fother == NULL)
 239                 error("Lex driver missing, file %s", ypath);
 240         while ((i = getc(fother)) != EOF)
 241                 (void) putc((char)i, fout);
 242         (void) fclose(fother);
 243         (void) fclose(fout);
 244         free(apath);
 245         if (report == 1)
 246                 statistics();
 247         (void) fclose(stdout);
 248         (void) fclose(stderr);
 249         return (0);     /* success return code */
 250 }
 251 
 252 static void
 253 get1core(void)
 254 {
 255         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 256         ccptr = ccl = (CHR *)myalloc(CCLSIZE, sizeof (*ccl));
 257         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 258         pcptr = pchar = (CHR *)myalloc(pchlen, sizeof (*pchar));
 259         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 260         def = (CHR **)myalloc(DEFSIZE, sizeof (*def));
 261         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 262         subs = (CHR **)myalloc(DEFSIZE, sizeof (*subs));
 263         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 264         dp = dchar = (CHR *)myalloc(DEFCHAR, sizeof (*dchar));
 265         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 266         sname = (CHR **)myalloc(STARTSIZE, sizeof (*sname));
 267         /* XCU4: exclusive start array */
 268         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 269         exclusive = (int *)myalloc(STARTSIZE, sizeof (*exclusive));
 270         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 271         sp = schar = (CHR *)myalloc(STARTCHAR, sizeof (*schar));
 272         if (ccl == 0 || def == 0 ||
 273             pchar == 0 || subs == 0 || dchar == 0 ||
 274             sname == 0 || exclusive == 0 || schar == 0)
 275                 error("Too little core to begin");
 276 }
 277 
 278 static void
 279 free1core(void)
 280 {
 281         free(def);
 282         free(subs);
 283         free(dchar);
 284 }
 285 
 286 static void
 287 get2core(void)
 288 {
 289         int i;
 290         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 291         gotof = (int *)myalloc(nstates, sizeof (*gotof));
 292         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 293         nexts = (int *)myalloc(ntrans, sizeof (*nexts));
 294         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 295         nchar = (CHR *)myalloc(ntrans, sizeof (*nchar));
 296         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 297         state = (int **)myalloc(nstates, sizeof (*state));
 298         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 299         atable = (int *)myalloc(nstates, sizeof (*atable));
 300         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 301         sfall = (int *)myalloc(nstates, sizeof (*sfall));
 302         cpackflg = (Boolean *)myalloc(nstates, sizeof (*cpackflg));
 303         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 304         tmpstat = (CHR *)myalloc(tptr+1, sizeof (*tmpstat));
 305         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 306         foll = (int **)myalloc(tptr+1, sizeof (*foll));
 307         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 308         nxtpos = positions = (int *)myalloc(maxpos, sizeof (*positions));
 309         if (tmpstat == 0 || foll == 0 || positions == 0 ||
 310             gotof == 0 || nexts == 0 || nchar == 0 ||
 311             state == 0 || atable == 0 || sfall == 0 || cpackflg == 0)
 312                 error("Too little core for state generation");
 313         for (i = 0; i <= tptr; i++)
 314                 foll[i] = 0;
 315 }
 316 
 317 static void
 318 free2core(void)
 319 {
 320         free(positions);
 321         free(tmpstat);
 322         free(foll);
 323         free(name);
 324         free(left);
 325         free(right);
 326         free(parent);
 327         free(nullstr);
 328         free(state);
 329         free(sname);
 330         /* XCU4: exclusive start array */
 331         free(exclusive);
 332         free(schar);
 333         free(ccl);
 334 }
 335 
 336 static void
 337 get3core(void)
 338 {
 339         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 340         verify = (int *)myalloc(outsize, sizeof (*verify));
 341         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 342         advance = (int *)myalloc(outsize, sizeof (*advance));
 343         /*LINTED: E_BAD_PTR_CAST_ALIGN*/
 344         stoff = (int *)myalloc(stnum+2, sizeof (*stoff));
 345         if (verify == 0 || advance == 0 || stoff == 0)
 346                 error("Too little core for final packing");
 347 }
 348 
 349 #ifdef DEBUG
 350 static void
 351 free3core(void)
 352 {
 353         free(advance);
 354         free(verify);
 355         free(stoff);
 356         free(gotof);
 357         free(nexts);
 358         free(nchar);
 359         free(atable);
 360         free(sfall);
 361         free(cpackflg);
 362 }
 363 #endif
 364 
 365 BYTE *
 366 myalloc(int a, int b)
 367 {
 368         BYTE *i;
 369         i = calloc(a,  b);
 370         if (i == 0)
 371                 warning("calloc returns a 0");
 372         return (i);
 373 }
 374 
 375 void
 376 yyerror(char *s)
 377 {
 378         (void) fprintf(stderr,
 379             "\"%s\":line %d: Error: %s\n", sargv[optind], yyline, s);
 380 }