| OLD | NEW | 
|---|
| (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() | 
| OLD | NEW | 
|---|