gen.c revision 262706
1290001Sglebius/* 2290001Sglebius * Copyright (C) 2004-2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") 3290001Sglebius * Copyright (C) 1998-2003 Internet Software Consortium. 4290001Sglebius * 5290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any 6290001Sglebius * purpose with or without fee is hereby granted, provided that the above 7290001Sglebius * copyright notice and this permission notice appear in all copies. 8290001Sglebius * 9290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11290001Sglebius * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15290001Sglebius * PERFORMANCE OF THIS SOFTWARE. 16290001Sglebius */ 17290001Sglebius 18290001Sglebius/*! \file */ 19290001Sglebius 20290001Sglebius#ifdef WIN32 21290001Sglebius/* 22290001Sglebius * Silence compiler warnings about using strcpy and friends. 23290001Sglebius */ 24290001Sglebius#define _CRT_SECURE_NO_DEPRECATE 1 25290001Sglebius/* 26290001Sglebius * We use snprintf. 27290001Sglebius */ 28290001Sglebius#define snprintf _snprintf 29290001Sglebius#endif 30290001Sglebius 31290001Sglebius#include <sys/types.h> 32290001Sglebius 33290001Sglebius#include <ctype.h> 34290001Sglebius#include <stdlib.h> 35290001Sglebius#include <stdio.h> 36290001Sglebius#include <stdlib.h> 37290001Sglebius#include <string.h> 38290001Sglebius#include <time.h> 39290001Sglebius 40290001Sglebius#ifdef WIN32 41290001Sglebius#include "gen-win32.h" 42290001Sglebius#else 43290001Sglebius#include "gen-unix.h" 44290001Sglebius#endif 45290001Sglebius 46290001Sglebius#define INSIST(cond) \ 47290001Sglebius if (!(cond)) { \ 48290001Sglebius fprintf(stderr, "%s:%d: INSIST(%s)\n", \ 49290001Sglebius __FILE__, __LINE__, #cond); \ 50290001Sglebius abort(); \ 51290001Sglebius } 52290001Sglebius 53290001Sglebius#define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks" 54290001Sglebius#define FROMTEXTCLASS "rdclass" 55290001Sglebius#define FROMTEXTTYPE "type" 56290001Sglebius#define FROMTEXTDEF "result = DNS_R_UNKNOWN" 57290001Sglebius 58290001Sglebius#define TOTEXTARGS "rdata, tctx, target" 59290001Sglebius#define TOTEXTCLASS "rdata->rdclass" 60290001Sglebius#define TOTEXTTYPE "rdata->type" 61290001Sglebius#define TOTEXTDEF "use_default = ISC_TRUE" 62290001Sglebius 63290001Sglebius#define FROMWIREARGS "rdclass, type, source, dctx, options, target" 64290001Sglebius#define FROMWIRECLASS "rdclass" 65290001Sglebius#define FROMWIRETYPE "type" 66290001Sglebius#define FROMWIREDEF "use_default = ISC_TRUE" 67290001Sglebius 68290001Sglebius#define TOWIREARGS "rdata, cctx, target" 69290001Sglebius#define TOWIRECLASS "rdata->rdclass" 70290001Sglebius#define TOWIRETYPE "rdata->type" 71290001Sglebius#define TOWIREDEF "use_default = ISC_TRUE" 72290001Sglebius 73290001Sglebius#define FROMSTRUCTARGS "rdclass, type, source, target" 74290001Sglebius#define FROMSTRUCTCLASS "rdclass" 75290001Sglebius#define FROMSTRUCTTYPE "type" 76290001Sglebius#define FROMSTRUCTDEF "use_default = ISC_TRUE" 77290001Sglebius 78290001Sglebius#define TOSTRUCTARGS "rdata, target, mctx" 79290001Sglebius#define TOSTRUCTCLASS "rdata->rdclass" 80290001Sglebius#define TOSTRUCTTYPE "rdata->type" 81290001Sglebius#define TOSTRUCTDEF "use_default = ISC_TRUE" 82290001Sglebius 83290001Sglebius#define FREESTRUCTARGS "source" 84290001Sglebius#define FREESTRUCTCLASS "common->rdclass" 85290001Sglebius#define FREESTRUCTTYPE "common->rdtype" 86290001Sglebius#define FREESTRUCTDEF NULL 87290001Sglebius 88290001Sglebius#define COMPAREARGS "rdata1, rdata2" 89290001Sglebius#define COMPARECLASS "rdata1->rdclass" 90290001Sglebius#define COMPARETYPE "rdata1->type" 91290001Sglebius#define COMPAREDEF "use_default = ISC_TRUE" 92290001Sglebius 93290001Sglebius#define ADDITIONALDATAARGS "rdata, add, arg" 94290001Sglebius#define ADDITIONALDATACLASS "rdata->rdclass" 95290001Sglebius#define ADDITIONALDATATYPE "rdata->type" 96290001Sglebius#define ADDITIONALDATADEF "use_default = ISC_TRUE" 97290001Sglebius 98290001Sglebius#define DIGESTARGS "rdata, digest, arg" 99290001Sglebius#define DIGESTCLASS "rdata->rdclass" 100290001Sglebius#define DIGESTTYPE "rdata->type" 101290001Sglebius#define DIGESTDEF "use_default = ISC_TRUE" 102290001Sglebius 103290001Sglebius#define CHECKOWNERARGS "name, rdclass, type, wildcard" 104290001Sglebius#define CHECKOWNERCLASS "rdclass" 105290001Sglebius#define CHECKOWNERTYPE "type" 106290001Sglebius#define CHECKOWNERDEF "result = ISC_TRUE" 107290001Sglebius 108290001Sglebius#define CHECKNAMESARGS "rdata, owner, bad" 109290001Sglebius#define CHECKNAMESCLASS "rdata->rdclass" 110290001Sglebius#define CHECKNAMESTYPE "rdata->type" 111290001Sglebius#define CHECKNAMESDEF "result = ISC_TRUE" 112290001Sglebius 113290001Sglebiusstatic const char copyright[] = 114290001Sglebius"/*\n" 115290001Sglebius" * Copyright (C) 2004%s Internet Systems Consortium, Inc. (\"ISC\")\n" 116290001Sglebius" * Copyright (C) 1998-2003 Internet Software Consortium.\n" 117290001Sglebius" *\n" 118290001Sglebius" * Permission to use, copy, modify, and distribute this software for any\n" 119290001Sglebius" * purpose with or without fee is hereby granted, provided that the above\n" 120290001Sglebius" * copyright notice and this permission notice appear in all copies.\n" 121290001Sglebius" *\n" 122290001Sglebius" * THE SOFTWARE IS PROVIDED \"AS IS\" AND ISC DISCLAIMS ALL WARRANTIES WITH\n" 123290001Sglebius" * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n" 124290001Sglebius" * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,\n" 125290001Sglebius" * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n" 126290001Sglebius" * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n" 127290001Sglebius" * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n" 128290001Sglebius" * PERFORMANCE OF THIS SOFTWARE.\n" 129290001Sglebius" */\n" 130290001Sglebius"\n" 131290001Sglebius"/***************\n" 132290001Sglebius" ***************\n" 133290001Sglebius" *************** THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n" 134290001Sglebius" *************** DO NOT EDIT!\n" 135290001Sglebius" ***************\n" 136290001Sglebius" ***************/\n" 137290001Sglebius"\n" 138290001Sglebius"/*! \\file */\n" 139290001Sglebius"\n"; 140290001Sglebius 141290001Sglebius#define STR_EXPAND(tok) #tok 142290001Sglebius#define STR(tok) STR_EXPAND(tok) 143290001Sglebius 144290001Sglebius#define TYPENAMES 256 145290001Sglebius#define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */ 146290001Sglebius#define TYPECLASSBUF (TYPECLASSLEN + 1) 147290001Sglebius#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d" 148290001Sglebius#define ATTRIBUTESIZE 256 149290001Sglebius#define DIRNAMESIZE 256 150290001Sglebius 151290001Sglebiusstatic struct cc { 152290001Sglebius struct cc *next; 153290001Sglebius int rdclass; 154290001Sglebius char classname[TYPECLASSBUF]; 155290001Sglebius} *classes; 156290001Sglebius 157290001Sglebiusstatic struct tt { 158290001Sglebius struct tt *next; 159290001Sglebius int rdclass; 160290001Sglebius int type; 161290001Sglebius char classname[TYPECLASSBUF]; 162290001Sglebius char typename[TYPECLASSBUF]; 163290001Sglebius char dirname[DIRNAMESIZE]; /* XXX Should be max path length */ 164290001Sglebius} *types; 165290001Sglebius 166290001Sglebiusstatic struct ttnam { 167290001Sglebius char typename[TYPECLASSBUF]; 168290001Sglebius char macroname[TYPECLASSBUF]; 169290001Sglebius char attr[ATTRIBUTESIZE]; 170290001Sglebius unsigned int sorted; 171290001Sglebius int type; 172290001Sglebius} typenames[TYPENAMES]; 173290001Sglebius 174290001Sglebiusstatic int maxtype = -1; 175290001Sglebius 176290001Sglebiusstatic char * 177290001Sglebiusupper(char *); 178290001Sglebiusstatic char * 179290001Sglebiusfunname(const char *, char *); 180290001Sglebiusstatic void 181290001Sglebiusdoswitch(const char *, const char *, const char *, const char *, 182290001Sglebius const char *, const char *); 183290001Sglebiusstatic void 184290001Sglebiusadd(int, const char *, int, const char *, const char *); 185290001Sglebiusstatic void 186290001Sglebiussd(int, const char *, const char *, char); 187290001Sglebiusstatic void 188290001Sglebiusinsert_into_typenames(int, const char *, const char *); 189290001Sglebius 190290001Sglebius/*% 191290001Sglebius * If you use more than 10 of these in, say, a printf(), you'll have problems. 192290001Sglebius */ 193290001Sglebiusstatic char * 194290001Sglebiusupper(char *s) { 195290001Sglebius static int buf_to_use = 0; 196290001Sglebius static char buf[10][256]; 197290001Sglebius char *b; 198290001Sglebius int c; 199290001Sglebius 200290001Sglebius buf_to_use++; 201290001Sglebius if (buf_to_use > 9) 202290001Sglebius buf_to_use = 0; 203290001Sglebius 204290001Sglebius b = buf[buf_to_use]; 205290001Sglebius memset(b, 0, 256); 206290001Sglebius 207290001Sglebius while ((c = (*s++) & 0xff)) 208290001Sglebius *b++ = islower(c) ? toupper(c) : c; 209290001Sglebius *b = '\0'; 210290001Sglebius return (buf[buf_to_use]); 211290001Sglebius} 212290001Sglebius 213290001Sglebiusstatic char * 214290001Sglebiusfunname(const char *s, char *buf) { 215290001Sglebius char *b = buf; 216290001Sglebius char c; 217290001Sglebius 218290001Sglebius INSIST(strlen(s) < TYPECLASSBUF); 219290001Sglebius while ((c = *s++)) { 220290001Sglebius *b++ = (c == '-') ? '_' : c; 221290001Sglebius } 222290001Sglebius *b = '\0'; 223290001Sglebius return (buf); 224290001Sglebius} 225290001Sglebius 226290001Sglebiusstatic void 227290001Sglebiusdoswitch(const char *name, const char *function, const char *args, 228290001Sglebius const char *tsw, const char *csw, const char *res) 229290001Sglebius{ 230290001Sglebius struct tt *tt; 231290001Sglebius int first = 1; 232290001Sglebius int lasttype = 0; 233290001Sglebius int subswitch = 0; 234290001Sglebius char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF]; 235290001Sglebius const char *result = " result ="; 236290001Sglebius 237290001Sglebius if (res == NULL) 238290001Sglebius result = ""; 239290001Sglebius 240290001Sglebius for (tt = types; tt != NULL; tt = tt->next) { 241290001Sglebius if (first) { 242290001Sglebius fprintf(stdout, "\n#define %s \\\n", name); 243290001Sglebius fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw); 244290001Sglebius first = 0; 245290001Sglebius } 246290001Sglebius if (tt->type != lasttype && subswitch) { 247290001Sglebius if (res == NULL) 248290001Sglebius fprintf(stdout, "\t\tdefault: break; \\\n"); 249290001Sglebius else 250290001Sglebius fprintf(stdout, 251290001Sglebius "\t\tdefault: %s; break; \\\n", res); 252290001Sglebius fputs(/*{*/ "\t\t} \\\n", stdout); 253290001Sglebius fputs("\t\tbreak; \\\n", stdout); 254290001Sglebius subswitch = 0; 255290001Sglebius } 256290001Sglebius if (tt->rdclass && tt->type != lasttype) { 257290001Sglebius fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/, 258290001Sglebius tt->type, csw); 259290001Sglebius subswitch = 1; 260290001Sglebius } 261290001Sglebius if (tt->rdclass == 0) 262290001Sglebius fprintf(stdout, 263290001Sglebius "\tcase %d:%s %s_%s(%s); break;", 264290001Sglebius tt->type, result, function, 265290001Sglebius funname(tt->typename, buf1), args); 266290001Sglebius else 267290001Sglebius fprintf(stdout, 268290001Sglebius "\t\tcase %d:%s %s_%s_%s(%s); break;", 269290001Sglebius tt->rdclass, result, function, 270290001Sglebius funname(tt->classname, buf1), 271290001Sglebius funname(tt->typename, buf2), args); 272290001Sglebius fputs(" \\\n", stdout); 273290001Sglebius lasttype = tt->type; 274290001Sglebius } 275290001Sglebius if (subswitch) { 276290001Sglebius if (res == NULL) 277290001Sglebius fprintf(stdout, "\t\tdefault: break; \\\n"); 278290001Sglebius else 279290001Sglebius fprintf(stdout, "\t\tdefault: %s; break; \\\n", res); 280290001Sglebius fputs(/*{*/ "\t\t} \\\n", stdout); 281290001Sglebius fputs("\t\tbreak; \\\n", stdout); 282290001Sglebius } 283290001Sglebius if (first) { 284290001Sglebius if (res == NULL) 285290001Sglebius fprintf(stdout, "\n#define %s\n", name); 286290001Sglebius else 287290001Sglebius fprintf(stdout, "\n#define %s %s;\n", name, res); 288290001Sglebius } else { 289290001Sglebius if (res == NULL) 290290001Sglebius fprintf(stdout, "\tdefault: break; \\\n"); 291290001Sglebius else 292290001Sglebius fprintf(stdout, "\tdefault: %s; break; \\\n", res); 293290001Sglebius fputs(/*{*/ "\t}\n", stdout); 294290001Sglebius } 295290001Sglebius} 296290001Sglebius 297290001Sglebiusstatic struct ttnam * 298290001Sglebiusfind_typename(int type) { 299290001Sglebius int i; 300290001Sglebius 301290001Sglebius for (i = 0; i < TYPENAMES; i++) { 302290001Sglebius if (typenames[i].typename[0] != 0 && 303290001Sglebius typenames[i].type == type) 304290001Sglebius return (&typenames[i]); 305290001Sglebius } 306290001Sglebius return (NULL); 307290001Sglebius} 308290001Sglebius 309290001Sglebiusstatic void 310290001Sglebiusinsert_into_typenames(int type, const char *typename, const char *attr) { 311290001Sglebius struct ttnam *ttn = NULL; 312290001Sglebius size_t c; 313290001Sglebius int i, n; 314290001Sglebius char tmp[256]; 315290001Sglebius 316290001Sglebius INSIST(strlen(typename) < TYPECLASSBUF); 317290001Sglebius for (i = 0; i < TYPENAMES; i++) { 318290001Sglebius if (typenames[i].typename[0] != 0 && 319290001Sglebius typenames[i].type == type && 320290001Sglebius strcmp(typename, typenames[i].typename) != 0) { 321290001Sglebius fprintf(stderr, 322290001Sglebius "Error: type %d has two names: %s, %s\n", 323290001Sglebius type, typenames[i].typename, typename); 324290001Sglebius exit(1); 325290001Sglebius } 326290001Sglebius if (typenames[i].typename[0] == 0 && ttn == NULL) 327290001Sglebius ttn = &typenames[i]; 328 } 329 if (ttn == NULL) { 330 fprintf(stderr, "Error: typenames array too small\n"); 331 exit(1); 332 } 333 334 if (strlen(typename) > sizeof(ttn->typename) - 1) { 335 fprintf(stderr, "Error: type name %s is too long\n", 336 typename); 337 exit(1); 338 } 339 strncpy(ttn->typename, typename, sizeof(ttn->typename)); 340 ttn->type = type; 341 342 strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname)); 343 c = strlen(ttn->macroname); 344 while (c > 0) { 345 if (ttn->macroname[c - 1] == '-') 346 ttn->macroname[c - 1] = '_'; 347 c--; 348 } 349 350 if (attr == NULL) { 351 n = snprintf(tmp, sizeof(tmp), 352 "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); 353 INSIST(n > 0 && (unsigned)n < sizeof(tmp)); 354 attr = tmp; 355 } 356 357 if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) { 358 fprintf(stderr, "Error: type %d has different attributes: " 359 "%s, %s\n", type, ttn->attr, attr); 360 exit(1); 361 } 362 363 if (strlen(attr) > sizeof(ttn->attr) - 1) { 364 fprintf(stderr, "Error: attr (%s) [name %s] is too long\n", 365 attr, typename); 366 exit(1); 367 } 368 strncpy(ttn->attr, attr, sizeof(ttn->attr)); 369 ttn->sorted = 0; 370 if (maxtype < type) 371 maxtype = type; 372} 373 374static void 375add(int rdclass, const char *classname, int type, const char *typename, 376 const char *dirname) 377{ 378 struct tt *newtt = (struct tt *)malloc(sizeof(*newtt)); 379 struct tt *tt, *oldtt; 380 struct cc *newcc; 381 struct cc *cc, *oldcc; 382 383 INSIST(strlen(typename) < TYPECLASSBUF); 384 INSIST(strlen(classname) < TYPECLASSBUF); 385 INSIST(strlen(dirname) < DIRNAMESIZE); 386 387 insert_into_typenames(type, typename, NULL); 388 389 if (newtt == NULL) { 390 fprintf(stderr, "malloc() failed\n"); 391 exit(1); 392 } 393 394 newtt->next = NULL; 395 newtt->rdclass = rdclass; 396 newtt->type = type; 397 strncpy(newtt->classname, classname, sizeof(newtt->classname)); 398 strncpy(newtt->typename, typename, sizeof(newtt->typename)); 399 if (strncmp(dirname, "./", 2) == 0) 400 dirname += 2; 401 strncpy(newtt->dirname, dirname, sizeof(newtt->dirname)); 402 403 tt = types; 404 oldtt = NULL; 405 406 while ((tt != NULL) && (tt->type < type)) { 407 oldtt = tt; 408 tt = tt->next; 409 } 410 411 while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) { 412 if (strcmp(tt->typename, typename) != 0) 413 exit(1); 414 oldtt = tt; 415 tt = tt->next; 416 } 417 418 if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass)) 419 exit(1); 420 421 newtt->next = tt; 422 if (oldtt != NULL) 423 oldtt->next = newtt; 424 else 425 types = newtt; 426 427 /* 428 * Do a class switch for this type. 429 */ 430 if (rdclass == 0) 431 return; 432 433 newcc = (struct cc *)malloc(sizeof(*newcc)); 434 if (newcc == NULL) { 435 fprintf(stderr, "malloc() failed\n"); 436 exit(1); 437 } 438 newcc->rdclass = rdclass; 439 strncpy(newcc->classname, classname, sizeof(newcc->classname)); 440 cc = classes; 441 oldcc = NULL; 442 443 while ((cc != NULL) && (cc->rdclass < rdclass)) { 444 oldcc = cc; 445 cc = cc->next; 446 } 447 448 if ((cc != NULL) && cc->rdclass == rdclass) { 449 free((char *)newcc); 450 return; 451 } 452 453 newcc->next = cc; 454 if (oldcc != NULL) 455 oldcc->next = newcc; 456 else 457 classes = newcc; 458} 459 460static void 461sd(int rdclass, const char *classname, const char *dirname, char filetype) { 462 char buf[TYPECLASSLEN + sizeof("_65535.h")]; 463 char typename[TYPECLASSBUF]; 464 int type, n; 465 isc_dir_t dir; 466 467 if (!start_directory(dirname, &dir)) 468 return; 469 470 while (next_file(&dir)) { 471 if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2) 472 continue; 473 if ((type > 65535) || (type < 0)) 474 continue; 475 476 n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename, 477 type, filetype); 478 INSIST(n > 0 && (unsigned)n < sizeof(buf)); 479 if (strcmp(buf, dir.filename) != 0) 480 continue; 481 add(rdclass, classname, type, typename, dirname); 482 } 483 484 end_directory(&dir); 485} 486 487static unsigned int 488HASH(char *string) { 489 size_t n; 490 unsigned char a, b; 491 492 n = strlen(string); 493 if (n == 0) { 494 fprintf(stderr, "n == 0?\n"); 495 exit(1); 496 } 497 a = tolower((unsigned char)string[0]); 498 b = tolower((unsigned char)string[n - 1]); 499 500 return ((a + n) * b) % 256; 501} 502 503int 504main(int argc, char **argv) { 505 char buf[DIRNAMESIZE]; /* XXX Should be max path length */ 506 char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */ 507 int rdclass; 508 char classname[TYPECLASSBUF]; 509 struct tt *tt; 510 struct cc *cc; 511 struct ttnam *ttn, *ttn2; 512 unsigned int hash; 513 struct tm *tm; 514 time_t now; 515 char year[11]; 516 int lasttype; 517 int code = 1; 518 int class_enum = 0; 519 int type_enum = 0; 520 int structs = 0; 521 int depend = 0; 522 int c, i, j, n; 523 char buf1[TYPECLASSBUF]; 524 char filetype = 'c'; 525 FILE *fd; 526 char *prefix = NULL; 527 char *suffix = NULL; 528 char *file = NULL; 529 isc_dir_t dir; 530 531 for (i = 0; i < TYPENAMES; i++) 532 memset(&typenames[i], 0, sizeof(typenames[i])); 533 534 strcpy(srcdir, ""); 535 while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1) 536 switch (c) { 537 case 'c': 538 code = 0; 539 depend = 0; 540 type_enum = 0; 541 class_enum = 1; 542 filetype = 'c'; 543 structs = 0; 544 break; 545 case 'd': 546 code = 0; 547 depend = 1; 548 class_enum = 0; 549 type_enum = 0; 550 structs = 0; 551 filetype = 'h'; 552 break; 553 case 't': 554 code = 0; 555 depend = 0; 556 class_enum = 0; 557 type_enum = 1; 558 filetype = 'c'; 559 structs = 0; 560 break; 561 case 'i': 562 code = 0; 563 depend = 0; 564 class_enum = 0; 565 type_enum = 0; 566 structs = 1; 567 filetype = 'h'; 568 break; 569 case 's': 570 if (strlen(isc_commandline_argument) > 571 DIRNAMESIZE - 2 * TYPECLASSLEN - 572 sizeof("/rdata/_65535_65535")) { 573 fprintf(stderr, "\"%s\" too long\n", 574 isc_commandline_argument); 575 exit(1); 576 } 577 n = snprintf(srcdir, sizeof(srcdir), "%s/", 578 isc_commandline_argument); 579 INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 580 break; 581 case 'F': 582 file = isc_commandline_argument; 583 break; 584 case 'P': 585 prefix = isc_commandline_argument; 586 break; 587 case 'S': 588 suffix = isc_commandline_argument; 589 break; 590 case '?': 591 exit(1); 592 } 593 594 n = snprintf(buf, sizeof(buf), "%srdata", srcdir); 595 INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 596 597 if (!start_directory(buf, &dir)) 598 exit(1); 599 600 while (next_file(&dir)) { 601 if (sscanf(dir.filename, TYPECLASSFMT, classname, 602 &rdclass) != 2) 603 continue; 604 if ((rdclass > 65535) || (rdclass < 0)) 605 continue; 606 607 n = snprintf(buf, sizeof(buf), "%srdata/%s_%d", 608 srcdir, classname, rdclass); 609 INSIST(n > 0 && (unsigned)n < sizeof(buf)); 610 if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) 611 continue; 612 sd(rdclass, classname, buf, filetype); 613 } 614 end_directory(&dir); 615 n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir); 616 INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); 617 sd(0, "", buf, filetype); 618 619 if (time(&now) != -1) { 620 if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) { 621 n = snprintf(year, sizeof(year), "-%d", 622 tm->tm_year + 1900); 623 INSIST(n > 0 && (unsigned)n < sizeof(year)); 624 } else 625 year[0] = 0; 626 } else 627 year[0] = 0; 628 629 if (!depend) fprintf(stdout, copyright, year); 630 631 if (code) { 632 fputs("#ifndef DNS_CODE_H\n", stdout); 633 fputs("#define DNS_CODE_H 1\n\n", stdout); 634 635 fputs("#include <isc/boolean.h>\n", stdout); 636 fputs("#include <isc/result.h>\n\n", stdout); 637 fputs("#include <dns/name.h>\n\n", stdout); 638 639 for (tt = types; tt != NULL; tt = tt->next) 640 fprintf(stdout, "#include \"%s/%s_%d.c\"\n", 641 tt->dirname, tt->typename, tt->type); 642 643 fputs("\n\n", stdout); 644 645 doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS, 646 FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF); 647 doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS, 648 TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF); 649 doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS, 650 FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF); 651 doswitch("TOWIRESWITCH", "towire", TOWIREARGS, 652 TOWIRETYPE, TOWIRECLASS, TOWIREDEF); 653 doswitch("COMPARESWITCH", "compare", COMPAREARGS, 654 COMPARETYPE, COMPARECLASS, COMPAREDEF); 655 doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS, 656 COMPARETYPE, COMPARECLASS, COMPAREDEF); 657 doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS, 658 FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF); 659 doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS, 660 TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF); 661 doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS, 662 FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF); 663 doswitch("ADDITIONALDATASWITCH", "additionaldata", 664 ADDITIONALDATAARGS, ADDITIONALDATATYPE, 665 ADDITIONALDATACLASS, ADDITIONALDATADEF); 666 doswitch("DIGESTSWITCH", "digest", 667 DIGESTARGS, DIGESTTYPE, 668 DIGESTCLASS, DIGESTDEF); 669 doswitch("CHECKOWNERSWITCH", "checkowner", 670 CHECKOWNERARGS, CHECKOWNERTYPE, 671 CHECKOWNERCLASS, CHECKOWNERDEF); 672 doswitch("CHECKNAMESSWITCH", "checknames", 673 CHECKNAMESARGS, CHECKNAMESTYPE, 674 CHECKNAMESCLASS, CHECKNAMESDEF); 675 676 /* 677 * From here down, we are processing the rdata names and 678 * attributes. 679 */ 680 681#define PRINT_COMMA(x) (x == maxtype ? "" : ",") 682 683#define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \ 684 "DNS_RDATATYPEATTR_NOTQUESTION" 685#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \ 686 "DNS_RDATATYPEATTR_QUESTIONONLY" 687#define RESERVED "DNS_RDATATYPEATTR_RESERVED" 688 689 /* 690 * Add in reserved/special types. This will let us 691 * sort them without special cases. 692 */ 693 insert_into_typenames(0, "reserved0", RESERVED); 694 insert_into_typenames(31, "eid", RESERVED); 695 insert_into_typenames(32, "nimloc", RESERVED); 696 insert_into_typenames(34, "atma", RESERVED); 697 insert_into_typenames(100, "uinfo", RESERVED); 698 insert_into_typenames(101, "uid", RESERVED); 699 insert_into_typenames(102, "gid", RESERVED); 700 insert_into_typenames(251, "ixfr", METAQUESTIONONLY); 701 insert_into_typenames(252, "axfr", METAQUESTIONONLY); 702 insert_into_typenames(253, "mailb", METAQUESTIONONLY); 703 insert_into_typenames(254, "maila", METAQUESTIONONLY); 704 insert_into_typenames(255, "any", METAQUESTIONONLY); 705 706 /* 707 * Spit out a quick and dirty hash function. Here, 708 * we walk through the list of type names, and calculate 709 * a hash. This isn't perfect, but it will generate "pretty 710 * good" estimates. Lowercase the characters before 711 * computing in all cases. 712 * 713 * Here, walk the list from top to bottom, calculating 714 * the hash (mod 256) for each name. 715 */ 716 fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n"); 717 fprintf(stdout, "\tdo { \\\n"); 718 fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n" 719 "\t\t strncasecmp(_s,(_tn)," 720 "(sizeof(_s) - 1)) == 0) { \\\n"); 721 fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & " 722 "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n"); 723 fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n"); 724 fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n"); 725 fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n"); 726 fprintf(stdout, "\t\t} \\\n"); 727 fprintf(stdout, "\t} while (0)\n\n"); 728 729 fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash," 730 "_typename,_length,_typep) \\\n"); 731 fprintf(stdout, "\tswitch (_hash) { \\\n"); 732 for (i = 0; i <= maxtype; i++) { 733 ttn = find_typename(i); 734 if (ttn == NULL) 735 continue; 736 737 /* 738 * Skip entries we already processed. 739 */ 740 if (ttn->sorted != 0) 741 continue; 742 743 hash = HASH(ttn->typename); 744 fprintf(stdout, "\t\tcase %u: \\\n", hash); 745 746 /* 747 * Find all other entries that happen to match 748 * this hash. 749 */ 750 for (j = 0; j <= maxtype; j++) { 751 ttn2 = find_typename(j); 752 if (ttn2 == NULL) 753 continue; 754 if (hash == HASH(ttn2->typename)) { 755 fprintf(stdout, "\t\t\tRDATATYPE_COMPARE" 756 "(\"%s\", %u, " 757 "_typename, _length, _typep); \\\n", 758 ttn2->typename, ttn2->type); 759 ttn2->sorted = 1; 760 } 761 } 762 fprintf(stdout, "\t\t\tbreak; \\\n"); 763 } 764 fprintf(stdout, "\t}\n"); 765 766 fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n"); 767 fprintf(stdout, "\tswitch (type) { \\\n"); 768 for (i = 0; i <= maxtype; i++) { 769 ttn = find_typename(i); 770 if (ttn == NULL) 771 continue; 772 fprintf(stdout, "\tcase %u: return (%s); \\\n", 773 i, upper(ttn->attr)); 774 } 775 fprintf(stdout, "\t}\n"); 776 777 fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n"); 778 fprintf(stdout, "\tswitch (type) { \\\n"); 779 for (i = 0; i <= maxtype; i++) { 780 ttn = find_typename(i); 781 if (ttn == NULL) 782 continue; 783 /* 784 * Remove KEYDATA (65533) from the type to memonic 785 * translation as it is internal use only. This 786 * stops the tools from displaying KEYDATA instead 787 * of TYPE65533. 788 */ 789 if (i == 65533U) 790 continue; 791 fprintf(stdout, "\tcase %u: return " 792 "(str_totext(\"%s\", target)); \\\n", 793 i, upper(ttn->typename)); 794 } 795 fprintf(stdout, "\t}\n"); 796 797 fputs("#endif /* DNS_CODE_H */\n", stdout); 798 } else if (type_enum) { 799 char *s; 800 801 fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n"); 802 fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n"); 803 804 fprintf(stdout, "enum {\n"); 805 fprintf(stdout, "\tdns_rdatatype_none = 0,\n"); 806 807 lasttype = 0; 808 for (tt = types; tt != NULL; tt = tt->next) 809 if (tt->type != lasttype) 810 fprintf(stdout, 811 "\tdns_rdatatype_%s = %d,\n", 812 funname(tt->typename, buf1), 813 lasttype = tt->type); 814 815 fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n"); 816 fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n"); 817 fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n"); 818 fprintf(stdout, "\tdns_rdatatype_maila = 254,\n"); 819 fprintf(stdout, "\tdns_rdatatype_any = 255\n"); 820 821 fprintf(stdout, "};\n\n"); 822 823 fprintf(stdout, "#define dns_rdatatype_none\t" 824 "((dns_rdatatype_t)dns_rdatatype_none)\n"); 825 826 for (tt = types; tt != NULL; tt = tt->next) 827 if (tt->type != lasttype) { 828 s = funname(tt->typename, buf1); 829 fprintf(stdout, 830 "#define dns_rdatatype_%s\t%s" 831 "((dns_rdatatype_t)dns_rdatatype_%s)" 832 "\n", 833 s, strlen(s) < 2U ? "\t" : "", s); 834 lasttype = tt->type; 835 } 836 837 fprintf(stdout, "#define dns_rdatatype_ixfr\t" 838 "((dns_rdatatype_t)dns_rdatatype_ixfr)\n"); 839 fprintf(stdout, "#define dns_rdatatype_axfr\t" 840 "((dns_rdatatype_t)dns_rdatatype_axfr)\n"); 841 fprintf(stdout, "#define dns_rdatatype_mailb\t" 842 "((dns_rdatatype_t)dns_rdatatype_mailb)\n"); 843 fprintf(stdout, "#define dns_rdatatype_maila\t" 844 "((dns_rdatatype_t)dns_rdatatype_maila)\n"); 845 fprintf(stdout, "#define dns_rdatatype_any\t" 846 "((dns_rdatatype_t)dns_rdatatype_any)\n"); 847 848 fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n"); 849 850 } else if (class_enum) { 851 char *s; 852 int classnum; 853 854 fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n"); 855 fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n"); 856 857 fprintf(stdout, "enum {\n"); 858 859 fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n"); 860 fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t" 861 "((dns_rdataclass_t)dns_rdataclass_reserved0)\n"); 862 863#define PRINTCLASS(name, num) \ 864 do { \ 865 s = funname(name, buf1); \ 866 classnum = num; \ 867 fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \ 868 classnum != 255 ? "," : ""); \ 869 fprintf(stdout, "#define dns_rdataclass_%s\t" \ 870 "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \ 871 } while (0) 872 873 for (cc = classes; cc != NULL; cc = cc->next) { 874 if (cc->rdclass == 3) 875 PRINTCLASS("chaos", 3); 876 else if (cc->rdclass == 255) 877 PRINTCLASS("none", 254); 878 PRINTCLASS(cc->classname, cc->rdclass); 879 } 880 881#undef PRINTCLASS 882 883 fprintf(stdout, "};\n\n"); 884 fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n"); 885 } else if (structs) { 886 if (prefix != NULL) { 887 if ((fd = fopen(prefix,"r")) != NULL) { 888 while (fgets(buf, sizeof(buf), fd) != NULL) 889 fputs(buf, stdout); 890 fclose(fd); 891 } 892 } 893 for (tt = types; tt != NULL; tt = tt->next) { 894 snprintf(buf, sizeof(buf), "%s/%s_%d.h", 895 tt->dirname, tt->typename, tt->type); 896 if ((fd = fopen(buf,"r")) != NULL) { 897 while (fgets(buf, sizeof(buf), fd) != NULL) 898 fputs(buf, stdout); 899 fclose(fd); 900 } 901 } 902 if (suffix != NULL) { 903 if ((fd = fopen(suffix,"r")) != NULL) { 904 while (fgets(buf, sizeof(buf), fd) != NULL) 905 fputs(buf, stdout); 906 fclose(fd); 907 } 908 } 909 } else if (depend) { 910 for (tt = types; tt != NULL; tt = tt->next) 911 fprintf(stdout, "%s:\t%s/%s_%d.h\n", file, 912 tt->dirname, tt->typename, tt->type); 913 } 914 915 if (ferror(stdout) != 0) 916 exit(1); 917 918 return (0); 919} 920