[libvirt] [PATCH] remote generator: Handle struct returning functions better

Matthias Bolte matthias.bolte at googlemail.com
Wed Jun 15 13:42:32 UTC 2011


The position of the struct parameter in the function signature
differs. Instead of hardcoding the handling for this add an annotation
to the .x file to define the position.
---
 daemon/remote_generator.pl   |   42 ++++++++++++++++++++++++------------------
 src/remote/remote_protocol.x |   23 ++++++++++++++---------
 2 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/daemon/remote_generator.pl b/daemon/remote_generator.pl
index ce35ebe..351866b 100755
--- a/daemon/remote_generator.pl
+++ b/daemon/remote_generator.pl
@@ -95,8 +95,9 @@ while (<PROTOCOL>) {
         $collect_args_members = 1;
         $collect_ret_members = 0;
         $last_name = $name;
-    } elsif (/^struct ${structprefix}_(.*)_ret/) {
+    } elsif (/^struct ${structprefix}_(.*)_ret\s+{(.*)$/) {
         $name = $1;
+        $flags = $2;
         $ProcName = name_to_ProcName ($name);
 
         if (exists $calls{$name}) {
@@ -112,6 +113,14 @@ while (<PROTOCOL>) {
             }
         }
 
+        if ($flags ne "" and ($opt_b or $opt_k)) {
+            if (!($flags =~ m/^\s*\/\*\s*insert@(\d+)\s*\*\/\s*$/)) {
+                die "invalid generator flags for $calls{$name}->{ret}";
+            }
+
+            $calls{$name}->{ret_offset} = int($1);
+        }
+
         $collect_args_members = 0;
         $collect_ret_members = 1;
         $last_name = $name;
@@ -668,29 +677,26 @@ elsif ($opt_b) {
 
         # select struct type for multi-return-value functions
         if ($multi_ret) {
-            if (! @args_list) {
+            if (!(defined $call->{ret_offset})) {
+                die "multi-return-value without insert@<offset> annotation: $call->{ret}";
+            }
+
+            if (!@args_list) {
                 push(@args_list, "conn");
             }
 
             my $struct_name = $call->{ProcName};
             $struct_name =~ s/Get//;
 
-            if ($call->{ProcName} eq "DomainGetBlockInfo") {
-                # SPECIAL: virDomainGetBlockInfo has flags parameter after
-                #          the struct parameter in its signature
-                my $flags = pop(@args_list);
-                push(@args_list, "&tmp");
-                push(@args_list, $flags);
-            } elsif ($call->{ProcName} eq "DomainBlockStats" ||
-                     $call->{ProcName} eq "DomainInterfaceStats") {
+            splice(@args_list, $call->{ret_offset}, 0, ("&tmp"));
+
+            if ($call->{ProcName} eq "DomainBlockStats" ||
+                $call->{ProcName} eq "DomainInterfaceStats") {
                 # SPECIAL: virDomainBlockStats and virDomainInterfaceStats
                 #          have a 'Struct' suffix on the actual struct name
                 #          and take the struct size as additional argument
                 $struct_name .= "Struct";
-                push(@args_list, "&tmp");
-                push(@args_list, "sizeof tmp");
-            } else {
-                push(@args_list, "&tmp");
+                splice(@args_list, $call->{ret_offset} + 1, 0, ("sizeof tmp"));
             }
 
             push(@vars_list, "vir$struct_name tmp");
@@ -1012,14 +1018,14 @@ elsif ($opt_k) {
                                          "        xdr_free((xdrproc_t)xdr_$call->{args}, (char *)&args);\n" .
                                          "        goto done;\n" .
                                          "    }");
-                } elsif ($args_member =~ m/^(unsigned )?int (\S+);\s*\/\*\s*call-by-reference\s*\*\//) {
-                    my $type_name = $1; $type_name .= "int *";
+                } elsif ($args_member =~ m/^((?:unsigned )?int) (\S+);\s*\/\*\s*call-by-reference\s*\*\//) {
+                    my $type_name = "$1 *";
                     my $arg_name = $2;
 
                     push(@args_list, "$type_name $arg_name");
                     push(@setters_list, "args.$arg_name = *$arg_name;");
-                } elsif ($args_member =~ m/^(unsigned )?int (\S+);/) {
-                    my $type_name = $1; $type_name .= "int";
+                } elsif ($args_member =~ m/^((?:unsigned )?int) (\S+);/) {
+                    my $type_name = $1;
                     my $arg_name = $2;
 
                     push(@args_list, "$type_name $arg_name");
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 0dd8b09..2b9784b 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -352,7 +352,12 @@ struct remote_node_get_memory_stats {
  *
  * 'remote_CALL_ret' members that are filled via call-by-reference must be
  * annotated with a insert@<offset> comment to indicate the offset in the
- * parameter list of the function to be called. */
+ * parameter list of the function to be called.
+ *
+ * If the 'remote_CALL_ret' maps to a struct in the public API then it is
+ * also filled via call-by-reference and must be annotated with a
+ * insert@<offset> comment to indicate the offset in the parameter list of
+ * the function to be called. */
 
 struct remote_open_args {
     /* NB. "name" might be NULL although in practice you can't
@@ -409,7 +414,7 @@ struct remote_get_max_vcpus_ret {
     int max_vcpus;
 };
 
-struct remote_node_get_info_ret {
+struct remote_node_get_info_ret { /* insert at 1 */
     char model[32];
     unsigned hyper memory;
     int cpus;
@@ -537,7 +542,7 @@ struct remote_domain_block_stats_args {
     remote_nonnull_string path;
 };
 
-struct remote_domain_block_stats_ret {
+struct remote_domain_block_stats_ret { /* insert at 2 */
     hyper rd_req;
     hyper rd_bytes;
     hyper wr_req;
@@ -550,7 +555,7 @@ struct remote_domain_interface_stats_args {
     remote_nonnull_string path;
 };
 
-struct remote_domain_interface_stats_ret {
+struct remote_domain_interface_stats_ret { /* insert at 2 */
     hyper rx_bytes;
     hyper rx_packets;
     hyper rx_errs;
@@ -605,7 +610,7 @@ struct remote_domain_get_block_info_args {
     unsigned int flags;
 };
 
-struct remote_domain_get_block_info_ret {
+struct remote_domain_get_block_info_ret { /* insert at 2 */
     unsigned hyper allocation;
     unsigned hyper capacity;
     unsigned hyper physical;
@@ -713,7 +718,7 @@ struct remote_domain_get_info_args {
     remote_nonnull_domain dom;
 };
 
-struct remote_domain_get_info_ret {
+struct remote_domain_get_info_ret { /* insert at 1 */
     unsigned char state;
     unsigned hyper maxMem;
     unsigned hyper memory;
@@ -1400,7 +1405,7 @@ struct remote_storage_pool_get_info_args {
     remote_nonnull_storage_pool pool;
 };
 
-struct remote_storage_pool_get_info_ret {
+struct remote_storage_pool_get_info_ret { /* insert at 1 */
     unsigned char state;
     unsigned hyper capacity;
     unsigned hyper allocation;
@@ -1510,7 +1515,7 @@ struct remote_storage_vol_get_info_args {
     remote_nonnull_storage_vol vol;
 };
 
-struct remote_storage_vol_get_info_ret {
+struct remote_storage_vol_get_info_ret { /* insert at 1 */
     char type;
     unsigned hyper capacity;
     unsigned hyper allocation;
@@ -1827,7 +1832,7 @@ struct remote_domain_get_job_info_args {
     remote_nonnull_domain dom;
 };
 
-struct remote_domain_get_job_info_ret {
+struct remote_domain_get_job_info_ret { /* insert at 1 */
     int type;
 
     unsigned hyper timeElapsed;
-- 
1.7.0.4




More information about the libvir-list mailing list