Teach gendispatch how to handle admin dispatching files

Since this is just a new option for gendispatch, it looks more like a
cleanup.  The only differences handled by it are connect pointers,
private pointers and API naming customs.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Martin Kletzander 2015-03-17 10:09:48 +01:00
parent a474611458
commit 87c2687943

View File

@ -49,6 +49,8 @@ my $procprefix = shift or die "missing procedure prefix argument";
my $protocol = shift or die "missing protocol argument";
my @autogen;
my $connect_ptr = $structprefix eq "admin" ? "virAdmConnectPtr" : "virConnectPtr";
my $prefix = ($structprefix eq "admin") ? "adm" : "vir";
sub fixup_name {
my $name = shift;
@ -78,9 +80,12 @@ sub fixup_name {
# Convert name_of_call to NameOfCall.
sub name_to_ProcName {
my $name = shift;
my $forcefix = $structprefix eq "admin";
my @elems;
if ($name =~ /_/ || (lc $name) eq "open" || (lc $name) eq "close") {
if ($forcefix || $name =~ /_/ ||
(lc $name) eq "open" || (lc $name) eq "close") {
@elems = split /_/, $name;
@elems = map lc, @elems;
@elems = map ucfirst, @elems;
@ -104,6 +109,19 @@ sub name_to_TypeName {
return $typename;
}
sub push_privconn {
my $args = shift;
if (!@$args) {
if ($structprefix eq "admin") {
push(@$args, "priv->dmn");
} else {
push(@$args, "priv->conn");
}
}
}
# Read the input file (usually remote_protocol.x) and form an
# opinion about the name, args and return type of each RPC.
my ($name, $ProcName, $id, $flags, %calls, @calls, %opts);
@ -505,21 +523,16 @@ elsif ($mode eq "server") {
push(@free_list,
" virObjectUnref(snapshot);\n" .
" virObjectUnref(dom);");
} elsif ($args_member =~ m/^(?:remote_string|remote_uuid) (\S+)<\S+>;/) {
if (! @args_list) {
push(@args_list, "priv->conn");
}
push(@args_list, "args->$1.$1_val");
push(@args_list, "args->$1.$1_len");
} elsif ($args_member =~ m/^(?:opaque|remote_nonnull_string) (\S+)<\S+>;(.*)$/) {
if (! @args_list) {
push(@args_list, "priv->conn");
}
} elsif ($args_member =~ m/^(?:(admin|remote)_string|remote_uuid) (\S+)<\S+>;/) {
push_privconn(\@args_list);
push(@args_list, "args->$2.$2_val");
push(@args_list, "args->$2.$2_len");
} elsif ($args_member =~ m/^(?:opaque|(admin|remote)_nonnull_string) (\S+)<\S+>;(.*)$/) {
push_privconn(\@args_list);
my $cast = "";
my $arg_name = $1;
my $annotation = $2;
my $arg_name = $2;
my $annotation = $3;
if ($annotation ne "") {
if ($annotation =~ m/\s*\/\*\s*(.*)\s*\*\//) {
@ -532,9 +545,7 @@ elsif ($mode eq "server") {
push(@args_list, "${cast}args->$arg_name.${arg_name}_val");
push(@args_list, "args->$arg_name.${arg_name}_len");
} elsif ($args_member =~ m/^(?:unsigned )?int (\S+)<\S+>;/) {
if (! @args_list) {
push(@args_list, "priv->conn");
}
push_privconn(\@args_list);
push(@args_list, "args->$1.$1_val");
push(@args_list, "args->$1.$1_len");
@ -556,35 +567,25 @@ elsif ($mode eq "server") {
# just make all other array types fail
die "unhandled type for argument value: $args_member";
} elsif ($args_member =~ m/^remote_uuid (\S+);/) {
if (! @args_list) {
push(@args_list, "priv->conn");
}
push_privconn(\@args_list);
push(@args_list, "(unsigned char *) args->$1");
} elsif ($args_member =~ m/^remote_string (\S+);/) {
if (! @args_list) {
push(@args_list, "priv->conn");
}
} elsif ($args_member =~ m/^(admin|remote)_string (\S+);/) {
push_privconn(\@args_list);
push(@vars_list, "char *$1");
push(@optionals_list, "$1");
push(@args_list, "$1");
} elsif ($args_member =~ m/^remote_nonnull_string (\S+);/) {
if (! @args_list) {
push(@args_list, "priv->conn");
}
push(@vars_list, "char *$2");
push(@optionals_list, "$2");
push(@args_list, "$2");
} elsif ($args_member =~ m/^(admin|remote)_nonnull_string (\S+);/) {
push_privconn(\@args_list);
push(@args_list, "args->$1");
push(@args_list, "args->$2");
} elsif ($args_member =~ m/^(unsigned )?int (\S+);/) {
if (! @args_list) {
push(@args_list, "priv->conn");
}
push_privconn(\@args_list);
push(@args_list, "args->$2");
} elsif ($args_member =~ m/^(unsigned )?hyper (\S+);/) {
if (! @args_list) {
push(@args_list, "priv->conn");
}
push_privconn(\@args_list);
my $arg_name = $2;
@ -635,52 +636,52 @@ elsif ($mode eq "server") {
} else {
die "unhandled type for multi-return-value: $ret_member";
}
} elsif ($ret_member =~ m/^remote_nonnull_string (\S+)<(\S+)>;\s*\/\*\s*insert@(\d+)\s*\*\//) {
} elsif ($ret_member =~ m/^(admin|remote)_nonnull_string (\S+)<(\S+)>;\s*\/\*\s*insert@(\d+)\s*\*\//) {
push(@vars_list, "int len");
splice(@args_list, int($3), 0, ("ret->$1.$1_val"));
push(@ret_list, "ret->$1.$1_len = len;");
push(@free_list_on_error, "VIR_FREE(ret->$1.$1_val);");
splice(@args_list, int($4), 0, ("ret->$2.$2_val"));
push(@ret_list, "ret->$2.$2_len = len;");
push(@free_list_on_error, "VIR_FREE(ret->$2.$2_val);");
$single_ret_var = "len";
$single_ret_by_ref = 0;
$single_ret_check = " < 0";
$single_ret_as_list = 1;
$single_ret_list_name = $1;
$single_ret_list_max_var = "max$1";
$single_ret_list_max_define = $2;
} elsif ($ret_member =~ m/^remote_nonnull_string (\S+)<\S+>;/) {
$single_ret_list_name = $2;
$single_ret_list_max_var = "max$2";
$single_ret_list_max_define = $3;
} elsif ($ret_member =~ m/^(admin|remote)_nonnull_string (\S+)<\S+>;/) {
# error out on unannotated arrays
die "remote_nonnull_string array without insert@<offset> annotation: $ret_member";
} elsif ($ret_member =~ m/^remote_nonnull_string (\S+);/) {
die "$1_nonnull_string array without insert@<offset> annotation: $ret_member";
} elsif ($ret_member =~ m/^(admin|remote)_nonnull_string (\S+);/) {
if ($call->{ProcName} eq "ConnectGetType") {
# SPECIAL: virConnectGetType returns a constant string that must
# not be freed. Therefore, duplicate the string here.
push(@vars_list, "const char *$1");
push(@vars_list, "const char *$2");
push(@ret_list, "/* We have to VIR_STRDUP because remoteDispatchClientRequest will");
push(@ret_list, " * free this string after it's been serialised. */");
push(@ret_list, "if (VIR_STRDUP(ret->type, type) < 0)");
push(@ret_list, " goto cleanup;");
} else {
push(@vars_list, "char *$1");
push(@ret_list, "ret->$1 = $1;");
push(@vars_list, "char *$2");
push(@ret_list, "ret->$2 = $2;");
}
$single_ret_var = $1;
$single_ret_var = $2;
$single_ret_by_ref = 0;
$single_ret_check = " == NULL";
} elsif ($ret_member =~ m/^remote_string (\S+);/) {
push(@vars_list, "char *$1 = NULL");
push(@vars_list, "char **$1_p = NULL");
push(@ret_list, "ret->$1 = $1_p;");
push(@free_list, " VIR_FREE($1);");
push(@free_list_on_error, "VIR_FREE($1_p);");
} elsif ($ret_member =~ m/^(admin|remote)_string (\S+);/) {
push(@vars_list, "char *$2 = NULL");
push(@vars_list, "char **$2_p = NULL");
push(@ret_list, "ret->$2 = $2_p;");
push(@free_list, " VIR_FREE($2);");
push(@free_list_on_error, "VIR_FREE($2_p);");
push(@prepare_ret_list,
"if (VIR_ALLOC($1_p) < 0)\n" .
"if (VIR_ALLOC($2_p) < 0)\n" .
" goto cleanup;\n" .
" \n" .
" if (VIR_STRDUP(*$1_p, $1) < 0)\n".
" if (VIR_STRDUP(*$2_p, $2) < 0)\n".
" goto cleanup;\n");
$single_ret_var = $1;
$single_ret_var = $2;
$single_ret_by_ref = 0;
$single_ret_check = " == NULL";
} elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|node_device|secret|nwfilter|domain_snapshot) (\S+);/) {
@ -819,9 +820,7 @@ elsif ($mode eq "server") {
die "multi-return-value without insert@<offset> annotation: $call->{ret}";
}
if (! @args_list) {
push(@args_list, "priv->conn");
}
push_privconn(\@args_list);
my $struct_name = $call->{ProcName};
$struct_name =~ s/Get//;
@ -871,7 +870,12 @@ elsif ($mode eq "server") {
foreach my $var (@vars_list) {
print " $var;\n";
}
print " struct daemonClientPrivate *priv =\n";
if ($structprefix eq "admin") {
print " struct daemonAdmClientPrivate *priv =\n";
} else {
print " struct daemonClientPrivate *priv =\n";
}
print " virNetServerClientGetPrivateData(client);\n";
if ($call->{streamflag} ne "none") {
@ -880,7 +884,13 @@ elsif ($mode eq "server") {
}
print "\n";
print " if (!priv->conn) {\n";
if ($structprefix eq "admin") {
print " if (!priv->dmn) {\n";
} else {
print " if (!priv->conn) {\n";
}
print " virReportError(VIR_ERR_INTERNAL_ERROR, \"%s\", _(\"connection not open\"));\n";
print " goto cleanup;\n";
print " }\n";
@ -919,18 +929,15 @@ elsif ($mode eq "server") {
}
if ($rettype eq "void") {
print " if (vir$call->{ProcName}(";
print " if ($prefix$call->{ProcName}(";
print join(', ', @args_list);
print ") < 0)\n";
print " goto cleanup;\n";
print "\n";
} elsif (!$multi_ret) {
my $prefix = "";
my $proc_name = $call->{ProcName};
if (! @args_list) {
push(@args_list, "priv->conn");
}
push_privconn(\@args_list);
if ($structprefix eq "qemu" &&
$call->{ProcName} =~ /^(Connect)?Domain/) {
@ -949,7 +956,7 @@ elsif ($mode eq "server") {
}
if ($single_ret_by_ref) {
print " if (vir$prefix$proc_name(";
print " if ($prefix$proc_name(";
print join(', ', @args_list);
if (defined $single_ret_var) {
@ -958,7 +965,7 @@ elsif ($mode eq "server") {
print ") < 0)\n";
} else {
print " if (($single_ret_var = vir$prefix$proc_name(";
print " if (($single_ret_var = $prefix$proc_name(";
print join(', ', @args_list);
print "))$single_ret_check)\n";
}
@ -1132,14 +1139,14 @@ elsif ($mode eq "client") {
} elsif ($args_member =~ m/^remote_uuid (\S+);/) {
push(@args_list, "const unsigned char *$1");
push(@setters_list, "memcpy(args.$1, $1, VIR_UUID_BUFLEN);");
} elsif ($args_member =~ m/^remote_string (\S+);/) {
push(@args_list, "const char *$1");
push(@setters_list, "args.$1 = $1 ? (char **)&$1 : NULL;");
} elsif ($args_member =~ m/^remote_nonnull_string (\S+)<(\S+)>;(.*)$/) {
} elsif ($args_member =~ m/^(admin|remote)_string (\S+);/) {
push(@args_list, "const char *$2");
push(@setters_list, "args.$2 = $2 ? (char **)&$2 : NULL;");
} elsif ($args_member =~ m/^(admin|remote)_nonnull_string (\S+)<(\S+)>;(.*)$/) {
my $type_name = "const char **";
my $arg_name = $1;
my $limit = $2;
my $annotation = $3;
my $arg_name = $2;
my $limit = $3;
my $annotation = $4;
if ($annotation ne "") {
if ($annotation =~ m/\s*\/\*\s*\((.*)\)\s*\*\//) {
@ -1153,10 +1160,10 @@ elsif ($mode eq "client") {
push(@args_list, "unsigned int ${arg_name}len");
push(@setters_list, "args.$arg_name.${arg_name}_val = (char **)$arg_name;");
push(@setters_list, "args.$arg_name.${arg_name}_len = ${arg_name}len;");
push(@args_check_list, { name => "\"$arg_name\"", arg => "${arg_name}len", limit => $2 });
} elsif ($args_member =~ m/^remote_nonnull_string (\S+);/) {
push(@args_list, "const char *$1");
push(@setters_list, "args.$1 = (char *)$1;");
push(@args_check_list, { name => "\"$arg_name\"", arg => "${arg_name}len", limit => $3 });
} elsif ($args_member =~ m/^(admin|remote)_nonnull_string (\S+);/) {
push(@args_list, "const char *$2");
push(@setters_list, "args.$2 = (char *)$2;");
} elsif ($args_member =~ m/^opaque (\S+)<(\S+)>;(.*)$/) {
my $type_name = "const char *";
my $arg_name = $1;
@ -1183,9 +1190,9 @@ elsif ($mode eq "client") {
push(@setters_list, "args.$arg_name.${arg_name}_val = (char *)$arg_name;");
push(@setters_list, "args.$arg_name.${arg_name}_len = ${arg_name}len;");
push(@args_check_list, { name => "\"$arg_name\"", arg => "${arg_name}len", limit => $limit });
} elsif ($args_member =~ m/^remote_string (\S+)<(\S+)>;/) {
my $arg_name = $1;
my $limit = $2;
} elsif ($args_member =~ m/^(admin|remote)_string (\S+)<(\S+)>;/) {
my $arg_name = $2;
my $limit = $3;
push(@args_list, "const char *$arg_name");
push(@args_list, "int ${arg_name}len");
@ -1241,15 +1248,15 @@ elsif ($mode eq "client") {
}
if ($is_first_arg and $priv_src eq "conn") {
unshift(@args_list, "virConnectPtr conn");
unshift(@args_list, "$connect_ptr conn");
}
$is_first_arg = 0;
}
}
if (! @args_list) {
push(@args_list, "virConnectPtr conn");
if (!@args_list) {
push(@args_list, "$connect_ptr conn");
}
# handle return values of the function
@ -1300,25 +1307,25 @@ elsif ($mode eq "client") {
die "unhandled type for multi-return-value for " .
"procedure $call->{name}: $ret_member";
}
} elsif ($ret_member =~ m/^remote_nonnull_string (\S+)<(\S+)>;\s*\/\*\s*insert@(\d+)\s*\*\//) {
splice(@args_list, int($3), 0, ("char **const $1"));
push(@ret_list, "rv = ret.$1.$1_len;");
} elsif ($ret_member =~ m/^(admin|remote)_nonnull_string (\S+)<(\S+)>;\s*\/\*\s*insert@(\d+)\s*\*\//) {
splice(@args_list, int($4), 0, ("char **const $2"));
push(@ret_list, "rv = ret.$2.$2_len;");
$single_ret_var = "int rv = -1";
$single_ret_type = "int";
$single_ret_as_list = 1;
$single_ret_list_name = $1;
$single_ret_list_max_var = "max$1";
$single_ret_list_max_define = $2;
} elsif ($ret_member =~ m/^remote_nonnull_string (\S+)<\S+>;/) {
$single_ret_list_name = $2;
$single_ret_list_max_var = "max$2";
$single_ret_list_max_define = $3;
} elsif ($ret_member =~ m/^(admin|remote)_nonnull_string (\S+)<\S+>;/) {
# error out on unannotated arrays
die "remote_nonnull_string array without insert@<offset> annotation: $ret_member";
} elsif ($ret_member =~ m/^remote_nonnull_string (\S+);/) {
push(@ret_list, "rv = ret.$1;");
die "$1_nonnull_string array without insert@<offset> annotation: $ret_member";
} elsif ($ret_member =~ m/^(admin|remote)_nonnull_string (\S+);/) {
push(@ret_list, "rv = ret.$2;");
$single_ret_var = "char *rv = NULL";
$single_ret_type = "char *";
} elsif ($ret_member =~ m/^remote_string (\S+);/) {
push(@ret_list, "rv = ret.$1 ? *ret.$1 : NULL;");
push(@ret_list, "VIR_FREE(ret.$1);");
} elsif ($ret_member =~ m/^(admin|remote)_string (\S+);/) {
push(@ret_list, "rv = ret.$2 ? *ret.$2 : NULL;");
push(@ret_list, "VIR_FREE(ret.$2);");
$single_ret_var = "char *rv = NULL";
$single_ret_type = "char *";
} elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|node_device|interface|secret|nwfilter|domain_snapshot) (\S+);/) {
@ -1442,7 +1449,11 @@ elsif ($mode eq "client") {
my $proc = $call->{ProcName};
my $extra = $structprefix;
$extra =~ s/^(\w)/uc $1/e;
$proc =~ s/^(Domain)(.*)/$1 . $extra . $2/e;
if ($structprefix eq "admin") {
$proc = $extra . $proc;
} else {
$proc =~ s/^(Domain)(.*)/$1 . $extra . $2/e;
}
print "remote$proc(";
}
@ -1451,7 +1462,11 @@ elsif ($mode eq "client") {
print ")\n";
print "{\n";
print " $single_ret_var;\n";
print " struct private_data *priv = $priv_src->privateData;\n";
if ($structprefix eq "admin") {
print " remoteAdminPrivPtr priv = $priv_src->privateData;\n";
} else {
print " struct private_data *priv = $priv_src->privateData;\n";
}
foreach my $var (@vars_list) {
print " $var;\n";
@ -1466,7 +1481,11 @@ elsif ($mode eq "client") {
}
print "\n";
print " remoteDriverLock(priv);\n";
if ($structprefix eq "admin") {
print " virObjectLock(priv);\n";
} else {
print " remoteDriverLock(priv);\n";
}
if ($call->{streamflag} ne "none") {
print "\n";
@ -1546,8 +1565,12 @@ elsif ($mode eq "client") {
$callflags = "REMOTE_CALL_LXC";
}
if ($structprefix ne "admin") {
$priv_src = "$priv_src, priv";
}
print "\n";
print " if (call($priv_src, priv, $callflags, $call->{constname},\n";
print " if (call($priv_src, $callflags, $call->{constname},\n";
print " (xdrproc_t)xdr_$argtype, (char *)$call_args,\n";
print " (xdrproc_t)xdr_$rettype, (char *)$call_ret) == -1) {\n";
@ -1622,7 +1645,12 @@ elsif ($mode eq "client") {
print join("\n", @free_list);
print " remoteDriverUnlock(priv);\n";
if ($structprefix eq "admin") {
print " virObjectUnlock(priv);\n";
} else {
print " remoteDriverUnlock(priv);\n";
}
print " return rv;\n";
print "}\n";
}
@ -1682,7 +1710,7 @@ elsif ($mode eq "client") {
next if $call->{acl}->[0] eq "none";
if ($mode eq "aclsym") {
my $apiname = "vir" . $call->{ProcName};
my $apiname = $prefix . $call->{ProcName};
if ($structprefix eq "qemu") {
$apiname =~ s/(vir(Connect)?Domain)/${1}Qemu/;
} elsif ($structprefix eq "lxc") {
@ -1722,7 +1750,7 @@ elsif ($mode eq "client") {
}
}
my $apiname = "vir" . $call->{ProcName};
my $apiname = $prefix . $call->{ProcName};
if ($structprefix eq "qemu") {
$apiname =~ s/(vir(Connect)?Domain)/${1}Qemu/;
} elsif ($structprefix eq "lxc") {
@ -1735,7 +1763,7 @@ elsif ($mode eq "client") {
$object =~ s/^(\w)/uc $1/e;
$object =~ s/_(\w)/uc $1/e;
$object =~ s/Nwfilter/NWFilter/;
my $objecttype = "vir" . $object . "DefPtr";
my $objecttype = $prefix . $object . "DefPtr";
$apiname .= $action . "ACL";
if ($arg eq "interface") {
@ -1743,7 +1771,7 @@ elsif ($mode eq "client") {
}
my @argdecls;
push @argdecls, "virConnectPtr conn";
push @argdecls, "$connect_ptr conn";
if ($object ne "Connect") {
if ($object eq "StorageVol") {
push @argdecls, "virStoragePoolDefPtr pool";
@ -1834,7 +1862,7 @@ elsif ($mode eq "client") {
sub generate_aclapi {
my $call = shift;
my $apiname = "vir" . $call->{ProcName};
my $apiname = $prefix . $call->{ProcName};
if ($structprefix eq "qemu") {
$apiname =~ s/(vir(Connect)?Domain)/${1}Qemu/;
} elsif ($structprefix eq "lxc") {