################################################### # 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;