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 |
| 31 |
| 32 def generate_empty_header_and_cpp(target_interface_name, output_headers_director
y, output_directory): |
| 33 header_basename = 'V8%s.h' % target_interface_name |
| 34 cpp_basename = 'V8%s.cpp' % target_interface_name |
| 35 header_fullname = os.path.join(output_headers_directory, header_basename) |
| 36 cpp_fullname = os.path.join(output_directory, cpp_basename) |
| 37 contents = """/* |
| 38 This file is generated just to tell build scripts that {header_basename} and |
| 39 {cpp_basename} are created for {target_interface_name}.idl, and thus |
| 40 prevent the build scripts from trying to generate {header_basename} and |
| 41 {cpp_basename} at every build. This file must not be tried to compile. |
| 42 */ |
| 43 """.format(**locals) |
| 44 # Better wording: |
| 45 # contents = """/* |
| 46 # This file is generated to tell build scripts that %(header_basename) and |
| 47 # %(cpp_basename) have been created for %(target_interface_name).idl, and th
us |
| 48 # prevent the build scripts from trying to generate them on every build. |
| 49 # This file must not be compiled. |
| 50 # */ |
| 51 # """ % locals() |
| 52 with open(header_fullname, 'w') as header_file: |
| 53 header_file.write(contents) |
| 54 with open(cpp_fullname, 'w') as cpp_file: |
| 55 cpp_file.write(contents) |
| 56 |
| 57 |
| 58 def write_file(filename, contents, only_if_changed): |
| 59 if only_if_changed and os.path.isfile(filename): |
| 60 with open(filename) as existing_file: |
| 61 old_contents = ''.join(list(existing_file)) |
| 62 if contents == old_contents: |
| 63 return |
| 64 with open(filename, 'w') as new_file: |
| 65 new_file.write(contents) |
| 66 |
| 67 |
| 68 class Block(): |
| 69 """Block of code, separated as header + contents + footer. |
| 70 |
| 71 header, contents, and footer are each a list, |
| 72 consisting of strings (separate lines, embedded newlines ok) and Blocks. |
| 73 """ |
| 74 def __init__(self, name=None, header=None, footer=None): |
| 75 self.name = name or 'Anonymous block' |
| 76 self.header = [] |
| 77 self.contents = [] |
| 78 self.footer = [] |
| 79 if header is not None: |
| 80 self.header.append(header) |
| 81 if footer is not None: |
| 82 self.footer.append(footer) |
| 83 |
| 84 def add_header(self, header=None): |
| 85 if header is not None: |
| 86 self.header.append(header) |
| 87 |
| 88 def add(self, content=None): |
| 89 if content is not None: |
| 90 self.contents.append(content) |
| 91 |
| 92 def add_footer(self, footer=None): |
| 93 if footer is not None: |
| 94 self.footer.append(footer) |
| 95 |
| 96 def __str__(self): |
| 97 # FIXME: fill in! |
| 98 return '' |
| 99 |
| 100 def verbose_string(self): |
| 101 # FIXME: fill in! |
| 102 return ''.join(self.header) |
| 103 |
| 104 |
| 105 class CodeGenerator(): |
| 106 def __init__(self, document, dependent_idl_files, options): |
| 107 self.document = document |
| 108 self.dependent_idl_files = dependent_idl_files |
| 109 self.verbose = options.verbose |
| 110 self.write_file_only_if_changed = options.write_file_only_if_changed |
| 111 |
| 112 self.header = {} |
| 113 self.implementation = {} |
| 114 self.header_includes = {} |
| 115 self.implied_includes = set() |
| 116 |
| 117 def write_interfaces(self, output_directory, output_headers_directory): |
| 118 interface_list = self.document.interfaces |
| 119 for interface in interface_list: |
| 120 if self.verbose: |
| 121 print 'Generating bindings code for IDL interface "%s"...' % int
erface['name'] |
| 122 self.generate_interface(interface) |
| 123 self.write_data(interface, output_directory, output_headers_director
y) |
| 124 |
| 125 def generate_interface(self, interface): |
| 126 # FIXME: fill in! |
| 127 self.header['root'] = Block('ROOT') |
| 128 self.implementation['root'] = Block('ROOT') |
| 129 self.implementation['includes'] = Block('Includes') |
| 130 self.make_implied_includes_explicit(interface) |
| 131 |
| 132 def make_implied_includes_explicit(self, interface): |
| 133 """Make implied includes into explicit include lines. |
| 134 |
| 135 Clears implied_includes, as now explicit.""" |
| 136 # FIXME: do not treat main header specially |
| 137 main_include = 'V8%s.h' % interface.name |
| 138 for include in sorted(self.implied_includes): |
| 139 if include == main_include: |
| 140 continue |
| 141 self.implementation['includes'].add('#include "%s"\n' % include) |
| 142 if not interface.is_callback: |
| 143 self.implementation['includes'].add('\n') |
| 144 self.implied_includes = set() |
| 145 |
| 146 def write_data(self, interface, output_directory, output_headers_directory): |
| 147 name = interface.name |
| 148 header_filename = '%s/V8%s.h' % (output_headers_directory, name) |
| 149 cpp_filename = '%s/V8%s.cpp' % (output_directory, name) |
| 150 write_file(header_filename, str(self.header['root']), self.write_file_on
ly_if_changed) |
| 151 write_file(cpp_filename, str(self.implementation['root']), self.write_fi
le_only_if_changed) |
OLD | NEW |