OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (C) 2013 Google Inc. All rights reserved. | 2 # Copyright (C) 2013 Google Inc. All rights reserved. |
3 # | 3 # |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 11 matching lines...) Expand all Loading... |
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 import os.path | 30 import os.path |
31 import sys | 31 import sys |
32 import shutil | |
33 | 32 |
34 from in_file import InFile | 33 from in_file import InFile |
| 34 import in_generator |
35 import license | 35 import license |
36 | 36 |
37 | 37 |
38 HEADER_TEMPLATE = """%(license)s | 38 HEADER_TEMPLATE = """%(license)s |
39 #ifndef %(class_name)s_h | 39 #ifndef %(class_name)s_h |
40 #define %(class_name)s_h | 40 #define %(class_name)s_h |
41 | 41 |
42 namespace WebCore { | 42 namespace WebCore { |
43 | 43 |
44 // A class that stores static enablers for all experimental features. | 44 // A class that stores static enablers for all experimental features. |
45 | 45 |
46 class %(class_name)s { | 46 class %(class_name)s { |
47 public: | 47 public: |
48 %(method_declarations)s | 48 %(method_declarations)s |
49 private: | 49 private: |
50 RuntimeEnabledFeatures() { } | 50 %(class_name)s() { } |
51 | 51 |
52 %(storage_declarations)s | 52 %(storage_declarations)s |
53 }; | 53 }; |
54 | 54 |
55 } // namespace WebCore | 55 } // namespace WebCore |
56 | 56 |
57 #endif // %(class_name)s_h | 57 #endif // %(class_name)s_h |
58 """ | 58 """ |
59 | 59 |
60 IMPLEMENTATION_TEMPLATE = """%(license)s | 60 IMPLEMENTATION_TEMPLATE = """%(license)s |
61 #include "config.h" | 61 #include "config.h" |
62 #include "RuntimeEnabledFeatures.h" | 62 #include "%(class_name)s.h" |
63 | 63 |
64 namespace WebCore { | 64 namespace WebCore { |
65 | 65 |
66 %(storage_definitions)s | 66 %(storage_definitions)s |
67 | 67 |
68 } // namespace WebCore | 68 } // namespace WebCore |
69 """ | 69 """ |
70 | 70 |
71 class RuntimeFeatureWriter(object): | 71 class RuntimeFeatureWriter(in_generator.Writer): |
| 72 class_name = "RuntimeEnabledFeatures" |
| 73 defaults = { |
| 74 'condition' : None, |
| 75 'depends_on' : [], |
| 76 'default': 'false', |
| 77 'custom': False, |
| 78 } |
| 79 |
72 def __init__(self, in_file_path): | 80 def __init__(self, in_file_path): |
73 # Assume that the class should be called the same as the file. | 81 super(RuntimeFeatureWriter, self).__init__(in_file_path) |
74 self.class_name, _ = os.path.splitext(os.path.basename(in_file_path)) | 82 self._all_features = self.in_file.name_dictionaries |
75 defaults = { | |
76 'condition' : None, | |
77 'depends_on' : [], | |
78 'default': 'false', | |
79 'custom': False, | |
80 } | |
81 self._all_features = InFile.load_from_path(in_file_path, defaults).name_
dictionaries | |
82 # Make sure the resulting dictionaries have all the keys we expect. | 83 # Make sure the resulting dictionaries have all the keys we expect. |
83 for feature in self._all_features: | 84 for feature in self._all_features: |
84 feature['first_lowered_name'] = self._lower_first(feature['name']) | 85 feature['first_lowered_name'] = self._lower_first(feature['name']) |
85 # Most features just check their isFooEnabled bool | 86 # Most features just check their isFooEnabled bool |
86 # but some depend on more than one bool. | 87 # but some depend on more than one bool. |
87 enabled_condition = "is%sEnabled" % feature['name'] | 88 enabled_condition = "is%sEnabled" % feature['name'] |
88 for dependant_name in feature['depends_on']: | 89 for dependant_name in feature['depends_on']: |
89 enabled_condition += " && is%sEnabled" % dependant_name | 90 enabled_condition += " && is%sEnabled" % dependant_name |
90 feature['enabled_condition'] = enabled_condition | 91 feature['enabled_condition'] = enabled_condition |
91 self._non_custom_features = filter(lambda feature: not feature['custom']
, self._all_features) | 92 self._non_custom_features = filter(lambda feature: not feature['custom']
, self._all_features) |
(...skipping 20 matching lines...) Expand all Loading... |
112 static bool %(first_lowered_name)sEnabled() { return false; } | 113 static bool %(first_lowered_name)sEnabled() { return false; } |
113 #endif | 114 #endif |
114 """ | 115 """ |
115 template = conditional if feature['condition'] else unconditional | 116 template = conditional if feature['condition'] else unconditional |
116 return template % feature | 117 return template % feature |
117 | 118 |
118 def _storage_declarations(self, feature): | 119 def _storage_declarations(self, feature): |
119 declaration = " static bool is%(name)sEnabled;" % feature | 120 declaration = " static bool is%(name)sEnabled;" % feature |
120 return self._wrap_with_condition(declaration, feature['condition']) | 121 return self._wrap_with_condition(declaration, feature['condition']) |
121 | 122 |
122 def _generate_header(self): | 123 def generate_header(self): |
123 return HEADER_TEMPLATE % { | 124 return HEADER_TEMPLATE % { |
124 'class_name' : self.class_name, | 125 'class_name' : self.class_name, |
125 'license' : license.license_for_generated_cpp(), | 126 'license' : license.license_for_generated_cpp(), |
126 'method_declarations' : "\n".join(map(self._method_declaration, self
._all_features)), | 127 'method_declarations' : "\n".join(map(self._method_declaration, self
._all_features)), |
127 'storage_declarations' : "\n".join(map(self._storage_declarations, s
elf._non_custom_features)), | 128 'storage_declarations' : "\n".join(map(self._storage_declarations, s
elf._non_custom_features)), |
128 } | 129 } |
129 | 130 |
130 def _storage_definition(self, feature): | 131 def _storage_definition(self, feature): |
131 definition = "bool RuntimeEnabledFeatures::is%(name)sEnabled = %(default
)s;" % feature | 132 definition = "bool RuntimeEnabledFeatures::is%(name)sEnabled = %(default
)s;" % feature |
132 return self._wrap_with_condition(definition, feature['condition']) | 133 return self._wrap_with_condition(definition, feature['condition']) |
133 | 134 |
134 def _generate_implementation(self): | 135 def generate_implementation(self): |
135 return IMPLEMENTATION_TEMPLATE % { | 136 return IMPLEMENTATION_TEMPLATE % { |
136 'class_name' : self.class_name, | 137 'class_name' : self.class_name, |
137 'license' : license.license_for_generated_cpp(), | 138 'license' : license.license_for_generated_cpp(), |
138 'storage_definitions' : "\n".join(map(self._storage_definition, self
._non_custom_features)), | 139 'storage_definitions' : "\n".join(map(self._storage_definition, self
._non_custom_features)), |
139 } | 140 } |
140 | 141 |
141 def _forcibly_create_text_file_at_path_with_contents(self, file_path, conten
ts): | |
142 # FIXME: This method can be made less force-full anytime after 6/1/2013. | |
143 # A gyp error was briefly checked into the tree, causing | |
144 # a directory to have been generated in place of one of | |
145 # our output files. Clean up after that error so that | |
146 # all users don't need to clobber their output directories. | |
147 shutil.rmtree(file_path, ignore_errors=True) | |
148 # The build system should ensure our output directory exists, but just i
n case. | |
149 directory = os.path.dirname(file_path) | |
150 if not os.path.exists(directory): | |
151 os.makedirs(directory) | |
152 | |
153 with open(file_path, "w") as file_to_write: | |
154 file_to_write.write(contents) | |
155 | |
156 def write_header(self, output_dir): | |
157 header_path = os.path.join(output_dir, self.class_name + ".h") | |
158 self._forcibly_create_text_file_at_path_with_contents(header_path, self.
_generate_header()) | |
159 | |
160 def write_implmentation(self, output_dir): | |
161 implmentation_path = os.path.join(output_dir, self.class_name + ".cpp") | |
162 self._forcibly_create_text_file_at_path_with_contents(implmentation_path
, self._generate_implementation()) | |
163 | |
164 | |
165 class MakeRuntimeFeatures(object): | |
166 def main(self, argv): | |
167 script_name = os.path.basename(argv[0]) | |
168 args = argv[1:] | |
169 if len(args) < 1: | |
170 print "USAGE: %i INPUT_FILE [OUTPUT_DIRECTORY]" % script_name | |
171 exit(1) | |
172 output_dir = args[1] if len(args) > 1 else os.getcwd() | |
173 | |
174 writer = RuntimeFeatureWriter(args[0]) | |
175 writer.write_header(output_dir) | |
176 writer.write_implmentation(output_dir) | |
177 | |
178 | 142 |
179 if __name__ == "__main__": | 143 if __name__ == "__main__": |
180 MakeRuntimeFeatures().main(sys.argv) | 144 in_generator.Maker(RuntimeFeatureWriter).main(sys.argv) |
OLD | NEW |