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); 35die "We've reached more than 1024 CSS properties, please make sure to update CSSProperty/StylePropertyMetadata accordingly" if (scalar(@NAMES) > 1024); 36 37my %namesHash; 38my @duplicates = (); 39 40my $numPredefinedProperties = 1; 41my @names = (); 42my %nameIsInherited; 43my %nameToId; 44my @aliases = (); 45foreach (@NAMES) { 46 next if (m/(^\s*$)/); 47 next if (/^#/); 48 49 # Input may use a different EOL sequence than $/, so avoid chomp. 50 $_ =~ s/\s*\[(.+?)\]\r?$//; 51 my @options = (); 52 if ($1) { 53 @options = split(/\s*,\s*/, $1); 54 } 55 56 $_ =~ s/[\r\n]+$//g; 57 if (exists $namesHash{$_}) { 58 push @duplicates, $_; 59 } else { 60 $namesHash{$_} = 1; 61 } 62 if ($_ =~ /=/) { 63 if (@options) { 64 die "Options are specified on an alias $_: ", join(", ", @options) . "\n"; 65 } 66 push @aliases, $_; 67 } else { 68 $nameIsInherited{$_} = 0; 69 foreach my $option (@options) { 70 if ($option eq "Inherited") { 71 $nameIsInherited{$_} = 1; 72 } 73 } 74 75 my $id = $_; 76 $id =~ s/(^[^-])|-(.)/uc($1||$2)/ge; 77 $nameToId{$_} = $id; 78 79 push @names, $_; 80 } 81} 82 83if (@duplicates > 0) { 84 die 'Duplicate CSS property names: ', join(', ', @duplicates) . "\n"; 85} 86 87open GPERF, ">CSSPropertyNames.gperf" || die "Could not open CSSPropertyNames.gperf for writing"; 88print GPERF << "EOF"; 89%{ 90/* This file is automatically generated from CSSPropertyNames.in by makeprop, do not edit */ 91#include "config.h" 92#include \"CSSProperty.h\" 93#include \"CSSPropertyNames.h\" 94#include \"HashTools.h\" 95#include <string.h> 96 97#include <wtf/ASCIICType.h> 98#include <wtf/text/AtomicString.h> 99#include <wtf/text/WTFString.h> 100 101#if defined(__clang__) 102#pragma clang diagnostic push 103#pragma clang diagnostic ignored \"-Wunknown-pragmas\" 104#pragma clang diagnostic ignored \"-Wdeprecated-register\" 105#pragma clang diagnostic ignored \"-Wimplicit-fallthrough\" 106#endif 107 108namespace WebCore { 109EOF 110 111print GPERF "const char* const propertyNameStrings[numCSSProperties] = {\n"; 112foreach my $name (@names) { 113 print GPERF " \"$name\",\n"; 114} 115print GPERF "};\n\n"; 116 117print GPERF << "EOF"; 118%} 119%struct-type 120struct Property; 121%omit-struct-type 122%language=C++ 123%readonly-tables 124%global-table 125%compare-strncmp 126%define class-name CSSPropertyNamesHash 127%define lookup-function-name findPropertyImpl 128%define hash-function-name propery_hash_function 129%define word-array-name property_wordlist 130%enum 131%% 132EOF 133 134foreach my $name (@names) { 135 print GPERF $name . ", CSSProperty" . $nameToId{$name} . "\n"; 136} 137 138foreach my $alias (@aliases) { 139 $alias =~ /^([^\s]*)[\s]*=[\s]*([^\s]*)/; 140 my $name = $1; 141 print GPERF $name . ", CSSProperty" . $nameToId{$2} . "\n"; 142} 143 144print GPERF<< "EOF"; 145%% 146const Property* findProperty(const char* str, unsigned int len) 147{ 148 return CSSPropertyNamesHash::findPropertyImpl(str, len); 149} 150 151const char* getPropertyName(CSSPropertyID id) 152{ 153 if (id < firstCSSProperty) 154 return 0; 155 int index = id - firstCSSProperty; 156 if (index >= numCSSProperties) 157 return 0; 158 return propertyNameStrings[index]; 159} 160 161const AtomicString& getPropertyNameAtomicString(CSSPropertyID id) 162{ 163 if (id < firstCSSProperty) 164 return nullAtom; 165 int index = id - firstCSSProperty; 166 if (index >= numCSSProperties) 167 return nullAtom; 168 169 static AtomicString* propertyStrings = new AtomicString[numCSSProperties]; // Intentionally never destroyed. 170 AtomicString& propertyString = propertyStrings[index]; 171 if (propertyString.isNull()) { 172 const char* propertyName = propertyNameStrings[index]; 173 propertyString = AtomicString(propertyName, strlen(propertyName), AtomicString::ConstructFromLiteral); 174 } 175 return propertyString; 176} 177 178String getPropertyNameString(CSSPropertyID id) 179{ 180 // We share the StringImpl with the AtomicStrings. 181 return getPropertyNameAtomicString(id).string(); 182} 183 184String getJSPropertyName(CSSPropertyID id) 185{ 186 char result[maxCSSPropertyNameLength + 1]; 187 const char* cssPropertyName = getPropertyName(id); 188 const char* propertyNamePointer = cssPropertyName; 189 if (!propertyNamePointer) 190 return emptyString(); 191 192 char* resultPointer = result; 193 while (char character = *propertyNamePointer++) { 194 if (character == '-') { 195 char nextCharacter = *propertyNamePointer++; 196 if (!nextCharacter) 197 break; 198 character = (propertyNamePointer - 2 != cssPropertyName) ? toASCIIUpper(nextCharacter) : nextCharacter; 199 } 200 *resultPointer++ = character; 201 } 202 *resultPointer = '\\0'; 203 return WTF::String(result); 204} 205 206static const bool isInheritedPropertyTable[numCSSProperties + $numPredefinedProperties] = { 207 false, // CSSPropertyInvalid 208EOF 209 210foreach my $name (@names) { 211 my $id = $nameToId{$name}; 212 my $value = $nameIsInherited{$name} ? "true " : "false"; 213 print GPERF " $value, // CSSProperty$id\n"; 214} 215 216print GPERF<< "EOF"; 217}; 218 219bool CSSProperty::isInheritedProperty(CSSPropertyID id) 220{ 221 ASSERT(id >= 0 && id <= lastCSSProperty); 222 ASSERT(id != CSSPropertyInvalid); 223 return isInheritedPropertyTable[id]; 224} 225 226} // namespace WebCore 227 228#if defined(__clang__) 229#pragma clang diagnostic pop 230#endif 231EOF 232 233open HEADER, ">CSSPropertyNames.h" || die "Could not open CSSPropertyNames.h for writing"; 234print HEADER << "EOF"; 235/* This file is automatically generated from CSSPropertyNames.in by makeprop, do not edit */ 236 237#ifndef CSSPropertyNames_h 238#define CSSPropertyNames_h 239 240#include <string.h> 241#include <wtf/HashFunctions.h> 242#include <wtf/HashTraits.h> 243 244namespace WTF { 245class AtomicString; 246class String; 247} 248 249namespace WebCore { 250 251enum CSSPropertyID { 252 CSSPropertyInvalid = 0, 253EOF 254 255my $first = $numPredefinedProperties; 256my $i = $numPredefinedProperties; 257my $maxLen = 0; 258foreach my $name (@names) { 259 print HEADER " CSSProperty" . $nameToId{$name} . " = " . $i . ",\n"; 260 $i = $i + 1; 261 if (length($name) > $maxLen) { 262 $maxLen = length($name); 263 } 264} 265my $num = $i - $first; 266my $last = $i - 1; 267 268print HEADER "};\n\n"; 269print HEADER "const int firstCSSProperty = $first;\n"; 270print HEADER "const int numCSSProperties = $num;\n"; 271print HEADER "const int lastCSSProperty = $last;\n"; 272print HEADER "const size_t maxCSSPropertyNameLength = $maxLen;\n"; 273 274print HEADER << "EOF"; 275 276const char* getPropertyName(CSSPropertyID); 277const WTF::AtomicString& getPropertyNameAtomicString(CSSPropertyID id); 278WTF::String getPropertyNameString(CSSPropertyID id); 279WTF::String getJSPropertyName(CSSPropertyID); 280 281inline CSSPropertyID convertToCSSPropertyID(int value) 282{ 283 ASSERT((value >= firstCSSProperty && value <= lastCSSProperty) || value == CSSPropertyInvalid); 284 return static_cast<CSSPropertyID>(value); 285} 286 287} // namespace WebCore 288 289namespace WTF { 290template<> struct DefaultHash<WebCore::CSSPropertyID> { typedef IntHash<unsigned> Hash; }; 291template<> struct HashTraits<WebCore::CSSPropertyID> : GenericHashTraits<WebCore::CSSPropertyID> { 292 static const bool emptyValueIsZero = true; 293 static const bool needsDestruction = false; 294 static void constructDeletedValue(WebCore::CSSPropertyID& slot) { slot = static_cast<WebCore::CSSPropertyID>(WebCore::lastCSSProperty + 1); } 295 static bool isDeletedValue(WebCore::CSSPropertyID value) { return value == (WebCore::lastCSSProperty + 1); } 296}; 297} 298 299#endif // CSSPropertyNames_h 300 301EOF 302 303close HEADER; 304 305my $gperf = $ENV{GPERF} ? $ENV{GPERF} : "gperf"; 306system("\"$gperf\" --key-positions=\"*\" -D -n -s 2 CSSPropertyNames.gperf --output-file=CSSPropertyNames.cpp") == 0 || die "calling gperf failed: $?"; 307