pidl: Allow ndrdump to print public structures
authorGary Lockyer <gary@catalyst.net.nz>
Tue, 4 Jun 2019 20:43:33 +0000 (08:43 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 6 Jun 2019 03:30:18 +0000 (03:30 +0000)
Generate code to allow ndrdump to operate on public structures.

Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>

librpc/ndr/libndr.h
pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm

index 8a15fccfe09ae6846cee4ee26ab5409be9f9ab40..8ece7374b9aa8537482799c48314a423debe7548 100644 (file)
@@ -455,6 +455,14 @@ struct ndr_interface_call {
        struct ndr_interface_call_pipes out_pipes;
 };
 
        struct ndr_interface_call_pipes out_pipes;
 };
 
+struct ndr_interface_public_struct {
+       const char *name;
+       size_t struct_size;
+       ndr_push_flags_fn_t ndr_push;
+       ndr_pull_flags_fn_t ndr_pull;
+       ndr_print_function_t ndr_print;
+};
+
 struct ndr_interface_string_array {
        uint32_t count;
        const char * const *names;
 struct ndr_interface_string_array {
        uint32_t count;
        const char * const *names;
@@ -466,6 +474,8 @@ struct ndr_interface_table {
        const char *helpstring;
        uint32_t num_calls;
        const struct ndr_interface_call *calls;
        const char *helpstring;
        uint32_t num_calls;
        const struct ndr_interface_call *calls;
+       uint32_t num_public_structs;
+       const struct ndr_interface_public_struct *public_structs;
        const struct ndr_interface_string_array *endpoints;
        const struct ndr_interface_string_array *authservices;
 };
        const struct ndr_interface_string_array *endpoints;
        const struct ndr_interface_string_array *authservices;
 };
index 432e52f89c4562f7ff32f8dd4fb8a2f12a910469..2fc4327faf48cf590339fac28322891ff8522e33 100644 (file)
@@ -1833,6 +1833,9 @@ sub ParseStructNdrSize($$$$)
 sub DeclStruct($$$$)
 {
        my ($e,$t,$name,$varname) = @_;
 sub DeclStruct($$$$)
 {
        my ($e,$t,$name,$varname) = @_;
+       if ($t eq "base") {
+               return "struct $name $varname";
+       }
        return ($t ne "pull"?"const ":"") . "struct $name *$varname";
 }
 
        return ($t ne "pull"?"const ":"") . "struct $name *$varname";
 }
 
@@ -2175,6 +2178,9 @@ sub ParseUnionPull($$$$)
 sub DeclUnion($$$$)
 {
        my ($e,$t,$name,$varname) = @_;
 sub DeclUnion($$$$)
 {
        my ($e,$t,$name,$varname) = @_;
+       if ($t eq "base") {
+               return "union $name $varname";
+       }
        return ($t ne "pull"?"const ":"") . "union $name *$varname";
 }
 
        return ($t ne "pull"?"const ":"") . "union $name *$varname";
 }
 
@@ -2752,21 +2758,52 @@ sub FunctionCallEntry($$)
        return 1;
 }
 
        return 1;
 }
 
+sub StructEntry($$)
+{
+       my ($self, $d) = @_;
+       my $type_decl = $typefamily{$d->{TYPE}}->{DECL}->($d, "base", $d->{NAME}, "");
+
+       $self->pidl("\t{");
+       $self->pidl("\t\t.name = \"$d->{NAME}\",");
+       $self->pidl("\t\t.struct_size = sizeof($type_decl),");
+       $self->pidl("\t\t.ndr_push = (ndr_push_flags_fn_t) ndr_push_$d->{NAME},");
+       $self->pidl("\t\t.ndr_pull = (ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},");
+       $self->pidl("\t\t.ndr_print = (ndr_print_function_t) ndr_print_$d->{NAME},");
+       $self->pidl("\t},");
+       return 1;
+}
+
 #####################################################################
 # produce a function call table
 sub FunctionTable($$)
 {
        my($self,$interface) = @_;
        my $count = 0;
 #####################################################################
 # produce a function call table
 sub FunctionTable($$)
 {
        my($self,$interface) = @_;
        my $count = 0;
+       my $count_public_structs = 0;
        my $uname = uc $interface->{NAME};
 
        my $uname = uc $interface->{NAME};
 
-       return if ($#{$interface->{FUNCTIONS}}+1 == 0);
+       foreach my $d (@{$interface->{TYPES}}) {
+               next unless (has_property($d, "public"));
+               $count_public_structs += 1;
+       }
+       return if ($#{$interface->{FUNCTIONS}}+1 == 0 and
+                  $count_public_structs == 0);
        return unless defined ($interface->{PROPERTIES}->{uuid});
 
        foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
                $self->FunctionCallPipes($d);
        }
 
        return unless defined ($interface->{PROPERTIES}->{uuid});
 
        foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
                $self->FunctionCallPipes($d);
        }
 
+       $self->pidl("static const struct ndr_interface_public_struct $interface->{NAME}\_public_structs[] = {");
+
+       foreach my $d (@{$interface->{TYPES}}) {
+               next unless (has_property($d, "public"));
+               $self->StructEntry($d)
+       }
+       $self->pidl("\t{ .name = NULL }");
+       $self->pidl("};");
+       $self->pidl("");
+
        $self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {");
 
        foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
        $self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {");
 
        foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
@@ -2807,6 +2844,8 @@ sub FunctionTable($$)
        $self->pidl("\t.helpstring\t= NDR_$uname\_HELPSTRING,");
        $self->pidl("\t.num_calls\t= $count,");
        $self->pidl("\t.calls\t\t= $interface->{NAME}\_calls,");
        $self->pidl("\t.helpstring\t= NDR_$uname\_HELPSTRING,");
        $self->pidl("\t.num_calls\t= $count,");
        $self->pidl("\t.calls\t\t= $interface->{NAME}\_calls,");
+       $self->pidl("\t.num_public_structs\t= $count_public_structs,");
+       $self->pidl("\t.public_structs\t\t= $interface->{NAME}\_public_structs,");
        $self->pidl("\t.endpoints\t= &$interface->{NAME}\_endpoints,");
        $self->pidl("\t.authservices\t= &$interface->{NAME}\_authservices");
        $self->pidl("};");
        $self->pidl("\t.endpoints\t= &$interface->{NAME}\_endpoints,");
        $self->pidl("\t.authservices\t= &$interface->{NAME}\_authservices");
        $self->pidl("};");