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