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