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

Side by Side Diff: ppapi/generators/apiidlc.py

Issue 9359040: WIP IDL-IPC2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Checkpoint before going back to returning ListValue via ExtensionMsg_Response. Created 8 years, 9 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 | « ppapi/apps_tests/test3.idl ('k') | ppapi/generators/apps_example.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2
3 import getopt
4 import os
5 import sys
6
7 from Cheetah.Template import Template
8 from datetime import datetime
9 from idl_option import ParseOptions
10 from idl_parser import IDLParser
11
12 class APIArgument:
13 def __init__(self, name, type):
14 self.name = name
15 self.type = type
16
17 def __str__(self):
18 return "%s: %s" % (self.type, self.name)
19
20 def mapped_type(self):
21 if self.type == "long":
22 return "int"
23 if self.type == "DOMString":
24 return "std::string"
25 if self.type.endswith("Options"):
26 return "ListValue"
27 return self.type
28
29 def mapped_arg_type(self):
30 if self.type == "long":
31 return "int"
32 if self.type == "DOMString":
33 return "const std::string&"
34 if self.type.endswith("Options"):
35 return "const ListValue&"
36 return self.type
37
38 class APIFunction:
39 def __init__(self, name, arguments, return_values, family=None,
40 is_experimental=False):
41 self.family = family
42 self.name = name
43 self.arguments = arguments
44 self.return_values = return_values
45 self.is_experimental = is_experimental
46
47 def class_name(self):
48 return self.family.name + self.name
49
50 def dotted_name(self):
51 dotted_name = self.family.name.lower() + '.' + self.name.lower()
52 if self.is_experimental:
53 return 'experimental.' + dotted_name
54 else:
55 return dotted_name
56
57 def __str__(self):
58 s = self.name + ": "
59 for argument in self.arguments:
60 s += str(argument) + ", "
61 s += " <- "
62 for return_value in self.return_values:
63 s += str(return_value) + ", "
64 return s
65
66 class APIFamily:
67 def __init__(self, name, functions):
68 self.name = name
69 self.functions = functions
70 for f in functions:
71 f.family = self
72
73 def __str__(self):
74 s = self.name + ": "
75 for function in self.functions:
76 s += str(function) + "; "
77 return s
78
79 def header_path(self):
80 return "chrome/browser/extensions/api/%(ln)s/%(ln)s_api.h" % {
81 'ln': self.name.lower() }
82
83 class TemplateHelper:
84 def __init__(self, template, families, input_dir,
85 output_filename, output_dir):
86 self.template = template
87 self.families = families
88 self.dirname = output_dir
89 self.basename = output_filename
90 self.pathname = os.path.join(output_dir, output_filename)
91
92 self.template.families = self.families
93 self.template.basename = self.basename
94 self.template.dirname = self.dirname
95 self.template.output_file = self.output_file
96 self.template.pathname = self.pathname
97 self.template.year = datetime.today().year
98
99 if self.basename.endswith(".cc"):
100 self.template.header_pathname = "chrome/%s" % (
101 self.basename.replace(".cc", ".h"))
102
103 path_parts = os.path.join(input_dir,
104 output_filename).replace('.', '/').split('/')
105 path_parts_upper = ['CHROME']
106 for part in path_parts:
107 if len(part.strip()) != 0:
108 path_parts_upper.append(part.upper())
109 self.template.guard = '_'.join(path_parts_upper) + '_'
110
111 def output_file(self):
112 self.make_path(self.dirname)
113 f = open(self.pathname, 'w+')
114 f.write(str(self.template))
115 f.close()
116
117 def make_path(self, path):
118 try:
119 os.makedirs(path)
120 except OSError, e:
121 if e.errno == 17:
122 pass
123 else:
124 raise e
125
126 def generate_file(template_filename, families, input_dir, output_dir):
127 output_filename = template_filename.replace(".tmpl", "")
128 template_pathname = os.path.join(input_dir, template_filename)
129 th = TemplateHelper(Template(file=template_pathname), families,
130 input_dir, output_filename, output_dir)
131 th.output_file()
132
133 def read_idl(idl_filename):
134 f = open(idl_filename, 'r')
135 contents = f.read()
136 f.close()
137
138 parser = IDLParser()
139 return parser.ParseData(contents, idl_filename)
140
141 def member_to_function(member):
142 if member.cls != "Member":
143 return None
144
145 name = member.GetProperty("NAME")
146 arguments = []
147 for member_part in member.children:
148 if member_part.cls != "Callspec":
149 continue
150 for child in member_part.children:
151 if child.cls == "Param":
152 # The last param is usually a callback, which is implied.
153 if child.GetProperty("NAME") == "callBack":
154 continue
155 arguments.append(APIArgument(child.GetProperty("NAME"),
156 child.GetProperty("TYPEREF")))
157 return APIFunction(name.capitalize(), arguments, [])
158
159 def nodes_to_families(nodes):
160 families = []
161 for node in nodes:
162 namespace = node.GetProperty("NAME")
163 if namespace.startswith("experimental."):
164 is_experimental = True
165 namespace = namespace.replace("experimental.", "")
166 else:
167 is_experimental = False
168 namespace = namespace.capitalize()
169 functions = []
170 for child in node.children:
171 if child.cls == "Interface":
172 if child.GetProperty("NAME") == "Functions":
173 for member in child.children:
174 function = member_to_function(member)
175 if function is not None:
176 function.is_experimental = is_experimental
177 functions.append(function)
178 families.append(APIFamily(namespace, functions))
179 return families
180
181 def main():
182 try:
183 opts, args = getopt.getopt(sys.argv[1:], "hi:o:d:",
184 ["help", "input=", "output=", "idl="])
185 except getopt.GetoptError, err:
186 print str(err)
187 usage()
188 sys.exit(2)
189
190 input_dir = None
191 output_dir = None
192 idl_filename = None
193
194 verbose = False
195 for o, a in opts:
196 if o in ("-h", "--help"):
197 usage()
198 sys.exit(0)
199 elif o in ("-i", "--input"):
200 input_dir = a
201 elif o in ("-o", "--output"):
202 output_dir = a
203 elif o in ("-d", "--idl"):
204 idl_filename = a
205 else:
206 assert False, "unhandled option: %s" % o
207
208 if (input_dir is None):
209 print "ERROR: Must specify input_dir."
210 usage()
211 sys.exit(2)
212
213 if (output_dir is None):
214 print "ERROR: Must specify output_dir."
215 usage()
216 sys.exit(2)
217
218 if (idl_filename is None):
219 print "ERROR: Must specify idl."
220 usage()
221 sys.exit(2)
222
223 nodes = read_idl(idl_filename)
224 families = nodes_to_families(nodes)
225
226 for arg in args:
227 generate_file(arg, families, input_dir, output_dir)
228
229 sys.exit(0)
230
231 def usage():
232 print """
233 Takes an input directory, an output directory, an IDL, and one or more names of
234 template files in the input directory, and generates files from those templates
235 in the output directory.
236
237 Usage: apiidlc -i input_directory -o output_directory -d idl_filename
238 [file1.tmpl] [file2.tmpl] ...
239 """
240
241 if __name__ == "__main__":
242 main()
OLDNEW
« no previous file with comments | « ppapi/apps_tests/test3.idl ('k') | ppapi/generators/apps_example.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698