From d0da601ff78c1df7422e3a558db5a4c4862eb785 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 5 Jan 2005 15:36:26 +0000 Subject: r4535: add full support for typedef bitmap { FLAG1 = 0x01 } fooflags; typedef struct { fooflags flags; } metze (This used to be commit 052a7d4f9a3a178149c65a616fdfd87152dff7eb) --- source4/build/pidl/header.pm | 29 +++++++++- source4/build/pidl/parser.pm | 117 +++++++++++++++++++++++++++++++++++++++-- source4/build/pidl/util.pm | 83 +++++++++++++++++++++++++---- source4/librpc/ndr/ndr_basic.c | 13 ++++- 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) -- cgit