]> www.infradead.org Git - users/dhowells/kafs-utils.git/commitdiff
rxgen: Extract C synchronous RPC func emitter
authorDavid Howells <dhowells@redhat.com>
Thu, 9 Jan 2014 14:59:13 +0000 (14:59 +0000)
committerDavid Howells <dhowells@redhat.com>
Thu, 9 Jan 2014 14:59:13 +0000 (14:59 +0000)
Extract the code to emit C functions to perform synchronous RPC calls from the
main rxgen script and put into its own module.

Signed-off-by: David Howells <dhowells@redhat.com>
rxgen/emit_c_sync_funcs.pm [new file with mode: 0644]
rxgen/rxgen.pl

diff --git a/rxgen/emit_c_sync_funcs.pm b/rxgen/emit_c_sync_funcs.pm
new file mode 100644 (file)
index 0000000..aaa939f
--- /dev/null
@@ -0,0 +1,195 @@
+#
+# 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 function to encode a request
+#
+###############################################################################
+sub emit_func_enc_request($$$$$@)
+{
+    my ($func, $op, $request_size, $req_has_charptr, $reply_size, @request) = @_;
+
+    # Function definition and arguments
+    print RXOUT "int rxgen_send_request_", $func, "(\n";
+    print RXOUT "\tstruct rx_connection *z_conn,\n";
+    print RXOUT "\tstruct rx_call *call";
+    foreach my $p (@request) {
+       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
+       print RXOUT ",\n\t";
+       print RXOUT "const " if ($type =~ "[*]");
+       print RXOUT "$type $name";
+       die "Array arg not supported '$name'" if ($array_size != -1);
+    }
+    print RXOUT ")\n";
+
+    # Function body, beginning with local variables
+    print RXOUT "{\n";
+    if ($req_has_charptr) {
+       print RXOUT "\tnet_xdr_t request[", $request_size / 4, " + 1], *xdr;\n";
+       print RXOUT "\tuint32_t tmp;\n";
+    } else {
+       print RXOUT "\tnet_xdr_t request[", $request_size / 4, "], *xdr;\n";
+    }
+
+    # Marshal the data
+    print RXOUT "\n";
+    print RXOUT "\txdr = request;\n";
+    print RXOUT "\t*xdr++ = htonl($op);\n";
+    foreach my $p (@request) {
+       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
+       if ($type eq "uint8_t" ||
+           $type eq "uint16_t" ||
+           $type eq "uint32_t") {
+           print RXOUT "\t*xdr++ = htonl($name);\n";
+       } elsif ($type eq "char*") {
+           print RXOUT "\ttmp = strlen($name);\n";
+           print RXOUT "\t*xdr++ = htonl(tmp);\n";
+           print RXOUT "\txdr[tmp / 4] = 0;\n";
+           print RXOUT "\tmemcpy(xdr, $name, tmp);\n";
+           print RXOUT "\txdr += (tmp + 3) / 4;\n";
+       } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
+           print RXOUT "\txdr = rxgen_encode_$1(xdr, $name);\n";
+       }
+    }
+
+    # Send the message
+    print RXOUT "\n";
+    print RXOUT "\treturn rxrpc_send_request(z_conn, call, request, (xdr - request) * 4, $reply_size);\n";
+    print RXOUT "}\n";
+}
+
+###############################################################################
+#
+# Emit a function to decode a reply
+#
+###############################################################################
+sub emit_func_dec_reply($$$@)
+{
+    my ($func, $op, $reply_size, @reply) = @_;
+
+    print RXOUT "\n";
+
+    # Function definition and arguments
+    print RXOUT "void rxgen_decode_reply_", $func, "(\n";
+    print RXOUT "\tstruct rx_connection *z_conn,\n";
+    print RXOUT "\tstruct rx_call *call";
+    foreach my $p (@reply) {
+       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
+       print RXOUT ",\n\t";
+       print RXOUT "$type $name";
+       die "Array arg not supported '$name'" if ($array_size != -1);
+    }
+    print RXOUT ")\n";
+
+    # Function body, beginning with local variables
+    print RXOUT "{\n";
+    print RXOUT "\tconst net_xdr_t *xdr;\n";
+
+    # Unmarshal the data
+    print RXOUT "\n";
+    print RXOUT "\txdr = call->reply;\n";
+    foreach my $p (@reply) {
+       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
+       if ($type eq "int8_t*"   ||
+           $type eq "int16_t*"  ||
+           $type eq "int32_t*"  ||
+           $type eq "uint8_t*"  ||
+           $type eq "uint16_t*" ||
+           $type eq "uint32_t*") {
+           print RXOUT "\t*$name = ntohl(*xdr++);\n";
+       } elsif ($type eq "int64_t*" ||
+                $type eq "uint64_t*") {
+           print RXOUT "\t*$name = (uint64_t)ntohl(*xdr++) << 32\n";
+           print RXOUT "\t\t | (uint64_t)ntohl(*xdr++);\n";
+       } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
+           print RXOUT "\txdr = rxgen_decode_$1($name, xdr);\n";
+       }
+    }
+
+    print RXOUT "}\n";
+}
+
+###############################################################################
+#
+# Emit a function to make a simple synchronous call
+#
+###############################################################################
+sub emit_func_simple_sync_call($$$$$@)
+{
+    my ($func, $request_size, $reply_size, $_request, $_reply, @params) = @_;
+    my @request = @{$_request};
+    my @reply = @{$_reply};
+
+    print RXOUT "\n";
+
+    # Function definition and arguments
+    print RXOUT "int ", $func, "(\n";
+    print RXOUT "\tstruct rx_connection *z_conn";
+    foreach my $p (@params) {
+       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
+       print RXOUT ",\n\t";
+       print RXOUT "const " if ($type =~ "[*]" && $dir eq "IN");
+       print RXOUT "$type $name";
+       die "Array arg not supported '$name'" if ($array_size != -1);
+    }
+    print RXOUT ")\n";
+
+    # Function body, beginning with local variables
+    print RXOUT "{\n";
+    print RXOUT "\tstruct rx_call *call;\n";
+    print RXOUT "\tint ret;\n";
+    print RXOUT "\n";
+
+    # Allocate a call record and reply buffer
+    print RXOUT "\tcall = malloc(sizeof(*call) + $reply_size);\n";
+    print RXOUT "\tif (!call)\n";
+    print RXOUT "\t\treturn -1;\n";
+    print RXOUT "\tcall->reply = (void *)call + sizeof(*call);\n";
+    print RXOUT "\n";
+
+    # Send the request
+    print RXOUT "\tret = rxgen_send_request_", $func, "(";
+    print RXOUT "z_conn, call";
+    foreach my $p (@request) {
+       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
+       print RXOUT ", $name";
+    }
+    print RXOUT ");\n";
+    print RXOUT "\tif (ret != 0) {\n";
+    print RXOUT "\t\tfree(call);\n";
+    print RXOUT "\t\treturn ret;\n";
+    print RXOUT "\t}\n";
+
+    # Wait for the reply
+    print RXOUT "\tret = rxrpc_wait_for_sync_reply(z_conn, call);\n";
+    print RXOUT "\tif (ret != 0) {\n";
+    print RXOUT "\t\tfree(call);\n";
+    print RXOUT "\t\treturn ret;\n";
+    print RXOUT "\t}\n";
+    print RXOUT "\n";
+
+    # Unmarshal the reply
+    if (@reply) {
+       print RXOUT "\trxgen_decode_reply_", $func, "(";
+       print RXOUT "z_conn, call";
+       foreach my $p (@reply) {
+           my ($type, $name, $array_size, $max_size, $dir) = @{$p};
+           print RXOUT ", $name";
+       }
+       print RXOUT ");\n";
+    }
+
+    print RXOUT "\n";
+    print RXOUT "\treturn 0;\n";
+    print RXOUT "}\n";
+}
+
+1;
index 22238e439fdb406f7964346360afa9b3718613bb..0d73803fc841b72e12f35a28d331e63903119a2b 100755 (executable)
@@ -19,6 +19,7 @@
 use strict;
 use lib "rxgen";
 use emit_c_struct;
+use emit_c_sync_funcs;
 use emit_py_types;
 use emit_py_sync_funcs;
 use emit_py_module;
@@ -166,41 +167,11 @@ while (my $line = <>) {
 
 }
 
-#print "----------------------------------------\n";
-
-#foreach $_ (sort keys %constants) {
-#    print $_, " -> (", $constants{$_}, ")\n";
-#}
-
-# foreach $_ (keys %structs) {
-#     print "-- ", $_, " --\n";
-#     my $p = $structs{$_};
-#     print $#{$p}, "\n";
-#     my @members = @{$p};
-#     shift @members;
-#     foreach my $m (@members) {
-#      if (@{$m}[2] eq -1) {
-#          print @{$m}[1], " IS ", @{$m}[0], "\n";
-#      } else {
-#          print @{$m}[1], " IS ", @{$m}[0], "[", @{$m}[2], "]\n";
-#      }
-#     }
-# }
-
-# foreach $_ (keys %funcs) {
-#     print "-- ", $_, " --\n";
-#     my $p = $funcs{$_};
-#     my @members = @{$p};
-#     shift @members;
-#     foreach my $m (@members) {
-#      if (@{$m}[2] eq -1) {
-#          print "\t", @{$m}[1], " IS ", @{$m}[0], "\n";
-#      } else {
-#          print "\t", @{$m}[1], " IS ", @{$m}[0], "[", @{$m}[2], "]\n";
-#      }
-#     }
-# }
-
+###############################################################################
+#
+# Create the output files and emit the file prologues.
+#
+###############################################################################
 open RXOUT, ">afs_xg.c" || die "afs_xg.c";
 print RXOUT "/* AUTOGENERATED */\n";
 print RXOUT "#define _XOPEN_SOURCE\n";
@@ -232,6 +203,7 @@ print PYOUT "#include \"afs_py.h\"\n";
 print PYOUT "#include <arpa/inet.h>\n";
 print PYOUT "#include \"py_rxgen.h\"\n";
 
+# Declare types
 foreach my $s (@structs) {
     my @members = @{$s};
     my $struct = shift @members;
@@ -241,191 +213,8 @@ foreach my $s (@structs) {
 
 ###############################################################################
 #
-# Emit a function to encode a request
-#
-###############################################################################
-sub emit_func_enc_request($$$$$@)
-{
-    my ($func, $op, $request_size, $req_has_charptr, $reply_size, @request) = @_;
-
-    # Function definition and arguments
-    print RXOUT "int rxgen_send_request_", $func, "(\n";
-    print RXOUT "\tstruct rx_connection *z_conn,\n";
-    print RXOUT "\tstruct rx_call *call";
-    foreach my $p (@request) {
-       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
-       print RXOUT ",\n\t";
-       print RXOUT "const " if ($type =~ "[*]");
-       print RXOUT "$type $name";
-       die "Array arg not supported '$name'" if ($array_size != -1);
-    }
-    print RXOUT ")\n";
-
-    # Function body, beginning with local variables
-    print RXOUT "{\n";
-    if ($req_has_charptr) {
-       print RXOUT "\tnet_xdr_t request[", $request_size / 4, " + 1], *xdr;\n";
-       print RXOUT "\tuint32_t tmp;\n";
-    } else {
-       print RXOUT "\tnet_xdr_t request[", $request_size / 4, "], *xdr;\n";
-    }
-
-    # Marshal the data
-    print RXOUT "\n";
-    print RXOUT "\txdr = request;\n";
-    print RXOUT "\t*xdr++ = htonl($op);\n";
-    foreach my $p (@request) {
-       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
-       if ($type eq "uint8_t" ||
-           $type eq "uint16_t" ||
-           $type eq "uint32_t") {
-           print RXOUT "\t*xdr++ = htonl($name);\n";
-       } elsif ($type eq "char*") {
-           print RXOUT "\ttmp = strlen($name);\n";
-           print RXOUT "\t*xdr++ = htonl(tmp);\n";
-           print RXOUT "\txdr[tmp / 4] = 0;\n";
-           print RXOUT "\tmemcpy(xdr, $name, tmp);\n";
-           print RXOUT "\txdr += (tmp + 3) / 4;\n";
-       } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
-           print RXOUT "\txdr = rxgen_encode_$1(xdr, $name);\n";
-       }
-    }
-
-    # Send the message
-    print RXOUT "\n";
-    print RXOUT "\treturn rxrpc_send_request(z_conn, call, request, (xdr - request) * 4, $reply_size);\n";
-    print RXOUT "}\n";
-}
-
-###############################################################################
-#
-# Emit a function to decode a reply
-#
-###############################################################################
-sub emit_func_dec_reply($$$@)
-{
-    my ($func, $op, $reply_size, @reply) = @_;
-
-    print RXOUT "\n";
-
-    # Function definition and arguments
-    print RXOUT "void rxgen_decode_reply_", $func, "(\n";
-    print RXOUT "\tstruct rx_connection *z_conn,\n";
-    print RXOUT "\tstruct rx_call *call";
-    foreach my $p (@reply) {
-       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
-       print RXOUT ",\n\t";
-       print RXOUT "$type $name";
-       die "Array arg not supported '$name'" if ($array_size != -1);
-    }
-    print RXOUT ")\n";
-
-    # Function body, beginning with local variables
-    print RXOUT "{\n";
-    print RXOUT "\tconst net_xdr_t *xdr;\n";
-
-    # Unmarshal the data
-    print RXOUT "\n";
-    print RXOUT "\txdr = call->reply;\n";
-    foreach my $p (@reply) {
-       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
-       if ($type eq "int8_t*"   ||
-           $type eq "int16_t*"  ||
-           $type eq "int32_t*"  ||
-           $type eq "uint8_t*"  ||
-           $type eq "uint16_t*" ||
-           $type eq "uint32_t*") {
-           print RXOUT "\t*$name = ntohl(*xdr++);\n";
-       } elsif ($type eq "int64_t*" ||
-                $type eq "uint64_t*") {
-           print RXOUT "\t*$name = (uint64_t)ntohl(*xdr++) << 32\n";
-           print RXOUT "\t\t | (uint64_t)ntohl(*xdr++);\n";
-       } elsif ($type =~ /struct ([a-zA-Z_][a-zA-Z0-9_]*)[*]/) {
-           print RXOUT "\txdr = rxgen_decode_$1($name, xdr);\n";
-       }
-    }
-
-    print RXOUT "}\n";
-}
-
-###############################################################################
-#
-# Emit a function to make a simple synchronous call
-#
-###############################################################################
-sub emit_func_simple_sync_call($$$$$@)
-{
-    my ($func, $request_size, $reply_size, $_request, $_reply, @params) = @_;
-    my @request = @{$_request};
-    my @reply = @{$_reply};
-
-    print RXOUT "\n";
-
-    # Function definition and arguments
-    print RXOUT "int ", $func, "(\n";
-    print RXOUT "\tstruct rx_connection *z_conn";
-    foreach my $p (@params) {
-       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
-       print RXOUT ",\n\t";
-       print RXOUT "const " if ($type =~ "[*]" && $dir eq "IN");
-       print RXOUT "$type $name";
-       die "Array arg not supported '$name'" if ($array_size != -1);
-    }
-    print RXOUT ")\n";
-
-    # Function body, beginning with local variables
-    print RXOUT "{\n";
-    print RXOUT "\tstruct rx_call *call;\n";
-    print RXOUT "\tint ret;\n";
-    print RXOUT "\n";
-
-    # Allocate a call record and reply buffer
-    print RXOUT "\tcall = malloc(sizeof(*call) + $reply_size);\n";
-    print RXOUT "\tif (!call)\n";
-    print RXOUT "\t\treturn -1;\n";
-    print RXOUT "\tcall->reply = (void *)call + sizeof(*call);\n";
-    print RXOUT "\n";
-
-    # Send the request
-    print RXOUT "\tret = rxgen_send_request_", $func, "(";
-    print RXOUT "z_conn, call";
-    foreach my $p (@request) {
-       my ($type, $name, $array_size, $max_size, $dir) = @{$p};
-       print RXOUT ", $name";
-    }
-    print RXOUT ");\n";
-    print RXOUT "\tif (ret != 0) {\n";
-    print RXOUT "\t\tfree(call);\n";
-    print RXOUT "\t\treturn ret;\n";
-    print RXOUT "\t}\n";
-
-    # Wait for the reply
-    print RXOUT "\tret = rxrpc_wait_for_sync_reply(z_conn, call);\n";
-    print RXOUT "\tif (ret != 0) {\n";
-    print RXOUT "\t\tfree(call);\n";
-    print RXOUT "\t\treturn ret;\n";
-    print RXOUT "\t}\n";
-    print RXOUT "\n";
-
-    # Unmarshal the reply
-    if (@reply) {
-       print RXOUT "\trxgen_decode_reply_", $func, "(";
-       print RXOUT "z_conn, call";
-       foreach my $p (@reply) {
-           my ($type, $name, $array_size, $max_size, $dir) = @{$p};
-           print RXOUT ", $name";
-       }
-       print RXOUT ");\n";
-    }
-
-    print RXOUT "\n";
-    print RXOUT "\treturn 0;\n";
-    print RXOUT "}\n";
-}
-
-###############################################################################
-#
-# Dump RPC call encoders and decoders
+# Emit RPC call functions.  For this we need to classify parameters according
+# to input and output usage and work out how big the RPC messages will be.
 #
 ###############################################################################
 foreach $func (sort keys %funcs) {