pyldb: avoid segfault when adding an element with no name
[kai/samba-autobuild/.git] / pidl / lib / Parse / Pidl / Samba4 / Header.pm
index 94e1efbfe4925a201c17643b3ea3e28821b103e6..e9b7bee040c922db15ded9dd1db73c9a9b3b718b 100644 (file)
@@ -5,7 +5,6 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba4::Header;
-
 require Exporter;
 
 @ISA = qw(Exporter);
@@ -39,7 +38,7 @@ sub HeaderProperties($$)
        my($props,$ignores) = @_;
        my $ret = "";
 
-       foreach my $d (keys %{$props}) {
+       foreach my $d (sort(keys %{$props})) {
                next if (grep(/^$d$/, @$ignores));
                if($props->{$d} ne "1") {
                        $ret.= "$d($props->{$d}),";
@@ -120,10 +119,20 @@ sub HeaderEnum($$;$)
                pidl " {\n";
                $tab_depth++;
                foreach my $e (@{$enum->{ELEMENTS}}) {
+                       my @enum_els = ();
                        unless ($first) { pidl ",\n"; }
                        $first = 0;
                        pidl tabs();
-                       pidl $e;
+                       @enum_els = split(/=/, $e);
+                       if (@enum_els == 2) {
+                               pidl $enum_els[0];
+                               pidl "=(int)";
+                               pidl "(";
+                               pidl $enum_els[1];
+                               pidl ")";
+                       } else {
+                               pidl $e;
+                       }
                }
                pidl "\n";
                $tab_depth--;
@@ -133,7 +142,7 @@ sub HeaderEnum($$;$)
                my $count = 0;
                my $with_val = 0;
                my $without_val = 0;
-               pidl " { __donnot_use_enum_$name=0x7FFFFFFF}\n";
+               pidl " { __do_not_use_enum_$name=0x7FFFFFFF}\n";
                foreach my $e (@{$enum->{ELEMENTS}}) {
                        my $t = "$e";
                        my $name;
@@ -183,14 +192,20 @@ sub HeaderUnion($$;$)
        return if (not defined($union->{ELEMENTS}));
        pidl " {\n";
        $tab_depth++;
+       my $needed = 0;
        foreach my $e (@{$union->{ELEMENTS}}) {
                if ($e->{TYPE} ne "EMPTY") {
                        if (! defined $done{$e->{NAME}}) {
                                HeaderElement($e);
                        }
                        $done{$e->{NAME}} = 1;
+                       $needed++;
                }
        }
+       if (!$needed) {
+               # sigh - some compilers don't like empty structures
+               pidl tabs()."int _dummy_element;\n";
+       }
        $tab_depth--;
        pidl "}";
 
@@ -200,6 +215,30 @@ sub HeaderUnion($$;$)
        pidl $tail if defined($tail);
 }
 
+#####################################################################
+# parse a pipe
+sub HeaderPipe($$;$)
+{
+       my($pipe,$name,$tail) = @_;
+
+       my $struct = $pipe->{DATA};
+       my $e = $struct->{ELEMENTS}[1];
+
+       pidl "struct $name;\n";
+       pidl "struct $struct->{NAME} {\n";
+       $tab_depth++;
+       pidl tabs()."uint32_t count;\n";
+       pidl tabs().mapTypeName($e->{TYPE})." *array;\n";
+       $tab_depth--;
+       pidl "}";
+
+       if (defined $struct->{PROPERTIES}) {
+               HeaderProperties($struct->{PROPERTIES}, []);
+       }
+
+       pidl $tail if defined($tail);
+}
+
 #####################################################################
 # parse a type
 sub HeaderType($$$;$)
@@ -210,6 +249,7 @@ sub HeaderType($$$;$)
                ($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
                ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name, $tail);
                ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name, $tail);
+               ($data->{TYPE} eq "PIPE") && HeaderPipe($data, $name, $tail);
                return;
        }
 
@@ -370,6 +410,7 @@ sub HeaderInterface($)
                HeaderUnion($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "UNION");
                HeaderEnum($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "ENUM");
                HeaderBitmap($t, $t->{NAME}) if ($t->{TYPE} eq "BITMAP");
+               HeaderPipe($t, $t->{NAME}, "\n\n") if ($t->{TYPE} eq "PIPE");
        }
 
        foreach my $fn (@{$interface->{FUNCTIONS}}) {
@@ -396,11 +437,28 @@ sub Parse($)
        $res = "";
        %headerstructs = ();
        pidl "/* header auto-generated by pidl */\n\n";
+
+       my $ifacename = "";
+
+       # work out a unique interface name
+       foreach (@{$ndr}) {
+               if ($_->{TYPE} eq "INTERFACE") {
+                       $ifacename = $_->{NAME};
+                       last;
+               }
+       }
+
+       pidl "#ifndef _PIDL_HEADER_$ifacename\n";
+       pidl "#define _PIDL_HEADER_$ifacename\n\n";
+
        if (!is_intree()) {
                pidl "#include <util/data_blob.h>\n";
        }
        pidl "#include <stdint.h>\n";
        pidl "\n";
+       # FIXME: Include this only if NTSTATUS was actually used
+       pidl choose_header("libcli/util/ntstatus.h", "core/ntstatus.h") . "\n";
+       pidl "\n";
 
        foreach (@{$ndr}) {
                ($_->{TYPE} eq "CPP_QUOTE") && HeaderQuote($_);
@@ -409,6 +467,8 @@ sub Parse($)
                ($_->{TYPE} eq "INCLUDE") && HeaderInclude(@{$_->{PATHS}});
        }
 
+       pidl "#endif /* _PIDL_HEADER_$ifacename */\n";
+
        return $res;
 }