gen.c 23.6 KB
Newer Older
1
/*
2
 * Copyright (C) 1998-2009, 2012-2016  Internet Systems Consortium, Inc. ("ISC")
3
 *
4 5 6
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 8
 */

9
/*! \file */
Bob Halley's avatar
Bob Halley committed
10

Mark Andrews's avatar
win32  
Mark Andrews committed
11 12 13 14 15
#ifdef WIN32
/*
 * Silence compiler warnings about using strcpy and friends.
 */
#define _CRT_SECURE_NO_DEPRECATE 1
Mark Andrews's avatar
Mark Andrews committed
16
/*
17
 * We use snprintf which was defined late in Windows even it is in C99.
Mark Andrews's avatar
Mark Andrews committed
18
 */
19
#if _MSC_VER < 1900
Mark Andrews's avatar
Mark Andrews committed
20
#define snprintf _snprintf
Mark Andrews's avatar
win32  
Mark Andrews committed
21
#endif
22
#endif
Mark Andrews's avatar
win32  
Mark Andrews committed
23

24 25 26
#include <sys/types.h>

#include <ctype.h>
27
#include <stdlib.h>
28 29 30 31 32
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

David Lawrence's avatar
David Lawrence committed
33 34 35 36 37
#ifdef WIN32
#include "gen-win32.h"
#else
#include "gen-unix.h"
#endif
38

39 40 41 42 43 44
#define INSIST(cond) \
	if (!(cond)) { \
		fprintf(stderr, "%s:%d: INSIST(%s)\n", \
			 __FILE__, __LINE__, #cond); \
		abort(); \
	}
45

46
#define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks"
47
#define FROMTEXTCLASS "rdclass"
48
#define FROMTEXTTYPE "type"
49
#define FROMTEXTDEF "result = DNS_R_UNKNOWN"
50

51
#define TOTEXTARGS "rdata, tctx, target"
52
#define TOTEXTCLASS "rdata->rdclass"
53
#define TOTEXTTYPE "rdata->type"
Mark Andrews's avatar
Mark Andrews committed
54
#define TOTEXTDEF "use_default = ISC_TRUE"
55

56
#define FROMWIREARGS "rdclass, type, source, dctx, options, target"
57
#define FROMWIRECLASS "rdclass"
58
#define FROMWIRETYPE "type"
Mark Andrews's avatar
Mark Andrews committed
59
#define FROMWIREDEF "use_default = ISC_TRUE"
60 61

#define TOWIREARGS "rdata, cctx, target"
62
#define TOWIRECLASS "rdata->rdclass"
63
#define TOWIRETYPE "rdata->type"
Mark Andrews's avatar
Mark Andrews committed
64
#define TOWIREDEF "use_default = ISC_TRUE"
65

66 67
#define FROMSTRUCTARGS "rdclass, type, source, target"
#define FROMSTRUCTCLASS "rdclass"
68
#define FROMSTRUCTTYPE "type"
Mark Andrews's avatar
Mark Andrews committed
69
#define FROMSTRUCTDEF "use_default = ISC_TRUE"
70

71
#define TOSTRUCTARGS "rdata, target, mctx"
72
#define TOSTRUCTCLASS "rdata->rdclass"
73
#define TOSTRUCTTYPE "rdata->type"
Mark Andrews's avatar
Mark Andrews committed
74
#define TOSTRUCTDEF "use_default = ISC_TRUE"
75

76 77 78 79 80
#define FREESTRUCTARGS "source"
#define FREESTRUCTCLASS "common->rdclass"
#define FREESTRUCTTYPE "common->rdtype"
#define FREESTRUCTDEF NULL

81
#define COMPAREARGS "rdata1, rdata2"
82
#define COMPARECLASS "rdata1->rdclass"
83
#define COMPARETYPE "rdata1->type"
Mark Andrews's avatar
Mark Andrews committed
84
#define COMPAREDEF "use_default = ISC_TRUE"
85

86 87 88 89 90
#define ADDITIONALDATAARGS "rdata, add, arg"
#define ADDITIONALDATACLASS "rdata->rdclass"
#define ADDITIONALDATATYPE "rdata->type"
#define ADDITIONALDATADEF "use_default = ISC_TRUE"

Bob Halley's avatar
Bob Halley committed
91 92 93 94 95
#define DIGESTARGS "rdata, digest, arg"
#define DIGESTCLASS "rdata->rdclass"
#define DIGESTTYPE "rdata->type"
#define DIGESTDEF "use_default = ISC_TRUE"

96 97 98 99 100 101 102 103 104 105
#define CHECKOWNERARGS "name, rdclass, type, wildcard"
#define CHECKOWNERCLASS "rdclass"
#define CHECKOWNERTYPE "type"
#define CHECKOWNERDEF "result = ISC_TRUE"

#define CHECKNAMESARGS "rdata, owner, bad"
#define CHECKNAMESCLASS "rdata->rdclass"
#define CHECKNAMESTYPE "rdata->type"
#define CHECKNAMESDEF "result = ISC_TRUE"

Mark Andrews's avatar
Mark Andrews committed
106
static const char copyright[] =
107
"/*\n"
Mark Andrews's avatar
Mark Andrews committed
108
" * Copyright (C) 1998%s  Internet Systems Consortium, Inc. (\"ISC\")\n"
109
" *\n"
Mark Andrews's avatar
Mark Andrews committed
110 111 112
" * This Source Code Form is subject to the terms of the Mozilla Public\n"
" * License, v. 2.0. If a copy of the MPL was not distributed with this\n"
" * file, You can obtain one at http://mozilla.org/MPL/2.0/.\n"
113 114 115 116 117 118 119 120
" */\n"
"\n"
"/***************\n"
" ***************\n"
" ***************   THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n"
" ***************   DO NOT EDIT!\n"
" ***************\n"
" ***************/\n"
121 122
"\n"
"/*! \\file */\n"
123
"\n";
124

125 126 127
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)

128
#define TYPENAMES 256
129 130 131 132 133
#define TYPECLASSLEN 20		/* DNS mnemonic size. Must be less than 100. */
#define TYPECLASSBUF (TYPECLASSLEN + 1)
#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d"
#define ATTRIBUTESIZE 256
#define DIRNAMESIZE 256
134

Mark Andrews's avatar
Mark Andrews committed
135
static struct cc {
136
	struct cc *next;
137
	int rdclass;
138
	char classname[TYPECLASSBUF];
139 140
} *classes;

Mark Andrews's avatar
Mark Andrews committed
141
static struct tt {
142
	struct tt *next;
143
	int rdclass;
144
	int type;
145 146 147
	char classname[TYPECLASSBUF];
	char typename[TYPECLASSBUF];
	char dirname[DIRNAMESIZE];	/* XXX Should be max path length */
148 149
} *types;

Mark Andrews's avatar
Mark Andrews committed
150
static struct ttnam {
151 152 153
	char typename[TYPECLASSBUF];
	char macroname[TYPECLASSBUF];
	char attr[ATTRIBUTESIZE];
154
	unsigned int sorted;
155 156 157
	int type;
} typenames[TYPENAMES];

Mark Andrews's avatar
Mark Andrews committed
158
static int maxtype = -1;
159

Mark Andrews's avatar
Mark Andrews committed
160
static char *
David Lawrence's avatar
David Lawrence committed
161
upper(char *);
Mark Andrews's avatar
Mark Andrews committed
162
static char *
163
funname(const char *, char *);
Mark Andrews's avatar
Mark Andrews committed
164
static void
David Lawrence's avatar
David Lawrence committed
165 166
doswitch(const char *, const char *, const char *, const char *,
	 const char *, const char *);
Mark Andrews's avatar
Mark Andrews committed
167
static void
David Lawrence's avatar
David Lawrence committed
168
add(int, const char *, int, const char *, const char *);
Mark Andrews's avatar
Mark Andrews committed
169
static void
David Lawrence's avatar
David Lawrence committed
170
sd(int, const char *, const char *, char);
Mark Andrews's avatar
Mark Andrews committed
171
static void
David Lawrence's avatar
David Lawrence committed
172
insert_into_typenames(int, const char *, const char *);
173

174
/*%
175 176
 * If you use more than 10 of these in, say, a printf(), you'll have problems.
 */
Mark Andrews's avatar
Mark Andrews committed
177
static char *
178
upper(char *s) {
179
	static int buf_to_use = 0;
180
	static char buf[10][256];
181
	char *b;
182
	int c;
183

184 185 186 187 188
	buf_to_use++;
	if (buf_to_use > 9)
		buf_to_use = 0;

	b = buf[buf_to_use];
189
	memset(b, 0, 256);
190

191
	while ((c = (*s++) & 0xff))
192 193
		*b++ = islower(c) ? toupper(c) : c;
	*b = '\0';
194
	return (buf[buf_to_use]);
195 196
}

Mark Andrews's avatar
Mark Andrews committed
197
static char *
198
funname(const char *s, char *buf) {
199 200 201
	char *b = buf;
	char c;

202
	INSIST(strlen(s) < TYPECLASSBUF);
203 204 205 206 207 208 209
	while ((c = *s++)) {
		*b++ = (c == '-') ? '_' : c;
	}
	*b = '\0';
	return (buf);
}

Mark Andrews's avatar
Mark Andrews committed
210
static void
David Lawrence's avatar
David Lawrence committed
211 212
doswitch(const char *name, const char *function, const char *args,
	 const char *tsw, const char *csw, const char *res)
213 214 215 216 217
{
	struct tt *tt;
	int first = 1;
	int lasttype = 0;
	int subswitch = 0;
218
	char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF];
David Lawrence's avatar
David Lawrence committed
219
	const char *result = " result =";
220 221 222

	if (res == NULL)
		result = "";
223

224
	for (tt = types; tt != NULL; tt = tt->next) {
225 226 227 228 229 230
		if (first) {
			fprintf(stdout, "\n#define %s \\\n", name);
			fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw);
			first = 0;
		}
		if (tt->type != lasttype && subswitch) {
231 232 233 234 235
			if (res == NULL)
				fprintf(stdout, "\t\tdefault: break; \\\n");
			else
				fprintf(stdout,
					"\t\tdefault: %s; break; \\\n", res);
236
			fputs(/*{*/ "\t\t} \\\n", stdout);
237
			fputs("\t\tbreak; \\\n", stdout);
238 239
			subswitch = 0;
		}
240
		if (tt->rdclass && tt->type != lasttype) {
241
			fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/,
242
				tt->type, csw);
243 244
			subswitch = 1;
		}
245
		if (tt->rdclass == 0)
246
			fprintf(stdout,
247 248
				"\tcase %d:%s %s_%s(%s); break;",
				tt->type, result, function,
249
				funname(tt->typename, buf1), args);
250 251
		else
			fprintf(stdout,
Brian Wellington's avatar
Brian Wellington committed
252
				"\t\tcase %d:%s %s_%s_%s(%s); break;",
253
				tt->rdclass, result, function,
254 255
				funname(tt->classname, buf1),
				funname(tt->typename, buf2), args);
256 257 258 259
		fputs(" \\\n", stdout);
		lasttype = tt->type;
	}
	if (subswitch) {
260 261
		if (res == NULL)
			fprintf(stdout, "\t\tdefault: break; \\\n");
262
		else
263
			fprintf(stdout, "\t\tdefault: %s; break; \\\n", res);
264
		fputs(/*{*/ "\t\t} \\\n", stdout);
265
		fputs("\t\tbreak; \\\n", stdout);
266
	}
267 268 269 270 271 272 273 274 275 276
	if (first) {
		if (res == NULL)
			fprintf(stdout, "\n#define %s\n", name);
		else
			fprintf(stdout, "\n#define %s %s;\n", name, res);
	} else {
		if (res == NULL)
			fprintf(stdout, "\tdefault: break; \\\n");
		else
			fprintf(stdout, "\tdefault: %s; break; \\\n", res);
277 278 279 280
		fputs(/*{*/ "\t}\n", stdout);
	}
}

281 282 283 284 285 286 287 288 289 290 291 292
static struct ttnam *
find_typename(int type) {
	int i;

	for (i = 0; i < TYPENAMES; i++) {
		if (typenames[i].typename[0] != 0 &&
		    typenames[i].type == type)
			return (&typenames[i]);
	}
	return (NULL);
}

Mark Andrews's avatar
Mark Andrews committed
293
static void
David Lawrence's avatar
David Lawrence committed
294
insert_into_typenames(int type, const char *typename, const char *attr) {
295
	struct ttnam *ttn = NULL;
296 297
	size_t c;
	int i, n;
298
	char tmp[256];
299

300
	INSIST(strlen(typename) < TYPECLASSBUF);
301 302 303 304 305 306 307
	for (i = 0; i < TYPENAMES; i++) {
		if (typenames[i].typename[0] != 0 &&
		    typenames[i].type == type &&
		    strcmp(typename, typenames[i].typename) != 0) {
			fprintf(stderr,
				"Error:  type %d has two names: %s, %s\n",
				type, typenames[i].typename, typename);
308 309
			exit(1);
		}
310 311 312 313 314
		if (typenames[i].typename[0] == 0 && ttn == NULL)
			ttn = &typenames[i];
	}
	if (ttn == NULL) {
		fprintf(stderr, "Error: typenames array too small\n");
315 316
		exit(1);
	}
317

318
	/* XXXMUKS: This is redundant due to the INSIST above. */
319 320 321 322 323
	if (strlen(typename) > sizeof(ttn->typename) - 1) {
		fprintf(stderr, "Error:  type name %s is too long\n",
			typename);
		exit(1);
	}
324

325
	strncpy(ttn->typename, typename, sizeof(ttn->typename));
326
	ttn->typename[sizeof(ttn->typename) - 1] = '\0';
327

328
	strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname));
329 330 331
	ttn->macroname[sizeof(ttn->macroname) - 1] = '\0';

	ttn->type = type;
332 333 334 335 336 337 338 339
	c = strlen(ttn->macroname);
	while (c > 0) {
		if (ttn->macroname[c - 1] == '-')
			ttn->macroname[c - 1] = '_';
		c--;
	}

	if (attr == NULL) {
340 341
		n = snprintf(tmp, sizeof(tmp),
			     "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname));
Mark Andrews's avatar
Mark Andrews committed
342
		INSIST(n > 0 && (unsigned)n < sizeof(tmp));
343 344 345 346 347 348 349 350 351 352 353 354 355 356
		attr = tmp;
	}

	if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) {
		fprintf(stderr, "Error:  type %d has different attributes: "
			"%s, %s\n", type, ttn->attr, attr);
		exit(1);
	}

	if (strlen(attr) > sizeof(ttn->attr) - 1) {
		fprintf(stderr, "Error:  attr (%s) [name %s] is too long\n",
			attr, typename);
		exit(1);
	}
357

Evan Hunt's avatar
Evan Hunt committed
358
	strncpy(ttn->attr, attr, sizeof(ttn->attr));
359 360
	ttn->attr[sizeof(ttn->attr) - 1] = '\0';

361
	ttn->sorted = 0;
362 363
	if (maxtype < type)
		maxtype = type;
364 365
}

Mark Andrews's avatar
Mark Andrews committed
366
static void
David Lawrence's avatar
David Lawrence committed
367 368 369
add(int rdclass, const char *classname, int type, const char *typename,
    const char *dirname)
{
Andreas Gustafsson's avatar
Andreas Gustafsson committed
370
	struct tt *newtt = (struct tt *)malloc(sizeof(*newtt));
371 372 373 374
	struct tt *tt, *oldtt;
	struct cc *newcc;
	struct cc *cc, *oldcc;

375 376 377 378
	INSIST(strlen(typename) < TYPECLASSBUF);
	INSIST(strlen(classname) < TYPECLASSBUF);
	INSIST(strlen(dirname) < DIRNAMESIZE);

379 380 381 382 383 384 385
	insert_into_typenames(type, typename, NULL);

	if (newtt == NULL) {
		fprintf(stderr, "malloc() failed\n");
		exit(1);
	}

386
	newtt->next = NULL;
387
	newtt->rdclass = rdclass;
388
	newtt->type = type;
389

390
	strncpy(newtt->classname, classname, sizeof(newtt->classname));
391 392
	newtt->classname[sizeof(newtt->classname) - 1] = '\0';

393
	strncpy(newtt->typename, typename, sizeof(newtt->typename));
394 395
	newtt->typename[sizeof(newtt->typename) - 1] = '\0';

396 397
	if (strncmp(dirname, "./", 2) == 0)
		dirname += 2;
398
	strncpy(newtt->dirname, dirname, sizeof(newtt->dirname));
399
	newtt->dirname[sizeof(newtt->dirname) - 1] = '\0';
400 401 402 403

	tt = types;
	oldtt = NULL;

Mark Andrews's avatar
Mark Andrews committed
404
	while ((tt != NULL) && (tt->type < type)) {
405 406 407 408
		oldtt = tt;
		tt = tt->next;
	}

409
	while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) {
410 411 412 413 414 415
		if (strcmp(tt->typename, typename) != 0)
			exit(1);
		oldtt = tt;
		tt = tt->next;
	}

416
	if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass))
417 418 419
		exit(1);

	newtt->next = tt;
Mark Andrews's avatar
Mark Andrews committed
420
	if (oldtt != NULL)
421 422 423 424
		oldtt->next = newtt;
	else
		types = newtt;

425 426 427
	/*
	 * Do a class switch for this type.
	 */
428
	if (rdclass == 0)
429 430
		return;

Andreas Gustafsson's avatar
Andreas Gustafsson committed
431
	newcc = (struct cc *)malloc(sizeof(*newcc));
432 433 434 435
	if (newcc == NULL) {
		fprintf(stderr, "malloc() failed\n");
		exit(1);
	}
436
	newcc->rdclass = rdclass;
437
	strncpy(newcc->classname, classname, sizeof(newcc->classname));
438
	newcc->classname[sizeof(newcc->classname) - 1] = '\0';
439 440
	cc = classes;
	oldcc = NULL;
441

442
	while ((cc != NULL) && (cc->rdclass < rdclass)) {
443 444 445 446
		oldcc = cc;
		cc = cc->next;
	}

447
	if ((cc != NULL) && cc->rdclass == rdclass) {
448 449 450 451 452
		free((char *)newcc);
		return;
	}

	newcc->next = cc;
Mark Andrews's avatar
Mark Andrews committed
453
	if (oldcc != NULL)
454 455 456 457 458
		oldcc->next = newcc;
	else
		classes = newcc;
}

Mark Andrews's avatar
Mark Andrews committed
459
static void
David Lawrence's avatar
David Lawrence committed
460
sd(int rdclass, const char *classname, const char *dirname, char filetype) {
461 462 463
	char buf[TYPECLASSLEN + sizeof("_65535.h")];
	char typename[TYPECLASSBUF];
	int type, n;
David Lawrence's avatar
David Lawrence committed
464
	isc_dir_t dir;
465

David Lawrence's avatar
David Lawrence committed
466
	if (!start_directory(dirname, &dir))
467 468
		return;

David Lawrence's avatar
David Lawrence committed
469
	while (next_file(&dir)) {
470
		if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2)
471 472 473 474
			continue;
		if ((type > 65535) || (type < 0))
			continue;

475 476
		n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename,
			     type, filetype);
Mark Andrews's avatar
Mark Andrews committed
477
		INSIST(n > 0 && (unsigned)n < sizeof(buf));
David Lawrence's avatar
David Lawrence committed
478
		if (strcmp(buf, dir.filename) != 0)
479
			continue;
David Lawrence's avatar
David Lawrence committed
480
		add(rdclass, classname, type, typename, dirname);
481
	}
David Lawrence's avatar
David Lawrence committed
482 483

	end_directory(&dir);
484 485
}

486
static unsigned int
David Lawrence's avatar
David Lawrence committed
487
HASH(char *string) {
488
	size_t n;
489 490 491
	unsigned char a, b;

	n = strlen(string);
Michael Graff's avatar
Michael Graff committed
492 493 494 495 496 497
	if (n == 0) {
		fprintf(stderr, "n == 0?\n");
		exit(1);
	}
	a = tolower((unsigned char)string[0]);
	b = tolower((unsigned char)string[n - 1]);
498 499 500 501

	return ((a + n) * b) % 256;
}

502 503
int
main(int argc, char **argv) {
504 505
	char buf[DIRNAMESIZE];		/* XXX Should be max path length */
	char srcdir[DIRNAMESIZE];	/* XXX Should be max path length */
506
	int rdclass;
507
	char classname[TYPECLASSBUF];
508
	struct tt *tt;
509
	struct cc *cc;
510 511
	struct ttnam *ttn, *ttn2;
	unsigned int hash;
512 513 514
	struct tm *tm;
	time_t now;
	char year[11];
515
	int lasttype;
Mark Andrews's avatar
Mark Andrews committed
516 517 518
	int code = 1;
	int class_enum = 0;
	int type_enum = 0;
519
	int structs = 0;
520
	int depend = 0;
521 522
	int c, i, j, n;
	char buf1[TYPECLASSBUF];
523 524
	char filetype = 'c';
	FILE *fd;
525 526
	char *prefix = NULL;
	char *suffix = NULL;
527
	char *file = NULL;
David Lawrence's avatar
David Lawrence committed
528
	isc_dir_t dir;
529

530
	for (i = 0; i < TYPENAMES; i++)
531
		memset(&typenames[i], 0, sizeof(typenames[i]));
Mark Andrews's avatar
Mark Andrews committed
532

533
	strcpy(srcdir, "");
534
	while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1)
Mark Andrews's avatar
Mark Andrews committed
535 536 537
		switch (c) {
		case 'c':
			code = 0;
538
			depend = 0;
Mark Andrews's avatar
Mark Andrews committed
539 540
			type_enum = 0;
			class_enum = 1;
541 542
			filetype = 'c';
			structs = 0;
Mark Andrews's avatar
Mark Andrews committed
543
			break;
544 545 546 547 548 549 550 551
		case 'd':
			code = 0;
			depend = 1;
			class_enum = 0;
			type_enum = 0;
			structs = 0;
			filetype = 'h';
			break;
Mark Andrews's avatar
Mark Andrews committed
552 553
		case 't':
			code = 0;
554
			depend = 0;
Mark Andrews's avatar
Mark Andrews committed
555 556
			class_enum = 0;
			type_enum = 1;
557 558 559 560 561
			filetype = 'c';
			structs = 0;
			break;
		case 'i':
			code = 0;
562
			depend = 0;
563 564 565 566
			class_enum = 0;
			type_enum = 0;
			structs = 1;
			filetype = 'h';
Mark Andrews's avatar
Mark Andrews committed
567
			break;
568
		case 's':
569 570 571 572 573 574 575 576 577
			if (strlen(isc_commandline_argument) >
			    DIRNAMESIZE - 2 * TYPECLASSLEN  -
			    sizeof("/rdata/_65535_65535")) {
				fprintf(stderr, "\"%s\" too long\n",
					isc_commandline_argument);
				exit(1);
			}
			n = snprintf(srcdir, sizeof(srcdir), "%s/",
				     isc_commandline_argument);
Mark Andrews's avatar
Mark Andrews committed
578
			INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
579
			break;
580 581 582
		case 'F':
			file = isc_commandline_argument;
			break;
583
		case 'P':
David Lawrence's avatar
David Lawrence committed
584
			prefix = isc_commandline_argument;
585 586
			break;
		case 'S':
David Lawrence's avatar
David Lawrence committed
587
			suffix = isc_commandline_argument;
588
			break;
Mark Andrews's avatar
Mark Andrews committed
589 590 591
		case '?':
			exit(1);
		}
592

593
	n = snprintf(buf, sizeof(buf), "%srdata", srcdir);
Mark Andrews's avatar
Mark Andrews committed
594
	INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
David Lawrence's avatar
David Lawrence committed
595 596

	if (!start_directory(buf, &dir))
597 598
		exit(1);

David Lawrence's avatar
David Lawrence committed
599
	while (next_file(&dir)) {
600 601
		if (sscanf(dir.filename, TYPECLASSFMT, classname,
			   &rdclass) != 2)
602
			continue;
603
		if ((rdclass > 65535) || (rdclass < 0))
604 605
			continue;

606 607
		n = snprintf(buf, sizeof(buf), "%srdata/%s_%d",
			     srcdir, classname, rdclass);
Mark Andrews's avatar
Mark Andrews committed
608
		INSIST(n > 0 && (unsigned)n < sizeof(buf));
David Lawrence's avatar
David Lawrence committed
609
		if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0)
610
			continue;
611
		sd(rdclass, classname, buf, filetype);
612
	}
David Lawrence's avatar
David Lawrence committed
613
	end_directory(&dir);
614
	n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir);
Mark Andrews's avatar
Mark Andrews committed
615
	INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
616
	sd(0, "", buf, filetype);
617 618

	if (time(&now) != -1) {
619 620 621
		if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) {
			n = snprintf(year, sizeof(year), "-%d",
				     tm->tm_year + 1900);
Mark Andrews's avatar
Mark Andrews committed
622
			INSIST(n > 0 && (unsigned)n < sizeof(year));
623
		} else
Mark Andrews's avatar
Mark Andrews committed
624
			strcpy(year, "-2016");
625
	} else
Mark Andrews's avatar
Mark Andrews committed
626
		strcpy(year, "-2016");
627

628
	if (!depend) fprintf(stdout, copyright, year);
629

Mark Andrews's avatar
Mark Andrews committed
630
	if (code) {
631 632 633 634 635 636 637
		fputs("#ifndef DNS_CODE_H\n", stdout);
		fputs("#define DNS_CODE_H 1\n\n", stdout);

		fputs("#include <isc/boolean.h>\n", stdout);
		fputs("#include <isc/result.h>\n\n", stdout);
		fputs("#include <dns/name.h>\n\n", stdout);

638
		for (tt = types; tt != NULL; tt = tt->next)
639 640
			fprintf(stdout, "#include \"%s/%s_%d.c\"\n",
				tt->dirname, tt->typename, tt->type);
641

642
		fputs("\n\n", stdout);
Mark Andrews's avatar
Mark Andrews committed
643 644 645 646 647 648 649 650 651 652 653

		doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS,
			 FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF);
		doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS,
			 TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF);
		doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS,
			 FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF);
		doswitch("TOWIRESWITCH", "towire", TOWIREARGS,
			 TOWIRETYPE, TOWIRECLASS, TOWIREDEF);
		doswitch("COMPARESWITCH", "compare", COMPAREARGS,
			  COMPARETYPE, COMPARECLASS, COMPAREDEF);
654 655
		doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS,
			  COMPARETYPE, COMPARECLASS, COMPAREDEF);
Mark Andrews's avatar
Mark Andrews committed
656 657 658 659
		doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS,
			  FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF);
		doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS,
			  TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF);
660 661
		doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS,
			  FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF);
662 663 664
		doswitch("ADDITIONALDATASWITCH", "additionaldata",
			 ADDITIONALDATAARGS, ADDITIONALDATATYPE,
			 ADDITIONALDATACLASS, ADDITIONALDATADEF);
Bob Halley's avatar
Bob Halley committed
665 666 667
		doswitch("DIGESTSWITCH", "digest",
			 DIGESTARGS, DIGESTTYPE,
			 DIGESTCLASS, DIGESTDEF);
668
		doswitch("CHECKOWNERSWITCH", "checkowner",
Mark Andrews's avatar
Mark Andrews committed
669 670
			CHECKOWNERARGS, CHECKOWNERTYPE,
			CHECKOWNERCLASS, CHECKOWNERDEF);
671
		doswitch("CHECKNAMESSWITCH", "checknames",
Mark Andrews's avatar
Mark Andrews committed
672 673
			CHECKNAMESARGS, CHECKNAMESTYPE,
			CHECKNAMESCLASS, CHECKNAMESDEF);
Mark Andrews's avatar
Mark Andrews committed
674

675 676 677 678
		/*
		 * From here down, we are processing the rdata names and
		 * attributes.
		 */
Mark Andrews's avatar
Mark Andrews committed
679

680
#define PRINT_COMMA(x) (x == maxtype ? "" : ",")
681

682 683 684 685
#define METANOTQUESTION  "DNS_RDATATYPEATTR_META | " \
			 "DNS_RDATATYPEATTR_NOTQUESTION"
#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \
			 "DNS_RDATATYPEATTR_QUESTIONONLY"
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
#define RESERVED "DNS_RDATATYPEATTR_RESERVED"

		/*
		 * Add in reserved/special types.  This will let us
		 * sort them without special cases.
		 */
		insert_into_typenames(0, "reserved0", RESERVED);
		insert_into_typenames(31, "eid", RESERVED);
		insert_into_typenames(32, "nimloc", RESERVED);
		insert_into_typenames(34, "atma", RESERVED);
		insert_into_typenames(100, "uinfo", RESERVED);
		insert_into_typenames(101, "uid", RESERVED);
		insert_into_typenames(102, "gid", RESERVED);
		insert_into_typenames(251, "ixfr", METAQUESTIONONLY);
		insert_into_typenames(252, "axfr", METAQUESTIONONLY);
		insert_into_typenames(253, "mailb", METAQUESTIONONLY);
		insert_into_typenames(254, "maila", METAQUESTIONONLY);
		insert_into_typenames(255, "any", METAQUESTIONONLY);
704

705 706 707 708 709 710 711 712 713 714
		/*
		 * Spit out a quick and dirty hash function.  Here,
		 * we walk through the list of type names, and calculate
		 * a hash.  This isn't perfect, but it will generate "pretty
		 * good" estimates.  Lowercase the characters before
		 * computing in all cases.
		 *
		 * Here, walk the list from top to bottom, calculating
		 * the hash (mod 256) for each name.
		 */
715
		fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n");
Danny Mayer's avatar
Danny Mayer committed
716
		fprintf(stdout, "\tdo { \\\n");
717 718 719
		fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n"
				"\t\t    strncasecmp(_s,(_tn),"
				"(sizeof(_s) - 1)) == 0) { \\\n");
Mark Andrews's avatar
Mark Andrews committed
720
		fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & "
721
				  "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n");
Danny Mayer's avatar
Danny Mayer committed
722 723 724 725 726
		fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n");
		fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n");
		fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n");
		fprintf(stdout, "\t\t} \\\n");
		fprintf(stdout, "\t} while (0)\n\n");
727

728 729
		fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash,"
				"_typename,_length,_typep) \\\n");
Danny Mayer's avatar
Danny Mayer committed
730
		fprintf(stdout, "\tswitch (_hash) { \\\n");
731 732 733 734
		for (i = 0; i <= maxtype; i++) {
			ttn = find_typename(i);
			if (ttn == NULL)
				continue;
735 736 737 738 739 740 741 742

			/*
			 * Skip entries we already processed.
			 */
			if (ttn->sorted != 0)
				continue;

			hash = HASH(ttn->typename);
Danny Mayer's avatar
Danny Mayer committed
743
			fprintf(stdout, "\t\tcase %u: \\\n", hash);
744 745 746 747 748

			/*
			 * Find all other entries that happen to match
			 * this hash.
			 */
749 750 751
			for (j = 0; j <= maxtype; j++) {
				ttn2 = find_typename(j);
				if (ttn2 == NULL)
Michael Graff's avatar
Michael Graff committed
752
					continue;
753
				if (hash == HASH(ttn2->typename)) {
Danny Mayer's avatar
Danny Mayer committed
754
					fprintf(stdout, "\t\t\tRDATATYPE_COMPARE"
755
					       "(\"%s\", %d, "
756
					       "_typename, _length, _typep); \\\n",
757
					       ttn2->typename, ttn2->type);
758 759 760
					ttn2->sorted = 1;
				}
			}
Danny Mayer's avatar
Danny Mayer committed
761
			fprintf(stdout, "\t\t\tbreak; \\\n");
762
		}
Danny Mayer's avatar
Danny Mayer committed
763
		fprintf(stdout, "\t}\n");
764

Mark Andrews's avatar
Mark Andrews committed
765 766 767 768 769 770
		fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n");
		fprintf(stdout, "\tswitch (type) { \\\n");
		for (i = 0; i <= maxtype; i++) {
			ttn = find_typename(i);
			if (ttn == NULL)
				continue;
771
			fprintf(stdout, "\tcase %d: return (%s); \\\n",
772
				i, upper(ttn->attr));
Mark Andrews's avatar
Mark Andrews committed
773 774 775 776 777 778 779 780 781
		}
		fprintf(stdout, "\t}\n");

		fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n");
		fprintf(stdout, "\tswitch (type) { \\\n");
		for (i = 0; i <= maxtype; i++) {
			ttn = find_typename(i);
			if (ttn == NULL)
				continue;
782 783 784 785 786 787 788 789
			/*
			 * Remove KEYDATA (65533) from the type to memonic
			 * translation as it is internal use only.  This
			 * stops the tools from displaying KEYDATA instead
			 * of TYPE65533.
			 */
			if (i == 65533U)
				continue;
790
			fprintf(stdout, "\tcase %d: return "
Mark Andrews's avatar
Mark Andrews committed
791
				"(str_totext(\"%s\", target)); \\\n",
792
				i, upper(ttn->typename));
Mark Andrews's avatar
Mark Andrews committed
793 794 795
		}
		fprintf(stdout, "\t}\n");

796
		fputs("#endif /* DNS_CODE_H */\n", stdout);
Mark Andrews's avatar
Mark Andrews committed
797
	} else if (type_enum) {
798 799
		char *s;

800
		fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n");
801
		fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n");
802

803 804
		fprintf(stdout, "enum {\n");
		fprintf(stdout, "\tdns_rdatatype_none = 0,\n");
Mark Andrews's avatar
Mark Andrews committed
805 806

		lasttype = 0;
807
		for (tt = types; tt != NULL; tt = tt->next)
Mark Andrews's avatar
Mark Andrews committed
808
			if (tt->type != lasttype)
809
				fprintf(stdout,
810
					"\tdns_rdatatype_%s = %d,\n",
811
					funname(tt->typename, buf1),
812 813 814 815 816 817 818 819 820 821 822 823 824
					lasttype = tt->type);

		fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n");
		fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n");
		fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n");
		fprintf(stdout, "\tdns_rdatatype_maila = 254,\n");
		fprintf(stdout, "\tdns_rdatatype_any = 255\n"