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