def GenerateHeader(self, source_filename, api_header_filename, macros, more_headers=None): """Generate header file with type conversion declarations.""" if more_headers is None: more_headers = [] for s in gen.Headlines(source_filename, [ 'absl/types/optional.h', api_header_filename, 'clif/python/postconv.h' ] + more_headers, ['memory']): yield s if self.types: for ns, ts in itertools.groupby(self.types, types.Namespace): yield '' yield gen.OpenNs(ns) if ns and ns != 'clif': yield 'using namespace ::clif;' yield '' for t in ts: for s in t.GenHeader(): yield s yield '' yield gen.CloseNs(ns) yield '' yield ('// CLIF init_module if (PyObject* m = PyImport_ImportModule(' '"%s")) Py_DECREF(m);' % self.path) yield '// CLIF init_module else goto err;' else: yield '// This module defines no types.' for m in macros: yield '' yield '// CLIF macro %s %s' % ( m.name, m.definition.decode('utf-8').replace('\n', r'\n'))
def GenerateBase(self, ast, more_headers): """Extension module generation.""" ast_manipulations.MoveExtendsBackIntoClassesInPlace(ast) self.init += ast.extra_init for s in gen.Headlines( ast.source, [ 'PYTHON', 'absl/memory/memory.h', 'absl/types/optional.h' ] + more_headers + # Container templates calling PyObj* go last. [ 'clif/python/stltypes.h', 'clif/python/slots.h' ], open_ns=self.wrap_namespace): yield s yield '' yield 'using namespace clif;' yield '' yield 'static const char* ThisModuleName = "%s";' % self.path for s in postconv.GenPostConvTable(self.typemap): yield s if astutils.HaveEnum(ast.decls): yield '' yield 'static PyObject *_Enum{}, *_IntEnum{}; // set below in Init()' self.catch_cpp_exceptions = ast.catch_exceptions for d in ast.decls: for s in self.WrapDecl(d): yield s assert not self.nested, 'decl stack not exhausted (in GenBase)' yield '' yield '// Initialize module' if self.methods: for s in gen.MethodDef(self.methods): yield s for s in self.GenTypesReady(): # extends self.init yield s for s in self.GenInitFunction(ast.source): # consumes self.init yield s yield '' yield '} // namespace %s' % self.wrap_namespace if self.types: # Assumed we always want a deterministic output. Since dict/set order # is not, do sorted() order traversal. # # Save sorted types for GenerateHeader. self.types = sorted(self.types, key=types.Order) for ns, ts in itertools.groupby(self.types, types.Namespace): for s in gen.TypeConverters(ns, ts, self.wrap_namespace, self.py3output): yield s if self.static_init: for s in gen.PyModInitFunction( init_name=self.static_init, ns=self.wrap_namespace, py3=self.py3output): yield s
def GenerateFrom(messages, proto_filename, clif_hdr, proto_hdr): """Traverse ast and generate output files.""" with open(FLAGS.header_out, 'w') as hout: gen.WriteTo( hout, gen.Headlines(proto_filename, [proto_hdr, 'clif/python/postconv.h'])) gen.WriteTo(hout, _GenHeader(messages)) with open(FLAGS.ccdeps_out, 'w') as cout: gen.WriteTo( cout, gen.Headlines( proto_filename, ['clif/python/runtime.h', 'clif/python/types.h', clif_hdr])) for ns, ts in itertools.groupby(messages, types.Namespace): if ns == '::': ns = 'clif' gen.WriteTo(cout, gen.TypeConverters(ns, ts))
def GenerateInit(self, source_filename, skip_initfunc=False): """Generate module initialization file.""" assert not self.nested, 'decl stack not exhausted (in GenInit)' for s in gen.Headlines(source_filename, ['PYTHON'], open_ns=self.wrap_namespace): yield s yield '' yield 'bool Ready();' yield 'PyObject* Init();' yield '' yield '} // namespace %s' % self.wrap_namespace if not skip_initfunc: for s in gen.PyModInitFunction(modname=self.modname, py3=self.py3output, ns=self.wrap_namespace): yield s
def GenerateInit(self, source_filename): """Generate module initialization file.""" assert not self.nested for s in (gen.Headlines(source_filename, ['PYTHON'], open_ns=self.wrap_namespace)): yield s yield '' yield 'bool Ready();' yield 'PyObject* Init();' yield '' yield '} // namespace %s' % self.wrap_namespace for s in (self._GeneratePyModInit( ('PyInit_' if self.py3output else 'init') + self.modname)): yield s
def GenerateBase(self, ast, api_header, more_headers): """Extension module generation.""" self.init += ast.extra_init for s in (gen.Headlines( ast.source, ['PYTHON', 'clif/python/ptr_util.h', 'clif/python/optional.h'] + more_headers + # Container templates calling PyObj* go last. ['clif/python/stltypes.h', 'clif/python/slots.h'], open_ns=self.wrap_namespace)): yield s yield 'using namespace clif;' for s in (postconv.GenPostConvTable(self.typemap)): yield s if astutils.HaveEnum(ast.decls): yield '' yield 'static PyObject *_Enum{}, *_IntEnum{}; // set below in Init()' self.catch_cpp_exceptions = ast.catch_exceptions yield '' for d in ast.decls: for s in (self.WrapDecl(d)): yield s assert not self.nested, 'decl stack not exhausted' yield '' yield '' yield '// Initialize module' if self.methods: for s in (gen.MethodDef(self.methods)): yield s for s in (self.GenTypesReady() # extends self.init ): yield s for s in (self.GenInitFunction(api_header) # consumes self.init ): yield s yield '' yield '} // namespace %s' % self.wrap_namespace if self.types: # Assumed we always want a deterministic output. Since dict/set order # is not, do sorted() order traversal. # # Save sorted types for GenerateHeader. self.types = sorted(self.types, key=types.Order) for ns, ts in itertools.groupby(self.types, types.Namespace): for s in (gen.TypeConverters(ns, ts, self.wrap_namespace, self.py3output)): yield s
def GenerateHeader(self, source_filename, api_header_filename, macros, is_extended_from_python, more_headers=None): """Generate header file with type conversion declarations.""" if more_headers is None: more_headers = [] for s in gen.Headlines(source_filename, [ 'absl/types/optional.h', api_header_filename, 'clif/python/postconv.h' ] + more_headers, ['memory']): yield s if self.types: for ns, ts in itertools.groupby(self.types, types.Namespace): yield '' yield gen.OpenNs(ns) if ns and ns != 'clif': yield 'using namespace ::clif;' yield '' for t in ts: for s in t.GenHeader(): yield s yield '' yield gen.CloseNs(ns) yield '' import_path = self.path if is_extended_from_python: flds = import_path.split('.') if not flds[-1].startswith('_'): raise ValueError( 'OPTION is_extended_from_python is applicable only to private' ' extensions (i.e. the unqualified name of the extension must' ' start with an underscore). Fully-qualified extension name: %s' % self.path) flds[-1] = flds[-1][1:] import_path = '.'.join(flds) yield ('// CLIF init_module if (PyObject* m = PyImport_ImportModule(' '"%s")) Py_DECREF(m);' % import_path) yield '// CLIF init_module else goto err;' else: yield '// This module defines no types.' for m in macros: yield '' yield '// CLIF macro %s %s' % ( m.name, m.definition.decode('utf-8').replace('\n', r'\n'))