| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 | 2 |
| 3 import os.path | 3 import os.path |
| 4 import re | 4 import re |
| 5 import subprocess | 5 import subprocess |
| 6 import sys | 6 import sys |
| 7 | 7 |
| 8 from in_file import InFile | 8 from in_file import InFile |
| 9 import in_generator | 9 import in_generator |
| 10 import license | 10 import license |
| 11 | 11 |
| 12 | 12 |
| 13 HEADER_TEMPLATE = """ | 13 HEADER_TEMPLATE = """ |
| 14 %(license)s | 14 %(license)s |
| 15 | 15 |
| 16 #ifndef %(class_name)s_h | 16 #ifndef %(class_name)s_h |
| 17 #define %(class_name)s_h | 17 #define %(class_name)s_h |
| 18 | 18 |
| 19 #include "core/css/CSSParserMode.h" |
| 19 #include <string.h> | 20 #include <string.h> |
| 20 | 21 |
| 21 namespace WebCore { | 22 namespace WebCore { |
| 22 | 23 |
| 23 enum CSSValueID { | 24 enum CSSValueID { |
| 24 CSSValueInvalid = 0, | |
| 25 %(value_keyword_enums)s | 25 %(value_keyword_enums)s |
| 26 }; | 26 }; |
| 27 | 27 |
| 28 const int numCSSValueKeywords = %(value_keywords_count)d; | 28 const int numCSSValueKeywords = %(value_keywords_count)d; |
| 29 const size_t maxCSSValueKeywordLength = %(max_value_keyword_length)d; | 29 const size_t maxCSSValueKeywordLength = %(max_value_keyword_length)d; |
| 30 | 30 |
| 31 const char* getValueName(unsigned short id); | 31 const char* getValueName(unsigned short id); |
| 32 bool isValueAllowedInMode(unsigned short id, CSSParserMode mode); |
| 32 | 33 |
| 33 } // namespace WebCore | 34 } // namespace WebCore |
| 34 | 35 |
| 35 #endif // %(class_name)s_h | 36 #endif // %(class_name)s_h |
| 36 """ | 37 """ |
| 37 | 38 |
| 38 GPERF_TEMPLATE = """ | 39 GPERF_TEMPLATE = """ |
| 39 %%{ | 40 %%{ |
| 40 %(license)s | 41 %(license)s |
| 41 | 42 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 71 return CSSValueKeywordsHash::findValueImpl(str, len); | 72 return CSSValueKeywordsHash::findValueImpl(str, len); |
| 72 } | 73 } |
| 73 | 74 |
| 74 const char* getValueName(unsigned short id) | 75 const char* getValueName(unsigned short id) |
| 75 { | 76 { |
| 76 if (id >= numCSSValueKeywords || id <= 0) | 77 if (id >= numCSSValueKeywords || id <= 0) |
| 77 return 0; | 78 return 0; |
| 78 return valueList[id]; | 79 return valueList[id]; |
| 79 } | 80 } |
| 80 | 81 |
| 82 bool isValueAllowedInMode(unsigned short id, CSSParserMode mode) |
| 83 { |
| 84 switch (id) { |
| 85 %(ua_sheet_mode_values_keywords)s |
| 86 return mode == UASheetMode; |
| 87 %(quirks_mode_values_keywords)s |
| 88 return mode == CSSQuirksMode; |
| 89 %(quirks_mode_or_ua_sheet_mode_values_keywords)s |
| 90 return mode == UASheetMode || mode == CSSQuirksMode; |
| 91 default: |
| 92 return true; |
| 93 } |
| 94 } |
| 95 |
| 81 } // namespace WebCore | 96 } // namespace WebCore |
| 82 """ | 97 """ |
| 83 | 98 |
| 84 | 99 |
| 85 class CSSValueKeywordsWriter(in_generator.Writer): | 100 class CSSValueKeywordsWriter(in_generator.Writer): |
| 86 class_name = "CSSValueKeywords" | 101 class_name = "CSSValueKeywords" |
| 87 defaults = { | 102 defaults = { |
| 88 'condition': None, | 103 'condition': None, |
| 104 'mode': None, |
| 89 } | 105 } |
| 90 | 106 |
| 91 def __init__(self, file_paths, enabled_conditions): | 107 def __init__(self, file_paths, enabled_conditions): |
| 92 in_generator.Writer.__init__(self, file_paths, enabled_conditions) | 108 in_generator.Writer.__init__(self, file_paths, enabled_conditions) |
| 93 self._outputs = {(self.class_name + ".h"): self.generate_header, | 109 self._outputs = {(self.class_name + ".h"): self.generate_header, |
| 94 (self.class_name + ".cpp"): self.generate_implementatio
n, | 110 (self.class_name + ".cpp"): self.generate_implementatio
n, |
| 95 } | 111 } |
| 96 | 112 |
| 97 all_properties = self.in_file.name_dictionaries | 113 all_properties = self.in_file.name_dictionaries |
| 98 self._value_keywords = filter(lambda property: not property['condition']
or property['condition'] in self._enabled_conditions, all_properties) | 114 self._value_keywords = filter(lambda property: not property['condition']
or property['condition'] in self._enabled_conditions, all_properties) |
| 99 first_property_id = 1 | 115 first_property_id = 1 |
| 100 for offset, property in enumerate(self._value_keywords): | 116 for offset, property in enumerate(self._value_keywords): |
| 101 property['name'] = property['name'].lower() | 117 property['name'] = property['name'].lower() |
| 102 property['enum_name'] = self._enum_name_from_value_keyword(property[
'name']) | 118 property['enum_name'] = self._enum_name_from_value_keyword(property[
'name']) |
| 103 property['enum_value'] = first_property_id + offset | 119 property['enum_value'] = first_property_id + offset |
| 120 if property['name'].startswith('-internal-'): |
| 121 assert property['mode'] is None, 'Can\'t specify mode for value
keywords with the prefix "-internal-".' |
| 122 property['mode'] = 'UASheet' |
| 123 else: |
| 124 assert property['mode'] != 'UASheet', 'UASheet mode only value k
eywords should have the prefix "-internal-".' |
| 104 | 125 |
| 105 def _enum_name_from_value_keyword(self, value_keyword): | 126 def _enum_name_from_value_keyword(self, value_keyword): |
| 106 return "CSSValue" + "".join(w.capitalize() for w in value_keyword.split(
"-")) | 127 return "CSSValue" + "".join(w.capitalize() for w in value_keyword.split(
"-")) |
| 107 | 128 |
| 108 def _enum_declaration(self, property): | 129 def _enum_declaration(self, property): |
| 109 return " %(enum_name)s = %(enum_value)s," % property | 130 return " %(enum_name)s = %(enum_value)s," % property |
| 110 | 131 |
| 132 def _case_value_keyword(self, property): |
| 133 return "case %(enum_name)s:" % property |
| 134 |
| 111 def generate_header(self): | 135 def generate_header(self): |
| 136 enum_enties = map(self._enum_declaration, [{'enum_name': 'CSSValueInvali
d', 'enum_value': 0}] + self._value_keywords) |
| 112 return HEADER_TEMPLATE % { | 137 return HEADER_TEMPLATE % { |
| 113 'license': license.license_for_generated_cpp(), | 138 'license': license.license_for_generated_cpp(), |
| 114 'class_name': self.class_name, | 139 'class_name': self.class_name, |
| 115 'value_keyword_enums': "\n".join(map(self._enum_declaration, self._v
alue_keywords)), | 140 'value_keyword_enums': "\n".join(enum_enties), |
| 116 'value_keywords_count': len(self._value_keywords), | 141 'value_keywords_count': len(enum_enties), |
| 117 'max_value_keyword_length': reduce(max, map(len, map(lambda property
: property['name'], self._value_keywords))), | 142 'max_value_keyword_length': reduce(max, map(len, map(lambda property
: property['name'], self._value_keywords))), |
| 118 } | 143 } |
| 119 | 144 |
| 145 def _value_keywords_with_mode(self, mode): |
| 146 return filter(lambda property: property['mode'] == mode, self._value_key
words) |
| 147 |
| 120 def generate_implementation(self): | 148 def generate_implementation(self): |
| 121 gperf_input = GPERF_TEMPLATE % { | 149 gperf_input = GPERF_TEMPLATE % { |
| 122 'license': license.license_for_generated_cpp(), | 150 'license': license.license_for_generated_cpp(), |
| 123 'class_name': self.class_name, | 151 'class_name': self.class_name, |
| 124 'value_keyword_strings': '\n'.join(map(lambda property: ' "%(name
)s",' % property, self._value_keywords)), | 152 'value_keyword_strings': '\n'.join(map(lambda property: ' "%(name
)s",' % property, self._value_keywords)), |
| 125 'value_keyword_to_enum_map': '\n'.join(map(lambda property: '%(name)
s, %(enum_name)s' % property, self._value_keywords)), | 153 'value_keyword_to_enum_map': '\n'.join(map(lambda property: '%(name)
s, %(enum_name)s' % property, self._value_keywords)), |
| 154 'ua_sheet_mode_values_keywords': '\n'.join(map(self._case_value_keyw
ord, self._value_keywords_with_mode('UASheet'))), |
| 155 'quirks_mode_values_keywords': '\n'.join(map(self._case_value_keywor
d, self._value_keywords_with_mode('Quirks'))), |
| 156 'quirks_mode_or_ua_sheet_mode_values_keywords': '\n'.join(map(self._
case_value_keyword, self._value_keywords_with_mode('QuirksOrUASheet'))), |
| 126 } | 157 } |
| 127 # FIXME: If we could depend on Python 2.7, we would use subprocess.check
_output | 158 # FIXME: If we could depend on Python 2.7, we would use subprocess.check
_output |
| 128 gperf_args = ['gperf', '--key-positions=*', '-D', '-n', '-s', '2'] | 159 gperf_args = ['gperf', '--key-positions=*', '-D', '-n', '-s', '2'] |
| 129 gperf = subprocess.Popen(gperf_args, stdin=subprocess.PIPE, stdout=subpr
ocess.PIPE) | 160 gperf = subprocess.Popen(gperf_args, stdin=subprocess.PIPE, stdout=subpr
ocess.PIPE) |
| 130 return gperf.communicate(gperf_input)[0] | 161 return gperf.communicate(gperf_input)[0] |
| 131 | 162 |
| 132 | 163 |
| 133 if __name__ == "__main__": | 164 if __name__ == "__main__": |
| 134 in_generator.Maker(CSSValueKeywordsWriter).main(sys.argv) | 165 in_generator.Maker(CSSValueKeywordsWriter).main(sys.argv) |
| OLD | NEW |