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