blob: 2cf3c186705887ec41551e0893836a259fb98d30 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (C) 2014 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
import os
import sys
import subprocess
def enumerablePseudoType(stringPseudoType):
output = ['CSSSelector::PseudoClass']
if stringPseudoType.endswith('('):
stringPseudoType = stringPseudoType[:-1]
webkitPrefix = '-webkit-'
if (stringPseudoType.startswith(webkitPrefix)):
stringPseudoType = stringPseudoType[len(webkitPrefix):]
khtmlPrefix = '-khtml-'
if (stringPseudoType.startswith(khtmlPrefix)):
stringPseudoType = stringPseudoType[len(khtmlPrefix):]
substring_start = 0
next_dash_position = stringPseudoType.find('-')
while (next_dash_position != -1):
output.append(stringPseudoType[substring_start].upper())
output.append(stringPseudoType[substring_start + 1:next_dash_position])
substring_start = next_dash_position + 1
next_dash_position = stringPseudoType.find('-', substring_start)
output.append(stringPseudoType[substring_start].upper())
output.append(stringPseudoType[substring_start + 1:])
return ''.join(output)
def expand_ifdef_condition(condition):
return condition.replace('(', '_').replace(')', '')
output_file = open('SelectorPseudoClassAndCompatibilityElementMap.gperf', 'w')
output_file.write("""
%{
/*
* Copyright (C) 2014-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
// This file is automatically generated from SelectorPseudoTypeMap.in by makeprop, do not edit by hand.
#include "config.h"
#include "SelectorPseudoTypeMap.h"
#include "CSSParserSelector.h"
IGNORE_WARNINGS_BEGIN("implicit-fallthrough")
// Older versions of gperf like to use the `register` keyword.
#define register
namespace WebCore {
struct SelectorPseudoClassOrCompatibilityPseudoElementEntry {
const char* name;
PseudoClassOrCompatibilityPseudoElement pseudoTypes;
};
%}
%struct-type
%define initializer-suffix ,{CSSSelector::PseudoClassUnknown,CSSSelector::PseudoElementUnknown}
%define class-name SelectorPseudoClassAndCompatibilityElementMapHash
%omit-struct-type
%language=C++
%readonly-tables
%global-table
%ignore-case
%compare-strncmp
%enum
struct SelectorPseudoClassOrCompatibilityPseudoElementEntry;
%%
""")
webcore_defines = [i.strip() for i in sys.argv[-1].split(' ')]
longest_keyword = 0
ignore_until_endif = False
input_file = open(sys.argv[1], 'r')
for line in input_file:
line = line.strip()
if not line:
continue
if line.startswith('#if '):
condition = line[4:].strip()
if expand_ifdef_condition(condition) not in webcore_defines:
ignore_until_endif = True
continue
if line.startswith('#endif'):
ignore_until_endif = False
continue
if ignore_until_endif:
continue
keyword_definition = line.split(',')
if len(keyword_definition) == 1:
keyword = keyword_definition[0].strip()
output_file.write('"%s", {%s, CSSSelector::PseudoElementUnknown}\n' % (keyword, enumerablePseudoType(keyword)))
else:
output_file.write('"%s", {CSSSelector::%s, CSSSelector::%s}\n' % (keyword_definition[0].strip(), keyword_definition[1].strip(), keyword_definition[2].strip()))
longest_keyword = max(longest_keyword, len(keyword))
output_file.write("""%%
static inline const SelectorPseudoClassOrCompatibilityPseudoElementEntry* parsePseudoClassAndCompatibilityElementString(const LChar* characters, unsigned length)
{
return SelectorPseudoClassAndCompatibilityElementMapHash::in_word_set(reinterpret_cast<const char*>(characters), length);
}""")
output_file.write("""
static inline const SelectorPseudoClassOrCompatibilityPseudoElementEntry* parsePseudoClassAndCompatibilityElementString(const UChar* characters, unsigned length)
{
const unsigned maxKeywordLength = %s;
LChar buffer[maxKeywordLength];
if (length > maxKeywordLength)
return nullptr;
for (unsigned i = 0; i < length; ++i) {
UChar character = characters[i];
if (!isLatin1(character))
return nullptr;
buffer[i] = static_cast<LChar>(character);
}
return parsePseudoClassAndCompatibilityElementString(buffer, length);
}
""" % longest_keyword)
output_file.write("""
PseudoClassOrCompatibilityPseudoElement parsePseudoClassAndCompatibilityElementString(StringView pseudoTypeString)
{
const SelectorPseudoClassOrCompatibilityPseudoElementEntry* entry;
if (pseudoTypeString.is8Bit())
entry = parsePseudoClassAndCompatibilityElementString(pseudoTypeString.characters8(), pseudoTypeString.length());
else
entry = parsePseudoClassAndCompatibilityElementString(pseudoTypeString.characters16(), pseudoTypeString.length());
if (entry)
return entry->pseudoTypes;
return { CSSSelector::PseudoClassUnknown, CSSSelector::PseudoElementUnknown };
}
} // namespace WebCore
IGNORE_WARNINGS_END
""")
output_file.close()
gperf_command = sys.argv[2]
if 'GPERF' in os.environ:
gperf_command = os.environ['GPERF']
if subprocess.call([gperf_command, '--key-positions=*', '-m', '10', '-s', '2', 'SelectorPseudoClassAndCompatibilityElementMap.gperf', '--output-file=SelectorPseudoClassAndCompatibilityElementMap.cpp']) != 0:
print("Error when generating SelectorPseudoClassAndCompatibilityElementMap.cpp from SelectorPseudoClassAndCompatibilityElementMap.gperf :(")
sys.exit(gperf_return)