xref: /openbsd-src/lib/libcurses/tinfo/make_hash.c (revision c7ef0cfc17afcba97172c25e1e3a943e893bc632)
1*c7ef0cfcSnicm /****************************************************************************
2*c7ef0cfcSnicm  * Copyright 2018-2019,2020 Thomas E. Dickey                                *
3*c7ef0cfcSnicm  * Copyright 2009-2013,2017 Free Software Foundation, Inc.                  *
4*c7ef0cfcSnicm  *                                                                          *
5*c7ef0cfcSnicm  * Permission is hereby granted, free of charge, to any person obtaining a  *
6*c7ef0cfcSnicm  * copy of this software and associated documentation files (the            *
7*c7ef0cfcSnicm  * "Software"), to deal in the Software without restriction, including      *
8*c7ef0cfcSnicm  * without limitation the rights to use, copy, modify, merge, publish,      *
9*c7ef0cfcSnicm  * distribute, distribute with modifications, sublicense, and/or sell       *
10*c7ef0cfcSnicm  * copies of the Software, and to permit persons to whom the Software is    *
11*c7ef0cfcSnicm  * furnished to do so, subject to the following conditions:                 *
12*c7ef0cfcSnicm  *                                                                          *
13*c7ef0cfcSnicm  * The above copyright notice and this permission notice shall be included  *
14*c7ef0cfcSnicm  * in all copies or substantial portions of the Software.                   *
15*c7ef0cfcSnicm  *                                                                          *
16*c7ef0cfcSnicm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17*c7ef0cfcSnicm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18*c7ef0cfcSnicm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19*c7ef0cfcSnicm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20*c7ef0cfcSnicm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21*c7ef0cfcSnicm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22*c7ef0cfcSnicm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23*c7ef0cfcSnicm  *                                                                          *
24*c7ef0cfcSnicm  * Except as contained in this notice, the name(s) of the above copyright   *
25*c7ef0cfcSnicm  * holders shall not be used in advertising or otherwise to promote the     *
26*c7ef0cfcSnicm  * sale, use or other dealings in this Software without prior written       *
27*c7ef0cfcSnicm  * authorization.                                                           *
28*c7ef0cfcSnicm  ****************************************************************************/
29*c7ef0cfcSnicm 
30*c7ef0cfcSnicm /****************************************************************************
31*c7ef0cfcSnicm  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
32*c7ef0cfcSnicm  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
33*c7ef0cfcSnicm  *     and: Thomas E. Dickey                        1996-on                 *
34*c7ef0cfcSnicm  ****************************************************************************/
35*c7ef0cfcSnicm 
36*c7ef0cfcSnicm /*
37*c7ef0cfcSnicm  *	make_hash.c --- build-time program for constructing comp_captab.c
38*c7ef0cfcSnicm  */
39*c7ef0cfcSnicm 
40*c7ef0cfcSnicm #include <build.priv.h>
41*c7ef0cfcSnicm 
42*c7ef0cfcSnicm #include <tic.h>
43*c7ef0cfcSnicm #include <hashsize.h>
44*c7ef0cfcSnicm 
45*c7ef0cfcSnicm #include <ctype.h>
46*c7ef0cfcSnicm 
47*c7ef0cfcSnicm MODULE_ID("$Id: make_hash.c,v 1.1 2023/10/17 09:52:09 nicm Exp $")
48*c7ef0cfcSnicm 
49*c7ef0cfcSnicm /*
50*c7ef0cfcSnicm  *	_nc_make_hash_table()
51*c7ef0cfcSnicm  *
52*c7ef0cfcSnicm  *	Takes the entries in table[] and hashes them into hash_table[]
53*c7ef0cfcSnicm  *	by name.  There are CAPTABSIZE entries in the predefined table[]
54*c7ef0cfcSnicm  *	and HASHTABSIZE slots in hash_table[].
55*c7ef0cfcSnicm  *
56*c7ef0cfcSnicm  */
57*c7ef0cfcSnicm 
58*c7ef0cfcSnicm #undef MODULE_ID
59*c7ef0cfcSnicm #define MODULE_ID(id)		/*nothing */
60*c7ef0cfcSnicm #include <tinfo/doalloc.c>
61*c7ef0cfcSnicm 
62*c7ef0cfcSnicm #define L_PAREN "("
63*c7ef0cfcSnicm #define R_PAREN ")"
64*c7ef0cfcSnicm #define L_BRACE "{"
65*c7ef0cfcSnicm #define R_BRACE "}"
66*c7ef0cfcSnicm 
67*c7ef0cfcSnicm static const char *typenames[] =
68*c7ef0cfcSnicm {"BOOLEAN", "NUMBER", "STRING"};
69*c7ef0cfcSnicm 
70*c7ef0cfcSnicm static void
failed(const char * s)71*c7ef0cfcSnicm failed(const char *s)
72*c7ef0cfcSnicm {
73*c7ef0cfcSnicm     perror(s);
74*c7ef0cfcSnicm     exit(EXIT_FAILURE);
75*c7ef0cfcSnicm }
76*c7ef0cfcSnicm 
77*c7ef0cfcSnicm static char *
strmalloc(char * s)78*c7ef0cfcSnicm strmalloc(char *s)
79*c7ef0cfcSnicm {
80*c7ef0cfcSnicm     size_t need = strlen(s) + 1;
81*c7ef0cfcSnicm     char *result = malloc(need);
82*c7ef0cfcSnicm     if (result == 0)
83*c7ef0cfcSnicm 	failed("strmalloc");
84*c7ef0cfcSnicm     _nc_STRCPY(result, s, need);
85*c7ef0cfcSnicm     return result;
86*c7ef0cfcSnicm }
87*c7ef0cfcSnicm 
88*c7ef0cfcSnicm /*
89*c7ef0cfcSnicm  *	int hash_function(string)
90*c7ef0cfcSnicm  *
91*c7ef0cfcSnicm  *	Computes the hashing function on the given string.
92*c7ef0cfcSnicm  *
93*c7ef0cfcSnicm  *	The current hash function is the sum of each consecutive pair
94*c7ef0cfcSnicm  *	of characters, taken as two-byte integers, mod HASHTABSIZE.
95*c7ef0cfcSnicm  *
96*c7ef0cfcSnicm  */
97*c7ef0cfcSnicm 
98*c7ef0cfcSnicm static int
hash_function(const char * string)99*c7ef0cfcSnicm hash_function(const char *string)
100*c7ef0cfcSnicm {
101*c7ef0cfcSnicm     long sum = 0;
102*c7ef0cfcSnicm 
103*c7ef0cfcSnicm     while (*string) {
104*c7ef0cfcSnicm 	sum += (long) (UChar(*string) + (UChar(*(string + 1)) << 8));
105*c7ef0cfcSnicm 	string++;
106*c7ef0cfcSnicm     }
107*c7ef0cfcSnicm 
108*c7ef0cfcSnicm     return (int) (sum % HASHTABSIZE);
109*c7ef0cfcSnicm }
110*c7ef0cfcSnicm 
111*c7ef0cfcSnicm #define UNUSED -1
112*c7ef0cfcSnicm 
113*c7ef0cfcSnicm static void
_nc_make_hash_table(struct user_table_entry * table,HashValue * hash_table,unsigned tablesize)114*c7ef0cfcSnicm _nc_make_hash_table(struct user_table_entry *table,
115*c7ef0cfcSnicm 		    HashValue * hash_table,
116*c7ef0cfcSnicm 		    unsigned tablesize)
117*c7ef0cfcSnicm {
118*c7ef0cfcSnicm     unsigned i;
119*c7ef0cfcSnicm     int hashvalue;
120*c7ef0cfcSnicm     int collisions = 0;
121*c7ef0cfcSnicm 
122*c7ef0cfcSnicm     for (i = 0; i < HASHTABSIZE; i++) {
123*c7ef0cfcSnicm 	hash_table[i] = UNUSED;
124*c7ef0cfcSnicm     }
125*c7ef0cfcSnicm     for (i = 0; i < tablesize; i++) {
126*c7ef0cfcSnicm 	hashvalue = hash_function(table[i].ute_name);
127*c7ef0cfcSnicm 
128*c7ef0cfcSnicm 	if (hash_table[hashvalue] >= 0)
129*c7ef0cfcSnicm 	    collisions++;
130*c7ef0cfcSnicm 
131*c7ef0cfcSnicm 	if (hash_table[hashvalue] != UNUSED) {
132*c7ef0cfcSnicm 	    table[i].ute_link = hash_table[hashvalue];
133*c7ef0cfcSnicm 	}
134*c7ef0cfcSnicm 	hash_table[hashvalue] = (HashValue) i;
135*c7ef0cfcSnicm     }
136*c7ef0cfcSnicm 
137*c7ef0cfcSnicm     printf("/* %d collisions out of %d entries */\n", collisions, tablesize);
138*c7ef0cfcSnicm }
139*c7ef0cfcSnicm 
140*c7ef0cfcSnicm /*
141*c7ef0cfcSnicm  * This filter reads from standard input a list of tab-delimited columns,
142*c7ef0cfcSnicm  * (e.g., from Caps.filtered) computes the hash-value of a specified column and
143*c7ef0cfcSnicm  * writes the hashed tables to standard output.
144*c7ef0cfcSnicm  *
145*c7ef0cfcSnicm  * By compiling the hash table at build time, we're able to make the entire
146*c7ef0cfcSnicm  * set of terminfo and termcap tables readonly (and also provide some runtime
147*c7ef0cfcSnicm  * performance enhancement).
148*c7ef0cfcSnicm  */
149*c7ef0cfcSnicm 
150*c7ef0cfcSnicm #define MAX_COLUMNS BUFSIZ	/* this _has_ to be worst-case */
151*c7ef0cfcSnicm 
152*c7ef0cfcSnicm static int
count_columns(char ** list)153*c7ef0cfcSnicm count_columns(char **list)
154*c7ef0cfcSnicm {
155*c7ef0cfcSnicm     int result = 0;
156*c7ef0cfcSnicm     if (list != 0) {
157*c7ef0cfcSnicm 	while (*list++) {
158*c7ef0cfcSnicm 	    ++result;
159*c7ef0cfcSnicm 	}
160*c7ef0cfcSnicm     }
161*c7ef0cfcSnicm     return result;
162*c7ef0cfcSnicm }
163*c7ef0cfcSnicm 
164*c7ef0cfcSnicm static char **
parse_columns(char * buffer)165*c7ef0cfcSnicm parse_columns(char *buffer)
166*c7ef0cfcSnicm {
167*c7ef0cfcSnicm     static char **list;
168*c7ef0cfcSnicm 
169*c7ef0cfcSnicm     int col = 0;
170*c7ef0cfcSnicm 
171*c7ef0cfcSnicm     if (buffer == 0) {
172*c7ef0cfcSnicm 	free(list);
173*c7ef0cfcSnicm 	list = 0;
174*c7ef0cfcSnicm 	return 0;
175*c7ef0cfcSnicm     }
176*c7ef0cfcSnicm 
177*c7ef0cfcSnicm     if (*buffer != '#') {
178*c7ef0cfcSnicm 	if (list == 0) {
179*c7ef0cfcSnicm 	    list = typeCalloc(char *, (MAX_COLUMNS + 1));
180*c7ef0cfcSnicm 	    if (list == 0)
181*c7ef0cfcSnicm 		return (0);
182*c7ef0cfcSnicm 	}
183*c7ef0cfcSnicm 	while (*buffer != '\0') {
184*c7ef0cfcSnicm 	    char *s;
185*c7ef0cfcSnicm 	    for (s = buffer; (*s != '\0') && !isspace(UChar(*s)); s++)
186*c7ef0cfcSnicm 		/*EMPTY */ ;
187*c7ef0cfcSnicm 	    if (s != buffer) {
188*c7ef0cfcSnicm 		char mark = *s;
189*c7ef0cfcSnicm 		*s = '\0';
190*c7ef0cfcSnicm 		if ((s - buffer) > 1
191*c7ef0cfcSnicm 		    && (*buffer == '"')
192*c7ef0cfcSnicm 		    && (s[-1] == '"')) {	/* strip the quotes */
193*c7ef0cfcSnicm 		    assert(s > buffer + 1);
194*c7ef0cfcSnicm 		    s[-1] = '\0';
195*c7ef0cfcSnicm 		    buffer++;
196*c7ef0cfcSnicm 		}
197*c7ef0cfcSnicm 		list[col] = buffer;
198*c7ef0cfcSnicm 		col++;
199*c7ef0cfcSnicm 		if (mark == '\0')
200*c7ef0cfcSnicm 		    break;
201*c7ef0cfcSnicm 		while (*++s && isspace(UChar(*s)))
202*c7ef0cfcSnicm 		    /*EMPTY */ ;
203*c7ef0cfcSnicm 		buffer = s;
204*c7ef0cfcSnicm 	    } else
205*c7ef0cfcSnicm 		break;
206*c7ef0cfcSnicm 	}
207*c7ef0cfcSnicm     }
208*c7ef0cfcSnicm     return col ? list : 0;
209*c7ef0cfcSnicm }
210*c7ef0cfcSnicm 
211*c7ef0cfcSnicm #define SetType(n,t) \
212*c7ef0cfcSnicm 	if (is_user) \
213*c7ef0cfcSnicm 	    name_table[n].ute_type |= (int)(1 << (t)); \
214*c7ef0cfcSnicm 	else \
215*c7ef0cfcSnicm 	    name_table[n].ute_type = (t)
216*c7ef0cfcSnicm 
217*c7ef0cfcSnicm #define GetType(n) \
218*c7ef0cfcSnicm 	(is_user \
219*c7ef0cfcSnicm 	 ? get_type(name_table[n].ute_type) \
220*c7ef0cfcSnicm 	 : typenames[name_table[n].ute_type])
221*c7ef0cfcSnicm 
222*c7ef0cfcSnicm static char *
get_type(int type_mask)223*c7ef0cfcSnicm get_type(int type_mask)
224*c7ef0cfcSnicm {
225*c7ef0cfcSnicm     static char result[80];
226*c7ef0cfcSnicm     unsigned n;
227*c7ef0cfcSnicm     _nc_STRCPY(result, L_PAREN, sizeof(result));
228*c7ef0cfcSnicm     for (n = 0; n < 3; ++n) {
229*c7ef0cfcSnicm 	if ((1 << n) & type_mask) {
230*c7ef0cfcSnicm 	    size_t want = 5 + strlen(typenames[n]);
231*c7ef0cfcSnicm 	    if (want > sizeof(result)) {
232*c7ef0cfcSnicm 		fprintf(stderr, "Buffer is not large enough for %s + %s\n",
233*c7ef0cfcSnicm 			result, typenames[n]);
234*c7ef0cfcSnicm 		exit(EXIT_FAILURE);
235*c7ef0cfcSnicm 	    }
236*c7ef0cfcSnicm 	    if (result[1])
237*c7ef0cfcSnicm 		_nc_STRCAT(result, "|", sizeof(result));
238*c7ef0cfcSnicm 	    _nc_STRCAT(result, "1<<", sizeof(result));
239*c7ef0cfcSnicm 	    _nc_STRCAT(result, typenames[n], sizeof(result));
240*c7ef0cfcSnicm 	}
241*c7ef0cfcSnicm     }
242*c7ef0cfcSnicm     _nc_STRCAT(result, R_PAREN, sizeof(result));
243*c7ef0cfcSnicm     return result;
244*c7ef0cfcSnicm }
245*c7ef0cfcSnicm 
246*c7ef0cfcSnicm int
main(int argc,char ** argv)247*c7ef0cfcSnicm main(int argc, char **argv)
248*c7ef0cfcSnicm {
249*c7ef0cfcSnicm     unsigned tablesize = CAPTABSIZE;
250*c7ef0cfcSnicm     struct user_table_entry *name_table = typeCalloc(struct
251*c7ef0cfcSnicm 						     user_table_entry, tablesize);
252*c7ef0cfcSnicm     HashValue *hash_table = typeCalloc(HashValue, HASHTABSIZE);
253*c7ef0cfcSnicm     const char *root_name = "";
254*c7ef0cfcSnicm     int column = 0;
255*c7ef0cfcSnicm     int bigstring = 0;
256*c7ef0cfcSnicm     unsigned n;
257*c7ef0cfcSnicm     unsigned nn;
258*c7ef0cfcSnicm     unsigned tableused = 0;
259*c7ef0cfcSnicm     bool is_user;
260*c7ef0cfcSnicm     const char *table_name;
261*c7ef0cfcSnicm     char buffer[BUFSIZ];
262*c7ef0cfcSnicm 
263*c7ef0cfcSnicm     short BoolCount = 0;
264*c7ef0cfcSnicm     short NumCount = 0;
265*c7ef0cfcSnicm     short StrCount = 0;
266*c7ef0cfcSnicm 
267*c7ef0cfcSnicm     /* The first argument is the column-number (starting with 0).
268*c7ef0cfcSnicm      * The second is the root name of the tables to generate.
269*c7ef0cfcSnicm      */
270*c7ef0cfcSnicm     if (argc <= 3
271*c7ef0cfcSnicm 	|| (column = atoi(argv[1])) <= 0
272*c7ef0cfcSnicm 	|| (column >= MAX_COLUMNS)
273*c7ef0cfcSnicm 	|| *(root_name = argv[2]) == 0
274*c7ef0cfcSnicm 	|| (bigstring = atoi(argv[3])) < 0
275*c7ef0cfcSnicm 	|| name_table == 0
276*c7ef0cfcSnicm 	|| hash_table == 0) {
277*c7ef0cfcSnicm 	fprintf(stderr, "usage: make_hash column root_name bigstring\n");
278*c7ef0cfcSnicm 	exit(EXIT_FAILURE);
279*c7ef0cfcSnicm     }
280*c7ef0cfcSnicm     is_user = (*root_name == 'u');
281*c7ef0cfcSnicm     table_name = (is_user ? "user" : "name");
282*c7ef0cfcSnicm 
283*c7ef0cfcSnicm     /*
284*c7ef0cfcSnicm      * Read the table into our arrays.
285*c7ef0cfcSnicm      */
286*c7ef0cfcSnicm     for (n = 0; (n < tablesize) && fgets(buffer, BUFSIZ, stdin);) {
287*c7ef0cfcSnicm 	char **list;
288*c7ef0cfcSnicm 	char *nlp = strchr(buffer, '\n');
289*c7ef0cfcSnicm 	if (nlp)
290*c7ef0cfcSnicm 	    *nlp = '\0';
291*c7ef0cfcSnicm 	else
292*c7ef0cfcSnicm 	    buffer[sizeof(buffer) - 2] = '\0';
293*c7ef0cfcSnicm 	list = parse_columns(buffer);
294*c7ef0cfcSnicm 	if (list == 0)		/* blank or comment */
295*c7ef0cfcSnicm 	    continue;
296*c7ef0cfcSnicm 	if (is_user) {
297*c7ef0cfcSnicm 	    if (strcmp(list[0], "userdef"))
298*c7ef0cfcSnicm 		continue;
299*c7ef0cfcSnicm 	} else if (!strcmp(list[0], "userdef")) {
300*c7ef0cfcSnicm 	    continue;
301*c7ef0cfcSnicm 	}
302*c7ef0cfcSnicm 	if (column < 0 || column > count_columns(list)) {
303*c7ef0cfcSnicm 	    fprintf(stderr, "expected %d columns, have %d:\n%s\n",
304*c7ef0cfcSnicm 		    column,
305*c7ef0cfcSnicm 		    count_columns(list),
306*c7ef0cfcSnicm 		    buffer);
307*c7ef0cfcSnicm 	    exit(EXIT_FAILURE);
308*c7ef0cfcSnicm 	}
309*c7ef0cfcSnicm 	nn = tableused;
310*c7ef0cfcSnicm 	if (is_user) {
311*c7ef0cfcSnicm 	    unsigned j;
312*c7ef0cfcSnicm 	    for (j = 0; j < tableused; ++j) {
313*c7ef0cfcSnicm 		if (!strcmp(list[column], name_table[j].ute_name)) {
314*c7ef0cfcSnicm 		    nn = j;
315*c7ef0cfcSnicm 		    break;
316*c7ef0cfcSnicm 		}
317*c7ef0cfcSnicm 	    }
318*c7ef0cfcSnicm 	}
319*c7ef0cfcSnicm 	if (nn == tableused) {
320*c7ef0cfcSnicm 	    name_table[nn].ute_link = -1;	/* end-of-hash */
321*c7ef0cfcSnicm 	    name_table[nn].ute_name = strmalloc(list[column]);
322*c7ef0cfcSnicm 	    ++tableused;
323*c7ef0cfcSnicm 	}
324*c7ef0cfcSnicm 
325*c7ef0cfcSnicm 	if (!strcmp(list[2], "bool")) {
326*c7ef0cfcSnicm 	    SetType(nn, BOOLEAN);
327*c7ef0cfcSnicm 	    name_table[nn].ute_index = BoolCount++;
328*c7ef0cfcSnicm 	} else if (!strcmp(list[2], "num")) {
329*c7ef0cfcSnicm 	    SetType(nn, NUMBER);
330*c7ef0cfcSnicm 	    name_table[nn].ute_index = NumCount++;
331*c7ef0cfcSnicm 	} else if (!strcmp(list[2], "str")) {
332*c7ef0cfcSnicm 	    SetType(nn, STRING);
333*c7ef0cfcSnicm 	    name_table[nn].ute_index = StrCount++;
334*c7ef0cfcSnicm 	    if (is_user) {
335*c7ef0cfcSnicm 		if (*list[3] != '-') {
336*c7ef0cfcSnicm 		    unsigned j;
337*c7ef0cfcSnicm 		    name_table[nn].ute_argc = (unsigned) strlen(list[3]);
338*c7ef0cfcSnicm 		    for (j = 0; j < name_table[nn].ute_argc; ++j) {
339*c7ef0cfcSnicm 			if (list[3][j] == 's') {
340*c7ef0cfcSnicm 			    name_table[nn].ute_args |= (1U << j);
341*c7ef0cfcSnicm 			}
342*c7ef0cfcSnicm 		    }
343*c7ef0cfcSnicm 		}
344*c7ef0cfcSnicm 	    }
345*c7ef0cfcSnicm 	} else {
346*c7ef0cfcSnicm 	    fprintf(stderr, "Unknown type: %s\n", list[2]);
347*c7ef0cfcSnicm 	    exit(EXIT_FAILURE);
348*c7ef0cfcSnicm 	}
349*c7ef0cfcSnicm 	n++;
350*c7ef0cfcSnicm     }
351*c7ef0cfcSnicm     if (tablesize > tableused)
352*c7ef0cfcSnicm 	tablesize = tableused;
353*c7ef0cfcSnicm     _nc_make_hash_table(name_table, hash_table, tablesize);
354*c7ef0cfcSnicm 
355*c7ef0cfcSnicm     /*
356*c7ef0cfcSnicm      * Write the compiled tables to standard output
357*c7ef0cfcSnicm      */
358*c7ef0cfcSnicm     if (bigstring) {
359*c7ef0cfcSnicm 	int len = 0;
360*c7ef0cfcSnicm 	int nxt;
361*c7ef0cfcSnicm 
362*c7ef0cfcSnicm 	printf("static const char %s_names_text[] = \\\n", root_name);
363*c7ef0cfcSnicm 	for (n = 0; n < tablesize; n++) {
364*c7ef0cfcSnicm 	    nxt = (int) strlen(name_table[n].ute_name) + 5;
365*c7ef0cfcSnicm 	    if (nxt + len > 72) {
366*c7ef0cfcSnicm 		printf("\\\n");
367*c7ef0cfcSnicm 		len = 0;
368*c7ef0cfcSnicm 	    }
369*c7ef0cfcSnicm 	    printf("\"%s\\0\" ", name_table[n].ute_name);
370*c7ef0cfcSnicm 	    len += nxt;
371*c7ef0cfcSnicm 	}
372*c7ef0cfcSnicm 	printf(";\n\n");
373*c7ef0cfcSnicm 
374*c7ef0cfcSnicm 	len = 0;
375*c7ef0cfcSnicm 	printf("static %s_table_data const %s_names_data[] =\n",
376*c7ef0cfcSnicm 	       table_name,
377*c7ef0cfcSnicm 	       root_name);
378*c7ef0cfcSnicm 	printf("%s\n", L_BRACE);
379*c7ef0cfcSnicm 	for (n = 0; n < tablesize; n++) {
380*c7ef0cfcSnicm 	    printf("\t%s %15d,\t%10s,", L_BRACE, len, GetType(n));
381*c7ef0cfcSnicm 	    if (is_user)
382*c7ef0cfcSnicm 		printf("\t%d,%d,",
383*c7ef0cfcSnicm 		       name_table[n].ute_argc,
384*c7ef0cfcSnicm 		       name_table[n].ute_args);
385*c7ef0cfcSnicm 	    printf("\t%3d, %3d %s%c\n",
386*c7ef0cfcSnicm 		   name_table[n].ute_index,
387*c7ef0cfcSnicm 		   name_table[n].ute_link,
388*c7ef0cfcSnicm 		   R_BRACE,
389*c7ef0cfcSnicm 		   n < tablesize - 1 ? ',' : ' ');
390*c7ef0cfcSnicm 	    len += (int) strlen(name_table[n].ute_name) + 1;
391*c7ef0cfcSnicm 	}
392*c7ef0cfcSnicm 	printf("%s;\n\n", R_BRACE);
393*c7ef0cfcSnicm 	printf("static struct %s_table_entry *_nc_%s_table = 0;\n\n",
394*c7ef0cfcSnicm 	       table_name,
395*c7ef0cfcSnicm 	       root_name);
396*c7ef0cfcSnicm     } else {
397*c7ef0cfcSnicm 
398*c7ef0cfcSnicm 	printf("static struct %s_table_entry const _nc_%s_table[] =\n",
399*c7ef0cfcSnicm 	       table_name,
400*c7ef0cfcSnicm 	       root_name);
401*c7ef0cfcSnicm 	printf("%s\n", L_BRACE);
402*c7ef0cfcSnicm 	for (n = 0; n < tablesize; n++) {
403*c7ef0cfcSnicm 	    _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) "\"%s\"",
404*c7ef0cfcSnicm 			name_table[n].ute_name);
405*c7ef0cfcSnicm 	    printf("\t%s %15s,\t%10s,", L_BRACE, buffer, GetType(n));
406*c7ef0cfcSnicm 	    if (is_user)
407*c7ef0cfcSnicm 		printf("\t%d,%d,",
408*c7ef0cfcSnicm 		       name_table[n].ute_argc,
409*c7ef0cfcSnicm 		       name_table[n].ute_args);
410*c7ef0cfcSnicm 	    printf("\t%3d, %3d %s%c\n",
411*c7ef0cfcSnicm 		   name_table[n].ute_index,
412*c7ef0cfcSnicm 		   name_table[n].ute_link,
413*c7ef0cfcSnicm 		   R_BRACE,
414*c7ef0cfcSnicm 		   n < tablesize - 1 ? ',' : ' ');
415*c7ef0cfcSnicm 	}
416*c7ef0cfcSnicm 	printf("%s;\n\n", R_BRACE);
417*c7ef0cfcSnicm     }
418*c7ef0cfcSnicm 
419*c7ef0cfcSnicm     printf("static const HashValue _nc_%s_hash_table[%d] =\n",
420*c7ef0cfcSnicm 	   root_name,
421*c7ef0cfcSnicm 	   HASHTABSIZE + 1);
422*c7ef0cfcSnicm     printf("%s\n", L_BRACE);
423*c7ef0cfcSnicm     for (n = 0; n < HASHTABSIZE; n++) {
424*c7ef0cfcSnicm 	printf("\t%3d,\n", hash_table[n]);
425*c7ef0cfcSnicm     }
426*c7ef0cfcSnicm     printf("\t0\t/* base-of-table */\n");
427*c7ef0cfcSnicm     printf("%s;\n\n", R_BRACE);
428*c7ef0cfcSnicm 
429*c7ef0cfcSnicm     if (!is_user) {
430*c7ef0cfcSnicm 	printf("#if (BOOLCOUNT!=%d)||(NUMCOUNT!=%d)||(STRCOUNT!=%d)\n",
431*c7ef0cfcSnicm 	       BoolCount, NumCount, StrCount);
432*c7ef0cfcSnicm 	printf("#error\t--> term.h and comp_captab.c disagree about the <--\n");
433*c7ef0cfcSnicm 	printf("#error\t--> numbers of booleans, numbers and/or strings <--\n");
434*c7ef0cfcSnicm 	printf("#endif\n\n");
435*c7ef0cfcSnicm     }
436*c7ef0cfcSnicm 
437*c7ef0cfcSnicm     free(hash_table);
438*c7ef0cfcSnicm     for (n = 0; (n < tablesize); ++n) {
439*c7ef0cfcSnicm 	free((void *) name_table[n].ute_name);
440*c7ef0cfcSnicm     }
441*c7ef0cfcSnicm     free(name_table);
442*c7ef0cfcSnicm     parse_columns(0);
443*c7ef0cfcSnicm 
444*c7ef0cfcSnicm     return EXIT_SUCCESS;
445*c7ef0cfcSnicm }
446