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