summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-01-05 15:36:26 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:08:19 -0500
commitd0da601ff78c1df7422e3a558db5a4c4862eb785 (patch)
tree1c1f1fa2893a369e8671de83eec4ba37f7f21e06
parent31de71f0a2fd8cbd9c75c6573a02189178ebabe8 (diff)
downloadsamba-d0da601ff78c1df7422e3a558db5a4c4862eb785.tar.gz
samba-d0da601ff78c1df7422e3a558db5a4c4862eb785.tar.bz2
samba-d0da601ff78c1df7422e3a558db5a4c4862eb785.zip
r4535: add full support for
typedef bitmap { FLAG1 = 0x01 } fooflags; typedef struct { fooflags flags; } metze (This used to be commit 052a7d4f9a3a178149c65a616fdfd87152dff7eb)
-rw-r--r--source4/build/pidl/header.pm29
-rw-r--r--source4/build/pidl/parser.pm117
-rw-r--r--source4/build/pidl/util.pm83
-rw-r--r--source4/librpc/ndr/ndr_basic.c13
4 files changed, 225 insertions, 17 deletions
diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/header.pm
index 85ccbcd814..15a0bd4276 100644
--- a/source4/build/pidl/header.pm
+++ b/source4/build/pidl/header.pm
@@ -92,7 +92,7 @@ sub HeaderStruct($$)
}
#####################################################################
-# parse a struct
+# parse a enum
sub HeaderEnum($$)
{
my($enum) = shift;
@@ -121,6 +121,26 @@ sub HeaderEnum($$)
$res .= "}";
}
+#####################################################################
+# parse a bitmap
+sub HeaderBitmap($$)
+{
+ my($bitmap) = shift;
+ my($name) = shift;
+
+ util::register_bitmap($bitmap, $name);
+
+ $res .= "\n/* bitmap $name */\n";
+
+ my $els = \@{$bitmap->{ELEMENTS}};
+ foreach my $i (0 .. $#{$els}) {
+ my $e = ${$els}[$i];
+ chomp $e;
+ $res .= "#define $e\n";
+ }
+
+ $res .= "\n";
+}
#####################################################################
# parse a union
@@ -155,6 +175,8 @@ sub HeaderType($$$)
if (ref($data) eq "HASH") {
($data->{TYPE} eq "ENUM") &&
HeaderEnum($data, $name);
+ ($data->{TYPE} eq "BITMAP") &&
+ HeaderBitmap($data, $name);
($data->{TYPE} eq "STRUCT") &&
HeaderStruct($data, $name);
($data->{TYPE} eq "UNION") &&
@@ -165,6 +187,9 @@ sub HeaderType($$$)
$res .= "const char *";
} elsif (util::is_enum($e->{TYPE})) {
$res .= "enum $data";
+ } elsif (util::is_bitmap($e->{TYPE})) {
+ my $bitmap = util::get_bitmap($e->{TYPE});
+ $res .= util::bitmap_type_decl($bitmap);
} elsif (util::is_scalar_type($data)) {
$res .= "$data";
} elsif (util::has_property($e, "switch_is")) {
@@ -180,7 +205,7 @@ sub HeaderTypedef($)
{
my($typedef) = shift;
HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
- $res .= ";\n";
+ $res .= ";\n" unless ($typedef->{DATA}->{TYPE} eq "BITMAP");
}
#####################################################################
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index c55b47dc59..00d48270de 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -468,13 +468,18 @@ sub ParseElementPullSwitch($$$$)
if (!defined $utype ||
!util::has_property($utype, "nodiscriminant")) {
my $e2 = find_sibling($e, $switch);
+ my $type_decl = $e2->{TYPE};
+ my $type_fn = $e2->{TYPE};
pidl "\tif (($ndr_flags) & NDR_SCALARS) {\n";
if (util::is_enum($e2->{TYPE})) {
- pidl "\t\t enum $e2->{TYPE} _level;\n";
- } else {
- pidl "\t\t $e2->{TYPE} _level;\n";
+ $type_decl = util::enum_type_decl($e2);
+ $type_fn = util::enum_type_fn($e2);
+ } elsif (util::is_bitmap($e2->{TYPE})) {
+ $type_decl = util::bitmap_type_decl($e2);
+ $type_fn = util::bitmap_type_fn($e2);
}
- pidl "\t\tNDR_CHECK(ndr_pull_$e2->{TYPE}(ndr, &_level));\n";
+ pidl "\t\t$type_decl _level;\n";
+ pidl "\t\tNDR_CHECK(ndr_pull_$type_fn(ndr, &_level));\n";
if ($switch_var =~ /r->in/) {
pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _level != $switch_var) {\n";
} else {
@@ -863,6 +868,78 @@ sub ParseEnumPrint($)
}
+#####################################################################
+# generate a push function for a bitmap
+sub ParseBitmapPush($)
+{
+ my($bitmap) = shift;
+ my($type_decl) = util::bitmap_type_decl($bitmap);
+ my($type_fn) = util::bitmap_type_fn($bitmap);
+
+ start_flags($bitmap);
+
+ pidl "\tNDR_CHECK(ndr_push_$type_fn(ndr, r));\n";
+
+ end_flags($bitmap);
+}
+
+#####################################################################
+# generate a pull function for an bitmap
+sub ParseBitmapPull($)
+{
+ my($bitmap) = shift;
+ my($type_decl) = util::bitmap_type_decl($bitmap);
+ my($type_fn) = util::bitmap_type_fn($bitmap);
+
+ start_flags($bitmap);
+
+ pidl "\t$type_decl v;\n";
+ pidl "\tNDR_CHECK(ndr_pull_$type_fn(ndr, &v));\n";
+ pidl "\t*r = v;\n";
+
+ end_flags($bitmap);
+}
+
+#####################################################################
+# generate a print function for an bitmap
+sub ParseBintmapPrintElement($$)
+{
+ my($e) = shift;
+ my($bitmap) = shift;
+ my($type_decl) = util::bitmap_type_decl($bitmap);
+ my($type_fn) = util::bitmap_type_fn($bitmap);
+ my($name) = $bitmap->{PARENT}->{NAME};
+ my($flag);
+
+ if ($e =~ /^(\w+) .*$/) {
+ $flag = "$1";
+ } else {
+ die "Bitmap: \"$name\" invalid Flag: \"$e\"";
+ }
+
+ pidl "\tndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, r);\n";
+}
+
+#####################################################################
+# generate a print function for an bitmap
+sub ParseBitmapPrint($)
+{
+ my($bitmap) = shift;
+ my($type_decl) = util::bitmap_type_decl($bitmap);
+ my($type_fn) = util::bitmap_type_fn($bitmap);
+
+ start_flags($bitmap);
+
+ pidl "\tndr_print_$type_fn(ndr, name, r);\n";
+
+ pidl "\tndr->depth++;\n";
+ foreach my $e (@{$bitmap->{ELEMENTS}}) {
+ ParseBintmapPrintElement($e, $bitmap);
+ }
+ pidl "\tndr->depth--;\n";
+
+ end_flags($bitmap);
+}
#####################################################################
# generate a struct print function
@@ -1139,6 +1216,8 @@ sub ParseTypePush($)
ParseUnionPush($data);
($data->{TYPE} eq "ENUM") &&
ParseEnumPush($data);
+ ($data->{TYPE} eq "BITMAP") &&
+ ParseBitmapPush($data);
}
}
@@ -1155,6 +1234,8 @@ sub ParseTypePrint($)
ParseUnionPrint($data);
($data->{TYPE} eq "ENUM") &&
ParseEnumPrint($data);
+ ($data->{TYPE} eq "BITMAP") &&
+ ParseBitmapPrint($data);
}
}
@@ -1171,6 +1252,8 @@ sub ParseTypePull($)
ParseUnionPull($data);
($data->{TYPE} eq "ENUM") &&
ParseEnumPull($data);
+ ($data->{TYPE} eq "BITMAP") &&
+ ParseBitmapPull($data);
}
}
@@ -1213,6 +1296,15 @@ sub ParseTypedefPush($)
pidl "\treturn NT_STATUS_OK;\n";
pidl "}\n\n";
}
+
+ if ($e->{DATA}->{TYPE} eq "BITMAP") {
+ my $type_decl = util::bitmap_type_fn($e->{DATA});
+ pidl $static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, $type_decl r)";
+ pidl "\n{\n";
+ ParseTypePush($e->{DATA});
+ pidl "\treturn NT_STATUS_OK;\n";
+ pidl "}\n\n";
+ }
}
@@ -1255,6 +1347,15 @@ sub ParseTypedefPull($)
pidl "\treturn NT_STATUS_OK;\n";
pidl "}\n\n";
}
+
+ if ($e->{DATA}->{TYPE} eq "BITMAP") {
+ my $type_decl = util::bitmap_type_fn($e->{DATA});
+ pidl $static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, $type_decl *r)";
+ pidl "\n{\n";
+ ParseTypePull($e->{DATA});
+ pidl "\treturn NT_STATUS_OK;\n";
+ pidl "}\n\n";
+ }
}
@@ -1290,6 +1391,14 @@ sub ParseTypedefPrint($)
ParseTypePrint($e->{DATA});
pidl "}\n\n";
}
+
+ if ($e->{DATA}->{TYPE} eq "BITMAP") {
+ my $type_decl = util::bitmap_type_fn($e->{DATA});
+ pidl "void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $type_decl r)";
+ pidl "\n{\n";
+ ParseTypePrint($e->{DATA});
+ pidl "}\n\n";
+ }
}
#####################################################################
diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm
index 0f09a8571f..1b00bdea1b 100644
--- a/source4/build/pidl/util.pm
+++ b/source4/build/pidl/util.pm
@@ -4,8 +4,6 @@
# released under the GNU GPL
package util;
-my %is_enum;
-
#####################################################################
# load a data structure from a file (as saved with SaveStructure)
sub LoadStructure($)
@@ -216,6 +214,59 @@ sub is_enum($)
return defined $enum_list{$name}
}
+sub enum_type_decl($)
+{
+ my $e = shift;
+ return "enum $e->{TYPE}";
+}
+
+sub enum_type_fn($)
+{
+ my $e = shift;
+ return "$e->{TYPE}";
+}
+
+my %bitmap_list;
+
+sub register_bitmap($$)
+{
+ my $bitmap = shift;
+ my $name = shift;
+ $bitmap_list{$name} = $bitmap;
+}
+
+sub is_bitmap($)
+{
+ my $name = shift;
+ return defined $bitmap_list{$name};
+}
+
+sub get_bitmap($)
+{
+ my $name = shift;
+ return $bitmap_list{$name};
+}
+
+sub bitmap_type_decl($)
+{
+ my $bitmap = shift;
+
+ if (util::has_property($bitmap->{PARENT}, "bitmap8bit")) {
+ return "uint8";
+ } elsif (util::has_property($bitmap->{PARENT}, "bitmap16bit")) {
+ return "uint16";
+ } elsif (util::has_property($bitmap->{PARENT}, "bitmap64bit")) {
+ return "uint64";
+ }
+ return "uint32";
+}
+
+sub bitmap_type_fn($)
+{
+ my $bitmap = shift;
+ return bitmap_type_decl($bitmap);
+}
+
sub is_scalar_type($)
{
my($type) = shift;
@@ -232,7 +283,11 @@ sub is_scalar_type($)
if (is_enum($type)) {
return 1;
}
-
+
+ if (is_bitmap($type)) {
+ return 1;
+ }
+
return 0;
}
@@ -246,19 +301,29 @@ sub type_align($)
return 4;
}
- return 4, if ($type eq "uint32");
- return 4, if ($type eq "long");
- return 2, if ($type eq "short");
return 1, if ($type eq "char");
+ return 1, if ($type eq "int8");
return 1, if ($type eq "uint8");
+
+ return 2, if ($type eq "short");
+ return 2, if ($type eq "wchar_t");
+ return 2, if ($type eq "int16");
return 2, if ($type eq "uint16");
+
+ return 4, if ($type eq "long");
+ return 4, if ($type eq "int32");
+ return 4, if ($type eq "uint32");
+
+ return 4, if ($type eq "int64");
+ return 4, if ($type eq "uint64");
+
return 4, if ($type eq "NTTIME");
return 4, if ($type eq "NTTIME_1sec");
return 4, if ($type eq "time_t");
- return 8, if ($type eq "HYPER_T");
- return 2, if ($type eq "wchar_t");
+
return 4, if ($type eq "DATA_BLOB");
- return 4, if ($type eq "int32");
+
+ return 8, if ($type eq "HYPER_T");
# it must be an external type - all we can do is guess
return 4;
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index 8874984f4b..8c9664771d 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -1000,9 +1000,18 @@ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
}
void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type,
- const char *val, uint32_t value)
+ const char *val, uint_t value)
{
- ndr->print(ndr, "%-25s: %s (%u)", name, val?val:"UNKNOWN", value);
+ ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
+}
+
+void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint_t flag, uint_t value)
+{
+ /* size can be later used to print something like:
+ * ...1.... .........: FLAG1_NAME
+ * .....0.. .........: FLAG2_NAME
+ */
+ ndr->print(ndr, "%s: %-25s", (flag & value)?"1":"0", flag_name);
}
void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)