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