| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 #!/usr/bin/env python |  | 
| 2 |  | 
| 3 import os.path |  | 
| 4 import re |  | 
| 5 import subprocess |  | 
| 6 import sys |  | 
| 7 |  | 
| 8 from in_file import InFile |  | 
| 9 import in_generator |  | 
| 10 import license |  | 
| 11 |  | 
| 12 |  | 
| 13 HEADER_TEMPLATE = """ |  | 
| 14 %(license)s |  | 
| 15 |  | 
| 16 #ifndef %(class_name)s_h |  | 
| 17 #define %(class_name)s_h |  | 
| 18 |  | 
| 19 #include "core/css/CSSParserMode.h" |  | 
| 20 #include "wtf/HashFunctions.h" |  | 
| 21 #include "wtf/HashTraits.h" |  | 
| 22 #include <string.h> |  | 
| 23 |  | 
| 24 namespace WTF { |  | 
| 25 class AtomicString; |  | 
| 26 class String; |  | 
| 27 } |  | 
| 28 |  | 
| 29 namespace WebCore { |  | 
| 30 |  | 
| 31 enum CSSPropertyID { |  | 
| 32     CSSPropertyInvalid = 0, |  | 
| 33     CSSPropertyVariable = 1, |  | 
| 34 %(property_enums)s |  | 
| 35 }; |  | 
| 36 |  | 
| 37 const int firstCSSProperty = %(first_property_id)s; |  | 
| 38 const int numCSSProperties = %(properties_count)s; |  | 
| 39 const int lastCSSProperty = %(last_property_id)d; |  | 
| 40 const size_t maxCSSPropertyNameLength = %(max_name_length)d; |  | 
| 41 |  | 
| 42 const char* getPropertyName(CSSPropertyID); |  | 
| 43 const WTF::AtomicString& getPropertyNameAtomicString(CSSPropertyID); |  | 
| 44 WTF::String getPropertyNameString(CSSPropertyID); |  | 
| 45 WTF::String getJSPropertyName(CSSPropertyID); |  | 
| 46 bool isInternalProperty(CSSPropertyID id); |  | 
| 47 |  | 
| 48 inline CSSPropertyID convertToCSSPropertyID(int value) |  | 
| 49 { |  | 
| 50     ASSERT((value >= firstCSSProperty && value <= lastCSSProperty) || value == C
     SSPropertyInvalid); |  | 
| 51     return static_cast<CSSPropertyID>(value); |  | 
| 52 } |  | 
| 53 |  | 
| 54 } // namespace WebCore |  | 
| 55 |  | 
| 56 namespace WTF { |  | 
| 57 template<> struct DefaultHash<WebCore::CSSPropertyID> { typedef IntHash<unsigned
     > Hash; }; |  | 
| 58 template<> struct HashTraits<WebCore::CSSPropertyID> : GenericHashTraits<WebCore
     ::CSSPropertyID> { |  | 
| 59     static const bool emptyValueIsZero = true; |  | 
| 60     static const bool needsDestruction = false; |  | 
| 61     static void constructDeletedValue(WebCore::CSSPropertyID& slot) { slot = sta
     tic_cast<WebCore::CSSPropertyID>(WebCore::lastCSSProperty + 1); } |  | 
| 62     static bool isDeletedValue(WebCore::CSSPropertyID value) { return value == (
     WebCore::lastCSSProperty + 1); } |  | 
| 63 }; |  | 
| 64 } |  | 
| 65 |  | 
| 66 #endif // %(class_name)s_h |  | 
| 67 """ |  | 
| 68 |  | 
| 69 GPERF_TEMPLATE = """ |  | 
| 70 %%{ |  | 
| 71 %(license)s |  | 
| 72 |  | 
| 73 #include "config.h" |  | 
| 74 #include "%(class_name)s.h" |  | 
| 75 #include "core/platform/HashTools.h" |  | 
| 76 #include <string.h> |  | 
| 77 |  | 
| 78 #include "wtf/ASCIICType.h" |  | 
| 79 #include "wtf/text/AtomicString.h" |  | 
| 80 #include "wtf/text/WTFString.h" |  | 
| 81 |  | 
| 82 namespace WebCore { |  | 
| 83 static const char propertyNameStringsPool[] = { |  | 
| 84 %(property_name_strings)s |  | 
| 85 }; |  | 
| 86 |  | 
| 87 static const unsigned short propertyNameStringsOffsets[] = { |  | 
| 88 %(property_name_offsets)s |  | 
| 89 }; |  | 
| 90 |  | 
| 91 %%} |  | 
| 92 %%struct-type |  | 
| 93 struct Property; |  | 
| 94 %%omit-struct-type |  | 
| 95 %%language=C++ |  | 
| 96 %%readonly-tables |  | 
| 97 %%global-table |  | 
| 98 %%compare-strncmp |  | 
| 99 %%define class-name %(class_name)sHash |  | 
| 100 %%define lookup-function-name findPropertyImpl |  | 
| 101 %%define hash-function-name propery_hash_function |  | 
| 102 %%define slot-name nameOffset |  | 
| 103 %%define word-array-name property_wordlist |  | 
| 104 %%enum |  | 
| 105 %%%% |  | 
| 106 %(property_to_enum_map)s |  | 
| 107 %%%% |  | 
| 108 const Property* findProperty(register const char* str, register unsigned int len
     ) |  | 
| 109 { |  | 
| 110     return %(class_name)sHash::findPropertyImpl(str, len); |  | 
| 111 } |  | 
| 112 |  | 
| 113 const char* getPropertyName(CSSPropertyID id) |  | 
| 114 { |  | 
| 115     if (id < firstCSSProperty) |  | 
| 116         return 0; |  | 
| 117     int index = id - firstCSSProperty; |  | 
| 118     if (index >= numCSSProperties) |  | 
| 119         return 0; |  | 
| 120     return propertyNameStringsPool + propertyNameStringsOffsets[index]; |  | 
| 121 } |  | 
| 122 |  | 
| 123 const AtomicString& getPropertyNameAtomicString(CSSPropertyID id) |  | 
| 124 { |  | 
| 125     if (id < firstCSSProperty) |  | 
| 126         return nullAtom; |  | 
| 127     int index = id - firstCSSProperty; |  | 
| 128     if (index >= numCSSProperties) |  | 
| 129         return nullAtom; |  | 
| 130 |  | 
| 131     static AtomicString* propertyStrings = new AtomicString[numCSSProperties]; /
     / Intentionally never destroyed. |  | 
| 132     AtomicString& propertyString = propertyStrings[index]; |  | 
| 133     if (propertyString.isNull()) { |  | 
| 134         const char* propertyName = propertyNameStringsPool + propertyNameStrings
     Offsets[index]; |  | 
| 135         propertyString = AtomicString(propertyName, strlen(propertyName), Atomic
     String::ConstructFromLiteral); |  | 
| 136     } |  | 
| 137     return propertyString; |  | 
| 138 } |  | 
| 139 |  | 
| 140 String getPropertyNameString(CSSPropertyID id) |  | 
| 141 { |  | 
| 142     // We share the StringImpl with the AtomicStrings. |  | 
| 143     return getPropertyNameAtomicString(id).string(); |  | 
| 144 } |  | 
| 145 |  | 
| 146 String getJSPropertyName(CSSPropertyID id) |  | 
| 147 { |  | 
| 148     char result[maxCSSPropertyNameLength + 1]; |  | 
| 149     const char* cssPropertyName = getPropertyName(id); |  | 
| 150     const char* propertyNamePointer = cssPropertyName; |  | 
| 151     if (!propertyNamePointer) |  | 
| 152         return emptyString(); |  | 
| 153 |  | 
| 154     char* resultPointer = result; |  | 
| 155     while (char character = *propertyNamePointer++) { |  | 
| 156         if (character == '-') { |  | 
| 157             char nextCharacter = *propertyNamePointer++; |  | 
| 158             if (!nextCharacter) |  | 
| 159                 break; |  | 
| 160             character = (propertyNamePointer - 2 != cssPropertyName) ? toASCIIUp
     per(nextCharacter) : nextCharacter; |  | 
| 161         } |  | 
| 162         *resultPointer++ = character; |  | 
| 163     } |  | 
| 164     *resultPointer = '\\0'; |  | 
| 165     return String(result); |  | 
| 166 } |  | 
| 167 |  | 
| 168 bool isInternalProperty(CSSPropertyID id) |  | 
| 169 { |  | 
| 170     switch (id) { |  | 
| 171         %(internal_properties)s |  | 
| 172             return true; |  | 
| 173         default: |  | 
| 174             return false; |  | 
| 175     } |  | 
| 176 } |  | 
| 177 |  | 
| 178 } // namespace WebCore |  | 
| 179 """ |  | 
| 180 |  | 
| 181 |  | 
| 182 class CSSPropertiesWriter(in_generator.Writer): |  | 
| 183     class_name = "CSSPropertyNames" |  | 
| 184     defaults = { |  | 
| 185         'alias_for': None, |  | 
| 186         'condition': None, |  | 
| 187         'is_internal': False, |  | 
| 188     } |  | 
| 189 |  | 
| 190     def __init__(self, file_paths, enabled_conditions): |  | 
| 191         in_generator.Writer.__init__(self, file_paths, enabled_conditions) |  | 
| 192         self._outputs = {(self.class_name + ".h"): self.generate_header, |  | 
| 193                          (self.class_name + ".cpp"): self.generate_implementatio
     n, |  | 
| 194                         } |  | 
| 195 |  | 
| 196         all_properties = self.in_file.name_dictionaries |  | 
| 197         self._aliases = filter(lambda property: property['alias_for'], all_prope
     rties) |  | 
| 198         for offset, property in enumerate(self._aliases): |  | 
| 199             # Aliases use the enum_name that they are an alias for. |  | 
| 200             property['enum_name'] = self._enum_name_from_property_name(property[
     'alias_for']) |  | 
| 201             # Aliases do not get an enum_value. |  | 
| 202 |  | 
| 203         self._properties = filter(lambda property: not property['alias_for'] and
      not property['condition'] or property['condition'] in self._enabled_conditions,
      all_properties) |  | 
| 204         if len(self._properties) > 1024: |  | 
| 205             print "ERROR : There is more than 1024 CSS Properties, you need to u
     pdate CSSProperty.h/StylePropertyMetadata m_propertyID accordingly." |  | 
| 206             exit(1) |  | 
| 207         self._first_property_id = 2  # We start after CSSPropertyInvalid and CSS
     PropertyVariable. |  | 
| 208         property_id = self._first_property_id |  | 
| 209         for offset, property in enumerate(self._properties): |  | 
| 210             property['enum_name'] = self._enum_name_from_property_name(property[
     'name']) |  | 
| 211             property['enum_value'] = self._first_property_id + offset |  | 
| 212             if property['name'].startswith('-internal-'): |  | 
| 213                 property['is_internal'] = True |  | 
| 214 |  | 
| 215     def _enum_name_from_property_name(self, property_name): |  | 
| 216         return "CSSProperty" + re.sub(r'(^[^-])|-(.)', lambda match: (match.grou
     p(1) or match.group(2)).upper(), property_name) |  | 
| 217 |  | 
| 218     def _enum_declaration(self, property): |  | 
| 219         return "    %(enum_name)s = %(enum_value)s," % property |  | 
| 220 |  | 
| 221     def generate_header(self): |  | 
| 222         return HEADER_TEMPLATE % { |  | 
| 223             'license': license.license_for_generated_cpp(), |  | 
| 224             'class_name': self.class_name, |  | 
| 225             'property_enums': "\n".join(map(self._enum_declaration, self._proper
     ties)), |  | 
| 226             'first_property_id': self._first_property_id, |  | 
| 227             'properties_count': len(self._properties), |  | 
| 228             'last_property_id': self._first_property_id + len(self._properties) 
     - 1, |  | 
| 229             'max_name_length': reduce(max, map(len, map(lambda property: propert
     y['name'], self._properties))), |  | 
| 230         } |  | 
| 231 |  | 
| 232     def _case_properties(self, property): |  | 
| 233         return "case %(enum_name)s:" % property |  | 
| 234 |  | 
| 235     def generate_implementation(self): |  | 
| 236         property_offsets = [] |  | 
| 237         current_offset = 0 |  | 
| 238         for property in self._properties: |  | 
| 239             property_offsets.append(current_offset) |  | 
| 240             current_offset += len(property["name"]) + 1 |  | 
| 241 |  | 
| 242         gperf_input = GPERF_TEMPLATE % { |  | 
| 243             'license': license.license_for_generated_cpp(), |  | 
| 244             'class_name': self.class_name, |  | 
| 245             'property_name_strings': '\n'.join(map(lambda property: '    "%(name
     )s\\0"' % property, self._properties)), |  | 
| 246             'property_name_offsets': '\n'.join(map(lambda offset: '    %d,' % of
     fset, property_offsets)), |  | 
| 247             'property_to_enum_map': '\n'.join(map(lambda property: '%(name)s, %(
     enum_name)s' % property, self._properties + self._aliases)), |  | 
| 248             'internal_properties': '\n'.join(map(self._case_properties, filter(l
     ambda property: property['is_internal'], self._properties))), |  | 
| 249         } |  | 
| 250         # FIXME: If we could depend on Python 2.7, we would use subprocess.check
     _output |  | 
| 251         gperf_args = ['gperf', '--key-positions=*', '-P', '-D', '-n', '-s', '2'] |  | 
| 252         gperf = subprocess.Popen(gperf_args, stdin=subprocess.PIPE, stdout=subpr
     ocess.PIPE) |  | 
| 253         return gperf.communicate(gperf_input)[0] |  | 
| 254 |  | 
| 255 |  | 
| 256 if __name__ == "__main__": |  | 
| 257     in_generator.Maker(CSSPropertiesWriter).main(sys.argv) |  | 
| OLD | NEW | 
|---|