1#!/usr/bin/env python
2
3HEADERS = [
4    (':authority', 0),
5    (':method', 1),
6    (':method', 2),
7    (':path', 3),
8    (':path', 4),
9    (':scheme', 5),
10    (':scheme', 6),
11    (':status', 7),
12    (':status', 8),
13    (':status', 9),
14    (':status', 10),
15    (':status', 11),
16    (':status', 12),
17    (':status', 13),
18    ('accept-charset', 14),
19    ('accept-encoding', 15),
20    ('accept-language', 16),
21    ('accept-ranges', 17),
22    ('accept', 18),
23    ('access-control-allow-origin', 19),
24    ('age', 20),
25    ('allow', 21),
26    ('authorization', 22),
27    ('cache-control', 23),
28    ('content-disposition', 24),
29    ('content-encoding', 25),
30    ('content-language', 26),
31    ('content-length', 27),
32    ('content-location', 28),
33    ('content-range', 29),
34    ('content-type', 30),
35    ('cookie', 31),
36    ('date', 32),
37    ('etag', 33),
38    ('expect', 34),
39    ('expires', 35),
40    ('from', 36),
41    ('host', 37),
42    ('if-match', 38),
43    ('if-modified-since', 39),
44    ('if-none-match', 40),
45    ('if-range', 41),
46    ('if-unmodified-since', 42),
47    ('last-modified', 43),
48    ('link', 44),
49    ('location', 45),
50    ('max-forwards', 46),
51    ('proxy-authenticate', 47),
52    ('proxy-authorization', 48),
53    ('range', 49),
54    ('referer', 50),
55    ('refresh', 51),
56    ('retry-after', 52),
57    ('server', 53),
58    ('set-cookie', 54),
59    ('strict-transport-security', 55),
60    ('transfer-encoding', 56),
61    ('user-agent', 57),
62    ('vary', 58),
63    ('via', 59),
64    ('www-authenticate', 60),
65    ('te', None),
66    ('connection', None),
67    ('keep-alive',None),
68    ('proxy-connection', None),
69    ('upgrade', None),
70    (':protocol', None),
71]
72
73def to_enum_hd(k):
74    res = 'NGHTTP2_TOKEN_'
75    for c in k.upper():
76        if c == ':' or c == '-':
77            res += '_'
78            continue
79        res += c
80    return res
81
82def build_header(headers):
83    res = {}
84    for k, _ in headers:
85        size = len(k)
86        if size not in res:
87            res[size] = {}
88        ent = res[size]
89        c = k[-1]
90        if c not in ent:
91            ent[c] = []
92        if k not in ent[c]:
93            ent[c].append(k)
94
95    return res
96
97def gen_enum():
98    name = ''
99    print 'typedef enum {'
100    for k, token in HEADERS:
101        if token is None:
102            print '  {},'.format(to_enum_hd(k))
103        else:
104            if name != k:
105                name = k
106                print '  {} = {},'.format(to_enum_hd(k), token)
107    print '} nghttp2_token;'
108
109def gen_index_header():
110    print '''\
111static int32_t lookup_token(const uint8_t *name, size_t namelen) {
112  switch (namelen) {'''
113    b = build_header(HEADERS)
114    for size in sorted(b.keys()):
115        ents = b[size]
116        print '''\
117  case {}:'''.format(size)
118        print '''\
119    switch (name[{}]) {{'''.format(size - 1)
120        for c in sorted(ents.keys()):
121            headers = sorted(ents[c])
122            print '''\
123    case '{}':'''.format(c)
124            for k in headers:
125                print '''\
126      if (memeq("{}", name, {})) {{
127        return {};
128      }}'''.format(k[:-1], size - 1, to_enum_hd(k))
129            print '''\
130      break;'''
131        print '''\
132    }
133    break;'''
134    print '''\
135  }
136  return -1;
137}'''
138
139if __name__ == '__main__':
140    gen_enum()
141    print ''
142    gen_index_header()
143