[libvirt] [PATCH 08/11] Make RPC code generator a little more flexible

Jiri Denemark jdenemar at redhat.com
Thu Jul 26 22:44:55 UTC 2012


On Tue, Jul 24, 2012 at 14:22:50 +0100, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
> 
> Update the gendispatch.pl script to get a little closer to
> being able to generate code for the LXC monitor, by passing
> in the struct prefix separately from the procedure prefix.
> Also allow method names using virCapitalLetters instead
> of vir_underscore_separator
> 
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
>  daemon/Makefile.am     |    4 +-
>  src/Makefile.am        |    4 +-
>  src/rpc/gendispatch.pl |  107 ++++++++++++++++++++++++++++++++----------------
>  3 files changed, 75 insertions(+), 40 deletions(-)
> 
> diff --git a/daemon/Makefile.am b/daemon/Makefile.am
> index 71e91cd..4de39bc 100644
> --- a/daemon/Makefile.am
> +++ b/daemon/Makefile.am
> @@ -58,12 +58,12 @@ QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
>  
>  $(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
>  		$(REMOTE_PROTOCOL)
> -	$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b remote \
> +	$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b remote REMOTE \
>  	  $(REMOTE_PROTOCOL) > $@
>  
>  $(srcdir)/qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
>  		$(QEMU_PROTOCOL)
> -	$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b qemu \
> +	$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b qemu QEMU \
>  	  $(QEMU_PROTOCOL) > $@
>  
>  if WITH_LIBVIRTD
> diff --git a/src/Makefile.am b/src/Makefile.am
> index a910aa1..492ce73 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -230,12 +230,12 @@ REMOTE_DRIVER_PROTOCOL = $(REMOTE_PROTOCOL) $(QEMU_PROTOCOL)
>  $(srcdir)/remote/remote_client_bodies.h: $(srcdir)/rpc/gendispatch.pl \
>  		$(REMOTE_PROTOCOL)
>  	$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
> -	  -k remote $(REMOTE_PROTOCOL) > $@
> +	  -k remote REMOTE $(REMOTE_PROTOCOL) > $@
>  
>  $(srcdir)/remote/qemu_client_bodies.h: $(srcdir)/rpc/gendispatch.pl \
>  		$(QEMU_PROTOCOL)
>  	$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
> -	  -k qemu $(QEMU_PROTOCOL) > $@
> +	  -k qemu QEMU $(QEMU_PROTOCOL) > $@
>  
>  REMOTE_DRIVER_SOURCES =						\
>  		gnutls_1_0_compat.h				\
> diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
> index 1fb5971..fe2c23d 100755
> --- a/src/rpc/gendispatch.pl
> +++ b/src/rpc/gendispatch.pl
> @@ -20,25 +20,50 @@ use strict;
>  use Getopt::Std;
>  
>  # Command line options.
> +# -k - client bodies
> +# -b - server bodies
>  our ($opt_p, $opt_t, $opt_a, $opt_r, $opt_d, $opt_b, $opt_k);
>  getopts ('ptardbk');
>  
> -my $structprefix = shift or die "missing prefix argument";
> +my $structprefix = shift or die "missing struct prefix argument";
> +my $procprefix = shift or die "missing procedure prefix argument";
>  my $protocol = shift or die "missing protocol argument";
>  my @autogen;
>  
> -my $procprefix = uc $structprefix;
>  
>  # Convert name_of_call to NameOfCall.
>  sub name_to_ProcName {
>      my $name = shift;
> +
> +    my @elems;
> +    if ($name =~ /_/ || (lc $name) eq "open" || (lc $name) eq "close") {
> +	@elems = split /_/, $name;
> +	@elems = map lc, @elems;
> +	@elems = map ucfirst, @elems;
> +    } else {
> +	@elems = $name;
> +    }
> +    @elems = map { $_ =~ s/Nwfilter/NWFilter/; $_ =~ s/Xml$/XML/;
> +		   $_ =~ s/Uri$/URI/; $_ =~ s/Uuid$/UUID/; $_ =~ s/Id$/ID/;
> +		   $_ =~ s/Mac$/MAC/; $_ =~ s/Cpu$/CPU/; $_ =~ s/Os$/OS/;
> +		   $_ =~ s/Nmi$/NMI/; $_ =~ s/Pm/PM/; $_ } @elems;

This map is worth separating into a dedicated function as it is already used
in two places.

> +    my $procname = join "", @elems;
> +
> +    return $procname;
> +}
> +
> +sub name_to_TypeName {
> +    my $name = shift;
> +
>      my @elems = split /_/, $name;
> +    @elems = map lc, @elems;
>      @elems = map ucfirst, @elems;
>      @elems = map { $_ =~ s/Nwfilter/NWFilter/; $_ =~ s/Xml$/XML/;
> -                   $_ =~ s/Uri$/URI/; $_ =~ s/Uuid$/UUID/; $_ =~ s/Id$/ID/;
> -                   $_ =~ s/Mac$/MAC/; $_ =~ s/Cpu$/CPU/; $_ =~ s/Os$/OS/;
> -                   $_ =~ s/Nmi$/NMI/; $_ =~ s/Pm/PM/; $_ } @elems;
> -    join "", @elems
> +		   $_ =~ s/Uri$/URI/; $_ =~ s/Uuid$/UUID/; $_ =~ s/Id$/ID/;
> +		   $_ =~ s/Mac$/MAC/; $_ =~ s/Cpu$/CPU/; $_ =~ s/Os$/OS/;
> +		   $_ =~ s/Nmi$/NMI/; $_ =~ s/Pm/PM/; $_ } @elems;
> +    my $typename = join "", @elems;
> +    return $typename;
>  }
>  
>  # Read the input file (usually remote_protocol.x) and form an
> @@ -64,18 +89,20 @@ while (<PROTOCOL>) {
>          } elsif ($_ =~ m/^\s*(.*\S)\s*$/) {
>              push(@{$calls{$name}->{ret_members}}, $1);
>          }
> -    } elsif (/^struct ${structprefix}_(.*)_args/) {
> -        $name = $1;
> +    } elsif (/^struct (${structprefix}_(.*)_args)/ ||
> +             /^struct (${structprefix}(.*)Args)/) {
> +        my $structname = $1;
> +        $name = $2;
>          $ProcName = name_to_ProcName ($name);
> -
> -        die "duplicate definition of ${structprefix}_${name}_args"
> +        $name = lc $name;
> +        $name =~ s/_//g;
> +        die "duplicate definition of $_"
>              if exists $calls{$name};
>  
>          $calls{$name} = {
>              name => $name,
>              ProcName => $ProcName,
> -            UC_NAME => uc $name,
> -            args => "${structprefix}_${name}_args",
> +            args => $structname,
>              args_members => [],
>              ret => "void"
>          };
> @@ -83,20 +110,23 @@ while (<PROTOCOL>) {
>          $collect_args_members = 1;
>          $collect_ret_members = 0;
>          $last_name = $name;
> -    } elsif (/^struct ${structprefix}_(.*)_ret\s+{(.*)$/) {
> -        $name = $1;
> -        $flags = $2;
> +    } elsif (/^struct (${structprefix}_(.*)_ret)\s+{(.*)$/ ||
> +             /^struct (${structprefix}(.*)Ret)\s+{(.*)$/) {
> +        my $structname = $1;
> +        $name = $2;
> +        $flags = $3;
>          $ProcName = name_to_ProcName ($name);
> +        $name = lc $name;
> +        $name =~ s/_//g;
>  
>          if (exists $calls{$name}) {
> -            $calls{$name}->{ret} = "${structprefix}_${name}_ret";
> +            $calls{$name}->{ret} = $structname;
>          } else {
>              $calls{$name} = {
>                  name => $name,
>                  ProcName => $ProcName,
> -                UC_NAME => uc $name,
>                  args => "void",
> -                ret => "${structprefix}_${name}_ret",
> +                ret => $structname,
>                  ret_members => []
>              }
>          }
> @@ -112,24 +142,29 @@ while (<PROTOCOL>) {
>          $collect_args_members = 0;
>          $collect_ret_members = 1;
>          $last_name = $name;
> -    } elsif (/^struct ${structprefix}_(.*)_msg/) {
> -        $name = $1;
> +    } elsif (/^struct (${structprefix}_(.*)_msg)/ ||
> +             /^struct (${structprefix}(.*)Msg)/) {
> +        my $structname = $1;
> +        $name = $2;
>          $ProcName = name_to_ProcName ($name);
> -
> +        $name = lc $name;
> +        $name =~ s/_//g;
>          $calls{$name} = {
>              name => $name,
>              ProcName => $ProcName,
> -            UC_NAME => uc $name,
> -            msg => "${structprefix}_${name}_msg"
> +            msg => $structname,
>          };
>  
>          $collect_args_members = 0;
>          $collect_ret_members = 0;
> -    } elsif (/^\s*${procprefix}_PROC_(.*?)\s*=\s*(\d+)\s*,?(.*)$/) {
> -        $name = lc $1;
> -        $id = $2;
> -        $flags = $3;
> +    } elsif (/^\s*(${procprefix}_PROC_(.*?))\s*=\s*(\d+)\s*,?(.*)$/) {
> +        my $constname = $1;
> +        $name = $2;
> +        $id = $3;
> +        $flags = $4;
>          $ProcName = name_to_ProcName ($name);
> +        $name = lc $name;
> +        $name =~ s/_//g;
>  
>          if (!exists $calls{$name}) {
>              # that the argument and return value cases have not yet added
> @@ -139,15 +174,15 @@ while (<PROTOCOL>) {
>              $calls{$name} = {
>                  name => $name,
>                  ProcName => $ProcName,
> -                UC_NAME => uc $name,
>                  args => "void",
>                  ret => "void"
>              }
>          }
> +	$calls{$name}->{constname} = $constname;

s/^/    / in the line above.

>  
>          if ($opt_b or $opt_k) {
>              if (!($flags =~ m/^\s*\/\*\s*(\S+)\s+(\S+)\s*(\|.*)?\s+(priority:(\S+))?\s*\*\/\s*$/)) {
> -                die "invalid generator flags for ${procprefix}_PROC_${name}"
> +                die "invalid generator flags '$flags' for $constname"
>              }
>  
>              my $genmode = $opt_b ? $1 : $2;
> @@ -371,7 +406,7 @@ elsif ($opt_b) {
>                      # ignore the name arg for node devices
>                      next
>                  } elsif ($args_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|secret|nwfilter) (\S+);/) {
> -                    my $type_name = name_to_ProcName($1);
> +                    my $type_name = name_to_TypeName($1);
>  
>                      push(@vars_list, "vir${type_name}Ptr $2 = NULL");
>                      push(@getters_list,
> @@ -580,7 +615,7 @@ elsif ($opt_b) {
>                      $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+);/) {
> -                    my $type_name = name_to_ProcName($1);
> +                    my $type_name = name_to_TypeName($1);
>  
>                      if ($call->{ProcName} eq "DomainCreateWithFlags") {
>                          # SPECIAL: virDomainCreateWithFlags updates the given
> @@ -1031,7 +1066,7 @@ elsif ($opt_k) {
>                  } elsif ($args_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|secret|nwfilter|domain_snapshot) (\S+);/) {
>                      my $name = $1;
>                      my $arg_name = $2;
> -                    my $type_name = name_to_ProcName($name);
> +                    my $type_name = name_to_TypeName($name);
>  
>                      if ($is_first_arg) {
>                          if ($name eq "domain_snapshot") {
> @@ -1254,7 +1289,7 @@ elsif ($opt_k) {
>                  } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|node_device|interface|secret|nwfilter|domain_snapshot) (\S+);/) {
>                      my $name = $1;
>                      my $arg_name = $2;
> -                    my $type_name = name_to_ProcName($name);
> +                    my $type_name = name_to_TypeName($name);
>  
>                      if ($name eq "node_device") {
>                          $priv_name = "devMonPrivateData";
> @@ -1400,7 +1435,7 @@ elsif ($opt_k) {
>  
>          if ($call->{streamflag} ne "none") {
>              print "\n";
> -            print "    if (!(netst = virNetClientStreamNew(priv->remoteProgram, REMOTE_PROC_$call->{UC_NAME}, priv->counter)))\n";
> +            print "    if (!(netst = virNetClientStreamNew(priv->remoteProgram, $call->{constname}, priv->counter)))\n";
>              print "        goto done;\n";
>              print "\n";
>              print "    if (virNetClientAddStream(priv->client, netst) < 0) {\n";
> @@ -1474,7 +1509,7 @@ elsif ($opt_k) {
>          }
>  
>          print "\n";
> -        print "    if (call($priv_src, priv, $callflags, ${procprefix}_PROC_$call->{UC_NAME},\n";
> +        print "    if (call($priv_src, priv, $callflags, $call->{constname},\n";
>          print "             (xdrproc_t)xdr_$argtype, (char *)$call_args,\n";
>          print "             (xdrproc_t)xdr_$rettype, (char *)$call_ret) == -1) {\n";
>  
> @@ -1542,7 +1577,7 @@ elsif ($opt_k) {
>          if ($single_ret_as_list or $single_ret_cleanup) {
>              print "\n";
>              print "cleanup:\n";
> -            print "    xdr_free((xdrproc_t)xdr_remote_$call->{name}_ret, (char *)&ret);\n";
> +            print "    xdr_free((xdrproc_t)xdr_$call->{ret}, (char *)&ret);\n";
>          }
>  
>          print "\n";

ACK with the nits fixed.

Jirka




More information about the libvir-list mailing list