1#!/usr/bin/env python
2
3import sys
4
5header_fname = sys.argv[1]
6output_fname = sys.argv[2]
7
8header = '''
9const char *
10wdns_rrclass_to_str(uint16_t rrclass)
11{
12	switch (rrclass) {
13'''
14
15footer = '''	}
16
17	return (NULL);
18}
19'''
20
21w = open(output_fname, 'w')
22
23w.write(header)
24
25for line in open(header_fname):
26    if 'WDNS_CLASS_' in line:
27        wdns_class = line.split()[1]
28        rrclass = wdns_class.replace('WDNS_CLASS_','',1).replace('_', '-')
29        w.write('\tcase %s: return ("%s");\n' % (wdns_class, rrclass))
30
31w.write(footer)
32
33w.write('''
34static struct u16str {
35    uint16_t u16;
36    const char *str;
37} rrclasses[] = {
38''')
39
40rrclasses = []
41for line in open(header_fname):
42    if 'WDNS_CLASS_' in line:
43        wdns_class = line.split()[1]
44        rrclass = wdns_class.replace('WDNS_CLASS_','',1).replace('_', '-')
45        rrclasses.append((wdns_class, rrclass))
46rrclasses.sort()
47for wdns_class, rrclass in rrclasses:
48    w.write('\t{ %s, "%s" },\n' % (wdns_class, rrclass))
49
50w.write('''};
51
52#define num_rrclasses (sizeof(rrclasses) / sizeof(struct u16str))
53
54static int
55cmp_u16str(const void *a, const void *b) {
56    struct u16str *u1 = (struct u16str *) a;
57    struct u16str *u2 = (struct u16str *) b;
58    return (strcasecmp(u1->str, u2->str));
59}
60
61static bool
62convert_generic_rrclass(const char *s, long int *val) {
63    char *endptr = NULL;
64
65    if (strlen(s) <= 5)
66        return (false);
67    if (strncasecmp(s, "CLASS", 5) != 0)
68        return (false);
69
70    s += 5; /* skip leading "CLASS" */
71
72    *val = strtol(s, &endptr, 10);
73    if (endptr != NULL && *endptr != '\\0')
74        return (false);
75    if (*val < 0 || *val > 65535)
76        return (false);
77
78    return (true);
79}
80
81uint16_t
82wdns_str_to_rrclass(const char *str) {
83    struct u16str key, *res;
84    key.str = str;
85    res = bsearch(&key, rrclasses, num_rrclasses, sizeof(struct u16str), cmp_u16str);
86    if (res != NULL) {
87        return (res->u16);
88    } else {
89        long int val = 0;
90        if (convert_generic_rrclass(str, &val))
91            return (val);
92    }
93    return (0);
94}
95''')
96
97w.close()
98