| 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 <string.h> | |
| 21 | |
| 22 namespace WebCore { | |
| 23 | |
| 24 enum CSSValueID { | |
| 25 %(value_keyword_enums)s | |
| 26 }; | |
| 27 | |
| 28 const int numCSSValueKeywords = %(value_keywords_count)d; | |
| 29 const size_t maxCSSValueKeywordLength = %(max_value_keyword_length)d; | |
| 30 | |
| 31 const char* getValueName(unsigned short id); | |
| 32 bool isValueAllowedInMode(unsigned short id, CSSParserMode mode); | |
| 33 | |
| 34 } // namespace WebCore | |
| 35 | |
| 36 #endif // %(class_name)s_h | |
| 37 """ | |
| 38 | |
| 39 GPERF_TEMPLATE = """ | |
| 40 %%{ | |
| 41 %(license)s | |
| 42 | |
| 43 #include "config.h" | |
| 44 #include "%(class_name)s.h" | |
| 45 #include "core/platform/HashTools.h" | |
| 46 #include <string.h> | |
| 47 | |
| 48 namespace WebCore { | |
| 49 static const char valueListStringPool[] = { | |
| 50 "\\0" | |
| 51 %(value_keyword_strings)s | |
| 52 }; | |
| 53 | |
| 54 static const unsigned short valueListStringOffsets[] = { | |
| 55 %(value_keyword_offsets)s | |
| 56 }; | |
| 57 | |
| 58 %%} | |
| 59 %%struct-type | |
| 60 struct Value; | |
| 61 %%omit-struct-type | |
| 62 %%language=C++ | |
| 63 %%readonly-tables | |
| 64 %%compare-strncmp | |
| 65 %%define class-name %(class_name)sHash | |
| 66 %%define lookup-function-name findValueImpl | |
| 67 %%define hash-function-name value_hash_function | |
| 68 %%define slot-name nameOffset | |
| 69 %%define word-array-name value_word_list | |
| 70 %%pic | |
| 71 %%enum | |
| 72 %%%% | |
| 73 %(value_keyword_to_enum_map)s | |
| 74 %%%% | |
| 75 const Value* findValue(register const char* str, register unsigned int len) | |
| 76 { | |
| 77 return CSSValueKeywordsHash::findValueImpl(str, len); | |
| 78 } | |
| 79 | |
| 80 const char* getValueName(unsigned short id) | |
| 81 { | |
| 82 if (id >= numCSSValueKeywords || id <= 0) | |
| 83 return 0; | |
| 84 return valueListStringPool + valueListStringOffsets[id]; | |
| 85 } | |
| 86 | |
| 87 bool isValueAllowedInMode(unsigned short id, CSSParserMode mode) | |
| 88 { | |
| 89 switch (id) { | |
| 90 %(ua_sheet_mode_values_keywords)s | |
| 91 return mode == UASheetMode; | |
| 92 %(quirks_mode_values_keywords)s | |
| 93 return mode == CSSQuirksMode; | |
| 94 %(quirks_mode_or_ua_sheet_mode_values_keywords)s | |
| 95 return mode == UASheetMode || mode == CSSQuirksMode; | |
| 96 default: | |
| 97 return true; | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 } // namespace WebCore | |
| 102 """ | |
| 103 | |
| 104 | |
| 105 class CSSValueKeywordsWriter(in_generator.Writer): | |
| 106 class_name = "CSSValueKeywords" | |
| 107 defaults = { | |
| 108 'condition': None, | |
| 109 'mode': None, | |
| 110 } | |
| 111 | |
| 112 def __init__(self, file_paths, enabled_conditions): | |
| 113 in_generator.Writer.__init__(self, file_paths, enabled_conditions) | |
| 114 self._outputs = {(self.class_name + ".h"): self.generate_header, | |
| 115 (self.class_name + ".cpp"): self.generate_implementatio
n, | |
| 116 } | |
| 117 | |
| 118 all_properties = self.in_file.name_dictionaries | |
| 119 self._value_keywords = filter(lambda property: not property['condition']
or property['condition'] in self._enabled_conditions, all_properties) | |
| 120 first_property_id = 1 | |
| 121 for offset, property in enumerate(self._value_keywords): | |
| 122 property['name'] = property['name'].lower() | |
| 123 property['enum_name'] = self._enum_name_from_value_keyword(property[
'name']) | |
| 124 property['enum_value'] = first_property_id + offset | |
| 125 if property['name'].startswith('-internal-'): | |
| 126 assert property['mode'] is None, 'Can\'t specify mode for value
keywords with the prefix "-internal-".' | |
| 127 property['mode'] = 'UASheet' | |
| 128 else: | |
| 129 assert property['mode'] != 'UASheet', 'UASheet mode only value k
eywords should have the prefix "-internal-".' | |
| 130 | |
| 131 def _enum_name_from_value_keyword(self, value_keyword): | |
| 132 return "CSSValue" + "".join(w.capitalize() for w in value_keyword.split(
"-")) | |
| 133 | |
| 134 def _enum_declaration(self, property): | |
| 135 return " %(enum_name)s = %(enum_value)s," % property | |
| 136 | |
| 137 def _case_value_keyword(self, property): | |
| 138 return "case %(enum_name)s:" % property | |
| 139 | |
| 140 def generate_header(self): | |
| 141 enum_enties = map(self._enum_declaration, [{'enum_name': 'CSSValueInvali
d', 'enum_value': 0}] + self._value_keywords) | |
| 142 return HEADER_TEMPLATE % { | |
| 143 'license': license.license_for_generated_cpp(), | |
| 144 'class_name': self.class_name, | |
| 145 'value_keyword_enums': "\n".join(enum_enties), | |
| 146 'value_keywords_count': len(enum_enties), | |
| 147 'max_value_keyword_length': reduce(max, map(len, map(lambda property
: property['name'], self._value_keywords))), | |
| 148 } | |
| 149 | |
| 150 def _value_keywords_with_mode(self, mode): | |
| 151 return filter(lambda property: property['mode'] == mode, self._value_key
words) | |
| 152 | |
| 153 def generate_implementation(self): | |
| 154 keyword_offsets = [0] | |
| 155 current_offset = 1 | |
| 156 for keyword in self._value_keywords: | |
| 157 keyword_offsets.append(current_offset) | |
| 158 current_offset += len(keyword["name"]) + 1 | |
| 159 | |
| 160 gperf_input = GPERF_TEMPLATE % { | |
| 161 'license': license.license_for_generated_cpp(), | |
| 162 'class_name': self.class_name, | |
| 163 'value_keyword_strings': '\n'.join(map(lambda property: ' "%(name
)s\\0"' % property, self._value_keywords)), | |
| 164 'value_keyword_offsets': '\n'.join(map(lambda offset: ' %d,' % offs
et, keyword_offsets)), | |
| 165 'value_keyword_to_enum_map': '\n'.join(map(lambda property: '%(name)
s, %(enum_name)s' % property, self._value_keywords)), | |
| 166 'ua_sheet_mode_values_keywords': '\n '.join(map(self._case_va
lue_keyword, self._value_keywords_with_mode('UASheet'))), | |
| 167 'quirks_mode_values_keywords': '\n '.join(map(self._case_valu
e_keyword, self._value_keywords_with_mode('Quirks'))), | |
| 168 'quirks_mode_or_ua_sheet_mode_values_keywords': '\n '.join(map(se
lf._case_value_keyword, self._value_keywords_with_mode('QuirksOrUASheet'))), | |
| 169 } | |
| 170 # FIXME: If we could depend on Python 2.7, we would use subprocess.check
_output | |
| 171 gperf_args = ['gperf', '--key-positions=*', '-D', '-n', '-s', '2'] | |
| 172 gperf = subprocess.Popen(gperf_args, stdin=subprocess.PIPE, stdout=subpr
ocess.PIPE) | |
| 173 return gperf.communicate(gperf_input)[0] | |
| 174 | |
| 175 | |
| 176 if __name__ == "__main__": | |
| 177 in_generator.Maker(CSSValueKeywordsWriter).main(sys.argv) | |
| OLD | NEW |