libvirt/qemud/remote_generate_stubs.pl
Daniel P. Berrange aa23d432cd Change code generator to give async event messages their own postfix
The naming convention for structs used in the RPC layer is for
incoming requests to be called XXXX_args, and the associated
outgoing reply to be called XXXX_ret.  Asynchronously emitted
messages (eg events) are re-using the XXXX_ret naming scheme.
This patch changes that such that async messages are XXXX_msg,
and stops adding entries for them in the dispatch table, avoiding
the need for a dummy no-op implementation.

* qemud/remote.c: Remove dummy remoteDispatchDomainEvent, no
  longer required. Update to replace remote_domain_event_ret
  with xdr_remote_domain_event_msg
* qemud/remote_protocol.x: Rename remote_domain_event_ret to
  remote_domain_event_msg
* qemud/remote_generate_stubs.pl: Adding handling for new
  XXX_msg structs.
* src/remote_internal.c: Rename remote_domain_event_ret to
  remote_domain_event_msg
* qemud/remote_dispatch_prototypes.h, qemud/remote_dispatch_ret.h,
  qemud/remote_dispatch_table.h, qemud/remote_protocol.h,
  qemud/remote_protocol.c: auto-regenerate
2009-07-16 16:09:47 +01:00

179 lines
4.4 KiB
Perl
Executable File

#!/usr/bin/perl -w
#
# This script parses remote_protocol.x and produces lots of boilerplate
# code for both ends of the remote connection.
#
# By Richard Jones <rjones@redhat.com>
use strict;
use Getopt::Std;
# Command line options.
our ($opt_p, $opt_t, $opt_a, $opt_r, $opt_d);
getopts ('ptard');
# Convert name_of_call to NameOfCall.
sub name_to_ProcName {
my $name = shift;
my @elems = split /_/, $name;
@elems = map ucfirst, @elems;
join "", @elems
}
# 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, %calls, @calls);
# REMOTE_PROC_CLOSE has no args or ret.
$calls{close} = {
name => "close",
ProcName => "Close",
UC_NAME => "CLOSE",
args => "void",
ret => "void",
};
while (<>) {
if (/^struct remote_(.*)_args/) {
$name = $1;
$ProcName = name_to_ProcName ($name);
die "duplicate definition of remote_${name}_args"
if exists $calls{$name};
$calls{$name} = {
name => $name,
ProcName => $ProcName,
UC_NAME => uc $name,
args => "remote_${name}_args",
ret => "void",
};
} elsif (/^struct remote_(.*)_ret/) {
$name = $1;
$ProcName = name_to_ProcName ($name);
if (exists $calls{$name}) {
$calls{$name}->{ret} = "remote_${name}_ret";
} else {
$calls{$name} = {
name => $name,
ProcName => $ProcName,
UC_NAME => uc $name,
args => "void",
ret => "remote_${name}_ret"
}
}
} elsif (/^struct remote_(.*)_msg/) {
$name = $1;
$ProcName = name_to_ProcName ($name);
$calls{$name} = {
name => $name,
ProcName => $ProcName,
UC_NAME => uc $name,
msg => "remote_${name}_msg"
}
} elsif (/^\s*REMOTE_PROC_(.*?)\s+=\s+(\d+),?$/) {
$name = lc $1;
$id = $2;
$ProcName = name_to_ProcName ($name);
$calls[$id] = $calls{$name};
}
}
#----------------------------------------------------------------------
# Output
print <<__EOF__;
/* Automatically generated by remote_generate_stubs.pl.
* Do not edit this file. Any changes you make will be lost.
*/
__EOF__
# Debugging.
if ($opt_d) {
my @keys = sort (keys %calls);
foreach (@keys) {
print "$_:\n";
print " name $calls{$_}->{name} ($calls{$_}->{ProcName})\n";
print " $calls{$_}->{args} -> $calls{$_}->{ret}\n";
}
}
# Prototypes for dispatch functions ("remote_dispatch_prototypes.h").
elsif ($opt_p) {
my @keys = sort (keys %calls);
foreach (@keys) {
# Skip things which are REMOTE_MESSAGE
next if $calls{$_}->{msg};
print "static int remoteDispatch$calls{$_}->{ProcName}(\n";
print " struct qemud_server *server,\n";
print " struct qemud_client *client,\n";
print " virConnectPtr conn,\n";
print " remote_error *err,\n";
print " $calls{$_}->{args} *args,\n";
print " $calls{$_}->{ret} *ret);\n";
}
}
# Union of all arg types
# ("remote_dispatch_args.h").
elsif ($opt_a) {
for ($id = 0 ; $id <= $#calls ; $id++) {
if (defined $calls[$id] &&
!$calls[$id]->{msg} &&
$calls[$id]->{args} ne "void") {
print " $calls[$id]->{args} val_$calls[$id]->{args};\n";
}
}
}
# Union of all arg types
# ("remote_dispatch_ret.h").
elsif ($opt_r) {
for ($id = 0 ; $id <= $#calls ; $id++) {
if (defined $calls[$id] &&
!$calls[$id]->{msg} &&
$calls[$id]->{ret} ne "void") {
print " $calls[$id]->{ret} val_$calls[$id]->{ret};\n";
}
}
}
# Inside the switch statement, prepare the 'fn', 'args_filter', etc
# ("remote_dispatch_table.h").
elsif ($opt_t) {
for ($id = 0 ; $id <= $#calls ; $id++) {
if (defined $calls[$id] && !$calls[$id]->{msg}) {
print "{ /* $calls[$id]->{ProcName} => $id */\n";
print " .fn = (dispatch_fn) remoteDispatch$calls[$id]->{ProcName},\n";
if ($calls[$id]->{args} ne "void") {
print " .args_filter = (xdrproc_t) xdr_$calls[$id]->{args},\n";
} else {
print " .args_filter = (xdrproc_t) xdr_void,\n";
}
if ($calls[$id]->{ret} ne "void") {
print " .ret_filter = (xdrproc_t) xdr_$calls[$id]->{ret},\n";
} else {
print " .ret_filter = (xdrproc_t) xdr_void,\n";
}
print "},\n";
} else {
if ($calls[$id]->{msg}) {
print "{ /* Async event $calls[$id]->{ProcName} => $id */\n";
} else {
print "{ /* (unused) => $id */\n";
}
print " .fn = NULL,\n";
print " .args_filter = (xdrproc_t) xdr_void,\n";
print " .ret_filter = (xdrproc_t) xdr_void,\n";
print "},\n";
}
}
}