$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}) {
}
}
+ 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;
# 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");
" 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");
*
* '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
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;
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;
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;
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;
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;
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;
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;
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;