| OLD | NEW |
| (Empty) |
| 1 # Copyright (C) 2013 Google Inc. All rights reserved. | |
| 2 # | |
| 3 # Redistribution and use in source and binary forms, with or without | |
| 4 # modification, are permitted provided that the following conditions are | |
| 5 # met: | |
| 6 # | |
| 7 # * Redistributions of source code must retain the above copyright | |
| 8 # notice, this list of conditions and the following disclaimer. | |
| 9 # * Redistributions in binary form must reproduce the above | |
| 10 # copyright notice, this list of conditions and the following disclaimer | |
| 11 # in the documentation and/or other materials provided with the | |
| 12 # distribution. | |
| 13 # * Neither the name of Google Inc. nor the names of its | |
| 14 # contributors may be used to endorse or promote products derived from | |
| 15 # this software without specific prior written permission. | |
| 16 # | |
| 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 28 | |
| 29 import os.path | |
| 30 import re | |
| 31 | |
| 32 from in_generator import Maker | |
| 33 import in_generator | |
| 34 import license | |
| 35 import name_utilities | |
| 36 | |
| 37 | |
| 38 HEADER_TEMPLATE = """%(license)s | |
| 39 | |
| 40 #ifndef %(namespace)s%(suffix)sHeaders_h | |
| 41 #define %(namespace)s%(suffix)sHeaders_h | |
| 42 %(base_header_for_suffix)s | |
| 43 %(includes)s | |
| 44 | |
| 45 #endif // %(namespace)s%(suffix)sHeaders_h | |
| 46 """ | |
| 47 | |
| 48 | |
| 49 INTERFACES_HEADER_TEMPLATE = """%(license)s | |
| 50 | |
| 51 #ifndef %(namespace)s%(suffix)sInterfaces_h | |
| 52 #define %(namespace)s%(suffix)sInterfaces_h | |
| 53 %(base_header_for_suffix)s | |
| 54 %(declare_conditional_macros)s | |
| 55 | |
| 56 #define %(macro_style_name)s_INTERFACES_FOR_EACH(macro) \\ | |
| 57 \\ | |
| 58 %(unconditional_macros)s | |
| 59 \\ | |
| 60 %(conditional_macros)s | |
| 61 | |
| 62 #endif // %(namespace)s%(suffix)sInterfaces_h | |
| 63 """ | |
| 64 | |
| 65 | |
| 66 class Writer(in_generator.Writer): | |
| 67 def __init__(self, in_file_path): | |
| 68 super(Writer, self).__init__(in_file_path) | |
| 69 self.namespace = self.in_file.parameters['namespace'].strip('"') | |
| 70 self.suffix = self.in_file.parameters['suffix'].strip('"') | |
| 71 self._entries_by_conditional = {} | |
| 72 self._unconditional_entries = [] | |
| 73 self._validate_entries() | |
| 74 self._sort_entries_by_conditional() | |
| 75 self._outputs = {(self.namespace + self.suffix + "Headers.h"): self.gene
rate_headers_header, | |
| 76 (self.namespace + self.suffix + "Interfaces.h"): self.g
enerate_interfaces_header, | |
| 77 } | |
| 78 | |
| 79 def _validate_entries(self): | |
| 80 # If there is more than one entry with the same script name, only the fi
rst one will ever | |
| 81 # be hit in practice, and so we'll silently ignore any properties reques
ted for the second | |
| 82 # (like RuntimeEnabled - see crbug.com/332588). | |
| 83 entries_by_script_name = dict() | |
| 84 for entry in self.in_file.name_dictionaries: | |
| 85 script_name = name_utilities.script_name(entry) | |
| 86 if script_name in entries_by_script_name: | |
| 87 self._fatal('Multiple entries with script_name=%(script_name)s:
%(name1)s %(name2)s' % { | |
| 88 'script_name': script_name, | |
| 89 'name1': entry['name'], | |
| 90 'name2': entries_by_script_name[script_name]['name']}) | |
| 91 entries_by_script_name[script_name] = entry | |
| 92 | |
| 93 def _fatal(self, message): | |
| 94 print 'FATAL ERROR: ' + message | |
| 95 exit(1) | |
| 96 | |
| 97 def _sort_entries_by_conditional(self): | |
| 98 unconditional_names = set() | |
| 99 for entry in self.in_file.name_dictionaries: | |
| 100 conditional = entry['Conditional'] | |
| 101 if not conditional: | |
| 102 cpp_name = name_utilities.cpp_name(entry) | |
| 103 if cpp_name in unconditional_names: | |
| 104 continue | |
| 105 unconditional_names.add(cpp_name) | |
| 106 self._unconditional_entries.append(entry) | |
| 107 continue | |
| 108 for entry in self.in_file.name_dictionaries: | |
| 109 cpp_name = name_utilities.cpp_name(entry) | |
| 110 if cpp_name in unconditional_names: | |
| 111 continue | |
| 112 conditional = entry['Conditional'] | |
| 113 if not conditional in self._entries_by_conditional: | |
| 114 self._entries_by_conditional[conditional] = [] | |
| 115 self._entries_by_conditional[conditional].append(entry) | |
| 116 | |
| 117 def _headers_header_include_path(self, entry): | |
| 118 if entry['ImplementedAs']: | |
| 119 path = os.path.dirname(entry['name']) | |
| 120 if len(path): | |
| 121 path += '/' | |
| 122 path += entry['ImplementedAs'] | |
| 123 else: | |
| 124 path = entry['name'] | |
| 125 return path + '.h' | |
| 126 | |
| 127 def _headers_header_includes(self, entries): | |
| 128 includes = dict() | |
| 129 for entry in entries: | |
| 130 cpp_name = name_utilities.cpp_name(entry) | |
| 131 # Avoid duplicate includes. | |
| 132 if cpp_name in includes: | |
| 133 continue | |
| 134 if self.suffix == 'Modules': | |
| 135 subdir_name = 'modules' | |
| 136 else: | |
| 137 subdir_name = 'core' | |
| 138 include = '#include "%(path)s"\n#include "bindings/%(subdir_name)s/v
8/V8%(script_name)s.h"' % { | |
| 139 'path': self._headers_header_include_path(entry), | |
| 140 'script_name': name_utilities.script_name(entry), | |
| 141 'subdir_name': subdir_name, | |
| 142 } | |
| 143 includes[cpp_name] = self.wrap_with_condition(include, entry['Condit
ional']) | |
| 144 return includes.values() | |
| 145 | |
| 146 def generate_headers_header(self): | |
| 147 base_header_for_suffix = '' | |
| 148 if self.suffix: | |
| 149 base_header_for_suffix = '\n#include "core/%(namespace)sHeaders.h"\n
' % {'namespace': self.namespace} | |
| 150 return HEADER_TEMPLATE % { | |
| 151 'license': license.license_for_generated_cpp(), | |
| 152 'namespace': self.namespace, | |
| 153 'suffix': self.suffix, | |
| 154 'base_header_for_suffix': base_header_for_suffix, | |
| 155 'includes': '\n'.join(self._headers_header_includes(self.in_file.nam
e_dictionaries)), | |
| 156 } | |
| 157 | |
| 158 def _declare_one_conditional_macro(self, conditional, entries): | |
| 159 macro_name = '%(macro_style_name)s_INTERFACES_FOR_EACH_%(conditional)s'
% { | |
| 160 'macro_style_name': name_utilities.to_macro_style(self.namespace + s
elf.suffix), | |
| 161 'conditional': conditional, | |
| 162 } | |
| 163 return self.wrap_with_condition("""#define %(macro_name)s(macro) \\ | |
| 164 %(declarations)s | |
| 165 | |
| 166 #else | |
| 167 #define %(macro_name)s(macro)""" % { | |
| 168 'macro_name': macro_name, | |
| 169 'declarations': '\n'.join(sorted(set([ | |
| 170 ' macro(%(cpp_name)s) \\' % {'cpp_name': name_utilities.cpp_n
ame(entry)} | |
| 171 for entry in entries]))), | |
| 172 }, conditional) | |
| 173 | |
| 174 def _declare_conditional_macros(self): | |
| 175 return '\n'.join([ | |
| 176 self._declare_one_conditional_macro(conditional, entries) | |
| 177 for conditional, entries in self._entries_by_conditional.items()]) | |
| 178 | |
| 179 def _unconditional_macro(self, entry): | |
| 180 return ' macro(%(cpp_name)s) \\' % {'cpp_name': name_utilities.cpp_na
me(entry)} | |
| 181 | |
| 182 def _conditional_macros(self, conditional): | |
| 183 return ' %(macro_style_name)s_INTERFACES_FOR_EACH_%(conditional)s(mac
ro) \\' % { | |
| 184 'macro_style_name': name_utilities.to_macro_style(self.namespace + s
elf.suffix), | |
| 185 'conditional': conditional, | |
| 186 } | |
| 187 | |
| 188 def generate_interfaces_header(self): | |
| 189 base_header_for_suffix = '' | |
| 190 if self.suffix: | |
| 191 base_header_for_suffix = '\n#include "core/%(namespace)sInterfaces.h
"\n' % {'namespace': self.namespace} | |
| 192 return INTERFACES_HEADER_TEMPLATE % { | |
| 193 'license': license.license_for_generated_cpp(), | |
| 194 'namespace': self.namespace, | |
| 195 'suffix': self.suffix, | |
| 196 'base_header_for_suffix': base_header_for_suffix, | |
| 197 'macro_style_name': name_utilities.to_macro_style(self.namespace + s
elf.suffix), | |
| 198 'declare_conditional_macros': self._declare_conditional_macros(), | |
| 199 'unconditional_macros': '\n'.join(sorted(set(map(self._unconditional
_macro, self._unconditional_entries)))), | |
| 200 'conditional_macros': '\n'.join(map(self._conditional_macros, self._
entries_by_conditional.keys())), | |
| 201 } | |
| OLD | NEW |