Home | History | Annotate | Line # | Download | only in dns
gen.c revision 1.2
      1 /*	$NetBSD: gen.c,v 1.2 2018/08/12 13:02:35 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * This Source Code Form is subject to the terms of the Mozilla Public
      7  * License, v. 2.0. If a copy of the MPL was not distributed with this
      8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9  *
     10  * See the COPYRIGHT file distributed with this work for additional
     11  * information regarding copyright ownership.
     12  */
     13 
     14 /*! \file */
     15 
     16 #ifdef WIN32
     17 /*
     18  * Silence compiler warnings about using strcpy and friends.
     19  */
     20 #define _CRT_SECURE_NO_DEPRECATE 1
     21 /*
     22  * We use snprintf which was defined late in Windows even it is in C99.
     23  */
     24 #if _MSC_VER < 1900
     25 #define snprintf _snprintf
     26 #endif
     27 #endif
     28 
     29 #include <sys/types.h>
     30 
     31 #include <ctype.h>
     32 #include <stdlib.h>
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 #include <string.h>
     36 #include <time.h>
     37 
     38 #ifdef WIN32
     39 #include "gen-win32.h"
     40 #else
     41 #include "gen-unix.h"
     42 #endif
     43 
     44 #define INSIST(cond) \
     45 	if (!(cond)) { \
     46 		fprintf(stderr, "%s:%d: INSIST(%s)\n", \
     47 			 __FILE__, __LINE__, #cond); \
     48 		abort(); \
     49 	}
     50 
     51 #define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks"
     52 #define FROMTEXTCLASS "rdclass"
     53 #define FROMTEXTTYPE "type"
     54 #define FROMTEXTDEF "result = DNS_R_UNKNOWN"
     55 
     56 #define TOTEXTARGS "rdata, tctx, target"
     57 #define TOTEXTCLASS "rdata->rdclass"
     58 #define TOTEXTTYPE "rdata->type"
     59 #define TOTEXTDEF "use_default = ISC_TRUE"
     60 
     61 #define FROMWIREARGS "rdclass, type, source, dctx, options, target"
     62 #define FROMWIRECLASS "rdclass"
     63 #define FROMWIRETYPE "type"
     64 #define FROMWIREDEF "use_default = ISC_TRUE"
     65 
     66 #define TOWIREARGS "rdata, cctx, target"
     67 #define TOWIRECLASS "rdata->rdclass"
     68 #define TOWIRETYPE "rdata->type"
     69 #define TOWIREDEF "use_default = ISC_TRUE"
     70 
     71 #define FROMSTRUCTARGS "rdclass, type, source, target"
     72 #define FROMSTRUCTCLASS "rdclass"
     73 #define FROMSTRUCTTYPE "type"
     74 #define FROMSTRUCTDEF "use_default = ISC_TRUE"
     75 
     76 #define TOSTRUCTARGS "rdata, target, mctx"
     77 #define TOSTRUCTCLASS "rdata->rdclass"
     78 #define TOSTRUCTTYPE "rdata->type"
     79 #define TOSTRUCTDEF "use_default = ISC_TRUE"
     80 
     81 #define FREESTRUCTARGS "source"
     82 #define FREESTRUCTCLASS "common->rdclass"
     83 #define FREESTRUCTTYPE "common->rdtype"
     84 #define FREESTRUCTDEF NULL
     85 
     86 #define COMPAREARGS "rdata1, rdata2"
     87 #define COMPARECLASS "rdata1->rdclass"
     88 #define COMPARETYPE "rdata1->type"
     89 #define COMPAREDEF "use_default = ISC_TRUE"
     90 
     91 #define ADDITIONALDATAARGS "rdata, add, arg"
     92 #define ADDITIONALDATACLASS "rdata->rdclass"
     93 #define ADDITIONALDATATYPE "rdata->type"
     94 #define ADDITIONALDATADEF "use_default = ISC_TRUE"
     95 
     96 #define DIGESTARGS "rdata, digest, arg"
     97 #define DIGESTCLASS "rdata->rdclass"
     98 #define DIGESTTYPE "rdata->type"
     99 #define DIGESTDEF "use_default = ISC_TRUE"
    100 
    101 #define CHECKOWNERARGS "name, rdclass, type, wildcard"
    102 #define CHECKOWNERCLASS "rdclass"
    103 #define CHECKOWNERTYPE "type"
    104 #define CHECKOWNERDEF "result = ISC_TRUE"
    105 
    106 #define CHECKNAMESARGS "rdata, owner, bad"
    107 #define CHECKNAMESCLASS "rdata->rdclass"
    108 #define CHECKNAMESTYPE "rdata->type"
    109 #define CHECKNAMESDEF "result = ISC_TRUE"
    110 
    111 static const char copyright[] =
    112 "/*\n"
    113 " * Copyright (C) 1998%s  Internet Systems Consortium, Inc. (\"ISC\")\n"
    114 " *\n"
    115 " * This Source Code Form is subject to the terms of the Mozilla Public\n"
    116 " * License, v. 2.0. If a copy of the MPL was not distributed with this\n"
    117 " * file, You can obtain one at http://mozilla.org/MPL/2.0/.\n"
    118 " */\n"
    119 "\n"
    120 "/***************\n"
    121 " ***************\n"
    122 " ***************   THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n"
    123 " ***************   DO NOT EDIT!\n"
    124 " ***************\n"
    125 " ***************/\n"
    126 "\n"
    127 "/*! \\file */\n"
    128 "\n";
    129 
    130 #define STR_EXPAND(tok) #tok
    131 #define STR(tok) STR_EXPAND(tok)
    132 
    133 #define TYPENAMES 256
    134 #define TYPECLASSLEN 20		/* DNS mnemonic size. Must be less than 100. */
    135 #define TYPECLASSBUF (TYPECLASSLEN + 1)
    136 #define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d"
    137 #define ATTRIBUTESIZE 256
    138 #define DIRNAMESIZE 256
    139 
    140 static struct cc {
    141 	struct cc *next;
    142 	int rdclass;
    143 	char classname[TYPECLASSBUF];
    144 } *classes;
    145 
    146 static struct tt {
    147 	struct tt *next;
    148 	int rdclass;
    149 	int type;
    150 	char classname[TYPECLASSBUF];
    151 	char typename[TYPECLASSBUF];
    152 	char dirname[DIRNAMESIZE];	/* XXX Should be max path length */
    153 } *types;
    154 
    155 static struct ttnam {
    156 	char typename[TYPECLASSBUF];
    157 	char macroname[TYPECLASSBUF];
    158 	char attr[ATTRIBUTESIZE];
    159 	unsigned int sorted;
    160 	int type;
    161 } typenames[TYPENAMES];
    162 
    163 static int maxtype = -1;
    164 
    165 static char *
    166 upper(char *);
    167 static char *
    168 funname(const char *, char *);
    169 static void
    170 doswitch(const char *, const char *, const char *, const char *,
    171 	 const char *, const char *);
    172 static void
    173 add(int, const char *, int, const char *, const char *);
    174 static void
    175 sd(int, const char *, const char *, char);
    176 static void
    177 insert_into_typenames(int, const char *, const char *);
    178 
    179 /*%
    180  * If you use more than 10 of these in, say, a printf(), you'll have problems.
    181  */
    182 static char *
    183 upper(char *s) {
    184 	static int buf_to_use = 0;
    185 	static char buf[10][256];
    186 	char *b;
    187 	int c;
    188 
    189 	buf_to_use++;
    190 	if (buf_to_use > 9)
    191 		buf_to_use = 0;
    192 
    193 	b = buf[buf_to_use];
    194 	memset(b, 0, 256);
    195 
    196 	while ((c = (*s++) & 0xff))
    197 		*b++ = islower(c) ? toupper(c) : c;
    198 	*b = '\0';
    199 	return (buf[buf_to_use]);
    200 }
    201 
    202 static char *
    203 funname(const char *s, char *buf) {
    204 	char *b = buf;
    205 	char c;
    206 
    207 	INSIST(strlen(s) < TYPECLASSBUF);
    208 	while ((c = *s++)) {
    209 		*b++ = (c == '-') ? '_' : c;
    210 	}
    211 	*b = '\0';
    212 	return (buf);
    213 }
    214 
    215 static void
    216 doswitch(const char *name, const char *function, const char *args,
    217 	 const char *tsw, const char *csw, const char *res)
    218 {
    219 	struct tt *tt;
    220 	int first = 1;
    221 	int lasttype = 0;
    222 	int subswitch = 0;
    223 	char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF];
    224 	const char *result = " result =";
    225 
    226 	if (res == NULL)
    227 		result = "";
    228 
    229 	for (tt = types; tt != NULL; tt = tt->next) {
    230 		if (first) {
    231 			fprintf(stdout, "\n#define %s \\\n", name);
    232 			fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw);
    233 			first = 0;
    234 		}
    235 		if (tt->type != lasttype && subswitch) {
    236 			if (res == NULL)
    237 				fprintf(stdout, "\t\tdefault: break; \\\n");
    238 			else
    239 				fprintf(stdout,
    240 					"\t\tdefault: %s; break; \\\n", res);
    241 			fputs(/*{*/ "\t\t} \\\n", stdout);
    242 			fputs("\t\tbreak; \\\n", stdout);
    243 			subswitch = 0;
    244 		}
    245 		if (tt->rdclass && tt->type != lasttype) {
    246 			fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/,
    247 				tt->type, csw);
    248 			subswitch = 1;
    249 		}
    250 		if (tt->rdclass == 0)
    251 			fprintf(stdout,
    252 				"\tcase %d:%s %s_%s(%s); break;",
    253 				tt->type, result, function,
    254 				funname(tt->typename, buf1), args);
    255 		else
    256 			fprintf(stdout,
    257 				"\t\tcase %d:%s %s_%s_%s(%s); break;",
    258 				tt->rdclass, result, function,
    259 				funname(tt->classname, buf1),
    260 				funname(tt->typename, buf2), args);
    261 		fputs(" \\\n", stdout);
    262 		lasttype = tt->type;
    263 	}
    264 	if (subswitch) {
    265 		if (res == NULL)
    266 			fprintf(stdout, "\t\tdefault: break; \\\n");
    267 		else
    268 			fprintf(stdout, "\t\tdefault: %s; break; \\\n", res);
    269 		fputs(/*{*/ "\t\t} \\\n", stdout);
    270 		fputs("\t\tbreak; \\\n", stdout);
    271 	}
    272 	if (first) {
    273 		if (res == NULL)
    274 			fprintf(stdout, "\n#define %s\n", name);
    275 		else
    276 			fprintf(stdout, "\n#define %s %s;\n", name, res);
    277 	} else {
    278 		if (res == NULL)
    279 			fprintf(stdout, "\tdefault: break; \\\n");
    280 		else
    281 			fprintf(stdout, "\tdefault: %s; break; \\\n", res);
    282 		fputs(/*{*/ "\t}\n", stdout);
    283 	}
    284 }
    285 
    286 static struct ttnam *
    287 find_typename(int type) {
    288 	int i;
    289 
    290 	for (i = 0; i < TYPENAMES; i++) {
    291 		if (typenames[i].typename[0] != 0 &&
    292 		    typenames[i].type == type)
    293 			return (&typenames[i]);
    294 	}
    295 	return (NULL);
    296 }
    297 
    298 static void
    299 insert_into_typenames(int type, const char *typename, const char *attr) {
    300 	struct ttnam *ttn = NULL;
    301 	size_t c;
    302 	int i, n;
    303 	char tmp[256];
    304 
    305 	INSIST(strlen(typename) < TYPECLASSBUF);
    306 	for (i = 0; i < TYPENAMES; i++) {
    307 		if (typenames[i].typename[0] != 0 &&
    308 		    typenames[i].type == type &&
    309 		    strcmp(typename, typenames[i].typename) != 0) {
    310 			fprintf(stderr,
    311 				"Error:  type %d has two names: %s, %s\n",
    312 				type, typenames[i].typename, typename);
    313 			exit(1);
    314 		}
    315 		if (typenames[i].typename[0] == 0 && ttn == NULL)
    316 			ttn = &typenames[i];
    317 	}
    318 	if (ttn == NULL) {
    319 		fprintf(stderr, "Error: typenames array too small\n");
    320 		exit(1);
    321 	}
    322 
    323 	/* XXXMUKS: This is redundant due to the INSIST above. */
    324 	if (strlen(typename) > sizeof(ttn->typename) - 1) {
    325 		fprintf(stderr, "Error:  type name %s is too long\n",
    326 			typename);
    327 		exit(1);
    328 	}
    329 
    330 	strncpy(ttn->typename, typename, sizeof(ttn->typename));
    331 	ttn->typename[sizeof(ttn->typename) - 1] = '\0';
    332 
    333 	strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname));
    334 	ttn->macroname[sizeof(ttn->macroname) - 1] = '\0';
    335 
    336 	ttn->type = type;
    337 	c = strlen(ttn->macroname);
    338 	while (c > 0) {
    339 		if (ttn->macroname[c - 1] == '-')
    340 			ttn->macroname[c - 1] = '_';
    341 		c--;
    342 	}
    343 
    344 	if (attr == NULL) {
    345 		n = snprintf(tmp, sizeof(tmp),
    346 			     "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname));
    347 		INSIST(n > 0 && (unsigned)n < sizeof(tmp));
    348 		attr = tmp;
    349 	}
    350 
    351 	if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) {
    352 		fprintf(stderr, "Error:  type %d has different attributes: "
    353 			"%s, %s\n", type, ttn->attr, attr);
    354 		exit(1);
    355 	}
    356 
    357 	if (strlen(attr) > sizeof(ttn->attr) - 1) {
    358 		fprintf(stderr, "Error:  attr (%s) [name %s] is too long\n",
    359 			attr, typename);
    360 		exit(1);
    361 	}
    362 
    363 	strncpy(ttn->attr, attr, sizeof(ttn->attr));
    364 	ttn->attr[sizeof(ttn->attr) - 1] = '\0';
    365 
    366 	ttn->sorted = 0;
    367 	if (maxtype < type)
    368 		maxtype = type;
    369 }
    370 
    371 static void
    372 add(int rdclass, const char *classname, int type, const char *typename,
    373     const char *dirname)
    374 {
    375 	struct tt *newtt = (struct tt *)malloc(sizeof(*newtt));
    376 	struct tt *tt, *oldtt;
    377 	struct cc *newcc;
    378 	struct cc *cc, *oldcc;
    379 
    380 	INSIST(strlen(typename) < TYPECLASSBUF);
    381 	INSIST(strlen(classname) < TYPECLASSBUF);
    382 	INSIST(strlen(dirname) < DIRNAMESIZE);
    383 
    384 	insert_into_typenames(type, typename, NULL);
    385 
    386 	if (newtt == NULL) {
    387 		fprintf(stderr, "malloc() failed\n");
    388 		exit(1);
    389 	}
    390 
    391 	newtt->next = NULL;
    392 	newtt->rdclass = rdclass;
    393 	newtt->type = type;
    394 
    395 	strncpy(newtt->classname, classname, sizeof(newtt->classname));
    396 	newtt->classname[sizeof(newtt->classname) - 1] = '\0';
    397 
    398 	strncpy(newtt->typename, typename, sizeof(newtt->typename));
    399 	newtt->typename[sizeof(newtt->typename) - 1] = '\0';
    400 
    401 	if (strncmp(dirname, "./", 2) == 0)
    402 		dirname += 2;
    403 	strncpy(newtt->dirname, dirname, sizeof(newtt->dirname));
    404 	newtt->dirname[sizeof(newtt->dirname) - 1] = '\0';
    405 
    406 	tt = types;
    407 	oldtt = NULL;
    408 
    409 	while ((tt != NULL) && (tt->type < type)) {
    410 		oldtt = tt;
    411 		tt = tt->next;
    412 	}
    413 
    414 	while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) {
    415 		if (strcmp(tt->typename, typename) != 0)
    416 			exit(1);
    417 		oldtt = tt;
    418 		tt = tt->next;
    419 	}
    420 
    421 	if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass))
    422 		exit(1);
    423 
    424 	newtt->next = tt;
    425 	if (oldtt != NULL)
    426 		oldtt->next = newtt;
    427 	else
    428 		types = newtt;
    429 
    430 	/*
    431 	 * Do a class switch for this type.
    432 	 */
    433 	if (rdclass == 0)
    434 		return;
    435 
    436 	newcc = (struct cc *)malloc(sizeof(*newcc));
    437 	if (newcc == NULL) {
    438 		fprintf(stderr, "malloc() failed\n");
    439 		exit(1);
    440 	}
    441 	newcc->rdclass = rdclass;
    442 	strncpy(newcc->classname, classname, sizeof(newcc->classname));
    443 	newcc->classname[sizeof(newcc->classname) - 1] = '\0';
    444 	cc = classes;
    445 	oldcc = NULL;
    446 
    447 	while ((cc != NULL) && (cc->rdclass < rdclass)) {
    448 		oldcc = cc;
    449 		cc = cc->next;
    450 	}
    451 
    452 	if ((cc != NULL) && cc->rdclass == rdclass) {
    453 		free((char *)newcc);
    454 		return;
    455 	}
    456 
    457 	newcc->next = cc;
    458 	if (oldcc != NULL)
    459 		oldcc->next = newcc;
    460 	else
    461 		classes = newcc;
    462 }
    463 
    464 static void
    465 sd(int rdclass, const char *classname, const char *dirname, char filetype) {
    466 	char buf[TYPECLASSLEN + sizeof("_65535.h")];
    467 	char typename[TYPECLASSBUF];
    468 	int type, n;
    469 	isc_dir_t dir;
    470 
    471 	if (!start_directory(dirname, &dir))
    472 		return;
    473 
    474 	while (next_file(&dir)) {
    475 		if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2)
    476 			continue;
    477 		if ((type > 65535) || (type < 0))
    478 			continue;
    479 
    480 		n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename,
    481 			     type, filetype);
    482 		INSIST(n > 0 && (unsigned)n < sizeof(buf));
    483 		if (strcmp(buf, dir.filename) != 0)
    484 			continue;
    485 		add(rdclass, classname, type, typename, dirname);
    486 	}
    487 
    488 	end_directory(&dir);
    489 }
    490 
    491 static unsigned int
    492 HASH(char *string) {
    493 	size_t n;
    494 	unsigned char a, b;
    495 
    496 	n = strlen(string);
    497 	if (n == 0) {
    498 		fprintf(stderr, "n == 0?\n");
    499 		exit(1);
    500 	}
    501 	a = tolower((unsigned char)string[0]);
    502 	b = tolower((unsigned char)string[n - 1]);
    503 
    504 	return ((a + n) * b) % 256;
    505 }
    506 
    507 int
    508 main(int argc, char **argv) {
    509 	char buf[DIRNAMESIZE];		/* XXX Should be max path length */
    510 	char srcdir[DIRNAMESIZE];	/* XXX Should be max path length */
    511 	int rdclass;
    512 	char classname[TYPECLASSBUF];
    513 	struct tt *tt;
    514 	struct cc *cc;
    515 	struct ttnam *ttn, *ttn2;
    516 	unsigned int hash;
    517 	struct tm *tm;
    518 	time_t now;
    519 	char year[11];
    520 	int lasttype;
    521 	int code = 1;
    522 	int class_enum = 0;
    523 	int type_enum = 0;
    524 	int structs = 0;
    525 	int depend = 0;
    526 	int c, i, j, n;
    527 	char buf1[TYPECLASSBUF];
    528 	char filetype = 'c';
    529 	FILE *fd;
    530 	char *prefix = NULL;
    531 	char *suffix = NULL;
    532 	char *file = NULL;
    533 	isc_dir_t dir;
    534 
    535 	for (i = 0; i < TYPENAMES; i++)
    536 		memset(&typenames[i], 0, sizeof(typenames[i]));
    537 
    538 	srcdir[0] = '\0';
    539 	while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1)
    540 		switch (c) {
    541 		case 'c':
    542 			code = 0;
    543 			depend = 0;
    544 			type_enum = 0;
    545 			class_enum = 1;
    546 			filetype = 'c';
    547 			structs = 0;
    548 			break;
    549 		case 'd':
    550 			code = 0;
    551 			depend = 1;
    552 			class_enum = 0;
    553 			type_enum = 0;
    554 			structs = 0;
    555 			filetype = 'h';
    556 			break;
    557 		case 't':
    558 			code = 0;
    559 			depend = 0;
    560 			class_enum = 0;
    561 			type_enum = 1;
    562 			filetype = 'c';
    563 			structs = 0;
    564 			break;
    565 		case 'i':
    566 			code = 0;
    567 			depend = 0;
    568 			class_enum = 0;
    569 			type_enum = 0;
    570 			structs = 1;
    571 			filetype = 'h';
    572 			break;
    573 		case 's':
    574 			if (strlen(isc_commandline_argument) >
    575 			    DIRNAMESIZE - 2 * TYPECLASSLEN  -
    576 			    sizeof("/rdata/_65535_65535")) {
    577 				fprintf(stderr, "\"%s\" too long\n",
    578 					isc_commandline_argument);
    579 				exit(1);
    580 			}
    581 			n = snprintf(srcdir, sizeof(srcdir), "%s/",
    582 				     isc_commandline_argument);
    583 			INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
    584 			break;
    585 		case 'F':
    586 			file = isc_commandline_argument;
    587 			break;
    588 		case 'P':
    589 			prefix = isc_commandline_argument;
    590 			break;
    591 		case 'S':
    592 			suffix = isc_commandline_argument;
    593 			break;
    594 		case '?':
    595 			exit(1);
    596 		}
    597 
    598 	n = snprintf(buf, sizeof(buf), "%srdata", srcdir);
    599 	INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
    600 
    601 	if (!start_directory(buf, &dir))
    602 		exit(1);
    603 
    604 	while (next_file(&dir)) {
    605 		if (sscanf(dir.filename, TYPECLASSFMT, classname,
    606 			   &rdclass) != 2)
    607 			continue;
    608 		if ((rdclass > 65535) || (rdclass < 0))
    609 			continue;
    610 
    611 		n = snprintf(buf, sizeof(buf), "%srdata/%s_%d",
    612 			     srcdir, classname, rdclass);
    613 		INSIST(n > 0 && (unsigned)n < sizeof(buf));
    614 		if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0)
    615 			continue;
    616 		sd(rdclass, classname, buf, filetype);
    617 	}
    618 	end_directory(&dir);
    619 	n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir);
    620 	INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
    621 	sd(0, "", buf, filetype);
    622 
    623 	if (time(&now) != -1) {
    624 		if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) {
    625 			n = snprintf(year, sizeof(year), "-%d",
    626 				     tm->tm_year + 1900);
    627 			INSIST(n > 0 && (unsigned)n < sizeof(year));
    628 		} else {
    629 			snprintf(year, sizeof(year), "-2016");
    630 		}
    631 	} else {
    632 		snprintf(year, sizeof(year), "-2016");
    633 	}
    634 
    635 	if (!depend)
    636 		fprintf(stdout, copyright, year);
    637 
    638 	if (code) {
    639 		fputs("#ifndef DNS_CODE_H\n", stdout);
    640 		fputs("#define DNS_CODE_H 1\n\n", stdout);
    641 
    642 		fputs("#include <isc/boolean.h>\n", stdout);
    643 		fputs("#include <isc/result.h>\n\n", stdout);
    644 		fputs("#include <dns/name.h>\n\n", stdout);
    645 
    646 		for (tt = types; tt != NULL; tt = tt->next)
    647 			fprintf(stdout, "#include \"%s/%s_%d.c\"\n",
    648 				tt->dirname, tt->typename, tt->type);
    649 
    650 		fputs("\n\n", stdout);
    651 
    652 		doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS,
    653 			 FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF);
    654 		doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS,
    655 			 TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF);
    656 		doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS,
    657 			 FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF);
    658 		doswitch("TOWIRESWITCH", "towire", TOWIREARGS,
    659 			 TOWIRETYPE, TOWIRECLASS, TOWIREDEF);
    660 		doswitch("COMPARESWITCH", "compare", COMPAREARGS,
    661 			  COMPARETYPE, COMPARECLASS, COMPAREDEF);
    662 		doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS,
    663 			  COMPARETYPE, COMPARECLASS, COMPAREDEF);
    664 		doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS,
    665 			  FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF);
    666 		doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS,
    667 			  TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF);
    668 		doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS,
    669 			  FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF);
    670 		doswitch("ADDITIONALDATASWITCH", "additionaldata",
    671 			 ADDITIONALDATAARGS, ADDITIONALDATATYPE,
    672 			 ADDITIONALDATACLASS, ADDITIONALDATADEF);
    673 		doswitch("DIGESTSWITCH", "digest",
    674 			 DIGESTARGS, DIGESTTYPE,
    675 			 DIGESTCLASS, DIGESTDEF);
    676 		doswitch("CHECKOWNERSWITCH", "checkowner",
    677 			CHECKOWNERARGS, CHECKOWNERTYPE,
    678 			CHECKOWNERCLASS, CHECKOWNERDEF);
    679 		doswitch("CHECKNAMESSWITCH", "checknames",
    680 			CHECKNAMESARGS, CHECKNAMESTYPE,
    681 			CHECKNAMESCLASS, CHECKNAMESDEF);
    682 
    683 		/*
    684 		 * From here down, we are processing the rdata names and
    685 		 * attributes.
    686 		 */
    687 
    688 #define PRINT_COMMA(x) (x == maxtype ? "" : ",")
    689 
    690 #define METANOTQUESTION  "DNS_RDATATYPEATTR_META | " \
    691 			 "DNS_RDATATYPEATTR_NOTQUESTION"
    692 #define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \
    693 			 "DNS_RDATATYPEATTR_QUESTIONONLY"
    694 #define RESERVED "DNS_RDATATYPEATTR_RESERVED"
    695 
    696 		/*
    697 		 * Add in reserved/special types.  This will let us
    698 		 * sort them without special cases.
    699 		 */
    700 		insert_into_typenames(0, "reserved0", RESERVED);
    701 		insert_into_typenames(31, "eid", RESERVED);
    702 		insert_into_typenames(32, "nimloc", RESERVED);
    703 		insert_into_typenames(34, "atma", RESERVED);
    704 		insert_into_typenames(100, "uinfo", RESERVED);
    705 		insert_into_typenames(101, "uid", RESERVED);
    706 		insert_into_typenames(102, "gid", RESERVED);
    707 		insert_into_typenames(251, "ixfr", METAQUESTIONONLY);
    708 		insert_into_typenames(252, "axfr", METAQUESTIONONLY);
    709 		insert_into_typenames(253, "mailb", METAQUESTIONONLY);
    710 		insert_into_typenames(254, "maila", METAQUESTIONONLY);
    711 		insert_into_typenames(255, "any", METAQUESTIONONLY);
    712 
    713 		/*
    714 		 * Spit out a quick and dirty hash function.  Here,
    715 		 * we walk through the list of type names, and calculate
    716 		 * a hash.  This isn't perfect, but it will generate "pretty
    717 		 * good" estimates.  Lowercase the characters before
    718 		 * computing in all cases.
    719 		 *
    720 		 * Here, walk the list from top to bottom, calculating
    721 		 * the hash (mod 256) for each name.
    722 		 */
    723 		fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n");
    724 		fprintf(stdout, "\tdo { \\\n");
    725 		fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n"
    726 				"\t\t    strncasecmp(_s,(_tn),"
    727 				"(sizeof(_s) - 1)) == 0) { \\\n");
    728 		fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & "
    729 				  "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n");
    730 		fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n");
    731 		fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n");
    732 		fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n");
    733 		fprintf(stdout, "\t\t} \\\n");
    734 		fprintf(stdout, "\t} while (/*CONSTCOND*/0)\n\n");
    735 
    736 		fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash,"
    737 				"_typename,_length,_typep) \\\n");
    738 		fprintf(stdout, "\tswitch (_hash) { \\\n");
    739 		for (i = 0; i <= maxtype; i++) {
    740 			ttn = find_typename(i);
    741 			if (ttn == NULL)
    742 				continue;
    743 
    744 			/*
    745 			 * Skip entries we already processed.
    746 			 */
    747 			if (ttn->sorted != 0)
    748 				continue;
    749 
    750 			hash = HASH(ttn->typename);
    751 			fprintf(stdout, "\t\tcase %u: \\\n", hash);
    752 
    753 			/*
    754 			 * Find all other entries that happen to match
    755 			 * this hash.
    756 			 */
    757 			for (j = 0; j <= maxtype; j++) {
    758 				ttn2 = find_typename(j);
    759 				if (ttn2 == NULL)
    760 					continue;
    761 				if (hash == HASH(ttn2->typename)) {
    762 					fprintf(stdout, "\t\t\tRDATATYPE_COMPARE"
    763 					       "(\"%s\", %d, "
    764 					       "_typename, _length, _typep); \\\n",
    765 					       ttn2->typename, ttn2->type);
    766 					ttn2->sorted = 1;
    767 				}
    768 			}
    769 			fprintf(stdout, "\t\t\tbreak; \\\n");
    770 		}
    771 		fprintf(stdout, "\t}\n");
    772 
    773 		fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n");
    774 		fprintf(stdout, "\tswitch (type) { \\\n");
    775 		for (i = 0; i <= maxtype; i++) {
    776 			ttn = find_typename(i);
    777 			if (ttn == NULL)
    778 				continue;
    779 			fprintf(stdout, "\tcase %d: return (%s); \\\n",
    780 				i, upper(ttn->attr));
    781 		}
    782 		fprintf(stdout, "\t}\n");
    783 
    784 		fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n");
    785 		fprintf(stdout, "\tswitch (type) { \\\n");
    786 		for (i = 0; i <= maxtype; i++) {
    787 			ttn = find_typename(i);
    788 			if (ttn == NULL)
    789 				continue;
    790 			/*
    791 			 * Remove KEYDATA (65533) from the type to memonic
    792 			 * translation as it is internal use only.  This
    793 			 * stops the tools from displaying KEYDATA instead
    794 			 * of TYPE65533.
    795 			 */
    796 			if (i == 65533U)
    797 				continue;
    798 			fprintf(stdout, "\tcase %d: return "
    799 				"(str_totext(\"%s\", target)); \\\n",
    800 				i, upper(ttn->typename));
    801 		}
    802 		fprintf(stdout, "\t}\n");
    803 
    804 		fputs("#endif /* DNS_CODE_H */\n", stdout);
    805 	} else if (type_enum) {
    806 		char *s;
    807 
    808 		fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n");
    809 		fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n");
    810 
    811 		fprintf(stdout, "enum {\n");
    812 		fprintf(stdout, "\tdns_rdatatype_none = 0,\n");
    813 
    814 		lasttype = 0;
    815 		for (tt = types; tt != NULL; tt = tt->next)
    816 			if (tt->type != lasttype)
    817 				fprintf(stdout,
    818 					"\tdns_rdatatype_%s = %d,\n",
    819 					funname(tt->typename, buf1),
    820 					lasttype = tt->type);
    821 
    822 		fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n");
    823 		fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n");
    824 		fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n");
    825 		fprintf(stdout, "\tdns_rdatatype_maila = 254,\n");
    826 		fprintf(stdout, "\tdns_rdatatype_any = 255\n");
    827 
    828 		fprintf(stdout, "};\n\n");
    829 
    830 		fprintf(stdout, "#define dns_rdatatype_none\t"
    831 			"((dns_rdatatype_t)dns_rdatatype_none)\n");
    832 
    833 		for (tt = types; tt != NULL; tt = tt->next)
    834 			if (tt->type != lasttype) {
    835 				s = funname(tt->typename, buf1);
    836 				fprintf(stdout,
    837 					"#define dns_rdatatype_%s\t%s"
    838 					"((dns_rdatatype_t)dns_rdatatype_%s)"
    839 					"\n",
    840 					s, strlen(s) < 2U ? "\t" : "", s);
    841 				lasttype = tt->type;
    842 			}
    843 
    844 		fprintf(stdout, "#define dns_rdatatype_ixfr\t"
    845 			"((dns_rdatatype_t)dns_rdatatype_ixfr)\n");
    846 		fprintf(stdout, "#define dns_rdatatype_axfr\t"
    847 			"((dns_rdatatype_t)dns_rdatatype_axfr)\n");
    848 		fprintf(stdout, "#define dns_rdatatype_mailb\t"
    849 			"((dns_rdatatype_t)dns_rdatatype_mailb)\n");
    850 		fprintf(stdout, "#define dns_rdatatype_maila\t"
    851 			"((dns_rdatatype_t)dns_rdatatype_maila)\n");
    852 		fprintf(stdout, "#define dns_rdatatype_any\t"
    853 			"((dns_rdatatype_t)dns_rdatatype_any)\n");
    854 
    855 		fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n");
    856 
    857 	} else if (class_enum) {
    858 		char *s;
    859 		int classnum;
    860 
    861 		fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n");
    862 		fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n");
    863 
    864 		fprintf(stdout, "enum {\n");
    865 
    866 		fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n");
    867 		fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t"
    868 			"((dns_rdataclass_t)dns_rdataclass_reserved0)\n");
    869 
    870 #define PRINTCLASS(name, num) \
    871 	do { \
    872 		s = funname(name, buf1); \
    873 		classnum = num; \
    874 		fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \
    875 		       classnum != 255 ? "," : ""); \
    876 		fprintf(stdout, "#define dns_rdataclass_%s\t" \
    877 		       "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \
    878 	} while (/*CONSTCOND*/0)
    879 
    880 		for (cc = classes; cc != NULL; cc = cc->next) {
    881 			if (cc->rdclass == 3)
    882 				PRINTCLASS("chaos", 3);
    883 			else if (cc->rdclass == 255)
    884 				PRINTCLASS("none", 254);
    885 			PRINTCLASS(cc->classname, cc->rdclass);
    886 		}
    887 
    888 #undef PRINTCLASS
    889 
    890 		fprintf(stdout, "};\n\n");
    891 		fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n");
    892 	} else if (structs) {
    893 		if (prefix != NULL) {
    894 			if ((fd = fopen(prefix,"r")) != NULL) {
    895 				while (fgets(buf, sizeof(buf), fd) != NULL)
    896 					fputs(buf, stdout);
    897 				fclose(fd);
    898 			}
    899 		}
    900 		for (tt = types; tt != NULL; tt = tt->next) {
    901 			snprintf(buf, sizeof(buf), "%s/%s_%d.h",
    902 				tt->dirname, tt->typename, tt->type);
    903 			if ((fd = fopen(buf,"r")) != NULL) {
    904 				while (fgets(buf, sizeof(buf), fd) != NULL)
    905 					fputs(buf, stdout);
    906 				fclose(fd);
    907 			}
    908 		}
    909 		if (suffix != NULL) {
    910 			if ((fd = fopen(suffix,"r")) != NULL) {
    911 				while (fgets(buf, sizeof(buf), fd) != NULL)
    912 					fputs(buf, stdout);
    913 				fclose(fd);
    914 			}
    915 		}
    916 	} else if (depend) {
    917 		for (tt = types; tt != NULL; tt = tt->next)
    918 			fprintf(stdout, "%s:\t%s/%s_%d.h\n", file,
    919 				tt->dirname, tt->typename, tt->type);
    920 	}
    921 
    922 	if (ferror(stdout) != 0)
    923 		exit(1);
    924 
    925 	return (0);
    926 }
    927