xref: /openbsd/usr.bin/awk/maketab.c (revision 3cab2bb3)
1 /*	$OpenBSD: maketab.c,v 1.20 2020/07/30 17:45:44 millert Exp $	*/
2 /****************************************************************
3 Copyright (C) Lucent Technologies 1997
4 All Rights Reserved
5 
6 Permission to use, copy, modify, and distribute this software and
7 its documentation for any purpose and without fee is hereby
8 granted, provided that the above copyright notice appear in all
9 copies and that both that the copyright notice and this
10 permission notice and warranty disclaimer appear in supporting
11 documentation, and that the name Lucent Technologies or any of
12 its entities not be used in advertising or publicity pertaining
13 to distribution of the software without specific, written prior
14 permission.
15 
16 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23 THIS 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 
38 struct 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, "sub", "sub" },
57 	{ GSUB, "gsub", "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)
113 const char *table[SIZE];
114 char *names[SIZE];
115 
116 int 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 			exit(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