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