8 from in_file
import InFile
9 from name_utilities
import upper_first_letter
17 #ifndef %(class_name)s_h
18 #define %(class_name)s_h
20 #include "core/css/parser/CSSParserMode.h"
26 %(value_keyword_enums)s
29 const int numCSSValueKeywords = %(value_keywords_count)d;
30 const size_t maxCSSValueKeywordLength = %(max_value_keyword_length)d;
32 const char* getValueName(CSSValueID);
33 bool isValueAllowedInMode(unsigned short id, CSSParserMode mode);
37 #endif // %(class_name)s_h
45 #include "%(class_name)s.h"
46 #include "core/css/HashTools.h"
50 static const char valueListStringPool[] = {
51 %(value_keyword_strings)s
54 static const unsigned short valueListStringOffsets[] = {
55 %(value_keyword_offsets)s
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
73 %(value_keyword_to_enum_map)s
75 const Value* findValue(register const char* str, register unsigned int len)
77 return CSSValueKeywordsHash::findValueImpl(str, len);
80 const char* getValueName(CSSValueID id)
82 ASSERT(id > 0 && id < numCSSValueKeywords);
83 return valueListStringPool + valueListStringOffsets[id - 1];
86 bool isValueAllowedInMode(unsigned short id, CSSParserMode mode)
89 %(ua_sheet_mode_values_keywords)s
90 return isUASheetBehavior(mode);
91 %(quirks_mode_or_ua_sheet_mode_values_keywords)s
92 return isUASheetBehavior(mode) || isQuirksModeBehavior(mode);
102 class CSSValueKeywordsWriter(in_generator
.Writer
):
103 class_name
= "CSSValueKeywords"
108 def __init__(self
, file_paths
):
109 in_generator
.Writer
.__init
__(self
, file_paths
)
110 self
._outputs
= {(self
.class_name
+ ".h"): self
.generate_header
,
111 (self
.class_name
+ ".cpp"): self
.generate_implementation
,
114 self
._value
_keywords
= self
.in_file
.name_dictionaries
115 first_property_id
= 1
116 for offset
, property in enumerate(self
._value
_keywords
):
117 property['lower_name'] = property['name'].lower()
118 property['enum_name'] = self
._enum
_name
_from
_value
_keyword
(property['name'])
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'
124 assert property['mode'] != 'UASheet', 'UASheet mode only value keywords should have the prefix "-internal-".'
126 def _enum_name_from_value_keyword(self
, value_keyword
):
127 return "CSSValue" + "".join(upper_first_letter(w
) for w
in value_keyword
.split("-"))
129 def _enum_declaration(self
, property):
130 return " %(enum_name)s = %(enum_value)s," % property
132 def _case_value_keyword(self
, property):
133 return "case %(enum_name)s:" % property
135 def generate_header(self
):
136 enum_enties
= map(self
._enum
_declaration
, [{'enum_name': 'CSSValueInvalid', 'enum_value': 0}] + self
._value
_keywords
)
137 return HEADER_TEMPLATE
% {
138 'license': license
.license_for_generated_cpp(),
139 'class_name': self
.class_name
,
140 'value_keyword_enums': "\n".join(enum_enties
),
141 'value_keywords_count': len(enum_enties
),
142 'max_value_keyword_length': reduce(max, map(len, map(lambda property: property['name'], self
._value
_keywords
))),
145 def _value_keywords_with_mode(self
, mode
):
146 return filter(lambda property: property['mode'] == mode
, self
._value
_keywords
)
148 def generate_implementation(self
):
151 for keyword
in self
._value
_keywords
:
152 keyword_offsets
.append(current_offset
)
153 current_offset
+= len(keyword
["name"]) + 1
155 gperf_input
= GPERF_TEMPLATE
% {
156 'license': license
.license_for_generated_cpp(),
157 'class_name': self
.class_name
,
158 'value_keyword_strings': '\n'.join(map(lambda property: ' "%(name)s\\0"' % property, self
._value
_keywords
)),
159 'value_keyword_offsets': '\n'.join(map(lambda offset
: ' %d,' % offset
, keyword_offsets
)),
160 'value_keyword_to_enum_map': '\n'.join('%(lower_name)s, %(enum_name)s' % keyword
for keyword
in self
._value
_keywords
),
161 'ua_sheet_mode_values_keywords': '\n '.join(map(self
._case
_value
_keyword
, self
._value
_keywords
_with
_mode
('UASheet'))),
162 'quirks_mode_or_ua_sheet_mode_values_keywords': '\n '.join(map(self
._case
_value
_keyword
, self
._value
_keywords
_with
_mode
('QuirksOrUASheet'))),
164 # FIXME: If we could depend on Python 2.7, we would use subprocess.check_output
165 gperf_args
= [self
.gperf_path
, '--key-positions=*', '-P', '-n']
166 gperf_args
.extend(['-m', '50']) # Pick best of 50 attempts.
167 gperf_args
.append('-D') # Allow duplicate hashes -> More compact code.
168 gperf
= subprocess
.Popen(gperf_args
, stdin
=subprocess
.PIPE
, stdout
=subprocess
.PIPE
, universal_newlines
=True)
169 return gperf
.communicate(gperf_input
)[0]
172 if __name__
== "__main__":
173 in_generator
.Maker(CSSValueKeywordsWriter
).main(sys
.argv
)