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 |