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