def getFile(fname): if os.path.exists(fname + '.cache') and os.path.getmtime(fname + '.cache') > os.path.getmtime(fname): res = json.load(file(fname + '.cache')) else: res = parse(file(fname).read()) with file(fname + '.cache', 'w') as fp: json.dump(res, fp) return res
def main(): global allTypes fns = ['ipcdefs/auto.id'] + [ x for x in glob.glob('ipcdefs/*.id') if x != 'ipcdefs/auto.id' ] if os.path.exists('ipcdefs/cache') and all( os.path.getmtime('ipcdefs/cache') > os.path.getmtime(x) for x in fns): res = json.load(file('ipcdefs/cache')) else: res = idparser.parse('\n'.join(file(fn).read() for fn in fns)) with file('ipcdefs/cache', 'w') as fp: json.dump(res, fp) types, ifaces, services = res allTypes = types typesByNs = splitByNs(types) ifacesByNs = splitByNs(ifaces) namespaces = {x: [] for x in typesByNs.keys() + ifacesByNs.keys()} for ns, types in typesByNs.items(): for name, spec in sorted(types.items(), key=lambda x: x[0]): retyped, plain = retype(spec, noIndex=True), retype(spec) namespaces[ns].append( 'using %s = %s;%s' % (name, retyped, ' // ' + plain if retyped != plain else '')) for ns, ifaces in ifacesByNs.items(): for name in sorted(ifaces.keys()): namespaces[ns].append('class %s;' % name) with file('IpcStubs.h', 'w') as fp: print >> fp, '#pragma once' print >> fp, '#include "Ctu.h"' print >> fp print >> fp, '#define SERVICE_MAPPING() do { \\' for iname, snames in sorted(services.items(), key=lambda x: x[0]): for sname in snames: print >> fp, '\tSERVICE("%s", %s); \\' % (sname, iname) print >> fp, '} while(0)' print >> fp for ns, elems in sorted(namespaces.items(), key=lambda x: x[0]): if ns is not None: print >> fp, 'namespace %s {' % ns hasUsing = False for elem in elems: if not hasUsing and elem.startswith('using'): hasUsing = True elif hasUsing and elem.startswith('class'): print >> fp hasUsing = False print >> fp, ('\t' if ns is not None else '') + elem if ns is not None: print >> fp, '}' print >> fp allcode = '\n'.join( file(fn, 'r').read() for fn in glob.glob('ipcimpl/*.cpp')) partials = parsePartials(allcode) for ns, ifaces in sorted(ifacesByNs.items(), key=lambda x: x[0]): print >> fp, '%snamespace %s {' % ('//// ' if ns is None else '', ns) for name, funcs in sorted(ifaces.items(), key=lambda x: x[0]): qname = '%s::%s' % (ns, name) if ns else name partial = partials[qname] if qname in partials else None print >> fp, '\tclass %s : public IpcService {' % name print >> fp, '\tpublic:' if re.search( '(^|[^a-zA-Z0-9:])%s::%s[^a-zA-Z0-9:]' % (qname, name), allcode): print >> fp, '\t\t%s(Ctu *_ctu%s);' % ( name, ', ' + ', '.join('%s _%s' % (k, v) for k, v in partial[1]) if partial and partial[1] else '') else: print >> fp, '\t\t%s(Ctu *_ctu%s) : IpcService(_ctu)%s {}' % ( name, ', ' + ', '.join('%s _%s' % (k, v) for k, v in partial[1]) if partial and partial[1] else '', ', ' + ', '.join('%s(_%s)' % (v, v) for k, v in partial[1]) if partial and partial[1] else '') print >> fp, '\t\tuint32_t dispatch(IncomingIpcMessage &req, OutgoingIpcMessage &resp) {' print >> fp, '\t\t\tswitch(req.cmdId) {' for fname, func in sorted(funcs.items(), key=lambda x: x[1]['cmdId']): print >> fp, '\t\t\tcase %i: {' % func['cmdId'] print >> fp, '\n'.join( '\t\t\t\t' + x for x in reorder(generateCaller(qname, fname, func))) print >> fp, '\t\t\t}' print >> fp, '\t\t\tdefault:' print >> fp, '\t\t\t\tLOG_ERROR(IpcStubs, "Unknown message cmdId %%u to interface %s", req.cmdId);' % ( '%s::%s' % (ns, name) if ns else name) print >> fp, '\t\t\t}' print >> fp, '\t\t}' for fname, func in sorted(funcs.items(), key=lambda x: x[0]): implemented = re.search( '[^a-zA-Z0-9:]%s::%s[^a-zA-Z0-9:]' % (qname, fname), allcode) print >> fp, '\t\tuint32_t %s(%s);' % ( fname, generatePrototype(func)) if partial: for x in partial[0]: print >> fp, '\t\t%s' % x print >> fp, '\t};' print >> fp, '%s}' % ('//// ' if ns is None else '') print >> fp, '#ifdef DEFINE_STUBS' for name, funcs in sorted(ifaces.items(), key=lambda x: x[0]): qname = '%s::%s' % (ns, name) if ns else name partial = partials[qname] if qname in partials else None for fname, func in sorted(funcs.items(), key=lambda x: x[0]): implemented = re.search( '[^a-zA-Z0-9:]%s::%s[^a-zA-Z0-9:]' % (qname, fname), allcode) if not implemented: print >> fp, 'uint32_t %s::%s(%s) {' % ( qname, fname, generatePrototype(func)) print >> fp, '\tLOG_DEBUG(IpcStubs, "Stub implementation for %s::%s");' % ( qname, fname) for i, (name, elem) in enumerate(func['outputs']): if elem[0] == 'object' and elem[1][0] != 'IUnknown': name = name if name else '_%i' % ( len(func['inputs']) + i) print >> fp, '\t%s = buildInterface(%s);' % ( name, elem[1][0]) if elem[1][0] in partials and partials[elem[1] [0]][1]: print 'Bare construction of interface %s requiring parameters. Created in %s::%s for parameter %s' % ( elem[1][0], qname, fname, name) sys.exit(1) elif elem[0] == 'KObject': name = name if name else '_%i' % ( len(func['inputs']) + i) print >> fp, '\t%s = make_shared<FauxHandle>(0x%x);' % ( name, uniqInt(qname, fname, name)) print >> fp, '\treturn 0;' print >> fp, '}' print >> fp, '#endif // DEFINE_STUBS'