--- /dev/null
+#
+# Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
+# Written by David Howells (dhowells@redhat.com)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public Licence
+# as published by the Free Software Foundation; either version
+# 2 of the Licence, or (at your option) any later version.
+#
+
+###############################################################################
+#
+# Emit python type wrappers for C structs.
+#
+###############################################################################
+sub emit_py_type_wrapper($@) {
+ my ($struct, @members) = @_;
+
+ # Dump the banner comment block
+ my @comments = @{shift @members};
+
+ print PYHDR "\n";
+ print PYHDR @comments;
+ print PYOUT "\n";
+ print PYOUT @comments;
+
+ # Write a python wrapper struct
+ print PYHDR "struct py_$struct {\n";
+ print PYHDR "\tPyObject_HEAD\n";
+ print PYHDR "\tstruct $struct x;\n";
+ print PYHDR "};\n";
+ print PYHDR "\n";
+
+ # We want allocation and deallocation functions
+ print PYOUT "static PyObject *\n";
+ print PYOUT "py_", $struct, "_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\n";
+ print PYOUT "{\n";
+ print PYOUT "\treturn (PyObject *)(struct py_$struct *)type->tp_alloc(type, 0);\n";
+ print PYOUT "}\n";
+ print PYOUT "\n";
+ print PYOUT "static void\n";
+ print PYOUT "py_", $struct, "_dealloc(struct py_$struct *self)\n";
+ print PYOUT "{\n";
+ print PYOUT "\tPy_TYPE(self)->tp_free((PyObject *)self);\n";
+ print PYOUT "}\n";
+ print PYOUT "\n";
+
+ # Divide into single members and array members
+ my @singles = ();
+ my @arrays = ();
+ foreach my $m (@members) {
+ my ($type, $name, $array_size, $max_size) = @{$m};
+ if ($array_size == -1) {
+ push @singles, $m;
+ } else {
+ push @arrays, $m;
+ }
+ }
+
+ # Any non-array elements are made directly accessible to the Python interpreter
+ print PYOUT "static PyMemberDef py_", $struct, "_members[] = {\n";
+ if (@singles) {
+ foreach my $m (@singles) {
+ my ($type, $name, $array_size, $max_size) = @{$m};
+ print PYOUT "\t{ \"$name\", ";
+ if ($type eq "char") {
+ print PYOUT "T_CHAR";
+ } elsif ($type eq "int8_t") {
+ print PYOUT "T_BYTE";
+ } elsif ($type eq "int16_t") {
+ print PYOUT "T_SHORT";
+ } elsif ($type eq "int32_t") {
+ print PYOUT "T_INT";
+ } elsif ($type eq "int64_t") {
+ print PYOUT "T_LONGLONG";
+ } elsif ($type eq "uint8_t") {
+ print PYOUT "T_UBYTE";
+ } elsif ($type eq "uint16_t") {
+ print PYOUT "T_USHORT";
+ } elsif ($type eq "uint32_t") {
+ print PYOUT "T_UINT";
+ } elsif ($type eq "uint64_t") {
+ print PYOUT "T_ULONGLONG";
+ } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
+ die "Don't py-wrap structs yet";
+ } else {
+ die "Unsupported type \"$type\"";
+ }
+ print PYOUT ", offsetof(struct py_$struct, x.$name), 0, \"\"},\n";
+ }
+ }
+ print PYOUT "\t{}\n";
+ print PYOUT "};\n";
+ print PYOUT "\n";
+
+ # Array elements have to be accessed through ->tp_[sg]etattro() as
+ # tuples (int[]/uint[]) or strings (char[])
+ if (@arrays) {
+ # The attribute get function
+ print PYOUT "static PyObject *\n";
+ print PYOUT "py_", $struct, "_getattro(PyObject *_self, PyObject *name)\n";
+ print PYOUT "{\n";
+ print PYOUT "\tstruct py_$struct *self = (struct py_$struct *)_self;\n";
+ print PYOUT "\n";
+ print PYOUT "\tif (PyUnicode_Check(name)) {\n";
+
+ foreach my $m (@arrays) {
+ my ($type, $name, $array_size, $max_size) = @{$m};
+
+ print PYOUT "\t\tif (PyUnicode_CompareWithASCIIString(name, \"$name\") == 0)\n";
+ if ($type eq "char") {
+ print PYOUT "\t\t\treturn py_rxgen_get_string(&self->x.$name, $array_size);\n";
+ } elsif ($type eq "uint8_t") {
+ print PYOUT "\t\t\treturn py_rxgen_get_uint8(&self->x.$name, $array_size);\n";
+ } elsif ($type eq "uint16_t") {
+ print PYOUT "\t\t\treturn py_rxgen_get_uint16(&self->x.$name, $array_size);\n";
+ } elsif ($type eq "uint32_t") {
+ print PYOUT "\t\t\treturn py_rxgen_get_uint32(&self->x.$name, $array_size);\n";
+ } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
+ die "Don't py-wrap struct arrays yet";
+ } else {
+ die "Unsupported array type \"$type\"";
+ }
+ }
+
+ print PYOUT "\t}\n";
+ print PYOUT "\n";
+ print PYOUT "\treturn PyObject_GenericGetAttr(_self, name);\n";
+ print PYOUT "}\n";
+ print PYOUT "\n";
+
+ # The attribute set function
+ print PYOUT "static int\n";
+ print PYOUT "py_", $struct, "_setattro(PyObject *_self, PyObject *name, PyObject *val)\n";
+ print PYOUT "{\n";
+ print PYOUT "\tstruct py_$struct *self = (struct py_$struct *)_self;\n";
+ print PYOUT "\n";
+ print PYOUT "\tif (PyUnicode_Check(name)) {\n";
+
+ foreach my $m (@arrays) {
+ my ($type, $name, $array_size, $max_size) = @{$m};
+
+ print PYOUT "\t\tif (PyUnicode_CompareWithASCIIString(name, \"$name\") == 0)\n";
+ if ($type eq "char") {
+ print PYOUT "\t\t\treturn py_rxgen_set_string(&self->x.$name, $array_size, val);\n";
+ } elsif ($type eq "uint8_t") {
+ print PYOUT "\t\t\treturn py_rxgen_set_uint8(&self->x.$name, $array_size, val);\n";
+ } elsif ($type eq "uint16_t") {
+ print PYOUT "\t\t\treturn py_rxgen_set_uint16(&self->x.$name, $array_size, val);\n";
+ } elsif ($type eq "uint32_t") {
+ print PYOUT "\t\t\treturn py_rxgen_set_uint32(&self->x.$name, $array_size, val);\n";
+ } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
+ die "Don't py-wrap struct arrays yet";
+ } else {
+ die "Unsupported array type \"$type\"";
+ }
+ }
+
+ print PYOUT "\t}\n";
+ print PYOUT "\n";
+ print PYOUT "\treturn PyObject_GenericSetAttr(_self, name, val);\n";
+ print PYOUT "}\n";
+ print PYOUT "\n";
+ }
+
+ # Emit the Python type definition
+ print PYOUT "static PyTypeObject py_", $struct, "Type = {\n";
+
+ print PYOUT "\tPyVarObject_HEAD_INIT(NULL, 0)\n";
+ print PYOUT "\t\"kafs.$struct\",\t\t/*tp_name*/\n";
+ print PYOUT "\tsizeof(struct py_$struct),\t/*tp_basicsize*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_itemsize*/\n";
+ print PYOUT "\t(destructor)py_", $struct, "_dealloc, /*tp_dealloc*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_print*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_getattr*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_setattr*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_compare*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_repr*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_as_number*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_as_sequence*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_as_mapping*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_hash */\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_call*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_str*/\n";
+ if (@arrays) {
+ print PYOUT "\tpy_", $struct, "_getattro,\n";
+ print PYOUT "\tpy_", $struct, "_setattro,\n";
+ } else {
+ print PYOUT "\t0,\t\t\t\t/*tp_getattro*/\n";
+ print PYOUT "\t0,\t\t\t\t/*tp_setattro*/\n";
+ }
+ print PYOUT "\t0,\t\t\t\t/*tp_as_buffer*/\n";
+ print PYOUT "\tPy_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/\n";
+ if (@comments) {
+ print PYOUT "\t";
+ foreach my $c (@comments) {
+ $c =~ s/\s+$//;
+ $c =~ s/^\s+//;
+ next if ($c eq "/*" || $c eq "*/");
+ $c =~ s/^[*] //;
+ $c =~ s/^[*]$//;
+ print PYOUT "\n\t\t\"", $c, "\\n\"";
+ }
+ print PYOUT ",\n";
+ } else {
+ print PYOUT "\t\"\",\t\t\t/* tp_doc */\n";
+ }
+ print PYOUT "\t0,\t\t\t\t/* tp_traverse */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_clear */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_richcompare */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_weaklistoffset */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_iter */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_iternext */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_methods */\n";
+ if (@singles) {
+ print PYOUT "\tpy_", $struct, "_members,\n";
+ } else {
+ print PYOUT "\t0,\t\t\t/* tp_members */\n";
+ }
+ print PYOUT "\t0,\t\t\t\t/* tp_getset */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_base */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_dict */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_descr_get */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_descr_set */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_dictoffset */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_init */\n";
+ print PYOUT "\t0,\t\t\t\t/* tp_alloc */\n";
+ print PYOUT "\tpy_", $struct, "_new,\t/* tp_new */\n";
+ print PYOUT "};\n";
+
+ # Emit a function to allocate such a type
+ print PYHDR "extern PyObject *kafs_new_py_$struct(PyObject *, PyObject *);\n";
+
+ print PYOUT "\n";
+ print PYOUT "PyObject *\n";
+ print PYOUT "kafs_new_py_$struct(PyObject *_self, PyObject *args)\n";
+ print PYOUT "{\n";
+ print PYOUT "\tPyObject *obj;\n";
+ print PYOUT "\tobj = _PyObject_New(&py_", $struct, "Type);\n";
+ print PYOUT "\treturn obj ?: PyExc_MemoryError;\n";
+ print PYOUT "}\n";
+}
+
+1;
use strict;
use lib "rxgen";
+use emit_py_types;
use emit_py_sync_funcs;
-sub emit_py_struct_wrapper($@);
-sub emit_py_func_simple_sync_call($$$@);
-
die "Need list of sources\n" if ($#ARGV < 0);
our @structs = (); # Structure definitions
my @members = @{$s};
my $struct = shift @members;
emit_struct_encdec($struct, @members);
- emit_py_struct_wrapper($struct, @members);
+ emit_py_type_wrapper($struct, @members);
}
###############################################################################
emit_py_func_simple_sync_call($func, \@request, \@reply, @params);
}
-###############################################################################
-#
-# Emit python structure wrappers
-#
-###############################################################################
-sub emit_py_struct_wrapper($@) {
- my ($struct, @members) = @_;
-
- # Dump the banner comment block
- my @comments = @{shift @members};
-
- print PYHDR "\n";
- print PYHDR @comments;
- print PYOUT "\n";
- print PYOUT @comments;
-
- # Write a python wrapper struct
- print PYHDR "struct py_$struct {\n";
- print PYHDR "\tPyObject_HEAD\n";
- print PYHDR "\tstruct $struct x;\n";
- print PYHDR "};\n";
- print PYHDR "\n";
-
- # We want allocation and deallocation functions
- print PYOUT "static PyObject *\n";
- print PYOUT "py_", $struct, "_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\n";
- print PYOUT "{\n";
- print PYOUT "\treturn (PyObject *)(struct py_$struct *)type->tp_alloc(type, 0);\n";
- print PYOUT "}\n";
- print PYOUT "\n";
- print PYOUT "static void\n";
- print PYOUT "py_", $struct, "_dealloc(struct py_$struct *self)\n";
- print PYOUT "{\n";
- print PYOUT "\tPy_TYPE(self)->tp_free((PyObject *)self);\n";
- print PYOUT "}\n";
- print PYOUT "\n";
-
- # Divide into single members and array members
- my @singles = ();
- my @arrays = ();
- foreach my $m (@members) {
- my ($type, $name, $array_size, $max_size) = @{$m};
- if ($array_size == -1) {
- push @singles, $m;
- } else {
- push @arrays, $m;
- }
- }
-
- # Any non-array elements are made directly accessible to the Python interpreter
- print PYOUT "static PyMemberDef py_", $struct, "_members[] = {\n";
- if (@singles) {
- foreach my $m (@singles) {
- my ($type, $name, $array_size, $max_size) = @{$m};
- print PYOUT "\t{ \"$name\", ";
- if ($type eq "char") {
- print PYOUT "T_CHAR";
- } elsif ($type eq "int8_t") {
- print PYOUT "T_BYTE";
- } elsif ($type eq "int16_t") {
- print PYOUT "T_SHORT";
- } elsif ($type eq "int32_t") {
- print PYOUT "T_INT";
- } elsif ($type eq "int64_t") {
- print PYOUT "T_LONGLONG";
- } elsif ($type eq "uint8_t") {
- print PYOUT "T_UBYTE";
- } elsif ($type eq "uint16_t") {
- print PYOUT "T_USHORT";
- } elsif ($type eq "uint32_t") {
- print PYOUT "T_UINT";
- } elsif ($type eq "uint64_t") {
- print PYOUT "T_ULONGLONG";
- } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
- die "Don't py-wrap structs yet";
- } else {
- die "Unsupported type \"$type\"";
- }
- print PYOUT ", offsetof(struct py_$struct, x.$name), 0, \"\"},\n";
- }
- }
- print PYOUT "\t{}\n";
- print PYOUT "};\n";
- print PYOUT "\n";
-
- # Array elements have to be accessed through ->tp_[sg]etattro() as
- # tuples (int[]/uint[]) or strings (char[])
- if (@arrays) {
- # The attribute get function
- print PYOUT "static PyObject *\n";
- print PYOUT "py_", $struct, "_getattro(PyObject *_self, PyObject *name)\n";
- print PYOUT "{\n";
- print PYOUT "\tstruct py_$struct *self = (struct py_$struct *)_self;\n";
- print PYOUT "\n";
- print PYOUT "\tif (PyUnicode_Check(name)) {\n";
-
- foreach my $m (@arrays) {
- my ($type, $name, $array_size, $max_size) = @{$m};
-
- print PYOUT "\t\tif (PyUnicode_CompareWithASCIIString(name, \"$name\") == 0)\n";
- if ($type eq "char") {
- print PYOUT "\t\t\treturn py_rxgen_get_string(&self->x.$name, $array_size);\n";
- } elsif ($type eq "uint8_t") {
- print PYOUT "\t\t\treturn py_rxgen_get_uint8(&self->x.$name, $array_size);\n";
- } elsif ($type eq "uint16_t") {
- print PYOUT "\t\t\treturn py_rxgen_get_uint16(&self->x.$name, $array_size);\n";
- } elsif ($type eq "uint32_t") {
- print PYOUT "\t\t\treturn py_rxgen_get_uint32(&self->x.$name, $array_size);\n";
- } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
- die "Don't py-wrap struct arrays yet";
- } else {
- die "Unsupported array type \"$type\"";
- }
- }
-
- print PYOUT "\t}\n";
- print PYOUT "\n";
- print PYOUT "\treturn PyObject_GenericGetAttr(_self, name);\n";
- print PYOUT "}\n";
- print PYOUT "\n";
-
- # The attribute set function
- print PYOUT "static int\n";
- print PYOUT "py_", $struct, "_setattro(PyObject *_self, PyObject *name, PyObject *val)\n";
- print PYOUT "{\n";
- print PYOUT "\tstruct py_$struct *self = (struct py_$struct *)_self;\n";
- print PYOUT "\n";
- print PYOUT "\tif (PyUnicode_Check(name)) {\n";
-
- foreach my $m (@arrays) {
- my ($type, $name, $array_size, $max_size) = @{$m};
-
- print PYOUT "\t\tif (PyUnicode_CompareWithASCIIString(name, \"$name\") == 0)\n";
- if ($type eq "char") {
- print PYOUT "\t\t\treturn py_rxgen_set_string(&self->x.$name, $array_size, val);\n";
- } elsif ($type eq "uint8_t") {
- print PYOUT "\t\t\treturn py_rxgen_set_uint8(&self->x.$name, $array_size, val);\n";
- } elsif ($type eq "uint16_t") {
- print PYOUT "\t\t\treturn py_rxgen_set_uint16(&self->x.$name, $array_size, val);\n";
- } elsif ($type eq "uint32_t") {
- print PYOUT "\t\t\treturn py_rxgen_set_uint32(&self->x.$name, $array_size, val);\n";
- } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
- die "Don't py-wrap struct arrays yet";
- } else {
- die "Unsupported array type \"$type\"";
- }
- }
-
- print PYOUT "\t}\n";
- print PYOUT "\n";
- print PYOUT "\treturn PyObject_GenericSetAttr(_self, name, val);\n";
- print PYOUT "}\n";
- print PYOUT "\n";
- }
-
- # Emit the Python type definition
- print PYOUT "static PyTypeObject py_", $struct, "Type = {\n";
-
- print PYOUT "\tPyVarObject_HEAD_INIT(NULL, 0)\n";
- print PYOUT "\t\"kafs.$struct\",\t\t/*tp_name*/\n";
- print PYOUT "\tsizeof(struct py_$struct),\t/*tp_basicsize*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_itemsize*/\n";
- print PYOUT "\t(destructor)py_", $struct, "_dealloc, /*tp_dealloc*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_print*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_getattr*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_setattr*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_compare*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_repr*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_as_number*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_as_sequence*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_as_mapping*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_hash */\n";
- print PYOUT "\t0,\t\t\t\t/*tp_call*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_str*/\n";
- if (@arrays) {
- print PYOUT "\tpy_", $struct, "_getattro,\n";
- print PYOUT "\tpy_", $struct, "_setattro,\n";
- } else {
- print PYOUT "\t0,\t\t\t\t/*tp_getattro*/\n";
- print PYOUT "\t0,\t\t\t\t/*tp_setattro*/\n";
- }
- print PYOUT "\t0,\t\t\t\t/*tp_as_buffer*/\n";
- print PYOUT "\tPy_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/\n";
- if (@comments) {
- print PYOUT "\t";
- foreach my $c (@comments) {
- $c =~ s/\s+$//;
- $c =~ s/^\s+//;
- next if ($c eq "/*" || $c eq "*/");
- $c =~ s/^[*] //;
- $c =~ s/^[*]$//;
- print PYOUT "\n\t\t\"", $c, "\\n\"";
- }
- print PYOUT ",\n";
- } else {
- print PYOUT "\t\"\",\t\t\t/* tp_doc */\n";
- }
- print PYOUT "\t0,\t\t\t\t/* tp_traverse */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_clear */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_richcompare */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_weaklistoffset */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_iter */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_iternext */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_methods */\n";
- if (@singles) {
- print PYOUT "\tpy_", $struct, "_members,\n";
- } else {
- print PYOUT "\t0,\t\t\t/* tp_members */\n";
- }
- print PYOUT "\t0,\t\t\t\t/* tp_getset */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_base */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_dict */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_descr_get */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_descr_set */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_dictoffset */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_init */\n";
- print PYOUT "\t0,\t\t\t\t/* tp_alloc */\n";
- print PYOUT "\tpy_", $struct, "_new,\t/* tp_new */\n";
- print PYOUT "};\n";
-
- # Emit a function to allocate such a type
- print PYHDR "extern PyObject *kafs_new_py_$struct(PyObject *, PyObject *);\n";
-
- print PYOUT "\n";
- print PYOUT "PyObject *\n";
- print PYOUT "kafs_new_py_$struct(PyObject *_self, PyObject *args)\n";
- print PYOUT "{\n";
- print PYOUT "\tPyObject *obj;\n";
- print PYOUT "\tobj = _PyObject_New(&py_", $struct, "Type);\n";
- print PYOUT "\treturn obj ?: PyExc_MemoryError;\n";
- print PYOUT "}\n";
-}
-
###############################################################################
#
# Emit python structure wrapper static method table