1#!/usr/bin/env python 2# 3# Copyright (C) 2014 Apple Inc. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 15# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 18# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24# THE POSSIBILITY OF SUCH DAMAGE. 25 26import os 27import sys 28 29 30def enumerablePseudoType(stringPseudoType): 31 output = ['CSSSelector::PseudoClass'] 32 33 if stringPseudoType.endswith('('): 34 stringPseudoType = stringPseudoType[:-1] 35 36 webkitPrefix = '-webkit-' 37 if (stringPseudoType.startswith(webkitPrefix)): 38 stringPseudoType = stringPseudoType[len(webkitPrefix):] 39 40 khtmlPrefix = '-khtml-' 41 if (stringPseudoType.startswith(khtmlPrefix)): 42 stringPseudoType = stringPseudoType[len(khtmlPrefix):] 43 44 substring_start = 0 45 next_dash_position = stringPseudoType.find('-') 46 while (next_dash_position != -1): 47 output.append(stringPseudoType[substring_start].upper()) 48 output.append(stringPseudoType[substring_start + 1:next_dash_position]) 49 substring_start = next_dash_position + 1 50 next_dash_position = stringPseudoType.find('-', substring_start) 51 52 output.append(stringPseudoType[substring_start].upper()) 53 output.append(stringPseudoType[substring_start + 1:]) 54 return ''.join(output) 55 56 57def expand_ifdef_condition(condition): 58 return condition.replace('(', '_').replace(')', '') 59 60output_file = open('SelectorPseudoClassAndCompatibilityElementMap.gperf', 'w') 61 62output_file.write(""" 63%{ 64/* 65 * Copyright (C) 2014 Apple Inc. All rights reserved. 66 * 67 * Redistribution and use in source and binary forms, with or without 68 * modification, are permitted provided that the following conditions 69 * are met: 70 * 1. Redistributions of source code must retain the above copyright 71 * notice, this list of conditions and the following disclaimer. 72 * 2. Redistributions in binary form must reproduce the above copyright 73 * notice, this list of conditions and the following disclaimer in the 74 * documentation and/or other materials provided with the distribution. 75 * 76 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 77 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 78 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 79 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 80 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 81 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 82 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 83 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 84 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 85 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 86 * THE POSSIBILITY OF SUCH DAMAGE. 87 */ 88 89// This file is automatically generated from SelectorPseudoTypeMap.in by makeprop, do not edit by hand. 90 91#include "config.h" 92#include "SelectorPseudoTypeMap.h" 93 94#if defined(__clang__) 95#pragma clang diagnostic push 96#pragma clang diagnostic ignored "-Wunknown-pragmas" 97#pragma clang diagnostic ignored "-Wdeprecated-register" 98#pragma clang diagnostic ignored "-Wimplicit-fallthrough" 99#endif 100 101namespace WebCore { 102 103struct SelectorPseudoClassOrCompatibilityPseudoElementEntry { 104 const char* name; 105 PseudoClassOrCompatibilityPseudoElement pseudoTypes; 106}; 107 108%} 109%struct-type 110%define initializer-suffix ,{CSSSelector::PseudoClassUnknown,CSSSelector::PseudoElementUnknown} 111%define class-name SelectorPseudoClassAndCompatibilityElementMapHash 112%omit-struct-type 113%language=C++ 114%readonly-tables 115%global-table 116%ignore-case 117%compare-strncmp 118%enum 119 120struct SelectorPseudoClassOrCompatibilityPseudoElementEntry; 121 122%% 123""") 124 125webcore_defines = [i.strip() for i in sys.argv[-1].split(' ')] 126 127longest_keyword = 0 128 129ignore_until_endif = False 130input_file = open(sys.argv[1], 'r') 131for line in input_file: 132 line = line.strip() 133 if not line: 134 continue 135 136 if line.startswith('#if '): 137 condition = line[4:].strip() 138 if expand_ifdef_condition(condition) not in webcore_defines: 139 ignore_until_endif = True 140 continue 141 142 if line.startswith('#endif'): 143 ignore_until_endif = False 144 continue 145 146 if ignore_until_endif: 147 continue 148 149 keyword_definition = line.split(',') 150 if len(keyword_definition) == 1: 151 keyword = keyword_definition[0].strip() 152 output_file.write('"%s", {%s, CSSSelector::PseudoElementUnknown}\n' % (keyword, enumerablePseudoType(keyword))) 153 else: 154 output_file.write('"%s", {CSSSelector::%s, CSSSelector::%s}\n' % (keyword_definition[0].strip(), keyword_definition[1].strip(), keyword_definition[2].strip())) 155 156 longest_keyword = max(longest_keyword, len(keyword)) 157 158output_file.write("""%% 159 160static inline const SelectorPseudoClassOrCompatibilityPseudoElementEntry* parsePseudoClassAndCompatibilityElementString(const LChar* characters, unsigned length) 161{ 162 return SelectorPseudoClassAndCompatibilityElementMapHash::in_word_set(reinterpret_cast<const char*>(characters), length); 163}""") 164 165output_file.write(""" 166 167static inline const SelectorPseudoClassOrCompatibilityPseudoElementEntry* parsePseudoClassAndCompatibilityElementString(const UChar* characters, unsigned length) 168{ 169 const unsigned maxKeywordLength = %s; 170 LChar buffer[maxKeywordLength]; 171 if (length > maxKeywordLength) 172 return nullptr; 173 174 for (unsigned i = 0; i < length; ++i) { 175 UChar character = characters[i]; 176 if (character & ~0xff) 177 return nullptr; 178 179 buffer[i] = static_cast<LChar>(character); 180 } 181 return parsePseudoClassAndCompatibilityElementString(buffer, length); 182} 183""" % longest_keyword) 184 185output_file.write(""" 186PseudoClassOrCompatibilityPseudoElement parsePseudoClassAndCompatibilityElementString(const CSSParserString& pseudoTypeString) 187{ 188 const SelectorPseudoClassOrCompatibilityPseudoElementEntry* entry; 189 if (pseudoTypeString.is8Bit()) 190 entry = parsePseudoClassAndCompatibilityElementString(pseudoTypeString.characters8(), pseudoTypeString.length()); 191 else 192 entry = parsePseudoClassAndCompatibilityElementString(pseudoTypeString.characters16(), pseudoTypeString.length()); 193 194 if (entry) 195 return entry->pseudoTypes; 196 return { CSSSelector::PseudoClassUnknown, CSSSelector::PseudoElementUnknown }; 197} 198 199} // namespace WebCore 200 201#if defined(__clang__) 202#pragma clang diagnostic pop 203#endif 204 205""") 206output_file.close() 207 208gperf_command = 'gperf' 209if 'GPERF' in os.environ: 210 gperf_command = os.environ['GPERF'] 211 212gperf_return = os.system("%s --key-positions='*' -m 10 -s 2 SelectorPseudoClassAndCompatibilityElementMap.gperf --output-file=SelectorPseudoClassAndCompatibilityElementMap.cpp" % gperf_command) 213if gperf_return != 0: 214 print("Error when generating SelectorPseudoClassAndCompatibilityElementMap.cpp from SelectorPseudoClassAndCompatibilityElementMap.gperf :(") 215 sys.exit(gperf_return) 216