gen.c revision 1.3
1/* $NetBSD: gen.c,v 1.3 2019/01/09 16:55:11 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 = true" 60 61#define FROMWIREARGS "rdclass, type, source, dctx, options, target" 62#define FROMWIRECLASS "rdclass" 63#define FROMWIRETYPE "type" 64#define FROMWIREDEF "use_default = true" 65 66#define TOWIREARGS "rdata, cctx, target" 67#define TOWIRECLASS "rdata->rdclass" 68#define TOWIRETYPE "rdata->type" 69#define TOWIREDEF "use_default = true" 70 71#define FROMSTRUCTARGS "rdclass, type, source, target" 72#define FROMSTRUCTCLASS "rdclass" 73#define FROMSTRUCTTYPE "type" 74#define FROMSTRUCTDEF "use_default = true" 75 76#define TOSTRUCTARGS "rdata, target, mctx" 77#define TOSTRUCTCLASS "rdata->rdclass" 78#define TOSTRUCTTYPE "rdata->type" 79#define TOSTRUCTDEF "use_default = 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 = true" 90 91#define ADDITIONALDATAARGS "rdata, add, arg" 92#define ADDITIONALDATACLASS "rdata->rdclass" 93#define ADDITIONALDATATYPE "rdata->type" 94#define ADDITIONALDATADEF "use_default = true" 95 96#define DIGESTARGS "rdata, digest, arg" 97#define DIGESTCLASS "rdata->rdclass" 98#define DIGESTTYPE "rdata->type" 99#define DIGESTDEF "use_default = true" 100 101#define CHECKOWNERARGS "name, rdclass, type, wildcard" 102#define CHECKOWNERCLASS "rdclass" 103#define CHECKOWNERTYPE "type" 104#define CHECKOWNERDEF "result = true" 105 106#define CHECKNAMESARGS "rdata, owner, bad" 107#define CHECKNAMESCLASS "rdata->rdclass" 108#define CHECKNAMESTYPE "rdata->type" 109#define CHECKNAMESDEF "result = 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 classbuf[TYPECLASSBUF]; 144} *classes; 145 146static struct tt { 147 struct tt *next; 148 int rdclass; 149 int type; 150 char classbuf[TYPECLASSBUF]; 151 char typebuf[TYPECLASSBUF]; 152 char dirbuf[DIRNAMESIZE-30]; /* XXX Should be max path length */ 153} *types; 154 155static struct ttnam { 156 char typebuf[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->typebuf, 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->classbuf, buf1), 260 funname(tt->typebuf, 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].typebuf[0] != 0 && 292 typenames[i].type == type) 293 { 294 return (&typenames[i]); 295 } 296 } 297 return (NULL); 298} 299 300static void 301insert_into_typenames(int type, const char *typebuf, const char *attr) { 302 struct ttnam *ttn = NULL; 303 size_t c; 304 int i, n; 305 char tmp[256]; 306 307 INSIST(strlen(typebuf) < TYPECLASSBUF); 308 for (i = 0; i < TYPENAMES; i++) { 309 if (typenames[i].typebuf[0] != 0 && 310 typenames[i].type == type && 311 strcmp(typebuf, typenames[i].typebuf) != 0) 312 { 313 fprintf(stderr, 314 "Error: type %d has two names: %s, %s\n", 315 type, typenames[i].typebuf, typebuf); 316 exit(1); 317 } 318 if (typenames[i].typebuf[0] == 0 && ttn == NULL) { 319 ttn = &typenames[i]; 320 } 321 } 322 if (ttn == NULL) { 323 fprintf(stderr, "Error: typenames array too small\n"); 324 exit(1); 325 } 326 327 /* XXXMUKS: This is redundant due to the INSIST above. */ 328 if (strlen(typebuf) > sizeof(ttn->typebuf) - 1) { 329 fprintf(stderr, "Error: type name %s is too long\n", 330 typebuf); 331 exit(1); 332 } 333 334 strncpy(ttn->typebuf, typebuf, sizeof(ttn->typebuf)); 335 ttn->typebuf[sizeof(ttn->typebuf) - 1] = '\0'; 336 337 strncpy(ttn->macroname, ttn->typebuf, sizeof(ttn->macroname)); 338 ttn->macroname[sizeof(ttn->macroname) - 1] = '\0'; 339 340 ttn->type = type; 341 c = strlen(ttn->macroname); 342 while (c > 0) { 343 if (ttn->macroname[c - 1] == '-') { 344 ttn->macroname[c - 1] = '_'; 345 } 346 c--; 347 } 348 349 if (attr == NULL) { 350 n = snprintf(tmp, sizeof(tmp), 351 "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); 352 INSIST(n > 0 && (unsigned)n < sizeof(tmp)); 353 attr = tmp; 354 } 355 356 if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) { 357 fprintf(stderr, "Error: type %d has different attributes: " 358 "%s, %s\n", type, ttn->attr, attr); 359 exit(1); 360 } 361 362 if (strlen(attr) > sizeof(ttn->attr) - 1) { 363 fprintf(stderr, "Error: attr (%s) [name %s] is too long\n", 364 attr, typebuf); 365 exit(1); 366 } 367 368 strncpy(ttn->attr, attr, sizeof(ttn->attr)); 369 ttn->attr[sizeof(ttn->attr) - 1] = '\0'; 370 371 ttn->sorted = 0; 372 if (maxtype < type) { 373 maxtype = type; 374 } 375} 376 377static void 378add(int rdclass, const char *classbuf, int type, const char *typebuf, 379 const char *dirbuf) 380{ 381 struct tt *newtt = (struct tt *)malloc(sizeof(*newtt)); 382 struct tt *tt, *oldtt; 383 struct cc *newcc; 384 struct cc *cc, *oldcc; 385 386 INSIST(strlen(typebuf) < TYPECLASSBUF); 387 INSIST(strlen(classbuf) < TYPECLASSBUF); 388 INSIST(strlen(dirbuf) < DIRNAMESIZE); 389 390 insert_into_typenames(type, typebuf, NULL); 391 392 if (newtt == NULL) { 393 fprintf(stderr, "malloc() failed\n"); 394 exit(1); 395 } 396 397 newtt->next = NULL; 398 newtt->rdclass = rdclass; 399 newtt->type = type; 400 401 strncpy(newtt->classbuf, classbuf, sizeof(newtt->classbuf)); 402 newtt->classbuf[sizeof(newtt->classbuf) - 1] = '\0'; 403 404 strncpy(newtt->typebuf, typebuf, sizeof(newtt->typebuf)); 405 newtt->typebuf[sizeof(newtt->typebuf) - 1] = '\0'; 406 407 if (strncmp(dirbuf, "./", 2) == 0) { 408 dirbuf += 2; 409 } 410 strncpy(newtt->dirbuf, dirbuf, sizeof(newtt->dirbuf)); 411 newtt->dirbuf[sizeof(newtt->dirbuf) - 1] = '\0'; 412 413 tt = types; 414 oldtt = NULL; 415 416 while ((tt != NULL) && (tt->type < type)) { 417 oldtt = tt; 418 tt = tt->next; 419 } 420 421 while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) { 422 if (strcmp(tt->typebuf, typebuf) != 0) { 423 exit(1); 424 } 425 oldtt = tt; 426 tt = tt->next; 427 } 428 429 if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass)) { 430 exit(1); 431 } 432 433 newtt->next = tt; 434 if (oldtt != NULL) { 435 oldtt->next = newtt; 436 } else { 437 types = newtt; 438 } 439 440 /* 441 * Do a class switch for this type. 442 */ 443 if (rdclass == 0) { 444 return; 445 } 446 447 newcc = (struct cc *)malloc(sizeof(*newcc)); 448 if (newcc == NULL) { 449 fprintf(stderr, "malloc() failed\n"); 450 exit(1); 451 } 452 newcc->rdclass = rdclass; 453 strncpy(newcc->classbuf, classbuf, sizeof(newcc->classbuf)); 454 newcc->classbuf[sizeof(newcc->classbuf) - 1] = '\0'; 455 cc = classes; 456 oldcc = NULL; 457 458 while ((cc != NULL) && (cc->rdclass < rdclass)) { 459 oldcc = cc; 460 cc = cc->next; 461 } 462 463 if ((cc != NULL) && cc->rdclass == rdclass) { 464 free((char *)newcc); 465 return; 466 } 467 468 newcc->next = cc; 469 if (oldcc != NULL) { 470 oldcc->next = newcc; 471 } else { 472 classes = newcc; 473 } 474} 475 476static void 477sd(int rdclass, const char *classbuf, const char *dirbuf, char filetype) { 478 char buf[TYPECLASSLEN + sizeof("_65535.h")]; 479 char typebuf[TYPECLASSBUF]; 480 int type, n; 481 isc_dir_t dir; 482 483 if (!start_directory(dirbuf, &dir)) { 484 return; 485 } 486 487 while (next_file(&dir)) { 488 if (sscanf(dir.filename, TYPECLASSFMT, typebuf, &type) != 2) { 489 continue; 490 } 491 if ((type > 65535) || (type < 0)) { 492 continue; 493 } 494 495 n = snprintf(buf, sizeof(buf), "%s_%d.%c", typebuf, 496 type, filetype); 497 INSIST(n > 0 && (unsigned)n < sizeof(buf)); 498 if (strcmp(buf, dir.filename) != 0) { 499 continue; 500 } 501 add(rdclass, classbuf, type, typebuf, dirbuf); 502 } 503 504 end_directory(&dir); 505} 506 507static unsigned int 508HASH(char *string) { 509 size_t n; 510 unsigned char a, b; 511 512 n = strlen(string); 513 if (n == 0) { 514 fprintf(stderr, "n == 0?\n"); 515 exit(1); 516 } 517 a = tolower((unsigned char)string[0]); 518 b = tolower((unsigned char)string[n - 1]); 519 520 return ((a + n) * b) % 256; 521} 522 523int 524main(int argc, char **argv) { 525 char buf[DIRNAMESIZE]; /* XXX Should be max path length */ 526 char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */ 527 int rdclass; 528 char classbuf[TYPECLASSBUF]; 529 struct tt *tt; 530 struct cc *cc; 531 struct ttnam *ttn, *ttn2; 532 unsigned int hash; 533 struct tm *tm; 534 time_t now; 535 char year[11]; 536 int lasttype; 537 int code = 1; 538 int class_enum = 0; 539 int type_enum = 0; 540 int structs = 0; 541 int depend = 0; 542 int c, i, j, n; 543 char buf1[TYPECLASSBUF]; 544 char filetype = 'c'; 545 FILE *fd; 546 char *prefix = NULL; 547 char *suffix = NULL; 548 char *file = NULL; 549 isc_dir_t dir; 550 551 for (i = 0; i < TYPENAMES; i++) 552 memset(&typenames[i], 0, sizeof(typenames[i])); 553 554 srcdir[0] = '\0'; 555 while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1) 556 switch (c) { 557 case 'c': 558 code = 0; 559 depend = 0; 560 type_enum = 0; 561 class_enum = 1; 562 filetype = 'c'; 563 structs = 0; 564 break; 565 case 'd': 566 code = 0; 567 depend = 1; 568 class_enum = 0; 569 type_enum = 0; 570 structs = 0; 571 filetype = 'h'; 572 break; 573 case 't': 574 code = 0; 575 depend = 0; 576 class_enum = 0; 577 type_enum = 1; 578 filetype = 'c'; 579 structs = 0; 580 break; 581 case 'i': 582 code = 0; 583 depend = 0; 584 class_enum = 0; 585 type_enum = 0; 586 structs = 1; 587 filetype = 'h'; 588 break; 589 case 's': 590 if (strlen(isc_commandline_argument) > 591 DIRNAMESIZE - 2 * TYPECLASSLEN - 592 sizeof("/rdata/_65535_65535")) 593 { 594 fprintf(stderr, "\"%s\" too long\n", 595 isc_commandline_argument); 596 exit(1); 597 } 598 n = snprintf(srcdir, sizeof(srcdir), "%s/", 599 isc_commandline_argument); 600 INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 601 break; 602 case 'F': 603 file = isc_commandline_argument; 604 break; 605 case 'P': 606 prefix = isc_commandline_argument; 607 break; 608 case 'S': 609 suffix = isc_commandline_argument; 610 break; 611 case '?': 612 exit(1); 613 } 614 615 n = snprintf(buf, sizeof(buf), "%srdata", srcdir); 616 INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 617 618 if (!start_directory(buf, &dir)) { 619 exit(1); 620 } 621 622 while (next_file(&dir)) { 623 if (sscanf(dir.filename, TYPECLASSFMT, classbuf, 624 &rdclass) != 2) 625 { 626 continue; 627 } 628 if ((rdclass > 65535) || (rdclass < 0)) { 629 continue; 630 } 631 632 n = snprintf(buf, sizeof(buf), "%srdata/%s_%d", 633 srcdir, classbuf, rdclass); 634 INSIST(n > 0 && (unsigned)n < sizeof(buf)); 635 if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) { 636 continue; 637 } 638 sd(rdclass, classbuf, buf, filetype); 639 } 640 end_directory(&dir); 641 n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir); 642 INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 643 sd(0, "", buf, filetype); 644 645 if (time(&now) != -1) { 646 if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) { 647 n = snprintf(year, sizeof(year), "-%d", 648 tm->tm_year + 1900); 649 INSIST(n > 0 && (unsigned)n < sizeof(year)); 650 } else { 651 snprintf(year, sizeof(year), "-2016"); 652 } 653 } else { 654 snprintf(year, sizeof(year), "-2016"); 655 } 656 657 if (!depend) { 658 fprintf(stdout, copyright, year); 659 } 660 661 if (code) { 662 fputs("#ifndef DNS_CODE_H\n", stdout); 663 fputs("#define DNS_CODE_H 1\n\n", stdout); 664 665 fputs("#include <stdbool.h>\n", stdout); 666 fputs("#include <isc/result.h>\n\n", stdout); 667 fputs("#include <dns/name.h>\n\n", stdout); 668 669 for (tt = types; tt != NULL; tt = tt->next) { 670 fprintf(stdout, "#include \"%s/%s_%d.c\"\n", 671 tt->dirbuf, tt->typebuf, tt->type); 672 } 673 674 fputs("\n\n", stdout); 675 676 doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS, 677 FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF); 678 doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS, 679 TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF); 680 doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS, 681 FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF); 682 doswitch("TOWIRESWITCH", "towire", TOWIREARGS, 683 TOWIRETYPE, TOWIRECLASS, TOWIREDEF); 684 doswitch("COMPARESWITCH", "compare", COMPAREARGS, 685 COMPARETYPE, COMPARECLASS, COMPAREDEF); 686 doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS, 687 COMPARETYPE, COMPARECLASS, COMPAREDEF); 688 doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS, 689 FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF); 690 doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS, 691 TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF); 692 doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS, 693 FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF); 694 doswitch("ADDITIONALDATASWITCH", "additionaldata", 695 ADDITIONALDATAARGS, ADDITIONALDATATYPE, 696 ADDITIONALDATACLASS, ADDITIONALDATADEF); 697 doswitch("DIGESTSWITCH", "digest", 698 DIGESTARGS, DIGESTTYPE, 699 DIGESTCLASS, DIGESTDEF); 700 doswitch("CHECKOWNERSWITCH", "checkowner", 701 CHECKOWNERARGS, CHECKOWNERTYPE, 702 CHECKOWNERCLASS, CHECKOWNERDEF); 703 doswitch("CHECKNAMESSWITCH", "checknames", 704 CHECKNAMESARGS, CHECKNAMESTYPE, 705 CHECKNAMESCLASS, CHECKNAMESDEF); 706 707 /* 708 * From here down, we are processing the rdata names and 709 * attributes. 710 */ 711 712#define PRINT_COMMA(x) (x == maxtype ? "" : ",") 713 714#define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \ 715 "DNS_RDATATYPEATTR_NOTQUESTION" 716#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \ 717 "DNS_RDATATYPEATTR_QUESTIONONLY" 718#define RESERVEDNAME "0" 719#define RESERVED "DNS_RDATATYPEATTR_RESERVED" 720 721 /* 722 * Add in reserved/special types. This will let us 723 * sort them without special cases. 724 */ 725 insert_into_typenames(0, "reserved0", RESERVED); 726 insert_into_typenames(100, "uinfo", RESERVEDNAME); 727 insert_into_typenames(101, "uid", RESERVEDNAME); 728 insert_into_typenames(102, "gid", RESERVEDNAME); 729 insert_into_typenames(251, "ixfr", METAQUESTIONONLY); 730 insert_into_typenames(252, "axfr", METAQUESTIONONLY); 731 insert_into_typenames(253, "mailb", METAQUESTIONONLY); 732 insert_into_typenames(254, "maila", METAQUESTIONONLY); 733 insert_into_typenames(255, "any", METAQUESTIONONLY); 734 735 /* 736 * Spit out a quick and dirty hash function. Here, 737 * we walk through the list of type names, and calculate 738 * a hash. This isn't perfect, but it will generate "pretty 739 * good" estimates. Lowercase the characters before 740 * computing in all cases. 741 * 742 * Here, walk the list from top to bottom, calculating 743 * the hash (mod 256) for each name. 744 */ 745 fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n"); 746 fprintf(stdout, "\tdo { \\\n"); 747 fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n" 748 "\t\t strncasecmp(_s,(_tn)," 749 "(sizeof(_s) - 1)) == 0) { \\\n"); 750 fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & " 751 "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n"); 752 fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n"); 753 fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n"); 754 fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n"); 755 fprintf(stdout, "\t\t} \\\n"); 756 fprintf(stdout, "\t} while (/*CONSTCOND*/0)\n\n"); 757 758 fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash," 759 "_typename,_length,_typep) \\\n"); 760 fprintf(stdout, "\tswitch (_hash) { \\\n"); 761 for (i = 0; i <= maxtype; i++) { 762 ttn = find_typename(i); 763 if (ttn == NULL) { 764 continue; 765 } 766 767 /* 768 * Skip entries we already processed. 769 */ 770 if (ttn->sorted != 0) { 771 continue; 772 } 773 774 hash = HASH(ttn->typebuf); 775 fprintf(stdout, "\t\tcase %u: \\\n", hash); 776 777 /* 778 * Find all other entries that happen to match 779 * this hash. 780 */ 781 for (j = 0; j <= maxtype; j++) { 782 ttn2 = find_typename(j); 783 if (ttn2 == NULL) { 784 continue; 785 } 786 if (hash == HASH(ttn2->typebuf)) { 787 fprintf(stdout, "\t\t\t" 788 "RDATATYPE_COMPARE" 789 "(\"%s\", %d, _typename, " 790 " _length, _typep); \\\n", 791 ttn2->typebuf, ttn2->type); 792 ttn2->sorted = 1; 793 } 794 } 795 fprintf(stdout, "\t\t\tbreak; \\\n"); 796 } 797 fprintf(stdout, "\t}\n"); 798 799 fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n"); 800 fprintf(stdout, "\tswitch (type) { \\\n"); 801 for (i = 0; i <= maxtype; i++) { 802 ttn = find_typename(i); 803 if (ttn == NULL) { 804 continue; 805 } 806 fprintf(stdout, "\tcase %d: return (%s); \\\n", 807 i, upper(ttn->attr)); 808 } 809 fprintf(stdout, "\t}\n"); 810 811 fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n"); 812 fprintf(stdout, "\tswitch (type) { \\\n"); 813 for (i = 0; i <= maxtype; i++) { 814 ttn = find_typename(i); 815 if (ttn == NULL) { 816 continue; 817 } 818 /* 819 * Remove KEYDATA (65533) from the type to memonic 820 * translation as it is internal use only. This 821 * stops the tools from displaying KEYDATA instead 822 * of TYPE65533. 823 */ 824 if (i == 65533U) { 825 continue; 826 } 827 fprintf(stdout, "\tcase %d: return " 828 "(str_totext(\"%s\", target)); \\\n", 829 i, upper(ttn->typebuf)); 830 } 831 fprintf(stdout, "\t}\n"); 832 833 fputs("#endif /* DNS_CODE_H */\n", stdout); 834 } else if (type_enum) { 835 char *s; 836 837 fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n"); 838 fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n"); 839 840 fprintf(stdout, "enum {\n"); 841 fprintf(stdout, "\tdns_rdatatype_none = 0,\n"); 842 843 lasttype = 0; 844 for (tt = types; tt != NULL; tt = tt->next) { 845 if (tt->type != lasttype) { 846 fprintf(stdout, 847 "\tdns_rdatatype_%s = %d,\n", 848 funname(tt->typebuf, buf1), 849 lasttype = tt->type); 850 } 851 } 852 853 fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n"); 854 fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n"); 855 fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n"); 856 fprintf(stdout, "\tdns_rdatatype_maila = 254,\n"); 857 fprintf(stdout, "\tdns_rdatatype_any = 255\n"); 858 859 fprintf(stdout, "};\n\n"); 860 861 fprintf(stdout, "#define dns_rdatatype_none\t" 862 "((dns_rdatatype_t)dns_rdatatype_none)\n"); 863 864 for (tt = types; tt != NULL; tt = tt->next) { 865 if (tt->type != lasttype) { 866 s = funname(tt->typebuf, buf1); 867 fprintf(stdout, 868 "#define dns_rdatatype_%s\t%s" 869 "((dns_rdatatype_t)dns_rdatatype_%s)" 870 "\n", 871 s, strlen(s) < 2U ? "\t" : "", s); 872 lasttype = tt->type; 873 } 874 } 875 876 fprintf(stdout, "#define dns_rdatatype_ixfr\t" 877 "((dns_rdatatype_t)dns_rdatatype_ixfr)\n"); 878 fprintf(stdout, "#define dns_rdatatype_axfr\t" 879 "((dns_rdatatype_t)dns_rdatatype_axfr)\n"); 880 fprintf(stdout, "#define dns_rdatatype_mailb\t" 881 "((dns_rdatatype_t)dns_rdatatype_mailb)\n"); 882 fprintf(stdout, "#define dns_rdatatype_maila\t" 883 "((dns_rdatatype_t)dns_rdatatype_maila)\n"); 884 fprintf(stdout, "#define dns_rdatatype_any\t" 885 "((dns_rdatatype_t)dns_rdatatype_any)\n"); 886 887 fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n"); 888 889 } else if (class_enum) { 890 char *s; 891 int classnum; 892 893 fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n"); 894 fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n"); 895 896 fprintf(stdout, "enum {\n"); 897 898 fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n"); 899 fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t" 900 "((dns_rdataclass_t)dns_rdataclass_reserved0)\n"); 901 902#define PRINTCLASS(name, num) \ 903 do { \ 904 s = funname(name, buf1); \ 905 classnum = num; \ 906 fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \ 907 classnum != 255 ? "," : ""); \ 908 fprintf(stdout, "#define dns_rdataclass_%s\t" \ 909 "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \ 910 } while (/*CONSTCOND*/0) 911 912 for (cc = classes; cc != NULL; cc = cc->next) { 913 if (cc->rdclass == 3) { 914 PRINTCLASS("chaos", 3); 915 } else if (cc->rdclass == 255) { 916 PRINTCLASS("none", 254); 917 } 918 PRINTCLASS(cc->classbuf, cc->rdclass); 919 } 920 921#undef PRINTCLASS 922 923 fprintf(stdout, "};\n\n"); 924 fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n"); 925 } else if (structs) { 926 if (prefix != NULL) { 927 if ((fd = fopen(prefix,"r")) != NULL) { 928 while (fgets(buf, sizeof(buf), fd) != NULL) { 929 fputs(buf, stdout); 930 } 931 fclose(fd); 932 } 933 } 934 for (tt = types; tt != NULL; tt = tt->next) { 935 snprintf(buf, sizeof(buf), "%s/%s_%d.h", 936 tt->dirbuf, tt->typebuf, tt->type); 937 if ((fd = fopen(buf,"r")) != NULL) { 938 while (fgets(buf, sizeof(buf), fd) != NULL) { 939 fputs(buf, stdout); 940 } 941 fclose(fd); 942 } 943 } 944 if (suffix != NULL) { 945 if ((fd = fopen(suffix,"r")) != NULL) { 946 while (fgets(buf, sizeof(buf), fd) != NULL) { 947 fputs(buf, stdout); 948 } 949 fclose(fd); 950 } 951 } 952 } else if (depend) { 953 for (tt = types; tt != NULL; tt = tt->next) { 954 fprintf(stdout, "%s:\t%s/%s_%d.h\n", file, 955 tt->dirbuf, tt->typebuf, tt->type); 956 } 957 } 958 959 if (ferror(stdout) != 0) { 960 exit(1); 961 } 962 963 return (0); 964} 965