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