1#! /usr/bin/perl 2# 3# This file is part of the WebKit project 4# 5# Copyright (C) 1999 Waldo Bastian (bastian@kde.org) 6# Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved. 7# Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 8# Copyright (C) 2010 Andras Becsi (abecsi@inf.u-szeged.hu), University of Szeged 9# 10# This library is free software; you can redistribute it and/or 11# modify it under the terms of the GNU Library General Public 12# License as published by the Free Software Foundation; either 13# version 2 of the License, or (at your option) any later version. 14# 15# This library is distributed in the hope that it will be useful, 16# but WITHOUT ANY WARRANTY; without even the implied warranty of 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18# Library General Public License for more details. 19# 20# You should have received a copy of the GNU Library General Public License 21# along with this library; see the file COPYING.LIB. If not, write to 22# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23# Boston, MA 02110-1301, USA. 24use Getopt::Long; 25use preprocessor; 26use strict; 27use warnings; 28 29my $defines; 30my $preprocessor; 31GetOptions('defines=s' => \$defines, 32 'preprocessor=s' => \$preprocessor); 33 34my @NAMES = applyPreprocessor("CSSPropertyNames.in", $defines, $preprocessor); 35 36my %namesHash; 37my @duplicates = (); 38 39my @names = (); 40my @aliases = (); 41foreach (@NAMES) { 42 next if (m/(^\s*$)/); 43 next if (/^#/); 44 45 # Input may use a different EOL sequence than $/, so avoid chomp. 46 $_ =~ s/[\r\n]+$//g; 47 if (exists $namesHash{$_}) { 48 push @duplicates, $_; 49 } else { 50 $namesHash{$_} = 1; 51 } 52 if ($_ =~ /=/) { 53 push @aliases, $_; 54 } else { 55 push @names, $_; 56 } 57} 58 59if (@duplicates > 0) { 60 die 'Duplicate CSS property names: ', join(', ', @duplicates) . "\n"; 61} 62 63open GPERF, ">CSSPropertyNames.gperf" || die "Could not open CSSPropertyNames.gperf for writing"; 64print GPERF << "EOF"; 65%{ 66/* This file is automatically generated from CSSPropertyNames.in by makeprop, do not edit */ 67#include "config.h" 68#include \"CSSPropertyNames.h\" 69#include \"HashTools.h\" 70#include <string.h> 71 72#include <wtf/ASCIICType.h> 73#include <wtf/text/AtomicString.h> 74#include <wtf/text/WTFString.h> 75 76namespace WebCore { 77EOF 78 79print GPERF "const char* const propertyNameStrings[numCSSProperties] = {\n"; 80foreach my $name (@names) { 81 print GPERF " \"$name\",\n"; 82} 83print GPERF "};\n\n"; 84 85print GPERF << "EOF"; 86%} 87%struct-type 88struct Property; 89%omit-struct-type 90%language=C++ 91%readonly-tables 92%global-table 93%compare-strncmp 94%define class-name CSSPropertyNamesHash 95%define lookup-function-name findPropertyImpl 96%define hash-function-name propery_hash_function 97%define word-array-name property_wordlist 98%enum 99%% 100EOF 101 102foreach my $name (@names) { 103 my $id = $name; 104 $id =~ s/(^[^-])|-(.)/uc($1||$2)/ge; 105 print GPERF $name . ", CSSProperty" . $id . "\n"; 106} 107 108foreach my $alias (@aliases) { 109 $alias =~ /^([^\s]*)[\s]*=[\s]*([^\s]*)/; 110 my $name = $1; 111 my $id = $2; 112 $id =~ s/(^[^-])|-(.)/uc($1||$2)/ge; 113 print GPERF $name . ", CSSProperty" . $id . "\n"; 114} 115 116print GPERF<< "EOF"; 117%% 118const Property* findProperty(register const char* str, register unsigned int len) 119{ 120 return CSSPropertyNamesHash::findPropertyImpl(str, len); 121} 122 123const char* getPropertyName(CSSPropertyID id) 124{ 125 if (id < firstCSSProperty) 126 return 0; 127 int index = id - firstCSSProperty; 128 if (index >= numCSSProperties) 129 return 0; 130 return propertyNameStrings[index]; 131} 132 133const AtomicString& getPropertyNameAtomicString(CSSPropertyID id) 134{ 135 if (id < firstCSSProperty) 136 return nullAtom; 137 int index = id - firstCSSProperty; 138 if (index >= numCSSProperties) 139 return nullAtom; 140 141 static AtomicString* propertyStrings = new AtomicString[numCSSProperties]; // Intentionally never destroyed. 142 AtomicString& propertyString = propertyStrings[index]; 143 if (propertyString.isNull()) { 144 const char* propertyName = propertyNameStrings[index]; 145 propertyString = AtomicString(propertyName, strlen(propertyName), AtomicString::ConstructFromLiteral); 146 } 147 return propertyString; 148} 149 150String getPropertyNameString(CSSPropertyID id) 151{ 152 // We share the StringImpl with the AtomicStrings. 153 return getPropertyNameAtomicString(id).string(); 154} 155 156String getJSPropertyName(CSSPropertyID id) 157{ 158 char result[maxCSSPropertyNameLength + 1]; 159 const char* cssPropertyName = getPropertyName(id); 160 const char* propertyNamePointer = cssPropertyName; 161 if (!propertyNamePointer) 162 return emptyString(); 163 164 char* resultPointer = result; 165 while (char character = *propertyNamePointer++) { 166 if (character == '-') { 167 char nextCharacter = *propertyNamePointer++; 168 if (!nextCharacter) 169 break; 170 character = (propertyNamePointer - 2 != cssPropertyName) ? toASCIIUpper(nextCharacter) : nextCharacter; 171 } 172 *resultPointer++ = character; 173 } 174 *resultPointer = '\\0'; 175 return WTF::String(result); 176} 177 178} // namespace WebCore 179EOF 180 181open HEADER, ">CSSPropertyNames.h" || die "Could not open CSSPropertyNames.h for writing"; 182print HEADER << "EOF"; 183/* This file is automatically generated from CSSPropertyNames.in by makeprop, do not edit */ 184 185#ifndef CSSPropertyNames_h 186#define CSSPropertyNames_h 187 188#include <string.h> 189#include <wtf/HashFunctions.h> 190#include <wtf/HashTraits.h> 191 192namespace WTF { 193class AtomicString; 194class String; 195} 196 197namespace WebCore { 198 199enum CSSPropertyID { 200 CSSPropertyInvalid = 0, 201#if ENABLE(CSS_VARIABLES) 202 CSSPropertyVariable = 1, 203#endif 204EOF 205 206my $first = 1001; 207my $i = 1001; 208my $maxLen = 0; 209foreach my $name (@names) { 210 my $id = $name; 211 $id =~ s/(^[^-])|-(.)/uc($1||$2)/ge; 212 print HEADER " CSSProperty" . $id . " = " . $i . ",\n"; 213 $i = $i + 1; 214 if (length($name) > $maxLen) { 215 $maxLen = length($name); 216 } 217} 218my $num = $i - $first; 219my $last = $i - 1; 220 221print HEADER "};\n\n"; 222print HEADER "const int firstCSSProperty = $first;\n"; 223print HEADER "const int numCSSProperties = $num;\n"; 224print HEADER "const int lastCSSProperty = $last;\n"; 225print HEADER "const size_t maxCSSPropertyNameLength = $maxLen;\n"; 226 227print HEADER << "EOF"; 228 229const char* getPropertyName(CSSPropertyID); 230const WTF::AtomicString& getPropertyNameAtomicString(CSSPropertyID id); 231WTF::String getPropertyNameString(CSSPropertyID id); 232WTF::String getJSPropertyName(CSSPropertyID); 233 234inline CSSPropertyID convertToCSSPropertyID(int value) 235{ 236 ASSERT((value >= firstCSSProperty && value <= lastCSSProperty) || value == CSSPropertyInvalid); 237 return static_cast<CSSPropertyID>(value); 238} 239 240} // namespace WebCore 241 242namespace WTF { 243template<> struct DefaultHash<WebCore::CSSPropertyID> { typedef IntHash<unsigned> Hash; }; 244template<> struct HashTraits<WebCore::CSSPropertyID> : GenericHashTraits<WebCore::CSSPropertyID> { 245 static const bool emptyValueIsZero = true; 246 static const bool needsDestruction = false; 247 static void constructDeletedValue(WebCore::CSSPropertyID& slot) { slot = static_cast<WebCore::CSSPropertyID>(WebCore::lastCSSProperty + 1); } 248 static bool isDeletedValue(WebCore::CSSPropertyID value) { return value == (WebCore::lastCSSProperty + 1); } 249}; 250} 251 252#endif // CSSPropertyNames_h 253 254EOF 255 256close HEADER; 257 258my $gperf = $ENV{GPERF} ? $ENV{GPERF} : "gperf"; 259system("\"$gperf\" --key-positions=\"*\" -D -n -s 2 CSSPropertyNames.gperf --output-file=CSSPropertyNames.cpp") == 0 || die "calling gperf failed: $?"; 260