################################################### # 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::Types qw(DeclShort); 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 warning($$) { my ($e,$s) = @_; warn("$e->{FILE}:$e->{LINE}: $s\n"); } sub ParseElement($) { my $e = shift; 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" . DeclShort($e) . ";"; } } } sub CreateStruct($$$$) { my ($if,$fn,$n,$t) = @_; pidl "typedef struct $n {"; ParseElement($_) foreach (@$t); 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 (@{$fn->{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 ParseUnion($$$) { my ($if,$u,$n) = @_; pidl "typedef union $if->{NAME}_$n {"; #FIXME: What about elements that require more then one variable? ParseElement($_) foreach (@{$u->{ELEMENTS}}); pidl "} ".uc($if->{NAME}."_".$n) .";"; pidl ""; } sub ParseEnum($$$) { my ($if,$s,$n) = @_; pidl "typedef enum {"; pidl "$_," foreach (@{$s->{ELEMENTS}}); 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 ""; foreach (@{$if->{TYPEDEFS}}) { ParseStruct($if, $_->{DATA}, $_->{NAME}) if ($_->{DATA}->{TYPE} eq "STRUCT"); ParseEnum($if, $_->{DATA}, $_->{NAME}) if ($_->{DATA}->{TYPE} eq "ENUM"); ParseBitmap($if, $_->{DATA}, $_->{NAME}) if ($_->{DATA}->{TYPE} eq "BITMAP"); ParseUnion($if, $_->{DATA}, $_->{NAME}) if ($_->{DATA}->{TYPE} eq "UNION"); } ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}}); 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;