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 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright (C) Lucent Technologies 1997
  28  * All Rights Reserved
  29  *
  30  * Permission to use, copy, modify, and distribute this software and
  31  * its documentation for any purpose and without fee is hereby
  32  * granted, provided that the above copyright notice appear in all
  33  * copies and that both that the copyright notice and this
  34  * permission notice and warranty disclaimer appear in supporting
  35  * documentation, and that the name Lucent Technologies or any of
  36  * its entities not be used in advertising or publicity pertaining
  37  * to distribution of the software without specific, written prior
  38  * permission.
  39  *
  40  * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  41  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  42  * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
  43  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  44  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  45  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  46  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
  47  * THIS SOFTWARE.
  48  */
  49 #include "awk.h"
  50 #include "y.tab.h"
  51 
  52 struct xx {
  53         int token;
  54         const char *name;
  55         const char *pname;
  56 } proc[] = {
  57         { PROGRAM, "program", NULL },
  58         { BOR, "boolop", " || " },
  59         { AND, "boolop", " && " },
  60         { NOT, "boolop", " !" },
  61         { NE, "relop", " != " },
  62         { EQ, "relop", " == " },
  63         { LE, "relop", " <= " },
  64         { LT, "relop", " < " },
  65         { GE, "relop", " >= " },
  66         { GT, "relop", " > " },
  67         { ARRAY, "array", NULL },
  68         { INDIRECT, "indirect", "$(" },
  69         { SUBSTR, "substr", "substr" },
  70         { SUB, "sub", "sub" },
  71         { GSUB, "gsub", "gsub" },
  72         { INDEX, "sindex", "sindex" },
  73         { SPRINTF, "awksprintf", "sprintf " },
  74         { ADD, "arith", " + " },
  75         { MINUS, "arith", " - " },
  76         { MULT, "arith", " * " },
  77         { DIVIDE, "arith", " / " },
  78         { MOD, "arith", " % " },
  79         { UMINUS, "arith", " -" },
  80         { POWER, "arith", " **" },
  81         { PREINCR, "incrdecr", "++" },
  82         { POSTINCR, "incrdecr", "++" },
  83         { PREDECR, "incrdecr", "--" },
  84         { POSTDECR, "incrdecr", "--" },
  85         { CAT, "cat", " " },
  86         { PASTAT, "pastat", NULL },
  87         { PASTAT2, "dopa2", NULL },
  88         { MATCH, "matchop", " ~ " },
  89         { NOTMATCH, "matchop", " !~ " },
  90         { MATCHFCN, "matchop", "matchop" },
  91         { INTEST, "intest", "intest" },
  92         { PRINTF, "awkprintf", "printf" },
  93         { PRINT, "printstat", "print" },
  94         { CLOSE, "closefile", "closefile" },
  95         { DELETE, "awkdelete", "awkdelete" },
  96         { SPLIT, "split", "split" },
  97         { ASSIGN, "assign", " = " },
  98         { ADDEQ, "assign", " += " },
  99         { SUBEQ, "assign", " -= " },
 100         { MULTEQ, "assign", " *= " },
 101         { DIVEQ, "assign", " /= " },
 102         { MODEQ, "assign", " %= " },
 103         { POWEQ, "assign", " ^= " },
 104         { CONDEXPR, "condexpr", " ?: " },
 105         { IF, "ifstat", "if(" },
 106         { WHILE, "whilestat", "while(" },
 107         { FOR, "forstat", "for(" },
 108         { DO, "dostat", "do" },
 109         { IN, "instat", "instat" },
 110         { NEXT, "jump", "next" },
 111         { NEXTFILE, "jump", "nextfile" },
 112         { EXIT, "jump", "exit" },
 113         { BREAK, "jump", "break" },
 114         { CONTINUE, "jump", "continue" },
 115         { RETURN, "jump", "ret" },
 116         { BLTIN, "bltin", "bltin" },
 117         { CALL, "call", "call" },
 118         { ARG, "arg", "arg" },
 119         { VARNF, "getnf", "NF" },
 120         { GETLINE, "awkgetline", "getline" },
 121         { 0, "", "" },
 122 };
 123 
 124 #define SIZE    (LASTTOKEN - FIRSTTOKEN + 1)
 125 const char *table[SIZE];
 126 char *names[SIZE];
 127 
 128 /* ARGSUSED */
 129 int
 130 main(int argc, char *argv[])
 131 {
 132         const struct xx *p;
 133         int i, n, tok;
 134         char c;
 135         FILE *fp;
 136         char buf[200], name[200], def[200];
 137 
 138         (void) printf("#include <stdio.h>\n");
 139         (void) printf("#include \"awk.h\"\n");
 140         (void) printf("#include \"y.tab.h\"\n\n");
 141         for (i = SIZE; --i >= 0; )
 142                 names[i] = "";
 143 
 144         if ((fp = fopen("y.tab.h", "r")) == NULL) {
 145                 (void) fprintf(stderr,
 146                     gettext("maketab can't open y.tab.h!\n"));
 147                 exit(1);
 148         }
 149         (void) printf("static uchar *printname[%d] = {\n", SIZE);
 150         i = 0;
 151         while (fgets(buf, sizeof (buf), fp) != NULL) {
 152                 /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
 153                 n = sscanf(buf, "%1c %s %s %d", &c, def, name, &tok);
 154                 /* not a valid #define? */
 155                 if (c != '#' || (n != 4 && strcmp(def, "define") != 0))
 156                         continue;
 157                 if (tok < FIRSTTOKEN || tok > LASTTOKEN)
 158                         continue;
 159                 names[tok-FIRSTTOKEN] = (char *)malloc(strlen(name)+1);
 160                 (void) strcpy(names[tok-FIRSTTOKEN], name);
 161                 (void) printf("\t(uchar *) \"%s\",\t/* %d */\n", name, tok);
 162                 i++;
 163         }
 164         (void) printf("};\n\n");
 165 
 166         for (p = proc; p->token != 0; p++)
 167                 table[p->token-FIRSTTOKEN] = p->name;
 168         (void) printf("\nCell *(*proctab[%d])(Node **, int) = {\n", SIZE);
 169         for (i = 0; i < SIZE; i++)
 170                 if (table[i] == 0)
 171                         (void) printf("\tnullproc,\t/* %s */\n", names[i]);
 172                 else
 173                         (void) printf("\t%s,\t/* %s */\n", table[i], names[i]);
 174         (void) printf("};\n\n");
 175 
 176         /* print a tokname() function */
 177         (void) printf("uchar *\ntokname(int n)\n");
 178         (void) printf("{\n");
 179         (void) printf(" static char buf[100];\n\n");
 180         (void) printf(" if (n < FIRSTTOKEN || n > LASTTOKEN) {\n");
 181         (void) printf("         (void) sprintf(buf, \"token %%d\", n);\n");
 182         (void) printf("         return ((uchar *)buf);\n");
 183         (void) printf(" }\n");
 184         (void) printf(" return printname[n-FIRSTTOKEN];\n");
 185         (void) printf("}\n");
 186         return (0);
 187 }