Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1029)

Side by Side Diff: tools/nixysa/nixysa/codegen.py

Issue 2043006: WTF NPAPI extension. Early draft. Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/nixysa/nixysa/codegen.bat ('k') | tools/nixysa/nixysa/codegen.sh » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 #!/usr/bin/python2.4
2 #
3 # Copyright 2008 Google Inc.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 """Code generator
18
19 This file is the main entry point for the code generator.
20 To use:
21 codegen.py --output-dir=output-path --generate=npapi file1.idl file2.idl ...
22 """
23
24 import glob
25 import imp
26 # Use hashlib if present (Python 2.5 and up), otherwise fall back to md5.
27 try:
28 import hashlib
29 except ImportError:
30 import md5
31 import os
32 import sys
33
34 import gflags
35
36 # local imports
37 import idl_parser
38 import locking
39 import log
40 import syntax_tree
41
42 # default supported generators
43 import header_generator
44 import cpp_header_generator
45 import js_header_generator
46 import npapi_generator
47
48 # default supported binding models
49 import pod_binding
50 import enum_binding
51 import callback_binding
52 import by_value_binding
53 import by_pointer_binding
54 import unsized_array_binding
55 import nullable_binding
56
57 generators = {'header': header_generator,
58 'cppheader': cpp_header_generator,
59 'jsheader': js_header_generator,
60 'npapi': npapi_generator}
61
62 binding_models = {'pod': pod_binding,
63 'callback': callback_binding,
64 'enum': enum_binding,
65 'by_value': by_value_binding,
66 'by_pointer': by_pointer_binding,
67 'unsized_array': unsized_array_binding,
68 'nullable': nullable_binding}
69
70
71 FLAGS = gflags.FLAGS
72 gflags.DEFINE_multistring('binding-module', [], 'include a binding model'
73 ' module. Value is name:path where \'name\' is the'
74 ' binding model name, and \'path\' is the binding'
75 ' model module path.')
76
77 gflags.DEFINE_multistring('generator-module', [], 'include a generator module.'
78 ' Value is name:path where \'name\' is the generator'
79 ' name, and \'path\' is the generator module path.')
80
81 gflags.DEFINE_multistring('generate', [], 'the generator to use')
82 gflags.DEFINE_string('output-dir', '.', 'the output directory')
83
84 gflags.DEFINE_boolean('exclusive-lock', False, 'Use file locking to make sure'
85 ' there is only one instance running at a time.')
86 gflags.DEFINE_boolean('force', False, 'force generation even if the source'
87 ' files have not changed')
88 gflags.DEFINE_boolean('force-docs', False, 'force all members to have'
89 ' documentation blocks or else raise an exception.')
90 gflags.DEFINE_boolean('no-return-docs', False, 'remove docs marked as'
91 ' noreturndocs.')
92 gflags.DEFINE_boolean('overloaded-function-docs', False,
93 'generate special overloaded function docs.')
94 gflags.DEFINE_boolean('properties-equal-undefined', False,
95 'Emit class.prototype.property = undefined;')
96
97 class NativeType(syntax_tree.Definition):
98 defn_type = 'Native'
99
100 def __init__(self, source, attributes, name, podtype):
101 syntax_tree.Definition.__init__(self, source, attributes, name)
102 self.podtype = podtype
103 self.is_type = True
104
105 def LookUpBindingModel(self):
106 """Implementation of LookUpBindingModel for NativeType."""
107 return 'pod'
108
109
110 def GetStdNamespace():
111 pod_attributes = {'binding_model': 'pod'}
112 source_file = idl_parser.File('<internal>')
113 source_file.header = "common.h"
114 source_file.npapi_cpp = None
115 source_file.npapi_header = None
116 source = idl_parser.SourceLocation(source_file, 0)
117 defn_list = [NativeType(source, pod_attributes, 'string', 'string'),
118 NativeType(source, pod_attributes, 'wstring', 'wstring')]
119 return syntax_tree.Namespace(source, [], 'std', defn_list)
120
121
122 def GetNativeTypes():
123 pod_attributes = {'binding_model': 'pod'}
124 source_file = idl_parser.File('<internal>')
125 source_file.header = None
126 source_file.npapi_cpp = None
127 source_file.npapi_header = None
128 source = idl_parser.SourceLocation(source_file, 0)
129 return [NativeType(source, pod_attributes, 'void', 'void'),
130 NativeType(source, pod_attributes, 'int', 'int'),
131 NativeType(source, pod_attributes, 'unsigned int', 'int'),
132 NativeType(source, pod_attributes, 'size_t', 'int'),
133 NativeType(source, pod_attributes, 'bool', 'bool'),
134 NativeType(source, pod_attributes, 'float', 'float'),
135 NativeType(source, pod_attributes, 'double', 'float'),
136 NativeType(source, pod_attributes, 'Variant', 'variant'),
137 GetStdNamespace()]
138
139
140 def AddModulesFromFlags(table, flag_values, md5_hash):
141 for entry in flag_values:
142 string_list = entry.split(':')
143 name = string_list[0]
144 path = ':'.join(string_list[1:])
145 try:
146 # hash the extra modules that we load
147 md5_hash.update(open(path).read())
148 table[name] = imp.load_source(name, path)
149 except IOError:
150 print 'Could not load module %s.' % path
151 raise
152
153
154 def main(argv):
155 files = argv[1:]
156 # generate a hash of all the inputs to figure out if we need to re-generate
157 # the outputs.
158 # Use hashlib if present (Python 2.5 and up), otherwise fall back to md5.
159 if globals().has_key('hashlib'):
160 md5_hash = hashlib.md5()
161 else:
162 md5_hash = md5.new();
163 # hash the input files and the source python files (globbing *.py in the
164 # directory of this file)
165 for source_file in files + glob.glob(os.path.join(os.path.dirname(__file__),
166 '*.py')):
167 md5_hash.update(open(source_file).read())
168 # hash the options since they may affect the output
169 for s in (FLAGS['generator-module'].value + FLAGS['binding-module'].value +
170 FLAGS.generate + [FLAGS['output-dir'].value]):
171 md5_hash.update(s)
172
173 # import generator and binding model modules, and hash them
174 AddModulesFromFlags(generators, FLAGS['generator-module'].value, md5_hash)
175 AddModulesFromFlags(binding_models, FLAGS['binding-module'].value, md5_hash)
176
177 output_dir = FLAGS['output-dir'].value
178 if not os.path.isdir(output_dir):
179 os.makedirs(output_dir)
180
181 hash_filename = os.path.join(output_dir, 'hash')
182 hash_value = md5_hash.hexdigest()
183 if not FLAGS.force:
184 try:
185 hash_file = open(hash_filename, 'r')
186 # Don't read while others are writing...
187 if FLAGS['exclusive-lock'].value:
188 locking.lockf(hash_file, locking.LOCK_SH)
189
190 old_hash = hash_file.read()
191
192 if FLAGS['exclusive-lock'].value:
193 locking.lockf(hash_file, locking.LOCK_UN)
194 hash_file.close()
195
196 if hash_value == old_hash:
197 print "Source files haven't changed: nothing to generate."
198 return
199 except IOError:
200 # Could not load the hash file, so there must be stuff to
201 # generate.
202 pass
203
204 hash_file = open(hash_filename, 'w')
205 if FLAGS['exclusive-lock'].value:
206 locking.lockf(hash_file, locking.LOCK_EX)
207
208 my_parser = idl_parser.Parser(output_dir)
209 pairs = []
210 for f in files:
211 idl_file = idl_parser.File(f)
212 defn = my_parser.Parse(idl_file)
213 pairs.append((idl_file, defn))
214 definitions = sum([defn for (f, defn) in pairs], []) + GetNativeTypes()
215 global_namespace = syntax_tree.Namespace(None, [], '', definitions)
216 syntax_tree.FinalizeObjects(global_namespace, binding_models)
217
218 writer_list = []
219 for generator_name in FLAGS.generate:
220 try:
221 generator = generators[generator_name]
222 writer_list += generator.ProcessFiles(output_dir, pairs, global_namespace)
223 except KeyError:
224 print 'Unknown generator %s.' % generator_name
225 raise
226 for writer in writer_list:
227 writer.Write()
228
229 # Save hash for next time
230 hash_file.write(hash_value)
231 if FLAGS['exclusive-lock'].value:
232 locking.lockf(hash_file, locking.LOCK_UN)
233 hash_file.close()
234 log.FailIfHaveErrors()
235
236
237 if __name__ == '__main__':
238 main(FLAGS(sys.argv))
OLDNEW
« no previous file with comments | « tools/nixysa/nixysa/codegen.bat ('k') | tools/nixysa/nixysa/codegen.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698