1135446Strhodes/*
2254402Serwin * Copyright (C) 2004-2009, 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 1998-2003  Internet Software Consortium.
4135446Strhodes *
5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18170222Sdougb/*! \file */
19170222Sdougb
20165071Sdougb#ifdef WIN32
21165071Sdougb/*
22165071Sdougb * Silence compiler warnings about using strcpy and friends.
23165071Sdougb */
24165071Sdougb#define _CRT_SECURE_NO_DEPRECATE 1
25254402Serwin/*
26254402Serwin * We use snprintf.
27254402Serwin */
28254402Serwin#define snprintf _snprintf
29165071Sdougb#endif
30135446Strhodes
31135446Strhodes#include <sys/types.h>
32135446Strhodes
33135446Strhodes#include <ctype.h>
34135446Strhodes#include <stdlib.h>
35135446Strhodes#include <stdio.h>
36135446Strhodes#include <stdlib.h>
37135446Strhodes#include <string.h>
38135446Strhodes#include <time.h>
39135446Strhodes
40135446Strhodes#ifdef WIN32
41135446Strhodes#include "gen-win32.h"
42135446Strhodes#else
43135446Strhodes#include "gen-unix.h"
44135446Strhodes#endif
45135446Strhodes
46254402Serwin#define INSIST(cond) \
47254402Serwin	if (!(cond)) { \
48254402Serwin		fprintf(stderr, "%s:%d: INSIST(%s)\n", \
49254402Serwin			 __FILE__, __LINE__, #cond); \
50254402Serwin		abort(); \
51254402Serwin	}
52193149Sdougb
53135446Strhodes#define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks"
54135446Strhodes#define FROMTEXTCLASS "rdclass"
55135446Strhodes#define FROMTEXTTYPE "type"
56135446Strhodes#define FROMTEXTDEF "result = DNS_R_UNKNOWN"
57135446Strhodes
58135446Strhodes#define TOTEXTARGS "rdata, tctx, target"
59135446Strhodes#define TOTEXTCLASS "rdata->rdclass"
60135446Strhodes#define TOTEXTTYPE "rdata->type"
61135446Strhodes#define TOTEXTDEF "use_default = ISC_TRUE"
62135446Strhodes
63135446Strhodes#define FROMWIREARGS "rdclass, type, source, dctx, options, target"
64135446Strhodes#define FROMWIRECLASS "rdclass"
65135446Strhodes#define FROMWIRETYPE "type"
66135446Strhodes#define FROMWIREDEF "use_default = ISC_TRUE"
67135446Strhodes
68135446Strhodes#define TOWIREARGS "rdata, cctx, target"
69135446Strhodes#define TOWIRECLASS "rdata->rdclass"
70135446Strhodes#define TOWIRETYPE "rdata->type"
71135446Strhodes#define TOWIREDEF "use_default = ISC_TRUE"
72135446Strhodes
73135446Strhodes#define FROMSTRUCTARGS "rdclass, type, source, target"
74135446Strhodes#define FROMSTRUCTCLASS "rdclass"
75135446Strhodes#define FROMSTRUCTTYPE "type"
76135446Strhodes#define FROMSTRUCTDEF "use_default = ISC_TRUE"
77135446Strhodes
78135446Strhodes#define TOSTRUCTARGS "rdata, target, mctx"
79135446Strhodes#define TOSTRUCTCLASS "rdata->rdclass"
80135446Strhodes#define TOSTRUCTTYPE "rdata->type"
81135446Strhodes#define TOSTRUCTDEF "use_default = ISC_TRUE"
82135446Strhodes
83135446Strhodes#define FREESTRUCTARGS "source"
84135446Strhodes#define FREESTRUCTCLASS "common->rdclass"
85135446Strhodes#define FREESTRUCTTYPE "common->rdtype"
86135446Strhodes#define FREESTRUCTDEF NULL
87135446Strhodes
88135446Strhodes#define COMPAREARGS "rdata1, rdata2"
89135446Strhodes#define COMPARECLASS "rdata1->rdclass"
90135446Strhodes#define COMPARETYPE "rdata1->type"
91135446Strhodes#define COMPAREDEF "use_default = ISC_TRUE"
92135446Strhodes
93135446Strhodes#define ADDITIONALDATAARGS "rdata, add, arg"
94135446Strhodes#define ADDITIONALDATACLASS "rdata->rdclass"
95135446Strhodes#define ADDITIONALDATATYPE "rdata->type"
96135446Strhodes#define ADDITIONALDATADEF "use_default = ISC_TRUE"
97135446Strhodes
98135446Strhodes#define DIGESTARGS "rdata, digest, arg"
99135446Strhodes#define DIGESTCLASS "rdata->rdclass"
100135446Strhodes#define DIGESTTYPE "rdata->type"
101135446Strhodes#define DIGESTDEF "use_default = ISC_TRUE"
102135446Strhodes
103135446Strhodes#define CHECKOWNERARGS "name, rdclass, type, wildcard"
104135446Strhodes#define CHECKOWNERCLASS "rdclass"
105135446Strhodes#define CHECKOWNERTYPE "type"
106135446Strhodes#define CHECKOWNERDEF "result = ISC_TRUE"
107135446Strhodes
108135446Strhodes#define CHECKNAMESARGS "rdata, owner, bad"
109135446Strhodes#define CHECKNAMESCLASS "rdata->rdclass"
110135446Strhodes#define CHECKNAMESTYPE "rdata->type"
111135446Strhodes#define CHECKNAMESDEF "result = ISC_TRUE"
112135446Strhodes
113254402Serwinstatic const char copyright[] =
114135446Strhodes"/*\n"
115135446Strhodes" * Copyright (C) 2004%s Internet Systems Consortium, Inc. (\"ISC\")\n"
116135446Strhodes" * Copyright (C) 1998-2003 Internet Software Consortium.\n"
117135446Strhodes" *\n"
118135446Strhodes" * Permission to use, copy, modify, and distribute this software for any\n"
119135446Strhodes" * purpose with or without fee is hereby granted, provided that the above\n"
120135446Strhodes" * copyright notice and this permission notice appear in all copies.\n"
121135446Strhodes" *\n"
122135446Strhodes" * THE SOFTWARE IS PROVIDED \"AS IS\" AND ISC DISCLAIMS ALL WARRANTIES WITH\n"
123135446Strhodes" * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n"
124135446Strhodes" * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,\n"
125135446Strhodes" * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n"
126135446Strhodes" * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n"
127135446Strhodes" * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n"
128135446Strhodes" * PERFORMANCE OF THIS SOFTWARE.\n"
129135446Strhodes" */\n"
130135446Strhodes"\n"
131135446Strhodes"/***************\n"
132135446Strhodes" ***************\n"
133135446Strhodes" ***************   THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n"
134135446Strhodes" ***************   DO NOT EDIT!\n"
135135446Strhodes" ***************\n"
136135446Strhodes" ***************/\n"
137170222Sdougb"\n"
138170222Sdougb"/*! \\file */\n"
139135446Strhodes"\n";
140135446Strhodes
141254402Serwin#define STR_EXPAND(tok) #tok
142254402Serwin#define STR(tok) STR_EXPAND(tok)
143254402Serwin
144135446Strhodes#define TYPENAMES 256
145254402Serwin#define TYPECLASSLEN 20		/* DNS mnemonic size. Must be less than 100. */
146254402Serwin#define TYPECLASSBUF (TYPECLASSLEN + 1)
147254402Serwin#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d"
148254402Serwin#define ATTRIBUTESIZE 256
149254402Serwin#define DIRNAMESIZE 256
150135446Strhodes
151254402Serwinstatic struct cc {
152135446Strhodes	struct cc *next;
153135446Strhodes	int rdclass;
154254402Serwin	char classname[TYPECLASSBUF];
155135446Strhodes} *classes;
156135446Strhodes
157254402Serwinstatic struct tt {
158135446Strhodes	struct tt *next;
159135446Strhodes	int rdclass;
160135446Strhodes	int type;
161254402Serwin	char classname[TYPECLASSBUF];
162254402Serwin	char typename[TYPECLASSBUF];
163254402Serwin	char dirname[DIRNAMESIZE];	/* XXX Should be max path length */
164135446Strhodes} *types;
165135446Strhodes
166254402Serwinstatic struct ttnam {
167254402Serwin	char typename[TYPECLASSBUF];
168254402Serwin	char macroname[TYPECLASSBUF];
169254402Serwin	char attr[ATTRIBUTESIZE];
170135446Strhodes	unsigned int sorted;
171135446Strhodes	int type;
172135446Strhodes} typenames[TYPENAMES];
173135446Strhodes
174254402Serwinstatic int maxtype = -1;
175135446Strhodes
176254402Serwinstatic char *
177135446Strhodesupper(char *);
178254402Serwinstatic char *
179135446Strhodesfunname(const char *, char *);
180254402Serwinstatic void
181135446Strhodesdoswitch(const char *, const char *, const char *, const char *,
182135446Strhodes	 const char *, const char *);
183254402Serwinstatic void
184135446Strhodesadd(int, const char *, int, const char *, const char *);
185254402Serwinstatic void
186135446Strhodessd(int, const char *, const char *, char);
187254402Serwinstatic void
188135446Strhodesinsert_into_typenames(int, const char *, const char *);
189135446Strhodes
190170222Sdougb/*%
191135446Strhodes * If you use more than 10 of these in, say, a printf(), you'll have problems.
192135446Strhodes */
193254402Serwinstatic char *
194135446Strhodesupper(char *s) {
195135446Strhodes	static int buf_to_use = 0;
196135446Strhodes	static char buf[10][256];
197135446Strhodes	char *b;
198135446Strhodes	int c;
199135446Strhodes
200135446Strhodes	buf_to_use++;
201135446Strhodes	if (buf_to_use > 9)
202135446Strhodes		buf_to_use = 0;
203135446Strhodes
204135446Strhodes	b = buf[buf_to_use];
205135446Strhodes	memset(b, 0, 256);
206135446Strhodes
207135446Strhodes	while ((c = (*s++) & 0xff))
208135446Strhodes		*b++ = islower(c) ? toupper(c) : c;
209135446Strhodes	*b = '\0';
210135446Strhodes	return (buf[buf_to_use]);
211135446Strhodes}
212135446Strhodes
213254402Serwinstatic char *
214135446Strhodesfunname(const char *s, char *buf) {
215135446Strhodes	char *b = buf;
216135446Strhodes	char c;
217135446Strhodes
218254402Serwin	INSIST(strlen(s) < TYPECLASSBUF);
219135446Strhodes	while ((c = *s++)) {
220135446Strhodes		*b++ = (c == '-') ? '_' : c;
221135446Strhodes	}
222135446Strhodes	*b = '\0';
223135446Strhodes	return (buf);
224135446Strhodes}
225135446Strhodes
226254402Serwinstatic void
227135446Strhodesdoswitch(const char *name, const char *function, const char *args,
228135446Strhodes	 const char *tsw, const char *csw, const char *res)
229135446Strhodes{
230135446Strhodes	struct tt *tt;
231135446Strhodes	int first = 1;
232135446Strhodes	int lasttype = 0;
233135446Strhodes	int subswitch = 0;
234254402Serwin	char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF];
235135446Strhodes	const char *result = " result =";
236135446Strhodes
237135446Strhodes	if (res == NULL)
238135446Strhodes		result = "";
239135446Strhodes
240135446Strhodes	for (tt = types; tt != NULL; tt = tt->next) {
241135446Strhodes		if (first) {
242135446Strhodes			fprintf(stdout, "\n#define %s \\\n", name);
243135446Strhodes			fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw);
244135446Strhodes			first = 0;
245135446Strhodes		}
246135446Strhodes		if (tt->type != lasttype && subswitch) {
247135446Strhodes			if (res == NULL)
248135446Strhodes				fprintf(stdout, "\t\tdefault: break; \\\n");
249135446Strhodes			else
250135446Strhodes				fprintf(stdout,
251135446Strhodes					"\t\tdefault: %s; break; \\\n", res);
252135446Strhodes			fputs(/*{*/ "\t\t} \\\n", stdout);
253135446Strhodes			fputs("\t\tbreak; \\\n", stdout);
254135446Strhodes			subswitch = 0;
255135446Strhodes		}
256135446Strhodes		if (tt->rdclass && tt->type != lasttype) {
257135446Strhodes			fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/,
258135446Strhodes				tt->type, csw);
259135446Strhodes			subswitch = 1;
260135446Strhodes		}
261135446Strhodes		if (tt->rdclass == 0)
262135446Strhodes			fprintf(stdout,
263135446Strhodes				"\tcase %d:%s %s_%s(%s); break;",
264135446Strhodes				tt->type, result, function,
265135446Strhodes				funname(tt->typename, buf1), args);
266135446Strhodes		else
267135446Strhodes			fprintf(stdout,
268135446Strhodes				"\t\tcase %d:%s %s_%s_%s(%s); break;",
269135446Strhodes				tt->rdclass, result, function,
270135446Strhodes				funname(tt->classname, buf1),
271135446Strhodes				funname(tt->typename, buf2), args);
272135446Strhodes		fputs(" \\\n", stdout);
273135446Strhodes		lasttype = tt->type;
274135446Strhodes	}
275135446Strhodes	if (subswitch) {
276135446Strhodes		if (res == NULL)
277135446Strhodes			fprintf(stdout, "\t\tdefault: break; \\\n");
278135446Strhodes		else
279135446Strhodes			fprintf(stdout, "\t\tdefault: %s; break; \\\n", res);
280135446Strhodes		fputs(/*{*/ "\t\t} \\\n", stdout);
281135446Strhodes		fputs("\t\tbreak; \\\n", stdout);
282135446Strhodes	}
283135446Strhodes	if (first) {
284135446Strhodes		if (res == NULL)
285135446Strhodes			fprintf(stdout, "\n#define %s\n", name);
286135446Strhodes		else
287135446Strhodes			fprintf(stdout, "\n#define %s %s;\n", name, res);
288135446Strhodes	} else {
289135446Strhodes		if (res == NULL)
290135446Strhodes			fprintf(stdout, "\tdefault: break; \\\n");
291135446Strhodes		else
292135446Strhodes			fprintf(stdout, "\tdefault: %s; break; \\\n", res);
293135446Strhodes		fputs(/*{*/ "\t}\n", stdout);
294135446Strhodes	}
295135446Strhodes}
296135446Strhodes
297135446Strhodesstatic struct ttnam *
298135446Strhodesfind_typename(int type) {
299135446Strhodes	int i;
300135446Strhodes
301135446Strhodes	for (i = 0; i < TYPENAMES; i++) {
302135446Strhodes		if (typenames[i].typename[0] != 0 &&
303135446Strhodes		    typenames[i].type == type)
304135446Strhodes			return (&typenames[i]);
305135446Strhodes	}
306135446Strhodes	return (NULL);
307135446Strhodes}
308135446Strhodes
309254402Serwinstatic void
310135446Strhodesinsert_into_typenames(int type, const char *typename, const char *attr) {
311135446Strhodes	struct ttnam *ttn = NULL;
312262706Serwin	size_t c;
313262706Serwin	int i, n;
314135446Strhodes	char tmp[256];
315135446Strhodes
316254402Serwin	INSIST(strlen(typename) < TYPECLASSBUF);
317135446Strhodes	for (i = 0; i < TYPENAMES; i++) {
318135446Strhodes		if (typenames[i].typename[0] != 0 &&
319135446Strhodes		    typenames[i].type == type &&
320135446Strhodes		    strcmp(typename, typenames[i].typename) != 0) {
321135446Strhodes			fprintf(stderr,
322135446Strhodes				"Error:  type %d has two names: %s, %s\n",
323135446Strhodes				type, typenames[i].typename, typename);
324135446Strhodes			exit(1);
325135446Strhodes		}
326135446Strhodes		if (typenames[i].typename[0] == 0 && ttn == NULL)
327135446Strhodes			ttn = &typenames[i];
328135446Strhodes	}
329135446Strhodes	if (ttn == NULL) {
330135446Strhodes		fprintf(stderr, "Error: typenames array too small\n");
331135446Strhodes		exit(1);
332135446Strhodes	}
333193149Sdougb
334135446Strhodes	if (strlen(typename) > sizeof(ttn->typename) - 1) {
335135446Strhodes		fprintf(stderr, "Error:  type name %s is too long\n",
336135446Strhodes			typename);
337135446Strhodes		exit(1);
338135446Strhodes	}
339254402Serwin	strncpy(ttn->typename, typename, sizeof(ttn->typename));
340135446Strhodes	ttn->type = type;
341135446Strhodes
342254402Serwin	strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname));
343135446Strhodes	c = strlen(ttn->macroname);
344135446Strhodes	while (c > 0) {
345135446Strhodes		if (ttn->macroname[c - 1] == '-')
346135446Strhodes			ttn->macroname[c - 1] = '_';
347135446Strhodes		c--;
348135446Strhodes	}
349135446Strhodes
350135446Strhodes	if (attr == NULL) {
351254402Serwin		n = snprintf(tmp, sizeof(tmp),
352254402Serwin			     "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname));
353254402Serwin		INSIST(n > 0 && (unsigned)n < sizeof(tmp));
354135446Strhodes		attr = tmp;
355135446Strhodes	}
356135446Strhodes
357135446Strhodes	if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) {
358135446Strhodes		fprintf(stderr, "Error:  type %d has different attributes: "
359135446Strhodes			"%s, %s\n", type, ttn->attr, attr);
360135446Strhodes		exit(1);
361135446Strhodes	}
362135446Strhodes
363135446Strhodes	if (strlen(attr) > sizeof(ttn->attr) - 1) {
364135446Strhodes		fprintf(stderr, "Error:  attr (%s) [name %s] is too long\n",
365135446Strhodes			attr, typename);
366135446Strhodes		exit(1);
367135446Strhodes	}
368254402Serwin	strncpy(ttn->attr, attr, sizeof(ttn->attr));
369135446Strhodes	ttn->sorted = 0;
370135446Strhodes	if (maxtype < type)
371135446Strhodes		maxtype = type;
372135446Strhodes}
373135446Strhodes
374254402Serwinstatic void
375135446Strhodesadd(int rdclass, const char *classname, int type, const char *typename,
376135446Strhodes    const char *dirname)
377135446Strhodes{
378135446Strhodes	struct tt *newtt = (struct tt *)malloc(sizeof(*newtt));
379135446Strhodes	struct tt *tt, *oldtt;
380135446Strhodes	struct cc *newcc;
381135446Strhodes	struct cc *cc, *oldcc;
382135446Strhodes
383254402Serwin	INSIST(strlen(typename) < TYPECLASSBUF);
384254402Serwin	INSIST(strlen(classname) < TYPECLASSBUF);
385254402Serwin	INSIST(strlen(dirname) < DIRNAMESIZE);
386254402Serwin
387135446Strhodes	insert_into_typenames(type, typename, NULL);
388135446Strhodes
389135446Strhodes	if (newtt == NULL) {
390135446Strhodes		fprintf(stderr, "malloc() failed\n");
391135446Strhodes		exit(1);
392135446Strhodes	}
393135446Strhodes
394135446Strhodes	newtt->next = NULL;
395135446Strhodes	newtt->rdclass = rdclass;
396135446Strhodes	newtt->type = type;
397254402Serwin	strncpy(newtt->classname, classname, sizeof(newtt->classname));
398254402Serwin	strncpy(newtt->typename, typename, sizeof(newtt->typename));
399193149Sdougb	if (strncmp(dirname, "./", 2) == 0)
400193149Sdougb		dirname += 2;
401254402Serwin	strncpy(newtt->dirname, dirname, sizeof(newtt->dirname));
402135446Strhodes
403135446Strhodes	tt = types;
404135446Strhodes	oldtt = NULL;
405135446Strhodes
406135446Strhodes	while ((tt != NULL) && (tt->type < type)) {
407135446Strhodes		oldtt = tt;
408135446Strhodes		tt = tt->next;
409135446Strhodes	}
410135446Strhodes
411135446Strhodes	while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) {
412135446Strhodes		if (strcmp(tt->typename, typename) != 0)
413135446Strhodes			exit(1);
414135446Strhodes		oldtt = tt;
415135446Strhodes		tt = tt->next;
416135446Strhodes	}
417135446Strhodes
418135446Strhodes	if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass))
419135446Strhodes		exit(1);
420135446Strhodes
421135446Strhodes	newtt->next = tt;
422135446Strhodes	if (oldtt != NULL)
423135446Strhodes		oldtt->next = newtt;
424135446Strhodes	else
425135446Strhodes		types = newtt;
426135446Strhodes
427135446Strhodes	/*
428135446Strhodes	 * Do a class switch for this type.
429135446Strhodes	 */
430135446Strhodes	if (rdclass == 0)
431135446Strhodes		return;
432135446Strhodes
433135446Strhodes	newcc = (struct cc *)malloc(sizeof(*newcc));
434254402Serwin	if (newcc == NULL) {
435254402Serwin		fprintf(stderr, "malloc() failed\n");
436254402Serwin		exit(1);
437254402Serwin	}
438135446Strhodes	newcc->rdclass = rdclass;
439254402Serwin	strncpy(newcc->classname, classname, sizeof(newcc->classname));
440135446Strhodes	cc = classes;
441135446Strhodes	oldcc = NULL;
442135446Strhodes
443135446Strhodes	while ((cc != NULL) && (cc->rdclass < rdclass)) {
444135446Strhodes		oldcc = cc;
445135446Strhodes		cc = cc->next;
446135446Strhodes	}
447135446Strhodes
448135446Strhodes	if ((cc != NULL) && cc->rdclass == rdclass) {
449135446Strhodes		free((char *)newcc);
450135446Strhodes		return;
451135446Strhodes	}
452135446Strhodes
453135446Strhodes	newcc->next = cc;
454135446Strhodes	if (oldcc != NULL)
455135446Strhodes		oldcc->next = newcc;
456135446Strhodes	else
457135446Strhodes		classes = newcc;
458135446Strhodes}
459135446Strhodes
460254402Serwinstatic void
461135446Strhodessd(int rdclass, const char *classname, const char *dirname, char filetype) {
462254402Serwin	char buf[TYPECLASSLEN + sizeof("_65535.h")];
463254402Serwin	char typename[TYPECLASSBUF];
464254402Serwin	int type, n;
465135446Strhodes	isc_dir_t dir;
466135446Strhodes
467135446Strhodes	if (!start_directory(dirname, &dir))
468135446Strhodes		return;
469135446Strhodes
470135446Strhodes	while (next_file(&dir)) {
471254402Serwin		if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2)
472135446Strhodes			continue;
473135446Strhodes		if ((type > 65535) || (type < 0))
474135446Strhodes			continue;
475135446Strhodes
476254402Serwin		n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename,
477254402Serwin			     type, filetype);
478254402Serwin		INSIST(n > 0 && (unsigned)n < sizeof(buf));
479135446Strhodes		if (strcmp(buf, dir.filename) != 0)
480135446Strhodes			continue;
481135446Strhodes		add(rdclass, classname, type, typename, dirname);
482135446Strhodes	}
483135446Strhodes
484135446Strhodes	end_directory(&dir);
485135446Strhodes}
486135446Strhodes
487135446Strhodesstatic unsigned int
488135446StrhodesHASH(char *string) {
489262706Serwin	size_t n;
490135446Strhodes	unsigned char a, b;
491135446Strhodes
492135446Strhodes	n = strlen(string);
493135446Strhodes	if (n == 0) {
494135446Strhodes		fprintf(stderr, "n == 0?\n");
495135446Strhodes		exit(1);
496135446Strhodes	}
497135446Strhodes	a = tolower((unsigned char)string[0]);
498135446Strhodes	b = tolower((unsigned char)string[n - 1]);
499135446Strhodes
500135446Strhodes	return ((a + n) * b) % 256;
501135446Strhodes}
502135446Strhodes
503135446Strhodesint
504135446Strhodesmain(int argc, char **argv) {
505254402Serwin	char buf[DIRNAMESIZE];		/* XXX Should be max path length */
506254402Serwin	char srcdir[DIRNAMESIZE];	/* XXX Should be max path length */
507135446Strhodes	int rdclass;
508254402Serwin	char classname[TYPECLASSBUF];
509135446Strhodes	struct tt *tt;
510135446Strhodes	struct cc *cc;
511135446Strhodes	struct ttnam *ttn, *ttn2;
512135446Strhodes	unsigned int hash;
513135446Strhodes	struct tm *tm;
514135446Strhodes	time_t now;
515135446Strhodes	char year[11];
516135446Strhodes	int lasttype;
517135446Strhodes	int code = 1;
518135446Strhodes	int class_enum = 0;
519135446Strhodes	int type_enum = 0;
520135446Strhodes	int structs = 0;
521135446Strhodes	int depend = 0;
522254402Serwin	int c, i, j, n;
523254402Serwin	char buf1[TYPECLASSBUF];
524135446Strhodes	char filetype = 'c';
525135446Strhodes	FILE *fd;
526135446Strhodes	char *prefix = NULL;
527135446Strhodes	char *suffix = NULL;
528135446Strhodes	char *file = NULL;
529135446Strhodes	isc_dir_t dir;
530135446Strhodes
531135446Strhodes	for (i = 0; i < TYPENAMES; i++)
532135446Strhodes		memset(&typenames[i], 0, sizeof(typenames[i]));
533135446Strhodes
534135446Strhodes	strcpy(srcdir, "");
535135446Strhodes	while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1)
536135446Strhodes		switch (c) {
537135446Strhodes		case 'c':
538135446Strhodes			code = 0;
539135446Strhodes			depend = 0;
540135446Strhodes			type_enum = 0;
541135446Strhodes			class_enum = 1;
542135446Strhodes			filetype = 'c';
543135446Strhodes			structs = 0;
544135446Strhodes			break;
545135446Strhodes		case 'd':
546135446Strhodes			code = 0;
547135446Strhodes			depend = 1;
548135446Strhodes			class_enum = 0;
549135446Strhodes			type_enum = 0;
550135446Strhodes			structs = 0;
551135446Strhodes			filetype = 'h';
552135446Strhodes			break;
553135446Strhodes		case 't':
554135446Strhodes			code = 0;
555135446Strhodes			depend = 0;
556135446Strhodes			class_enum = 0;
557135446Strhodes			type_enum = 1;
558135446Strhodes			filetype = 'c';
559135446Strhodes			structs = 0;
560135446Strhodes			break;
561135446Strhodes		case 'i':
562135446Strhodes			code = 0;
563135446Strhodes			depend = 0;
564135446Strhodes			class_enum = 0;
565135446Strhodes			type_enum = 0;
566135446Strhodes			structs = 1;
567135446Strhodes			filetype = 'h';
568135446Strhodes			break;
569135446Strhodes		case 's':
570254402Serwin			if (strlen(isc_commandline_argument) >
571254402Serwin			    DIRNAMESIZE - 2 * TYPECLASSLEN  -
572254402Serwin			    sizeof("/rdata/_65535_65535")) {
573254402Serwin				fprintf(stderr, "\"%s\" too long\n",
574254402Serwin					isc_commandline_argument);
575254402Serwin				exit(1);
576254402Serwin			}
577254402Serwin			n = snprintf(srcdir, sizeof(srcdir), "%s/",
578254402Serwin				     isc_commandline_argument);
579254402Serwin			INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
580135446Strhodes			break;
581135446Strhodes		case 'F':
582135446Strhodes			file = isc_commandline_argument;
583135446Strhodes			break;
584135446Strhodes		case 'P':
585135446Strhodes			prefix = isc_commandline_argument;
586135446Strhodes			break;
587135446Strhodes		case 'S':
588135446Strhodes			suffix = isc_commandline_argument;
589135446Strhodes			break;
590135446Strhodes		case '?':
591135446Strhodes			exit(1);
592135446Strhodes		}
593135446Strhodes
594254402Serwin	n = snprintf(buf, sizeof(buf), "%srdata", srcdir);
595254402Serwin	INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
596135446Strhodes
597135446Strhodes	if (!start_directory(buf, &dir))
598135446Strhodes		exit(1);
599135446Strhodes
600135446Strhodes	while (next_file(&dir)) {
601254402Serwin		if (sscanf(dir.filename, TYPECLASSFMT, classname,
602254402Serwin			   &rdclass) != 2)
603135446Strhodes			continue;
604135446Strhodes		if ((rdclass > 65535) || (rdclass < 0))
605135446Strhodes			continue;
606135446Strhodes
607254402Serwin		n = snprintf(buf, sizeof(buf), "%srdata/%s_%d",
608254402Serwin			     srcdir, classname, rdclass);
609254402Serwin		INSIST(n > 0 && (unsigned)n < sizeof(buf));
610135446Strhodes		if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0)
611135446Strhodes			continue;
612135446Strhodes		sd(rdclass, classname, buf, filetype);
613135446Strhodes	}
614135446Strhodes	end_directory(&dir);
615254402Serwin	n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir);
616254402Serwin	INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
617135446Strhodes	sd(0, "", buf, filetype);
618135446Strhodes
619135446Strhodes	if (time(&now) != -1) {
620254402Serwin		if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) {
621254402Serwin			n = snprintf(year, sizeof(year), "-%d",
622254402Serwin				     tm->tm_year + 1900);
623254402Serwin			INSIST(n > 0 && (unsigned)n < sizeof(year));
624254402Serwin		} else
625135446Strhodes			year[0] = 0;
626135446Strhodes	} else
627135446Strhodes		year[0] = 0;
628135446Strhodes
629135446Strhodes	if (!depend) fprintf(stdout, copyright, year);
630135446Strhodes
631135446Strhodes	if (code) {
632135446Strhodes		fputs("#ifndef DNS_CODE_H\n", stdout);
633135446Strhodes		fputs("#define DNS_CODE_H 1\n\n", stdout);
634135446Strhodes
635135446Strhodes		fputs("#include <isc/boolean.h>\n", stdout);
636135446Strhodes		fputs("#include <isc/result.h>\n\n", stdout);
637135446Strhodes		fputs("#include <dns/name.h>\n\n", stdout);
638135446Strhodes
639135446Strhodes		for (tt = types; tt != NULL; tt = tt->next)
640135446Strhodes			fprintf(stdout, "#include \"%s/%s_%d.c\"\n",
641135446Strhodes				tt->dirname, tt->typename, tt->type);
642135446Strhodes
643135446Strhodes		fputs("\n\n", stdout);
644135446Strhodes
645135446Strhodes		doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS,
646135446Strhodes			 FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF);
647135446Strhodes		doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS,
648135446Strhodes			 TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF);
649135446Strhodes		doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS,
650135446Strhodes			 FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF);
651135446Strhodes		doswitch("TOWIRESWITCH", "towire", TOWIREARGS,
652135446Strhodes			 TOWIRETYPE, TOWIRECLASS, TOWIREDEF);
653135446Strhodes		doswitch("COMPARESWITCH", "compare", COMPAREARGS,
654135446Strhodes			  COMPARETYPE, COMPARECLASS, COMPAREDEF);
655224092Sdougb		doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS,
656224092Sdougb			  COMPARETYPE, COMPARECLASS, COMPAREDEF);
657135446Strhodes		doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS,
658135446Strhodes			  FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF);
659135446Strhodes		doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS,
660135446Strhodes			  TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF);
661135446Strhodes		doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS,
662135446Strhodes			  FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF);
663135446Strhodes		doswitch("ADDITIONALDATASWITCH", "additionaldata",
664135446Strhodes			 ADDITIONALDATAARGS, ADDITIONALDATATYPE,
665135446Strhodes			 ADDITIONALDATACLASS, ADDITIONALDATADEF);
666135446Strhodes		doswitch("DIGESTSWITCH", "digest",
667135446Strhodes			 DIGESTARGS, DIGESTTYPE,
668135446Strhodes			 DIGESTCLASS, DIGESTDEF);
669135446Strhodes		doswitch("CHECKOWNERSWITCH", "checkowner",
670135446Strhodes			CHECKOWNERARGS, CHECKOWNERTYPE,
671135446Strhodes			CHECKOWNERCLASS, CHECKOWNERDEF);
672135446Strhodes		doswitch("CHECKNAMESSWITCH", "checknames",
673135446Strhodes			CHECKNAMESARGS, CHECKNAMESTYPE,
674135446Strhodes			CHECKNAMESCLASS, CHECKNAMESDEF);
675135446Strhodes
676135446Strhodes		/*
677135446Strhodes		 * From here down, we are processing the rdata names and
678135446Strhodes		 * attributes.
679135446Strhodes		 */
680135446Strhodes
681135446Strhodes#define PRINT_COMMA(x) (x == maxtype ? "" : ",")
682135446Strhodes
683135446Strhodes#define METANOTQUESTION  "DNS_RDATATYPEATTR_META | " \
684135446Strhodes			 "DNS_RDATATYPEATTR_NOTQUESTION"
685135446Strhodes#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \
686135446Strhodes			 "DNS_RDATATYPEATTR_QUESTIONONLY"
687135446Strhodes#define RESERVED "DNS_RDATATYPEATTR_RESERVED"
688135446Strhodes
689135446Strhodes		/*
690135446Strhodes		 * Add in reserved/special types.  This will let us
691135446Strhodes		 * sort them without special cases.
692135446Strhodes		 */
693135446Strhodes		insert_into_typenames(0, "reserved0", RESERVED);
694135446Strhodes		insert_into_typenames(31, "eid", RESERVED);
695135446Strhodes		insert_into_typenames(32, "nimloc", RESERVED);
696135446Strhodes		insert_into_typenames(34, "atma", RESERVED);
697135446Strhodes		insert_into_typenames(100, "uinfo", RESERVED);
698135446Strhodes		insert_into_typenames(101, "uid", RESERVED);
699135446Strhodes		insert_into_typenames(102, "gid", RESERVED);
700135446Strhodes		insert_into_typenames(251, "ixfr", METAQUESTIONONLY);
701135446Strhodes		insert_into_typenames(252, "axfr", METAQUESTIONONLY);
702135446Strhodes		insert_into_typenames(253, "mailb", METAQUESTIONONLY);
703135446Strhodes		insert_into_typenames(254, "maila", METAQUESTIONONLY);
704135446Strhodes		insert_into_typenames(255, "any", METAQUESTIONONLY);
705135446Strhodes
706135446Strhodes		/*
707135446Strhodes		 * Spit out a quick and dirty hash function.  Here,
708135446Strhodes		 * we walk through the list of type names, and calculate
709135446Strhodes		 * a hash.  This isn't perfect, but it will generate "pretty
710135446Strhodes		 * good" estimates.  Lowercase the characters before
711135446Strhodes		 * computing in all cases.
712135446Strhodes		 *
713135446Strhodes		 * Here, walk the list from top to bottom, calculating
714135446Strhodes		 * the hash (mod 256) for each name.
715135446Strhodes		 */
716135446Strhodes		fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n");
717135446Strhodes		fprintf(stdout, "\tdo { \\\n");
718135446Strhodes		fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n"
719135446Strhodes				"\t\t    strncasecmp(_s,(_tn),"
720135446Strhodes				"(sizeof(_s) - 1)) == 0) { \\\n");
721135446Strhodes		fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & "
722193149Sdougb				  "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n");
723135446Strhodes		fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n");
724135446Strhodes		fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n");
725135446Strhodes		fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n");
726135446Strhodes		fprintf(stdout, "\t\t} \\\n");
727135446Strhodes		fprintf(stdout, "\t} while (0)\n\n");
728135446Strhodes
729135446Strhodes		fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash,"
730135446Strhodes				"_typename,_length,_typep) \\\n");
731135446Strhodes		fprintf(stdout, "\tswitch (_hash) { \\\n");
732135446Strhodes		for (i = 0; i <= maxtype; i++) {
733135446Strhodes			ttn = find_typename(i);
734135446Strhodes			if (ttn == NULL)
735135446Strhodes				continue;
736135446Strhodes
737135446Strhodes			/*
738135446Strhodes			 * Skip entries we already processed.
739135446Strhodes			 */
740135446Strhodes			if (ttn->sorted != 0)
741135446Strhodes				continue;
742135446Strhodes
743135446Strhodes			hash = HASH(ttn->typename);
744135446Strhodes			fprintf(stdout, "\t\tcase %u: \\\n", hash);
745135446Strhodes
746135446Strhodes			/*
747135446Strhodes			 * Find all other entries that happen to match
748135446Strhodes			 * this hash.
749135446Strhodes			 */
750135446Strhodes			for (j = 0; j <= maxtype; j++) {
751135446Strhodes				ttn2 = find_typename(j);
752135446Strhodes				if (ttn2 == NULL)
753135446Strhodes					continue;
754135446Strhodes				if (hash == HASH(ttn2->typename)) {
755135446Strhodes					fprintf(stdout, "\t\t\tRDATATYPE_COMPARE"
756135446Strhodes					       "(\"%s\", %u, "
757135446Strhodes					       "_typename, _length, _typep); \\\n",
758135446Strhodes					       ttn2->typename, ttn2->type);
759135446Strhodes					ttn2->sorted = 1;
760135446Strhodes				}
761135446Strhodes			}
762135446Strhodes			fprintf(stdout, "\t\t\tbreak; \\\n");
763135446Strhodes		}
764135446Strhodes		fprintf(stdout, "\t}\n");
765135446Strhodes
766135446Strhodes		fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n");
767135446Strhodes		fprintf(stdout, "\tswitch (type) { \\\n");
768135446Strhodes		for (i = 0; i <= maxtype; i++) {
769135446Strhodes			ttn = find_typename(i);
770135446Strhodes			if (ttn == NULL)
771135446Strhodes				continue;
772135446Strhodes			fprintf(stdout, "\tcase %u: return (%s); \\\n",
773193149Sdougb				i, upper(ttn->attr));
774135446Strhodes		}
775135446Strhodes		fprintf(stdout, "\t}\n");
776135446Strhodes
777135446Strhodes		fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n");
778135446Strhodes		fprintf(stdout, "\tswitch (type) { \\\n");
779135446Strhodes		for (i = 0; i <= maxtype; i++) {
780135446Strhodes			ttn = find_typename(i);
781135446Strhodes			if (ttn == NULL)
782135446Strhodes				continue;
783262706Serwin			/*
784262706Serwin			 * Remove KEYDATA (65533) from the type to memonic
785262706Serwin			 * translation as it is internal use only.  This
786262706Serwin			 * stops the tools from displaying KEYDATA instead
787262706Serwin			 * of TYPE65533.
788262706Serwin			 */
789262706Serwin			if (i == 65533U)
790262706Serwin				continue;
791135446Strhodes			fprintf(stdout, "\tcase %u: return "
792135446Strhodes				"(str_totext(\"%s\", target)); \\\n",
793193149Sdougb				i, upper(ttn->typename));
794135446Strhodes		}
795135446Strhodes		fprintf(stdout, "\t}\n");
796135446Strhodes
797135446Strhodes		fputs("#endif /* DNS_CODE_H */\n", stdout);
798135446Strhodes	} else if (type_enum) {
799135446Strhodes		char *s;
800135446Strhodes
801135446Strhodes		fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n");
802135446Strhodes		fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n");
803135446Strhodes
804135446Strhodes		fprintf(stdout, "enum {\n");
805135446Strhodes		fprintf(stdout, "\tdns_rdatatype_none = 0,\n");
806135446Strhodes
807135446Strhodes		lasttype = 0;
808135446Strhodes		for (tt = types; tt != NULL; tt = tt->next)
809135446Strhodes			if (tt->type != lasttype)
810135446Strhodes				fprintf(stdout,
811135446Strhodes					"\tdns_rdatatype_%s = %d,\n",
812135446Strhodes					funname(tt->typename, buf1),
813135446Strhodes					lasttype = tt->type);
814135446Strhodes
815135446Strhodes		fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n");
816135446Strhodes		fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n");
817135446Strhodes		fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n");
818135446Strhodes		fprintf(stdout, "\tdns_rdatatype_maila = 254,\n");
819135446Strhodes		fprintf(stdout, "\tdns_rdatatype_any = 255\n");
820135446Strhodes
821135446Strhodes		fprintf(stdout, "};\n\n");
822135446Strhodes
823135446Strhodes		fprintf(stdout, "#define dns_rdatatype_none\t"
824135446Strhodes			"((dns_rdatatype_t)dns_rdatatype_none)\n");
825135446Strhodes
826135446Strhodes		for (tt = types; tt != NULL; tt = tt->next)
827135446Strhodes			if (tt->type != lasttype) {
828135446Strhodes				s = funname(tt->typename, buf1);
829135446Strhodes				fprintf(stdout,
830135446Strhodes					"#define dns_rdatatype_%s\t%s"
831135446Strhodes					"((dns_rdatatype_t)dns_rdatatype_%s)"
832135446Strhodes					"\n",
833135446Strhodes					s, strlen(s) < 2U ? "\t" : "", s);
834135446Strhodes				lasttype = tt->type;
835135446Strhodes			}
836135446Strhodes
837135446Strhodes		fprintf(stdout, "#define dns_rdatatype_ixfr\t"
838135446Strhodes			"((dns_rdatatype_t)dns_rdatatype_ixfr)\n");
839135446Strhodes		fprintf(stdout, "#define dns_rdatatype_axfr\t"
840135446Strhodes			"((dns_rdatatype_t)dns_rdatatype_axfr)\n");
841135446Strhodes		fprintf(stdout, "#define dns_rdatatype_mailb\t"
842135446Strhodes			"((dns_rdatatype_t)dns_rdatatype_mailb)\n");
843135446Strhodes		fprintf(stdout, "#define dns_rdatatype_maila\t"
844135446Strhodes			"((dns_rdatatype_t)dns_rdatatype_maila)\n");
845135446Strhodes		fprintf(stdout, "#define dns_rdatatype_any\t"
846135446Strhodes			"((dns_rdatatype_t)dns_rdatatype_any)\n");
847135446Strhodes
848135446Strhodes		fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n");
849135446Strhodes
850135446Strhodes	} else if (class_enum) {
851135446Strhodes		char *s;
852135446Strhodes		int classnum;
853135446Strhodes
854135446Strhodes		fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n");
855135446Strhodes		fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n");
856135446Strhodes
857135446Strhodes		fprintf(stdout, "enum {\n");
858135446Strhodes
859135446Strhodes		fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n");
860135446Strhodes		fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t"
861135446Strhodes			"((dns_rdataclass_t)dns_rdataclass_reserved0)\n");
862135446Strhodes
863135446Strhodes#define PRINTCLASS(name, num) \
864135446Strhodes	do { \
865135446Strhodes		s = funname(name, buf1); \
866135446Strhodes		classnum = num; \
867135446Strhodes		fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \
868135446Strhodes		       classnum != 255 ? "," : ""); \
869135446Strhodes		fprintf(stdout, "#define dns_rdataclass_%s\t" \
870135446Strhodes		       "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \
871135446Strhodes	} while (0)
872135446Strhodes
873135446Strhodes		for (cc = classes; cc != NULL; cc = cc->next) {
874170222Sdougb			if (cc->rdclass == 3)
875135446Strhodes				PRINTCLASS("chaos", 3);
876170222Sdougb			else if (cc->rdclass == 255)
877135446Strhodes				PRINTCLASS("none", 254);
878135446Strhodes			PRINTCLASS(cc->classname, cc->rdclass);
879135446Strhodes		}
880135446Strhodes
881135446Strhodes#undef PRINTCLASS
882135446Strhodes
883135446Strhodes		fprintf(stdout, "};\n\n");
884135446Strhodes		fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n");
885135446Strhodes	} else if (structs) {
886135446Strhodes		if (prefix != NULL) {
887135446Strhodes			if ((fd = fopen(prefix,"r")) != NULL) {
888135446Strhodes				while (fgets(buf, sizeof(buf), fd) != NULL)
889135446Strhodes					fputs(buf, stdout);
890135446Strhodes				fclose(fd);
891135446Strhodes			}
892135446Strhodes		}
893135446Strhodes		for (tt = types; tt != NULL; tt = tt->next) {
894254402Serwin			snprintf(buf, sizeof(buf), "%s/%s_%d.h",
895135446Strhodes				tt->dirname, tt->typename, tt->type);
896135446Strhodes			if ((fd = fopen(buf,"r")) != NULL) {
897135446Strhodes				while (fgets(buf, sizeof(buf), fd) != NULL)
898135446Strhodes					fputs(buf, stdout);
899135446Strhodes				fclose(fd);
900135446Strhodes			}
901135446Strhodes		}
902135446Strhodes		if (suffix != NULL) {
903135446Strhodes			if ((fd = fopen(suffix,"r")) != NULL) {
904135446Strhodes				while (fgets(buf, sizeof(buf), fd) != NULL)
905135446Strhodes					fputs(buf, stdout);
906135446Strhodes				fclose(fd);
907135446Strhodes			}
908135446Strhodes		}
909135446Strhodes	} else if (depend) {
910135446Strhodes		for (tt = types; tt != NULL; tt = tt->next)
911135446Strhodes			fprintf(stdout, "%s:\t%s/%s_%d.h\n", file,
912135446Strhodes				tt->dirname, tt->typename, tt->type);
913135446Strhodes	}
914135446Strhodes
915135446Strhodes	if (ferror(stdout) != 0)
916135446Strhodes		exit(1);
917135446Strhodes
918135446Strhodes	return (0);
919135446Strhodes}
920