From: David Howells Date: Thu, 9 Jan 2014 14:29:25 +0000 (+0000) Subject: rxgen: Extract py wrapper func emitter X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=46cd9ac19a184a1759c796987677263dc642fd81;p=users%2Fdhowells%2Fkafs-utils.git rxgen: Extract py wrapper func emitter Extract the code to emit python wrapper functions from the main rxgen script and put into its own module. Signed-off-by: David Howells --- diff --git a/rxgen/emit_py_sync_funcs.pm b/rxgen/emit_py_sync_funcs.pm new file mode 100644 index 0000000..52649d3 --- /dev/null +++ b/rxgen/emit_py_sync_funcs.pm @@ -0,0 +1,247 @@ +# +# 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 a python wrapper function to make a simple synchronous call +# +############################################################################### +sub emit_py_func_simple_sync_call($$$@) +{ + my ($func, $_request, $_reply, @params) = @_; + my @request = @{$_request}; + my @reply = @{$_reply}; + + print PYOUT "PyObject *\n"; + print PYOUT "kafs_", $func, "(PyObject *_self, PyObject *args)\n"; + print PYOUT "{\n"; + + # Declare parameter variables + my $need_tmp = 0; + print PYOUT "\tstruct py_rx_connection *z_conn;\n"; + foreach my $p (@params) { + my ($type, $name, $array_size, $max_size, $dir) = @{$p}; + if ($type eq "char*") { + die "String output args not supported" unless ($dir eq "IN"); + print PYOUT "\tconst char *param_$name;\n"; + } elsif ($type eq "int8_t" || $type eq "int8_t*" || + $type eq "int16_t" || $type eq "int16_t*" || + $type eq "int32_t" || $type eq "int32_t*" || + $type eq "int64_t" || $type eq "int64_t*" || + $type eq "uint8_t" || $type eq "uint8_t*" || + $type eq "uint16_t" || $type eq "uint16_t*" || + $type eq "uint32_t" || $type eq "uint32_t*" || + $type eq "uint64_t" || $type eq "uint64_t*" + ) { + $type =~ s/[*]$//; + $need_tmp = 1 unless ($dir eq "IN"); + print PYOUT "\t$type param_$name;\n"; + } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { + die "INOUT struct args not supported" if ($dir eq "INOUT"); + print PYOUT "\tstruct py_$1 *param_$name;\n"; + } else { + die "Unsupported type \"$type\""; + } + } + + # Replies are passed back into lists provided by the caller. INOUT variable + # input values must already occupy the lists. + foreach my $p (@reply) { + my ($type, $name, $array_size, $max_size, $dir) = @{$p}; + print PYOUT "\tPyObject *reply_$name;\n"; + } + + print PYOUT "\tPyObject *tmp;\n" if ($need_tmp); + print PYOUT "\tPyObject *res = NULL;\n"; + print PYOUT "\tint ret;\n"; + + # Make use of the tuple parser to extract the arguments and check their + # types for us. + print PYOUT "\n"; + print PYOUT "\tif (!PyArg_ParseTuple(args, \"O!"; + + foreach my $p (@params) { + my ($type, $name, $array_size, $max_size, $dir) = @{$p}; + if ($dir ne "IN") { + print PYOUT "O!"; + } elsif ($type eq "char*") { + print PYOUT "s"; + } elsif ($type eq "int8_t") { + print PYOUT "B"; + } elsif ($type eq "int16_t") { + print PYOUT "h"; + } elsif ($type eq "int32_t") { + print PYOUT "i"; + } elsif ($type eq "int64_t") { + print PYOUT "L"; + } elsif ($type eq "uint8_t") { + print PYOUT "b"; + } elsif ($type eq "uint16_t") { + print PYOUT "H"; + } elsif ($type eq "uint32_t") { + print PYOUT "I"; + } elsif ($type eq "uint64_t") { + print PYOUT "K"; + } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { + print PYOUT "O!"; + } + } + + print PYOUT "\",\n"; + print PYOUT "\t\t\t &py_rx_connectionType, &z_conn"; + + foreach my $p (@params) { + my ($type, $name, $array_size, $max_size, $dir) = @{$p}; + print PYOUT ",\n"; + print PYOUT "\t\t\t /*$dir*/ "; + if ($dir ne "IN") { + print PYOUT "&PyList_Type, &reply_$name"; + } elsif ($type eq "char*" || + $type eq "int8_t" || $type eq "int8_t" || + $type eq "int16_t" || $type eq "int16_t" || + $type eq "int32_t" || $type eq "int32_t" || + $type eq "int64_t" || $type eq "int64_t" || + $type eq "uint8_t" || $type eq "uint8_t" || + $type eq "uint16_t" || $type eq "uint16_t" || + $type eq "uint32_t" || $type eq "uint32_t" || + $type eq "uint64_t" || $type eq "uint64_t") { + print PYOUT "¶m_$name"; + } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { + print PYOUT "&py_", $1, "Type, ¶m_$name"; + } else { + die "Unsupported type \"$type\""; + } + } + print PYOUT "))\n"; + print PYOUT "\t\treturn NULL;\n"; + + # Allocate reply buffer objects + if (@reply) { + print PYOUT "\n"; + foreach my $p (@reply) { + my ($type, $name, $array_size, $max_size, $dir) = @{$p}; + if ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { + print PYOUT "\tparam_$name = (struct py_$1 *)kafs_new_py_$1(NULL, NULL);\n"; + print PYOUT "\tif (!param_$name)\n"; + print PYOUT "\t\tgoto error_alloc_$name;\n"; + } + } + } + + # Make the call + print PYOUT "\n"; + print PYOUT "\tret = $func(\n"; + print PYOUT "\t\tz_conn->x"; + + foreach my $p (@params) { + print PYOUT ",\n"; + my ($type, $name, $array_size, $max_size, $dir) = @{$p}; + if ($type eq "char*" || + $type eq "int8_t" || $type eq "int8_t*" || + $type eq "int16_t" || $type eq "int16_t*" || + $type eq "int32_t" || $type eq "int32_t*" || + $type eq "int64_t" || $type eq "int64_t*" || + $type eq "uint8_t" || $type eq "uint8_t*" || + $type eq "uint16_t" || $type eq "uint16_t*" || + $type eq "uint32_t" || $type eq "uint32_t*" || + $type eq "uint64_t" || $type eq "uint64_t*") { + if ($dir eq "IN") { + print PYOUT "\t\tparam_$name"; + } else { + print PYOUT "\t\t¶m_$name"; + } + } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { + print PYOUT "\t\t¶m_$name->x"; + } else { + die "Unsupported type \"$type\""; + } + } + print PYOUT ");\n"; + print PYOUT "\tif (ret != 0) {\n"; + print PYOUT "\t\tif (ret == -1 && errno == ENOMEM)\n"; + print PYOUT "\t\t\tres = PyExc_MemoryError;\n"; + print PYOUT "\t\telse if (ret == -1)\n"; + print PYOUT "\t\t\tres = PyErr_SetFromErrno(PyExc_IOError);\n"; + print PYOUT "\t\telse\n"; + print PYOUT "\t\t\tres = PyLong_FromLong(ret);\n"; + print PYOUT "\t\tgoto error;\n"; + print PYOUT "\t}\n"; + + # Pass back any replies + if (@reply) { + print PYOUT "\n"; + foreach my $p (@reply) { + my ($type, $name, $array_size, $max_size, $dir) = @{$p}; + + my $set_null = 0; + my $var = "tmp"; + + if ($type eq "int8_t" || $type eq "int8_t*" || + $type eq "int16_t" || $type eq "int16_t*" || + $type eq "int32_t" || $type eq "int32_t*") { + print PYOUT "\ttmp = PyLong_FromLong(param_$name);\n"; + } elsif ($type eq "int64_t" || $type eq "int64_t*") { + print PYOUT "\ttmp = PyLong_FromLongLong(param_$name);\n"; + } elsif ($type eq "uint8_t" || $type eq "uint8_t*" || + $type eq "uint16_t" || $type eq "uint16_t*" || + $type eq "uint32_t" || $type eq "uint32_t*") { + + print PYOUT "\ttmp = PyLong_FromUnsignedLong(param_$name);\n"; + + } elsif ($type eq "uint64_t" || $type eq "uint64_t*") { + print PYOUT "\ttmp = PyLong_FromUnsignedLongLong(param_$name);\n"; + + } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { + $var = "(PyObject *)param_$name"; + $set_null = 1; + } else { + die "Unsupported type \"$type\""; + } + + if ($var eq "tmp") { + print PYOUT "\tif (!tmp)\n"; + print PYOUT "\t\tgoto error;\n"; + } + + print PYOUT "\tif (PyList_Insert(reply_$name, 0, $var) == -1)\n"; + print PYOUT "\t\tgoto error", $need_tmp ? "_tmp" : "", ";\n"; + print PYOUT "\tparam_$name = NULL;\n" if ($set_null); + } + + } + + # Successful return + print PYOUT "\n"; + print PYOUT "\treturn PyLong_FromLong(0);\n"; + + # Error cleanups + print PYOUT "\n"; + if ($need_tmp) { + print PYOUT "error_tmp:\n"; + print PYOUT "\tPy_DECREF(tmp);\n"; + } + print PYOUT "error:\n"; + if (@reply) { + foreach my $p (reverse @reply) { + my ($type, $name, $array_size, $max_size, $dir) = @{$p}; + if ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { + print PYOUT "\tPy_XDECREF(param_$name);\n"; + print PYOUT "error_alloc_$name:\n"; + } + } + } + + print PYOUT "\treturn res;\n"; + + # End the function + print PYOUT "}\n"; +} + +1; diff --git a/rxgen/rxgen.pl b/rxgen/rxgen.pl index a377e24..59d4cc3 100755 --- a/rxgen/rxgen.pl +++ b/rxgen/rxgen.pl @@ -17,6 +17,8 @@ # use strict; +use lib "rxgen"; +use emit_py_sync_funcs; sub emit_py_struct_wrapper($@); sub emit_py_func_simple_sync_call($$$@); @@ -907,239 +909,3 @@ if (@structs) { } print PYOUT "}\n"; - -############################################################################### -# -# Emit a python wrapper function to make a simple synchronous call -# -############################################################################### -sub emit_py_func_simple_sync_call($$$@) -{ - my ($func, $_request, $_reply, @params) = @_; - my @request = @{$_request}; - my @reply = @{$_reply}; - - print PYOUT "PyObject *\n"; - print PYOUT "kafs_", $func, "(PyObject *_self, PyObject *args)\n"; - print PYOUT "{\n"; - - # Declare parameter variables - my $need_tmp = 0; - print PYOUT "\tstruct py_rx_connection *z_conn;\n"; - foreach my $p (@params) { - my ($type, $name, $array_size, $max_size, $dir) = @{$p}; - if ($type eq "char*") { - die "String output args not supported" unless ($dir eq "IN"); - print PYOUT "\tconst char *param_$name;\n"; - } elsif ($type eq "int8_t" || $type eq "int8_t*" || - $type eq "int16_t" || $type eq "int16_t*" || - $type eq "int32_t" || $type eq "int32_t*" || - $type eq "int64_t" || $type eq "int64_t*" || - $type eq "uint8_t" || $type eq "uint8_t*" || - $type eq "uint16_t" || $type eq "uint16_t*" || - $type eq "uint32_t" || $type eq "uint32_t*" || - $type eq "uint64_t" || $type eq "uint64_t*" - ) { - $type =~ s/[*]$//; - $need_tmp = 1 unless ($dir eq "IN"); - print PYOUT "\t$type param_$name;\n"; - } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { - die "INOUT struct args not supported" if ($dir eq "INOUT"); - print PYOUT "\tstruct py_$1 *param_$name;\n"; - } else { - die "Unsupported type \"$type\""; - } - } - - # Replies are passed back into lists provided by the caller. INOUT variable - # input values must already occupy the lists. - foreach my $p (@reply) { - my ($type, $name, $array_size, $max_size, $dir) = @{$p}; - print PYOUT "\tPyObject *reply_$name;\n"; - } - - print PYOUT "\tPyObject *tmp;\n" if ($need_tmp); - print PYOUT "\tPyObject *res = NULL;\n"; - print PYOUT "\tint ret;\n"; - - # Make use of the tuple parser to extract the arguments and check their - # types for us. - print PYOUT "\n"; - print PYOUT "\tif (!PyArg_ParseTuple(args, \"O!"; - - foreach my $p (@params) { - my ($type, $name, $array_size, $max_size, $dir) = @{$p}; - if ($dir ne "IN") { - print PYOUT "O!"; - } elsif ($type eq "char*") { - print PYOUT "s"; - } elsif ($type eq "int8_t") { - print PYOUT "B"; - } elsif ($type eq "int16_t") { - print PYOUT "h"; - } elsif ($type eq "int32_t") { - print PYOUT "i"; - } elsif ($type eq "int64_t") { - print PYOUT "L"; - } elsif ($type eq "uint8_t") { - print PYOUT "b"; - } elsif ($type eq "uint16_t") { - print PYOUT "H"; - } elsif ($type eq "uint32_t") { - print PYOUT "I"; - } elsif ($type eq "uint64_t") { - print PYOUT "K"; - } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { - print PYOUT "O!"; - } - } - - print PYOUT "\",\n"; - print PYOUT "\t\t\t &py_rx_connectionType, &z_conn"; - - foreach my $p (@params) { - my ($type, $name, $array_size, $max_size, $dir) = @{$p}; - print PYOUT ",\n"; - print PYOUT "\t\t\t /*$dir*/ "; - if ($dir ne "IN") { - print PYOUT "&PyList_Type, &reply_$name"; - } elsif ($type eq "char*" || - $type eq "int8_t" || $type eq "int8_t" || - $type eq "int16_t" || $type eq "int16_t" || - $type eq "int32_t" || $type eq "int32_t" || - $type eq "int64_t" || $type eq "int64_t" || - $type eq "uint8_t" || $type eq "uint8_t" || - $type eq "uint16_t" || $type eq "uint16_t" || - $type eq "uint32_t" || $type eq "uint32_t" || - $type eq "uint64_t" || $type eq "uint64_t") { - print PYOUT "¶m_$name"; - } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { - print PYOUT "&py_", $1, "Type, ¶m_$name"; - } else { - die "Unsupported type \"$type\""; - } - } - print PYOUT "))\n"; - print PYOUT "\t\treturn NULL;\n"; - - # Allocate reply buffer objects - if (@reply) { - print PYOUT "\n"; - foreach my $p (@reply) { - my ($type, $name, $array_size, $max_size, $dir) = @{$p}; - if ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { - print PYOUT "\tparam_$name = (struct py_$1 *)kafs_new_py_$1(NULL, NULL);\n"; - print PYOUT "\tif (!param_$name)\n"; - print PYOUT "\t\tgoto error_alloc_$name;\n"; - } - } - } - - # Make the call - print PYOUT "\n"; - print PYOUT "\tret = $func(\n"; - print PYOUT "\t\tz_conn->x"; - - foreach my $p (@params) { - print PYOUT ",\n"; - my ($type, $name, $array_size, $max_size, $dir) = @{$p}; - if ($type eq "char*" || - $type eq "int8_t" || $type eq "int8_t*" || - $type eq "int16_t" || $type eq "int16_t*" || - $type eq "int32_t" || $type eq "int32_t*" || - $type eq "int64_t" || $type eq "int64_t*" || - $type eq "uint8_t" || $type eq "uint8_t*" || - $type eq "uint16_t" || $type eq "uint16_t*" || - $type eq "uint32_t" || $type eq "uint32_t*" || - $type eq "uint64_t" || $type eq "uint64_t*") { - if ($dir eq "IN") { - print PYOUT "\t\tparam_$name"; - } else { - print PYOUT "\t\t¶m_$name"; - } - } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { - print PYOUT "\t\t¶m_$name->x"; - } else { - die "Unsupported type \"$type\""; - } - } - print PYOUT ");\n"; - print PYOUT "\tif (ret != 0) {\n"; - print PYOUT "\t\tif (ret == -1 && errno == ENOMEM)\n"; - print PYOUT "\t\t\tres = PyExc_MemoryError;\n"; - print PYOUT "\t\telse if (ret == -1)\n"; - print PYOUT "\t\t\tres = PyErr_SetFromErrno(PyExc_IOError);\n"; - print PYOUT "\t\telse\n"; - print PYOUT "\t\t\tres = PyLong_FromLong(ret);\n"; - print PYOUT "\t\tgoto error;\n"; - print PYOUT "\t}\n"; - - # Pass back any replies - if (@reply) { - print PYOUT "\n"; - foreach my $p (@reply) { - my ($type, $name, $array_size, $max_size, $dir) = @{$p}; - - my $set_null = 0; - my $var = "tmp"; - - if ($type eq "int8_t" || $type eq "int8_t*" || - $type eq "int16_t" || $type eq "int16_t*" || - $type eq "int32_t" || $type eq "int32_t*") { - print PYOUT "\ttmp = PyLong_FromLong(param_$name);\n"; - } elsif ($type eq "int64_t" || $type eq "int64_t*") { - print PYOUT "\ttmp = PyLong_FromLongLong(param_$name);\n"; - } elsif ($type eq "uint8_t" || $type eq "uint8_t*" || - $type eq "uint16_t" || $type eq "uint16_t*" || - $type eq "uint32_t" || $type eq "uint32_t*") { - - print PYOUT "\ttmp = PyLong_FromUnsignedLong(param_$name);\n"; - - } elsif ($type eq "uint64_t" || $type eq "uint64_t*") { - print PYOUT "\ttmp = PyLong_FromUnsignedLongLong(param_$name);\n"; - - } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { - $var = "(PyObject *)param_$name"; - $set_null = 1; - } else { - die "Unsupported type \"$type\""; - } - - if ($var eq "tmp") { - print PYOUT "\tif (!tmp)\n"; - print PYOUT "\t\tgoto error;\n"; - } - - print PYOUT "\tif (PyList_Insert(reply_$name, 0, $var) == -1)\n"; - print PYOUT "\t\tgoto error", $need_tmp ? "_tmp" : "", ";\n"; - print PYOUT "\tparam_$name = NULL;\n" if ($set_null); - } - - } - - # Successful return - print PYOUT "\n"; - print PYOUT "\treturn PyLong_FromLong(0);\n"; - - # Error cleanups - print PYOUT "\n"; - if ($need_tmp) { - print PYOUT "error_tmp:\n"; - print PYOUT "\tPy_DECREF(tmp);\n"; - } - print PYOUT "error:\n"; - if (@reply) { - foreach my $p (reverse @reply) { - my ($type, $name, $array_size, $max_size, $dir) = @{$p}; - if ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) { - print PYOUT "\tPy_XDECREF(param_$name);\n"; - print PYOUT "error_alloc_$name:\n"; - } - } - } - - print PYOUT "\treturn res;\n"; - - # End the function - print PYOUT "}\n"; -}