accessible/src/xpcom/AccEventGen.py

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 #!/usr/bin/env python
michael@0 2 #
michael@0 3 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 6
michael@0 7 import sys, os, xpidl, makeutils
michael@0 8
michael@0 9 def findIDL(includePath, interfaceFileName):
michael@0 10 for d in includePath:
michael@0 11 # Not os.path.join: we need a forward slash even on Windows because
michael@0 12 # this filename ends up in makedepend output.
michael@0 13 path = d + '/' + interfaceFileName
michael@0 14 if os.path.exists(path):
michael@0 15 return path
michael@0 16 raise BaseException("No IDL file found for interface %s "
michael@0 17 "in include path %r"
michael@0 18 % (interfaceFileName, includePath))
michael@0 19
michael@0 20 def loadEventIDL(parser, includePath, eventname):
michael@0 21 eventidl = ("nsIAccessible%s.idl" % eventname)
michael@0 22 idlFile = findIDL(includePath, eventidl)
michael@0 23 if not idlFile in makeutils.dependencies:
michael@0 24 makeutils.dependencies.append(idlFile)
michael@0 25 idl = p.parse(open(idlFile).read(), idlFile)
michael@0 26 idl.resolve(includePath, p)
michael@0 27 return idl
michael@0 28
michael@0 29 class Configuration:
michael@0 30 def __init__(self, filename):
michael@0 31 config = {}
michael@0 32 execfile(filename, config)
michael@0 33 self.simple_events = config.get('simple_events', [])
michael@0 34
michael@0 35 def readConfigFile(filename):
michael@0 36 return Configuration(filename)
michael@0 37
michael@0 38 def firstCap(str):
michael@0 39 return str[0].upper() + str[1:]
michael@0 40
michael@0 41 def writeAttributeParams(a):
michael@0 42 return ("%s a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
michael@0 43
michael@0 44 def print_header_file(fd, conf):
michael@0 45 fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n")
michael@0 46 fd.write("#ifndef _mozilla_a11y_generated_AccEvents_h_\n"
michael@0 47 "#define _mozilla_a11y_generated_AccEvents_h_\n\n")
michael@0 48 fd.write("#include \"nscore.h\"\n")
michael@0 49 fd.write("#include \"nsCOMPtr.h\"\n")
michael@0 50 fd.write("#include \"nsCycleCollectionParticipant.h\"\n")
michael@0 51 fd.write("#include \"nsString.h\"\n")
michael@0 52 for e in conf.simple_events:
michael@0 53 fd.write("#include \"nsIAccessible%s.h\"\n" % e)
michael@0 54 for e in conf.simple_events:
michael@0 55 idl = loadEventIDL(p, options.incdirs, e)
michael@0 56 for iface in filter(lambda p: p.kind == "interface", idl.productions):
michael@0 57 classname = ("xpcAcc%s" % e)
michael@0 58 baseinterfaces = interfaces(iface)
michael@0 59
michael@0 60 fd.write("\nclass %s MOZ_FINAL : public %s\n" % (classname, iface.name))
michael@0 61 fd.write("{\n")
michael@0 62 fd.write("public:\n")
michael@0 63
michael@0 64 attributes = allAttributes(iface)
michael@0 65 args = map(writeAttributeParams, attributes)
michael@0 66 fd.write(" %s(%s) :\n" % (classname, ", ".join(args)))
michael@0 67
michael@0 68 initializers = []
michael@0 69 for a in attributes:
michael@0 70 initializers.append("m%s(a%s)" % (firstCap(a.name), firstCap(a.name)))
michael@0 71 fd.write(" %s\n {}\n" % ", ".join(initializers))
michael@0 72 fd.write(" ~%s() {}\n\n" % classname)
michael@0 73 fd.write(" NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n")
michael@0 74 fd.write(" NS_DECL_CYCLE_COLLECTION_CLASS(%s)\n" % (classname))
michael@0 75
michael@0 76 for iface in filter(lambda i: i.name != "nsISupports", baseinterfaces):
michael@0 77 fd.write(" NS_DECL_%s\n" % iface.name.upper())
michael@0 78
michael@0 79 fd.write("private:\n")
michael@0 80 for a in attributes:
michael@0 81 fd.write(" %s\n" % attributeVariableTypeAndName(a))
michael@0 82 fd.write("};\n\n")
michael@0 83
michael@0 84 fd.write("#endif\n")
michael@0 85
michael@0 86 def interfaceAttributeTypes(idl):
michael@0 87 ifaces = filter(lambda p: p.kind == "interface", idl.productions)
michael@0 88 attributes = []
michael@0 89 for i in ifaces:
michael@0 90 ifaceAttributes = allAttributes(i)
michael@0 91 attributes.extend(ifaceAttributes)
michael@0 92 ifaceAttrs = filter(lambda a: a.realtype.nativeType("in").endswith("*"), attributes)
michael@0 93 return map(lambda a: a.realtype.nativeType("in").strip(" *"), ifaceAttrs)
michael@0 94
michael@0 95 def print_cpp(idl, fd, conf, eventname):
michael@0 96 for p in idl.productions:
michael@0 97 if p.kind == 'interface':
michael@0 98 write_cpp(eventname, p, fd)
michael@0 99
michael@0 100 def print_cpp_file(fd, conf):
michael@0 101 fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n")
michael@0 102 fd.write('#include "xpcAccEvents.h"\n')
michael@0 103
michael@0 104 includes = []
michael@0 105 for e in conf.simple_events:
michael@0 106 if not e in includes:
michael@0 107 includes.append(("nsIAccessible%s" % e))
michael@0 108
michael@0 109 types = []
michael@0 110 for e in conf.simple_events:
michael@0 111 idl = loadEventIDL(p, options.incdirs, e)
michael@0 112 types.extend(interfaceAttributeTypes(idl))
michael@0 113
michael@0 114 for c in types:
michael@0 115 fd.write("#include \"%s.h\"\n" % c)
michael@0 116
michael@0 117 fd.write("\n")
michael@0 118 for e in conf.simple_events:
michael@0 119 print_cpp(loadEventIDL(p, options.incdirs, e), fd, conf, e)
michael@0 120
michael@0 121 def attributeVariableTypeAndName(a):
michael@0 122 if a.realtype.nativeType('in').endswith('*'):
michael@0 123 l = ["nsCOMPtr<%s> m%s;" % (a.realtype.nativeType('in').strip('* '),
michael@0 124 firstCap(a.name))]
michael@0 125 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 126 l = ["nsString m%s;" % firstCap(a.name)]
michael@0 127 elif a.realtype.nativeType('in').count("nsACString"):
michael@0 128 l = ["nsCString m%s;" % firstCap(a.name)]
michael@0 129 else:
michael@0 130 l = ["%sm%s;" % (a.realtype.nativeType('in'),
michael@0 131 firstCap(a.name))]
michael@0 132 return ", ".join(l)
michael@0 133
michael@0 134 def writeAttributeGetter(fd, classname, a):
michael@0 135 fd.write("NS_IMETHODIMP\n")
michael@0 136 fd.write("%s::Get%s(" % (classname, firstCap(a.name)))
michael@0 137 if a.realtype.nativeType('in').endswith('*'):
michael@0 138 fd.write("%s** a%s" % (a.realtype.nativeType('in').strip('* '), firstCap(a.name)))
michael@0 139 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 140 fd.write("nsAString& a%s" % firstCap(a.name))
michael@0 141 elif a.realtype.nativeType('in').count("nsACString"):
michael@0 142 fd.write("nsACString& a%s" % firstCap(a.name))
michael@0 143 else:
michael@0 144 fd.write("%s*a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
michael@0 145 fd.write(")\n");
michael@0 146 fd.write("{\n");
michael@0 147 if a.realtype.nativeType('in').endswith('*'):
michael@0 148 fd.write(" NS_IF_ADDREF(*a%s = m%s);\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 149 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 150 fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 151 elif a.realtype.nativeType('in').count("nsACString"):
michael@0 152 fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 153 else:
michael@0 154 fd.write(" *a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 155 fd.write(" return NS_OK;\n");
michael@0 156 fd.write("}\n\n");
michael@0 157
michael@0 158 def interfaces(iface):
michael@0 159 interfaces = []
michael@0 160 while iface.base:
michael@0 161 interfaces.append(iface)
michael@0 162 iface = iface.idl.getName(iface.base, iface.location)
michael@0 163 interfaces.append(iface)
michael@0 164 interfaces.reverse()
michael@0 165 return interfaces
michael@0 166
michael@0 167 def allAttributes(iface):
michael@0 168 attributes = []
michael@0 169 for i in interfaces(iface):
michael@0 170 attrs = filter(lambda m: isinstance(m, xpidl.Attribute), i.members)
michael@0 171 attributes.extend(attrs)
michael@0 172
michael@0 173 return attributes
michael@0 174
michael@0 175 def write_cpp(eventname, iface, fd):
michael@0 176 classname = "xpcAcc%s" % eventname
michael@0 177 attributes = allAttributes(iface)
michael@0 178 ccattributes = filter(lambda m: m.realtype.nativeType('in').endswith('*'), attributes)
michael@0 179 fd.write("NS_IMPL_CYCLE_COLLECTION(%s" % classname)
michael@0 180 for c in ccattributes:
michael@0 181 fd.write(", m%s" % firstCap(c.name))
michael@0 182 fd.write(")\n\n");
michael@0 183
michael@0 184 fd.write("NS_IMPL_CYCLE_COLLECTING_ADDREF(%s)\n" % classname)
michael@0 185 fd.write("NS_IMPL_CYCLE_COLLECTING_RELEASE(%s)\n\n" % classname)
michael@0 186
michael@0 187 fd.write("NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(%s)\n" % classname)
michael@0 188 for baseiface in interfaces(iface):
michael@0 189 fd.write(" NS_INTERFACE_MAP_ENTRY(%s)\n" % baseiface.name)
michael@0 190 fd.write("NS_INTERFACE_MAP_END\n\n")
michael@0 191
michael@0 192 for a in attributes:
michael@0 193 writeAttributeGetter(fd, classname, a)
michael@0 194
michael@0 195
michael@0 196 def main():
michael@0 197 from optparse import OptionParser
michael@0 198 o = OptionParser(usage="usage: %prog [options] configfile")
michael@0 199 o.add_option('-I', action='append', dest='incdirs', default=['.'],
michael@0 200 help="Directory to search for imported files")
michael@0 201 o.add_option('-o', "--stub-output",
michael@0 202 type='string', dest='stub_output', default=None,
michael@0 203 help="C++ source output file", metavar="FILE")
michael@0 204 o.add_option('--header-output', type='string', default=None,
michael@0 205 help="Quick stub header output file", metavar="FILE")
michael@0 206 o.add_option('--makedepend-output', type='string', default=None,
michael@0 207 help="gnumake dependencies output file", metavar="FILE")
michael@0 208 o.add_option('--cachedir', dest='cachedir', default=None,
michael@0 209 help="Directory in which to cache lex/parse tables.")
michael@0 210 global options
michael@0 211 (options, filenames) = o.parse_args()
michael@0 212 if len(filenames) != 1:
michael@0 213 o.error("Exactly one config filename is needed.")
michael@0 214 filename = filenames[0]
michael@0 215
michael@0 216 if options.cachedir is not None:
michael@0 217 if not os.path.isdir(options.cachedir):
michael@0 218 os.mkdir(options.cachedir)
michael@0 219 sys.path.append(options.cachedir)
michael@0 220
michael@0 221 # Instantiate the parser.
michael@0 222 global p
michael@0 223 p = xpidl.IDLParser(outputdir=options.cachedir)
michael@0 224
michael@0 225 conf = readConfigFile(filename)
michael@0 226
michael@0 227 if options.stub_output is not None:
michael@0 228 makeutils.targets.append(options.stub_output)
michael@0 229 outfd = open(options.stub_output, 'w')
michael@0 230 print_cpp_file(outfd, conf)
michael@0 231 outfd.close()
michael@0 232 if options.makedepend_output is not None:
michael@0 233 makeutils.writeMakeDependOutput(options.makedepend_output)
michael@0 234 if options.header_output is not None:
michael@0 235 outfd = open(options.header_output, 'w')
michael@0 236 print_header_file(outfd, conf)
michael@0 237 outfd.close()
michael@0 238
michael@0 239 if __name__ == '__main__':
michael@0 240 main()

mercurial