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

Unified 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, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/apps_tests/test3.idl ('k') | ppapi/generators/apps_example.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/generators/apiidlc.py
diff --git a/ppapi/generators/apiidlc.py b/ppapi/generators/apiidlc.py
new file mode 100644
index 0000000000000000000000000000000000000000..19e92b2463eae9452d9a5160ae56cbeb1d5d49ef
--- /dev/null
+++ b/ppapi/generators/apiidlc.py
@@ -0,0 +1,242 @@
+#!/usr/bin/env python
+
+import getopt
+import os
+import sys
+
+from Cheetah.Template import Template
+from datetime import datetime
+from idl_option import ParseOptions
+from idl_parser import IDLParser
+
+class APIArgument:
+ def __init__(self, name, type):
+ self.name = name
+ self.type = type
+
+ def __str__(self):
+ return "%s: %s" % (self.type, self.name)
+
+ def mapped_type(self):
+ if self.type == "long":
+ return "int"
+ if self.type == "DOMString":
+ return "std::string"
+ if self.type.endswith("Options"):
+ return "ListValue"
+ return self.type
+
+ def mapped_arg_type(self):
+ if self.type == "long":
+ return "int"
+ if self.type == "DOMString":
+ return "const std::string&"
+ if self.type.endswith("Options"):
+ return "const ListValue&"
+ return self.type
+
+class APIFunction:
+ def __init__(self, name, arguments, return_values, family=None,
+ is_experimental=False):
+ self.family = family
+ self.name = name
+ self.arguments = arguments
+ self.return_values = return_values
+ self.is_experimental = is_experimental
+
+ def class_name(self):
+ return self.family.name + self.name
+
+ def dotted_name(self):
+ dotted_name = self.family.name.lower() + '.' + self.name.lower()
+ if self.is_experimental:
+ return 'experimental.' + dotted_name
+ else:
+ return dotted_name
+
+ def __str__(self):
+ s = self.name + ": "
+ for argument in self.arguments:
+ s += str(argument) + ", "
+ s += " <- "
+ for return_value in self.return_values:
+ s += str(return_value) + ", "
+ return s
+
+class APIFamily:
+ def __init__(self, name, functions):
+ self.name = name
+ self.functions = functions
+ for f in functions:
+ f.family = self
+
+ def __str__(self):
+ s = self.name + ": "
+ for function in self.functions:
+ s += str(function) + "; "
+ return s
+
+ def header_path(self):
+ return "chrome/browser/extensions/api/%(ln)s/%(ln)s_api.h" % {
+ 'ln': self.name.lower() }
+
+class TemplateHelper:
+ def __init__(self, template, families, input_dir,
+ output_filename, output_dir):
+ self.template = template
+ self.families = families
+ self.dirname = output_dir
+ self.basename = output_filename
+ self.pathname = os.path.join(output_dir, output_filename)
+
+ self.template.families = self.families
+ self.template.basename = self.basename
+ self.template.dirname = self.dirname
+ self.template.output_file = self.output_file
+ self.template.pathname = self.pathname
+ self.template.year = datetime.today().year
+
+ if self.basename.endswith(".cc"):
+ self.template.header_pathname = "chrome/%s" % (
+ self.basename.replace(".cc", ".h"))
+
+ path_parts = os.path.join(input_dir,
+ output_filename).replace('.', '/').split('/')
+ path_parts_upper = ['CHROME']
+ for part in path_parts:
+ if len(part.strip()) != 0:
+ path_parts_upper.append(part.upper())
+ self.template.guard = '_'.join(path_parts_upper) + '_'
+
+ def output_file(self):
+ self.make_path(self.dirname)
+ f = open(self.pathname, 'w+')
+ f.write(str(self.template))
+ f.close()
+
+ def make_path(self, path):
+ try:
+ os.makedirs(path)
+ except OSError, e:
+ if e.errno == 17:
+ pass
+ else:
+ raise e
+
+def generate_file(template_filename, families, input_dir, output_dir):
+ output_filename = template_filename.replace(".tmpl", "")
+ template_pathname = os.path.join(input_dir, template_filename)
+ th = TemplateHelper(Template(file=template_pathname), families,
+ input_dir, output_filename, output_dir)
+ th.output_file()
+
+def read_idl(idl_filename):
+ f = open(idl_filename, 'r')
+ contents = f.read()
+ f.close()
+
+ parser = IDLParser()
+ return parser.ParseData(contents, idl_filename)
+
+def member_to_function(member):
+ if member.cls != "Member":
+ return None
+
+ name = member.GetProperty("NAME")
+ arguments = []
+ for member_part in member.children:
+ if member_part.cls != "Callspec":
+ continue
+ for child in member_part.children:
+ if child.cls == "Param":
+ # The last param is usually a callback, which is implied.
+ if child.GetProperty("NAME") == "callBack":
+ continue
+ arguments.append(APIArgument(child.GetProperty("NAME"),
+ child.GetProperty("TYPEREF")))
+ return APIFunction(name.capitalize(), arguments, [])
+
+def nodes_to_families(nodes):
+ families = []
+ for node in nodes:
+ namespace = node.GetProperty("NAME")
+ if namespace.startswith("experimental."):
+ is_experimental = True
+ namespace = namespace.replace("experimental.", "")
+ else:
+ is_experimental = False
+ namespace = namespace.capitalize()
+ functions = []
+ for child in node.children:
+ if child.cls == "Interface":
+ if child.GetProperty("NAME") == "Functions":
+ for member in child.children:
+ function = member_to_function(member)
+ if function is not None:
+ function.is_experimental = is_experimental
+ functions.append(function)
+ families.append(APIFamily(namespace, functions))
+ return families
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "hi:o:d:",
+ ["help", "input=", "output=", "idl="])
+ except getopt.GetoptError, err:
+ print str(err)
+ usage()
+ sys.exit(2)
+
+ input_dir = None
+ output_dir = None
+ idl_filename = None
+
+ verbose = False
+ for o, a in opts:
+ if o in ("-h", "--help"):
+ usage()
+ sys.exit(0)
+ elif o in ("-i", "--input"):
+ input_dir = a
+ elif o in ("-o", "--output"):
+ output_dir = a
+ elif o in ("-d", "--idl"):
+ idl_filename = a
+ else:
+ assert False, "unhandled option: %s" % o
+
+ if (input_dir is None):
+ print "ERROR: Must specify input_dir."
+ usage()
+ sys.exit(2)
+
+ if (output_dir is None):
+ print "ERROR: Must specify output_dir."
+ usage()
+ sys.exit(2)
+
+ if (idl_filename is None):
+ print "ERROR: Must specify idl."
+ usage()
+ sys.exit(2)
+
+ nodes = read_idl(idl_filename)
+ families = nodes_to_families(nodes)
+
+ for arg in args:
+ generate_file(arg, families, input_dir, output_dir)
+
+ sys.exit(0)
+
+def usage():
+ print """
+Takes an input directory, an output directory, an IDL, and one or more names of
+template files in the input directory, and generates files from those templates
+in the output directory.
+
+Usage: apiidlc -i input_directory -o output_directory -d idl_filename
+ [file1.tmpl] [file2.tmpl] ...
+"""
+
+if __name__ == "__main__":
+ main()
« 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