r4535: add full support for
authorStefan Metzmacher <metze@samba.org>
Wed, 5 Jan 2005 15:36:26 +0000 (15:36 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:08:19 +0000 (13:08 -0500)
typedef bitmap {
    FLAG1 = 0x01
} fooflags;

typedef struct {
    fooflags flags;
}

metze

source/build/pidl/header.pm
source/build/pidl/parser.pm
source/build/pidl/util.pm
source/librpc/ndr/ndr_basic.c

index 85ccbcd814c755c24dd3e0574fb1bcbfe7a0a995..15a0bd427618a1651ab6c8dd52a8d158488373ea 100644 (file)
@@ -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");
 }
 
 #####################################################################
index c55b47dc5916484dfa2cd2110c02cfefaade3c2f..00d48270deb81ef3a85d953090bc02d5dfaac420 100644 (file)
@@ -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";
+       }
 }
 
 #####################################################################
index 0f09a8571f6c308a00a64d5db6e8453d6f2a51c7..1b00bdea1bd597d1dad364fba85f3bb42dd4a601 100644 (file)
@@ -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;
index 8874984f4b0c1b5c6a1cd22e3ae00f4060a22f2d..8c9664771d267295f94a0a97f96d345203111922 100644 (file)
@@ -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)