[PATCH] remote generator: Handle struct returning functions better

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@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@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@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@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@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@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@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@1 */
     int type;
 
     unsigned hyper timeElapsed;
-- 
1.7.0.4

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]