1#!/usr/bin/env python
2# Copyright (c) 2014 Apple Inc. All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met:
7# 
8#     * Redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer.
10#     * Redistributions in binary form must reproduce the above
11# copyright notice, this list of conditions and the following disclaimer
12# in the documentation and/or other materials provided with the
13# distribution.
14#     * Neither the name of Google Inc. nor the names of its
15# contributors may be used to endorse or promote products derived from
16# this software without specific prior written permission.
17# 
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30import os
31import sys
32
33program_name = os.path.basename(__file__)
34if len(sys.argv) < 2:
35    sys.stderr.write("Usage: %s INPUT_FILE\n" % program_name)
36    exit(1)
37
38input_path = sys.argv[1]
39input_file = open(input_path)
40
41http_header_name_to_id = { }
42http_header_names = []
43
44for line in input_file.xreadlines():
45    http_header_name = line.strip()
46    if not http_header_name or http_header_name[:2] == '//':
47        continue
48    
49    http_header_name_to_id[http_header_name] = http_header_name.replace('-', '').replace('.', '')
50    
51    http_header_names.append(http_header_name)
52
53input_file.close()
54
55http_header_names.sort()
56
57gperf_file = open('HTTPHeaderNames.gperf', 'w')
58gperf_file.write('''
59%{
60/*
61 * Copyright (C) 2014 Apple Inc. All rights reserved.
62 *
63 * Redistribution and use in source and binary forms, with or without
64 * modification, are permitted provided that the following conditions
65 * are met:
66 * 1. Redistributions of source code must retain the above copyright
67 *    notice, this list of conditions and the following disclaimer.
68 * 2. Redistributions in binary form must reproduce the above copyright
69 *    notice, this list of conditions and the following disclaimer in the
70 *    documentation and/or other materials provided with the distribution.
71 *
72 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
73 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
74 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
75 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
76 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
77 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
78 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
79 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
80 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
81 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
82 * THE POSSIBILITY OF SUCH DAMAGE.
83 */
84
85/// This file is generated by create-http-header-name-table, do not edit.
86
87#include "config.h"
88#include "HTTPHeaderNames.h"
89
90#include <wtf/text/StringView.h>
91
92#if defined(__clang__)
93#pragma clang diagnostic push
94#pragma clang diagnostic ignored "-Wunknown-pragmas"
95#pragma clang diagnostic ignored "-Wdeprecated-register"
96#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
97#endif
98
99namespace WebCore {
100
101static const struct HeaderNameString {
102    const char* const name;
103    unsigned length;
104} headerNameStrings[] = {
105''')
106
107for http_header_name in http_header_names:
108    gperf_file.write('    { "%s", %u },\n' % (http_header_name, len(http_header_name)))
109
110gperf_file.write('};\n\n')
111
112gperf_file.write('''
113%}
114
115%language=C++
116%readonly-tables
117%global-table
118%compare-strncmp
119%ignore-case
120%struct-type
121struct HeaderNameHashEntry {
122    const char* name;
123    HTTPHeaderName headerName;
124};
125%define class-name HTTPHeaderNamesHash
126%define lookup-function-name findHeaderNameImpl
127%define hash-function-name header_name_hash_function
128%define word-array-name header_name_wordlist
129%enum
130%%
131''')
132
133for http_header_name in http_header_names:
134    gperf_file.write('%s, HTTPHeaderName::%s\n' % (http_header_name, http_header_name_to_id[http_header_name]))
135
136gperf_file.write('''%%
137bool findHTTPHeaderName(StringView stringView, HTTPHeaderName& headerName)
138{
139    unsigned length = stringView.length();
140    if (length > maxHTTPHeaderNameLength || length < minHTTPHeaderNameLength)
141        return false;
142
143    if (stringView.is8Bit()) {
144        if (auto nameAndString = HTTPHeaderNamesHash::findHeaderNameImpl(reinterpret_cast<const char*>(stringView.characters8()), length)) {
145            headerName = nameAndString->headerName;
146            return true;
147        }
148    } else {
149        LChar characters[maxHTTPHeaderNameLength];
150        for (unsigned i = 0; i < length; ++i) {
151            UChar character = stringView.characters16()[i];
152            if (!isASCII(character))
153                return false;
154                
155            characters[i] = static_cast<LChar>(character);
156        }
157        
158        if (auto nameAndString = HTTPHeaderNamesHash::findHeaderNameImpl(reinterpret_cast<const char*>(characters), length)) {
159            headerName = nameAndString->headerName;
160            return true;
161        }
162    }
163
164    return false;
165}
166
167StringView httpHeaderNameString(HTTPHeaderName headerName)
168{
169    ASSERT(static_cast<unsigned>(headerName) < numHTTPHeaderNames);
170    
171    const auto& name = headerNameStrings[static_cast<unsigned>(headerName)];
172    
173    return StringView { reinterpret_cast<const LChar*>(name.name), static_cast<unsigned>(name.length) };
174}
175
176} // namespace WebCore
177
178#if defined(__clang__)
179#pragma clang diagnostic pop
180#endif
181''')
182
183gperf_file.close()
184
185header_file = open('HTTPHeaderNames.h', 'w')
186header_file.write('''
187/*
188 * Copyright (C) 2014 Apple Inc. All rights reserved.
189 *
190 * Redistribution and use in source and binary forms, with or without
191 * modification, are permitted provided that the following conditions
192 * are met:
193 * 1. Redistributions of source code must retain the above copyright
194 *    notice, this list of conditions and the following disclaimer.
195 * 2. Redistributions in binary form must reproduce the above copyright
196 *    notice, this list of conditions and the following disclaimer in the
197 *    documentation and/or other materials provided with the distribution.
198 *
199 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
200 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
201 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
202 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
203 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
204 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
205 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
206 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
207 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
208 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
209 * THE POSSIBILITY OF SUCH DAMAGE.
210 */
211
212/// This file is generated by create-http-header-name-table, do not edit.
213
214#ifndef HTTPHeaderNames_h
215#define HTTPHeaderNames_h
216
217#include <wtf/Forward.h>
218
219namespace WebCore {
220
221enum class HTTPHeaderName {
222''')
223
224for http_header_name in http_header_names:
225    header_file.write('    %s,\n' % http_header_name_to_id[http_header_name])
226
227header_file.write('};\n\n')
228header_file.write('const unsigned numHTTPHeaderNames = %u;\n' % len(http_header_names));
229header_file.write('const size_t minHTTPHeaderNameLength = %u;\n' % len(min(http_header_names, key=len)));
230header_file.write('const size_t maxHTTPHeaderNameLength = %u;\n' % len(max(http_header_names, key=len)));
231header_file.write('''
232bool findHTTPHeaderName(StringView, HTTPHeaderName&);
233StringView httpHeaderNameString(HTTPHeaderName);
234
235} // namespace WebCore
236
237#endif // HTTPHeaderNames_h
238''')
239header_file.close()
240
241gperf = os.getenv('GPERF') or 'gperf'
242
243if os.system('%s --key-positions="*" -D -n -s 2 HTTPHeaderNames.gperf --output-file=HTTPHeaderNames.cpp' % gperf):
244    sys.stderr.write('Failed to run gperf.')
245    exit(1)
246