gen.c revision 1.1
1/* $NetBSD: gen.c,v 1.1 2018/08/12 12:08:10 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 111static 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 140static struct cc { 141 struct cc *next; 142 int rdclass; 143 char classname[TYPECLASSBUF]; 144} *classes; 145 146static 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 155static 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 163static int maxtype = -1; 164 165static char * 166upper(char *); 167static char * 168funname(const char *, char *); 169static void 170doswitch(const char *, const char *, const char *, const char *, 171 const char *, const char *); 172static void 173add(int, const char *, int, const char *, const char *); 174static void 175sd(int, const char *, const char *, char); 176static void 177insert_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 */ 182static char * 183upper(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 202static char * 203funname(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 215static void 216doswitch(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 286static struct ttnam * 287find_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 298static void 299insert_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 371static void 372add(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 464static void 465sd(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 491static unsigned int 492HASH(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 507int 508main(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 (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 (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