diff options
Diffstat (limited to 'source4/pidl/lib/Parse/Pidl/Samba3/Header.pm')
-rw-r--r-- | source4/pidl/lib/Parse/Pidl/Samba3/Header.pm | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm new file mode 100644 index 0000000000..be7f1ca5c4 --- /dev/null +++ b/source4/pidl/lib/Parse/Pidl/Samba3/Header.pm @@ -0,0 +1,160 @@ +################################################### +# Samba3 NDR header generator for IDL structures +# Copyright jelmer@samba.org 2005 +# released under the GNU GPL + +package Parse::Pidl::Samba3::Header; + +use strict; +use Parse::Pidl::Typelist qw(hasType getType); +use Parse::Pidl::Util qw(has_property ParseExpr); +use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); +use Parse::Pidl::Samba3::Util qw(MapSamba3Type); + +use vars qw($VERSION); +$VERSION = '0.01'; + +my $res = ""; +sub pidl($) { my $x = shift; $res .= "$x\n"; } +sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); } + +sub CreateStruct($$$$) +{ + my ($if,$fn,$n,$t) = @_; + + pidl "typedef struct $n {"; + foreach my $e (@$t) { + foreach my $l (@{$e->{LEVELS}}) { + if ($l->{TYPE} eq "POINTER") { + return if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "top"); + pidl "\tuint32 ptr_$e->{NAME};"; + } elsif ($l->{TYPE} eq "SWITCH") { + pidl "\tuint32 level_$e->{NAME};"; + } elsif ($l->{TYPE} eq "DATA") { + pidl "\t" . MapSamba3Type($e) . ";"; + } + } + } + + if (not @$t) { + # Some compilers don't like empty structs + pidl "\tuint32 dummy;"; + } + + pidl "} " . uc($n) . ";"; + pidl ""; +} + +sub ParseFunction($$) +{ + my ($if,$fn) = @_; + + my @in = (); + my @out = (); + + foreach (@{$_->{ELEMENTS}}) { + push (@in, $_) if (grep(/in/, @{$_->{DIRECTION}})); + push (@out, $_) if (grep(/out/, @{$_->{DIRECTION}})); + } + + if (defined($fn->{RETURN_TYPE})) { + push (@out, { + NAME => "status", + TYPE => $fn->{RETURN_TYPE}, + LEVELS => [ + { + TYPE => "DATA", + DATA_TYPE => $fn->{RETURN_TYPE} + } + ] + } ); + } + + # define Q + R structures for functions + + CreateStruct($if, $fn, "$if->{NAME}_q_$fn->{NAME}", \@in); + CreateStruct($if, $fn, "$if->{NAME}_r_$fn->{NAME}", \@out); +} + +sub ParseStruct($$$) +{ + my ($if,$s,$n) = @_; + + CreateStruct($if, $s, "$if->{NAME}_$n", $s->{ELEMENTS}); +} + +sub ParseEnum($$$) +{ + my ($if,$s,$n) = @_; + + pidl "typedef enum {"; + + foreach (@{$s->{ELEMENTS}}) { + pidl "$_,"; + } + + pidl "} $n;"; +} + +sub ParseBitmap($$$) +{ + my ($if,$s,$n) = @_; + + pidl "#define $_" foreach (@{$s->{ELEMENTS}}); +} + +sub ParseInterface($) +{ + my $if = shift; + + my $def = "_RPC_" . uc($if->{NAME}) . "_H"; + + pidl ""; + + pidl "\#ifndef $def"; + pidl "\#define $def"; + + pidl ""; + + foreach (@{$if->{FUNCTIONS}}) { + pidl "\#define " . uc($_->{NAME}) . " $_->{OPNUM}" ; + } + + pidl ""; + + ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}}); + + foreach (@{$if->{TYPEDEFS}}) { + ParseStruct($if, $_->{DATA}, $_->{NAME}) if ($_->{TYPE} eq "STRUCT"); + ParseEnum($if, $_->{DATA}, $_->{NAME}) if ($_->{TYPE} eq "ENUM"); + ParseBitmap($if, $_->{DATA}, $_->{NAME}) if ($_->{TYPE} eq "BITMAP"); + fatal($_, "Unions not supported for Samba3 yet") if ($_->{TYPE} eq "STRUCT"); + } + + foreach (@{$if->{CONSTS}}) { + pidl "$_->{NAME} ($_->{VALUE})"; + } + + pidl "\#endif /* $def */"; +} + +sub Parse($$) +{ + my($ndr,$filename) = @_; + + $res = ""; + + pidl "/*"; + pidl " * Unix SMB/CIFS implementation."; + pidl " * header auto-generated by pidl. DO NOT MODIFY!"; + pidl " */"; + pidl ""; + + # Loop over interfaces + foreach (@{$ndr}) { + ParseInterface($_) if ($_->{TYPE} eq "INTERFACE"); + } + return $res; +} + +1; |