summaryrefslogtreecommitdiff
path: root/source4/build
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-08-02 20:12:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:30:59 -0500
commitf30eba52225df456e341beac380ab05469bde76b (patch)
tree9c2f48926ecbac5c09e6a08877ca7535b0676f43 /source4/build
parent1439697d339e5a866589d425d8d1a1e74b553ff3 (diff)
downloadsamba-f30eba52225df456e341beac380ab05469bde76b.tar.gz
samba-f30eba52225df456e341beac380ab05469bde76b.tar.bz2
samba-f30eba52225df456e341beac380ab05469bde76b.zip
r8940: Add TDR (Trivial Data Representation). The aim is to use this later for
NBT/WINS/etc rather then having to depend on NDR. (This used to be commit 5ee7af26dd220de06f1764cd1683abedeeda5131)
Diffstat (limited to 'source4/build')
-rw-r--r--source4/build/pidl/Parse/Pidl/Samba/TDR.pm252
-rwxr-xr-xsource4/build/pidl/pidl18
2 files changed, 270 insertions, 0 deletions
diff --git a/source4/build/pidl/Parse/Pidl/Samba/TDR.pm b/source4/build/pidl/Parse/Pidl/Samba/TDR.pm
new file mode 100644
index 0000000000..fb9dd0daea
--- /dev/null
+++ b/source4/build/pidl/Parse/Pidl/Samba/TDR.pm
@@ -0,0 +1,252 @@
+###################################################
+# Trivial Parser Generator
+# Copyright jelmer@samba.org 2005
+# released under the GNU GPL
+
+package Parse::Pidl::Samba::TDR;
+use Parse::Pidl::Util qw(has_property ParseExpr is_constant);
+use Data::Dumper;
+
+use strict;
+
+my $ret = "";
+my $tabs = "";
+
+sub indent() { $tabs.="\t"; }
+sub deindent() { $tabs = substr($tabs, 1); }
+sub pidl($) { $ret .= $tabs.(shift)."\n"; }
+sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); }
+sub static($) { my $p = shift; return("static ") unless ($p); return ""; }
+sub printarg($) {
+ my $t = shift;
+ return(", const char *name") if ($t eq "print");
+ return("");
+}
+
+sub ContainsArray($)
+{
+ my $e = shift;
+ foreach (@{$e->{ELEMENTS}}) {
+ next if (has_property($_, "charset") and
+ scalar(@{$_->{ARRAY_LEN}}) == 1);
+ return 1 if (defined($_->{ARRAY_LEN}) and
+ scalar(@{$_->{ARRAY_LEN}}) > 0);
+ }
+ return 0;
+}
+
+sub ParserElement($$$)
+{
+ my ($e,$t,$env) = @_;
+ my $switch = "";
+ my $array = "";
+ my $name = "";
+
+ fatal($e,"Pointers not supported in TDR") if ($e->{POINTERS} > 0);
+ fatal($e,"size_is() not supported in TDR") if (has_property($e, "size_is"));
+ fatal($e,"length_is() not supported in TDR") if (has_property($e, "length_is"));
+
+ if ($t eq "print") {
+ $name = ", \"$e->{NAME}\"$array";
+ }
+
+ if (has_property($e, "charset")) {
+ fatal($e,"charset() on non-array element") unless (defined($e->{ARRAY_LEN}) and scalar(@{$e->{ARRAY_LEN}}) > 0);
+
+ my $len = @{$e->{ARRAY_LEN}}[0];
+ if ($len eq "*") { $len = "-1"; }
+ pidl "TDR_CHECK(tdr_$t\_charset(tdr$name, &v->$e->{NAME}, $len, sizeof($e->{TYPE}_t), CH_$e->{PROPERTIES}->{charset}));";
+ return;
+ }
+
+ if (has_property($e, "switch_is")) {
+ $switch = ", " . ParseExpr($e->{PROPERTIES}->{switch_is}, $env);
+ }
+
+ if (defined($e->{ARRAY_LEN}) and scalar(@{$e->{ARRAY_LEN}}) > 0) {
+ my $len = ParseExpr($e->{ARRAY_LEN}[0], $env);
+
+ if ($t eq "pull" and not is_constant($len)) {
+ pidl "TDR_ALLOC(tdr, v->$e->{NAME}, $len);"
+ }
+
+ pidl "for (i = 0; i < $len; i++) {";
+ indent;
+ $array = "[i]";
+ }
+
+ if (has_property($e, "value") && $t eq "push") {
+ pidl "v->$e->{NAME} = ".ParseExpr($e->{PROPERTIES}->{value}, $env).";";
+ }
+
+ pidl "TDR_CHECK(tdr_$t\_$e->{TYPE}(tdr$name$switch, &v->$e->{NAME}$array));";
+
+ if ($array) { deindent; pidl "}"; }
+}
+
+sub ParserStruct($$$$)
+{
+ my ($e,$n,$t,$p) = @_;
+
+ pidl static($p)."NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".printarg($t).", struct $n *v)";
+ pidl "{"; indent;
+ pidl "int i;" if (ContainsArray($e));
+
+ if ($t eq "print") {
+ pidl "tdr->print(tdr, \"\%-25s: struct $n\", name);";
+ pidl "tdr->level++;";
+ }
+
+ my %env = map { $_->{NAME} => "v->$_->{NAME}" } @{$e->{ELEMENTS}};
+ ParserElement($_, $t, \%env) foreach (@{$e->{ELEMENTS}});
+
+ if ($t eq "print") {
+ pidl "tdr->level--;";
+ }
+
+ pidl "return NT_STATUS_OK;";
+
+ deindent; pidl "}";
+}
+
+sub ParserUnion($$$$)
+{
+ my ($e,$n,$t,$p) = @_;
+
+ pidl static($p)."NTSTATUS tdr_$t\_$n(struct tdr_$t *tdr".printarg($t).", int level, union $n *v)";
+ pidl "{"; indent;
+ pidl "int i;" if (ContainsArray($e));
+
+ if ($t eq "print") {
+ pidl "tdr->print(tdr, \"\%-25s: union $n\", name);";
+ pidl "tdr->level++;";
+ }
+
+ pidl "switch (level) {"; indent;
+ foreach (@{$e->{ELEMENTS}}) {
+ if (has_property($_, "case")) {
+ pidl "case " . $_->{PROPERTIES}->{case} . ":";
+ } elsif (has_property($_, "default")) {
+ pidl "default:";
+ }
+ indent; ParserElement($_, $t, {}); deindent;
+ pidl "break;";
+ }
+ deindent; pidl "}";
+
+ if ($t eq "print") {
+ pidl "tdr->level--;";
+ }
+
+ pidl "return NT_STATUS_OK;\n";
+ deindent; pidl "}";
+}
+
+sub ParserBitmap($$$$)
+{
+ my ($e,$n,$t,$p) = @_;
+ return if ($p);
+ pidl "#define tdr_$t\_$n tdr_$t\_" . Parse::Pidl::Typelist::bitmap_type_fn($e);
+}
+
+sub ParserEnum($$$$)
+{
+ my ($e,$n,$t,$p) = @_;
+ my $bt = Parse::Pidl::Typelist::enum_type_fn($e);
+
+ pidl static($p)."NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".printarg($t).", enum $n *v)";
+ pidl "{";
+ if ($t eq "pull") {
+ pidl "\t$bt\_t r;";
+ pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, \&r));";
+ pidl "\t*v = r;";
+ } elsif ($t eq "push") {
+ pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, ($bt\_t *)v));";
+ } elsif ($t eq "print") {
+ pidl "\t/* FIXME */";
+ }
+ pidl "\treturn NT_STATUS_OK;";
+ pidl "}";
+}
+
+sub ParserTypedef($$)
+{
+ my ($e,$t) = @_;
+
+ return if (has_property($e, "no$t"));
+
+ { STRUCT => \&ParserStruct, UNION => \&ParserUnion,
+ ENUM => \&ParserEnum, BITMAP => \&ParserBitmap
+ }->{$e->{DATA}->{TYPE}}($e->{DATA}, $e->{NAME}, $t, has_property($e, "public"));
+
+ pidl "";
+}
+
+sub ParserInterface($)
+{
+ my $x = shift;
+
+ foreach (@{$x->{DATA}}) {
+ next if ($_->{TYPE} ne "TYPEDEF");
+ ParserTypedef($_, "pull");
+ ParserTypedef($_, "push");
+ ParserTypedef($_, "print");
+ }
+}
+
+sub Parser($$)
+{
+ my ($idl,$hdrname) = @_;
+ $ret = "";
+ pidl "/* autogenerated by pidl */";
+ pidl "#include \"includes.h\"";
+ pidl "#include \"$hdrname\"";
+ foreach (@$idl) { ParserInterface($_) if ($_->{TYPE} eq "INTERFACE"); }
+ return $ret;
+}
+
+sub HeaderInterface($$)
+{
+ my ($x,$outputdir) = @_;
+
+ pidl "#ifndef __TDR_$x->{NAME}_HEADER__";
+ pidl "#define __TDR_$x->{NAME}_HEADER__";
+
+ pidl "#include \"$outputdir/$x->{NAME}.h\"";
+
+ foreach my $e (@{$x->{DATA}}) {
+ next unless ($e->{TYPE} eq "TYPEDEF");
+ next unless has_property($e, "public");
+
+ my $switch = "";
+
+ $switch = ", int level" if ($e->{DATA}->{TYPE} eq "UNION");
+
+ if ($e->{DATA}->{TYPE} eq "BITMAP") {
+ # FIXME
+ } else {
+ my ($n, $d) = ($e->{NAME}, lc($e->{DATA}->{TYPE}));
+ pidl "NTSTATUS tdr_pull\_$n(struct tdr_pull *tdr$switch, $d $n *v);";
+ pidl "NTSTATUS tdr_print\_$n(struct tdr_print *tdr, const char *name$switch, $d $n *v);";
+ pidl "NTSTATUS tdr_push\_$n(struct tdr_push *tdr$switch, $d $n *v);";
+ }
+
+ pidl "";
+ }
+
+ pidl "#endif /* __TDR_$x->{NAME}_HEADER__ */";
+}
+
+sub Header($$)
+{
+ my ($idl,$outputdir) = @_;
+ $ret = "";
+ pidl "/* Generated by pidl */";
+
+ foreach (@$idl) {
+ HeaderInterface($_, $outputdir) if ($_->{TYPE} eq "INTERFACE");
+ }
+ return $ret;
+}
+
+1;
diff --git a/source4/build/pidl/pidl b/source4/build/pidl/pidl
index 7523f03495..99e5cbc076 100755
--- a/source4/build/pidl/pidl
+++ b/source4/build/pidl/pidl
@@ -43,6 +43,8 @@ my($opt_template) = 0;
my($opt_client);
my($opt_server);
my($opt_ndr_parser);
+my($opt_tdr_header);
+my($opt_tdr_parser);
my($opt_eth_parser);
my($opt_eth_header);
my($opt_keep);
@@ -74,6 +76,8 @@ Options:
--header[=OUTFILE] create generic header file
--ndr-header[=OUTFILE]create a C NDR-specific header file
--ndr-parser[=OUTFILE]create a C NDR parser
+ --tdr-header[=OUTFILE]create a C TDR header file
+ --tdr-parser[=OUTFILE]create a C TDR parser
--ejs[=OUTFILE] create ejs wrapper file
--client[=OUTFILE] create a C NDR client
--server[=OUTFILE] create server boilerplate
@@ -103,6 +107,8 @@ GetOptions (
'ndr-header:s' => \$opt_ndr_header,
'header:s' => \$opt_header,
'server:s' => \$opt_server,
+ 'tdr-header:s' => \$opt_tdr_header,
+ 'tdr-parser:s' => \$opt_tdr_parser,
'template' => \$opt_template,
'ndr-parser:s' => \$opt_ndr_parser,
'client:s' => \$opt_client,
@@ -295,6 +301,18 @@ $dcom
Parse::Pidl::Util::FileSave($eparser, Parse::Pidl::Ethereal::NDR::Parser::Parse($ndr, $basename, $eparser));
}
+ my $tdr_parser = ($opt_tdr_parser or "$outputdir/tdr_$basename.c");
+ my $tdr_header = ($opt_tdr_header or "$outputdir/tdr_$basename.h");
+ if (defined($opt_tdr_parser)) {
+ require Parse::Pidl::Samba::TDR;
+ Parse::Pidl::Util::FileSave($tdr_parser, Parse::Pidl::Samba::TDR::Parser($pidl, $tdr_header));
+ }
+
+ if (defined($opt_tdr_header)) {
+ require Parse::Pidl::Samba::TDR;
+ Parse::Pidl::Util::FileSave($tdr_header, Parse::Pidl::Samba::TDR::Header($pidl, $outputdir));
+ }
+
if ($opt_template) {
require Parse::Pidl::Samba::Template;
print Parse::Pidl::Samba::Template::Parse($pidl);