def ctypes_decl(self): """Generates a ctypes.Structure declaration for self.""" indent = codegen_util.Indenter() lines = [] lines.append( textwrap.dedent(""" class {0.ctypes_typename}(ctypes.Structure): \"\"\"{0.docstring}\"\"\"""".format(self))) anonymous_fields = [ member.name for member in self.members.values() if isinstance(member, AnonymousUnion) ] with indent: if anonymous_fields: lines.append(indent("_anonymous_ = [")) with indent: with indent: for name in anonymous_fields: lines.append(indent("'" + name + "',")) lines.append(indent("]")) if self.members: lines.append(indent("_fields_ = [")) with indent: with indent: for member in self.members.values(): lines.append(indent(member.ctypes_field_decl + ",")) lines.append(indent("]\n")) return "\n".join(lines)
def wrapper_class(self): """Generates a Python class containing getter/setter methods for members.""" indent = codegen_util.Indenter() s = textwrap.dedent(""" class {0.wrapper_name}(util.WrapperBase): \"\"\"{0.docstring:}\"\"\" """.format(self)) with indent: s += "".join(indent(m.getters_setters) for m in six.itervalues(self.members)) return s
def docstring(self): """Generates a docstring.""" indent = codegen_util.Indenter() s = "\n".join(textwrap.wrap(self.comment, 80)) + "\n\nArgs:\n" with indent: for a in six.itervalues(self.arguments): s += indent("{a.name:}: {a.arg:}{const:}\n".format( a=a, const=(" <const>" if a.is_const else ""))) s += "Returns:\n" with indent: s += indent("{0.return_value.arg}{1:}\n".format( # pylint: disable=missing-format-attribute self, (" <const>" if self.return_value.is_const else ""))) return s
def write_index_dict(self, fname): pp = pprint.PrettyPrinter() output_string = pp.pformat(dict(self.index_dict)) indent = codegen_util.Indenter() imports = [ "# pylint: disable=bad-continuation", "# pylint: disable=line-too-long", ] with open(fname, "w") as f: f.write(self.make_header(imports)) f.write("array_sizes = (\n") with indent: f.write(output_string) f.write("\n)") f.write("\n" + codegen_util.comment_line("End of generated code"))
def ctypes_struct_decl(self): """Generates a ctypes.Structure declaration for self.""" indent = codegen_util.Indenter() s = textwrap.dedent(""" class {0.ctypes_typename:}(ctypes.Structure): \"\"\"{0.docstring:}\"\"\" """.format(self)) with indent: if self.members: s += indent("\n_fields_ = [\n") with indent: with indent: s += ",\n".join(indent(m.ctypes_field_decl) for m in six.itervalues(self.members)) s += indent("\n]\n") return s
def docstring(self): """Generates a docstring.""" indent = codegen_util.Indenter() lines = textwrap.wrap(self.comment, width=80) if self.arguments: lines.append("\nArgs:") with indent: for a in self.arguments.values(): s = "{a.name}: {a.arg}{const}".format( a=a, const=(" <const>" if a.is_const else "")) lines.append(indent(s)) if self.return_value: lines.append("\nReturns:") with indent: lines.append(indent(self.return_value.arg)) lines.append("") # Force a newline at the end of the docstring. return "\n".join(lines)
def ctypes_decl(self): """Generates a ctypes.Union declaration for self.""" indent = codegen_util.Indenter() lines = [] lines.append( textwrap.dedent(""" class {0.ctypes_typename}(ctypes.Union): \"\"\"{0.docstring}\"\"\"""".format(self))) with indent: if self.members: lines.append(indent("_fields_ = [")) with indent: with indent: for member in self.members.values(): lines.append(indent(member.ctypes_field_decl + ",")) lines.append(indent("]\n")) return "\n".join(lines)
def wrapper_class(self): """Generates a Python class containing getter/setter methods for members.""" indent = codegen_util.Indenter() lines = [ textwrap.dedent(""" class {0.wrapper_name}(util.WrapperBase): \"\"\"{0.docstring}\"\"\"""".format(self)) ] with indent: for member in self.members.values(): if isinstance(member, AnonymousUnion): for submember in member.members.values(): lines.append(indent(submember.getters_setters)) else: lines.append(indent(member.getters_setters)) lines.append( "") # Add an extra newline at the end of the class definition. return "\n".join(lines)
def ctypes_func_decl(self, cdll_name): """Generates a ctypes function declaration.""" indent = codegen_util.Indenter() lines = [] lines.append("{0}.{1}.__doc__ = \"\"\"\n{2}\"\"\"".format( cdll_name, self.name, self.docstring)) if self.arguments: lines.append("{0}.{1}.argtypes = [".format(cdll_name, self.name)) with indent: with indent: lines.extend(indent(a.arg + ",") for a in six.itervalues(self.arguments)) lines.append("]") else: lines.append("{0}.{1}.argtypes = None".format(cdll_name, self.name)) if self.return_value: lines.append("{0}.{1}.restype = {2}".format( cdll_name, self.name, self.return_value.arg)) else: lines.append("{0}.{1}.restype = None".format(cdll_name, self.name)) lines.append("") # Force a newline after the declaration. return "\n".join(lines)
def ctypes_func_decl(self, cdll_name): """Generates a ctypes function declaration.""" indent = codegen_util.Indenter() # triple-quoted docstring s = ( "{0:}.{1.name:}.__doc__ = \"\"\"\n{1.docstring:}\"\"\"\n" # pylint: disable=missing-format-attribute ).format(cdll_name, self) # arguments s += "{0:}.{1.name:}.argtypes = [".format(cdll_name, self) # pylint: disable=missing-format-attribute if len(self.arguments) > 1: s += "\n" with indent: with indent: s += ",\n".join( indent(a.arg) for a in six.itervalues(self.arguments)) s += "\n" else: s += ", ".join( indent(a.arg) for a in six.itervalues(self.arguments)) s += "]\n" # return value s += "{0:}.{1.name:}.restype = {2:}\n".format( # pylint: disable=missing-format-attribute cdll_name, self, self.return_value.arg) return s
def write_funcs_and_globals(self, fname): """Write ctypes declarations for functions and global data.""" imports = [ "import collections", "import ctypes", "# pylint: disable=undefined-variable", "# pylint: disable=wildcard-import", "from {} import util".format(_MODULE), "from {}.mjbindings.types import *".format(_MODULE), "import numpy as np", "# pylint: disable=line-too-long", "# pylint: disable=invalid-name", "# common_typos_disable", ] with open(fname, "w") as f: f.write(self.make_header(imports)) f.write("mjlib = util.get_mjlib()\n") f.write("\n" + codegen_util.comment_line("ctypes function declarations")) for function in self.funcs_dict.values(): f.write("\n" + function.ctypes_func_decl(cdll_name="mjlib")) # Only require strings for UI purposes. f.write("\n" + codegen_util.comment_line("String arrays") + "\n") for string_arr in self.strings_dict.values(): f.write(string_arr.ctypes_var_decl(cdll_name="mjlib")) f.write("\n" + codegen_util.comment_line("Callback function pointers")) fields = [ "'_{0}'".format(func_ptr.name) for func_ptr in self.func_ptrs_dict.values() ] values = [ func_ptr.ctypes_var_decl(cdll_name="mjlib") for func_ptr in self.func_ptrs_dict.values() ] f.write( textwrap.dedent(""" class _Callbacks: __slots__ = [ {0} ] def __init__(self): {1} """).format(",\n ".join(fields), "\n ".join(values))) indent = codegen_util.Indenter() with indent: for func_ptr in self.func_ptrs_dict.values(): f.write( indent( func_ptr.getters_setters_with_custom_prefix( "self._"))) f.write( "\n\ncallbacks = _Callbacks() # pylint: disable=invalid-name") f.write("\ndel _Callbacks\n") f.write("\n" + codegen_util.comment_line("End of generated code"))