From 89a17e60a14783e8560d3babc8a9a328adc3c94c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Mon, 30 May 2005 00:19:58 +0000
Subject: r7084: - readd the work from rev 6516,6517,6572

- use a single list of scalars

- let "string" not be so special anymore

- fix support for "string_array"

metze
(This used to be commit e1fa7ae6c8420dc582578e084b9c0d641bcfbd73)
---
 source4/build/pidl/com_header.pm |   2 +-
 source4/build/pidl/eth_parser.pm |  10 +-
 source4/build/pidl/ndr.pm        |  50 +--------
 source4/build/pidl/ndr_header.pm |  30 ++---
 source4/build/pidl/ndr_parser.pm |  18 ++-
 source4/build/pidl/typelist.pm   | 237 ++++++++++++++++++++++++++++++---------
 6 files changed, 217 insertions(+), 130 deletions(-)

(limited to 'source4/build')

diff --git a/source4/build/pidl/com_header.pm b/source4/build/pidl/com_header.pm
index 1e178eed850..3300d840927 100644
--- a/source4/build/pidl/com_header.pm
+++ b/source4/build/pidl/com_header.pm
@@ -17,7 +17,7 @@ sub GetArgumentProtoList($)
 		$res .= ", " . typelist::mapType($a->{TYPE}) . " ";
 
 		my $l = $a->{POINTERS};
-		$l-- if ($a->{TYPE} eq "string");
+		$l-- if (typelist::scalar_is_reference($a->{TYPE}));
 		foreach my $i (1..$l) {
 			$res .= "*";
 		}
diff --git a/source4/build/pidl/eth_parser.pm b/source4/build/pidl/eth_parser.pm
index 43ed8b841a2..a285dacf239 100644
--- a/source4/build/pidl/eth_parser.pm
+++ b/source4/build/pidl/eth_parser.pm
@@ -213,8 +213,7 @@ sub append_prefix($$)
 				return get_value_of($var_name) 
 			}
 		} elsif ($l->{TYPE} eq "DATA") {
-			if ($l->{DATA_TYPE} eq "string" or
-			    $l->{DATA_TYPE} eq "nbt_string") {
+			if (typelist::scalar_is_reference($l->{DATA_TYPE})) {
 				return get_value_of($var_name) unless ($pointers);
 			}
 		}
@@ -576,18 +575,17 @@ sub ParseData($$$$$)
 	my $var_name = shift;
 	my $ndr_flags = shift;
 
-	$var_name = get_pointer_to($var_name);
-
 	#
 	#  ALAND! for packet-dcerpc-lsa.c, uncommenting this code
 	#  produces constructs like &(&r->string), to pass to another
 	#  function, which gives compiler errors.
 	#
-	if ($l->{DATA_TYPE} eq "string" or 
-	    $l->{DATA_TYPE} eq "nbt_string") {
+	if (typelist::scalar_is_reference($l->{DATA_TYPE})) {
 		$var_name = get_pointer_to($var_name);
 	}
 
+	$var_name = get_pointer_to($var_name);
+
 	pidl "offset += dissect_$l->{DATA_TYPE}(tvb, offset, pinfo, tree, drep, hf_FIXME, NULL);";
 
 	if (my $range = util::has_property($e, "range")) {
diff --git a/source4/build/pidl/ndr.pm b/source4/build/pidl/ndr.pm
index 98e3d2b4bc6..aa1a557dd19 100644
--- a/source4/build/pidl/ndr.pm
+++ b/source4/build/pidl/ndr.pm
@@ -177,7 +177,7 @@ sub can_contain_deferred
 	my $e = shift;
 
 	return 1 if ($e->{POINTERS});
-	return 0 if (is_scalar_type($e->{TYPE}));
+	return 0 if (typelist::is_scalar($e->{TYPE}));
 	return 0 if (util::has_property($e, "subcontext"));
 	return 1 unless (typelist::hasType($e->{TYPE})); # assume the worst
 
@@ -190,19 +190,6 @@ sub can_contain_deferred
 	return 0;
 }
 
-sub is_scalar_type($)
-{
-    my $type = shift;
-
-	return 0 unless(typelist::hasType($type));
-
-	if (my $dt = typelist::getType($type)->{DATA}->{TYPE}) {
-		return 1 if ($dt eq "SCALAR" or $dt eq "ENUM" or $dt eq "BITMAP");
-	}
-
-    return 0;
-}
-
 sub pointer_type($)
 {
 	my $e = shift;
@@ -252,35 +239,6 @@ sub find_largest_alignment($)
 	return $align;
 }
 
-my %scalar_alignments = 
-(
-     "char"           => 1,
-     "int8"           => 1,
-     "uint8"          => 1,
-     "short"          => 2,
-     "wchar_t"        => 2,
-     "int16"          => 2,
-     "uint16"         => 2,
-     "long"           => 4,
-     "int32"          => 4,
-     "uint32"         => 4,
-     "dlong"          => 4,
-     "udlong"         => 4,
-     "udlongr"        => 4,
-     "NTTIME"         => 4,
-     "NTTIME_1sec"    => 4,
-     "time_t"         => 4,
-     "DATA_BLOB"      => 4,
-     "error_status_t" => 4,
-     "WERROR"         => 4,
-	 "NTSTATUS" 	  => 4,
-     "boolean32"      => 4,
-     "unsigned32"     => 4,
-     "ipv4address"    => 4,
-     "hyper"          => 8,
-     "NTTIME_hyper"   => 8
-);
-
 #####################################################################
 # align a type
 sub align_type
@@ -302,10 +260,10 @@ sub align_type
 	} elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) {
 		return find_largest_alignment($dt);
 	} elsif ($dt->{TYPE} eq "SCALAR") {
-		return $scalar_alignments{$dt->{NAME}};
-	} else { 
-		die("Unknown data type type $dt->{TYPE}");
+		return typelist::getScalarAlignment($dt->{NAME});
 	}
+
+	die("Unknown data type type $dt->{TYPE}");
 }
 
 # determine if an element needs a reference pointer on the wire
diff --git a/source4/build/pidl/ndr_header.pm b/source4/build/pidl/ndr_header.pm
index 576361260f1..dfc20389eac 100644
--- a/source4/build/pidl/ndr_header.pm
+++ b/source4/build/pidl/ndr_header.pm
@@ -52,22 +52,24 @@ sub HeaderProperties($$)
 # parse a structure element
 sub HeaderElement($)
 {
-    my($element) = shift;
+	my($element) = shift;
 
-    if (defined $element->{PROPERTIES}) {
+	if (defined $element->{PROPERTIES}) {
 		HeaderProperties($element->{PROPERTIES}, {"in" => 1, "out" => 1});
 	}
-    pidl tabs();
-    HeaderType($element, $element->{TYPE}, "");
-    pidl " ";
+	pidl tabs();
+	HeaderType($element, $element->{TYPE}, "");
+	pidl " ";
 	my $prefix = "";
 	my $postfix = "";
 	foreach my $l (@{$element->{LEVELS}}) 
 	{
 		if (($l->{TYPE} eq "POINTER")) {
-			next if ($element->{TYPE} eq "string");
+			my $nl = Ndr::GetNextLevel($element, $l);
+			$nl = Ndr::GetNextLevel($element, $nl) if ($nl->{TYPE} eq "SUBCONTEXT");
+			next if ($nl->{TYPE} eq "DATA" and typelist::scalar_is_reference($nl->{DATA_TYPE}));
 			$prefix .= "*";
-	    } elsif (($l->{TYPE} eq "ARRAY")) {
+		} elsif (($l->{TYPE} eq "ARRAY")) {
 			my $pl = Ndr::GetPrevLevel($element, $l);
 			next if ($pl and $pl->{TYPE} eq "POINTER");
 
@@ -76,15 +78,15 @@ sub HeaderElement($)
 			} else {
 				$prefix .= "*";
 			}
-	    } elsif ($l->{TYPE} eq "DATA") {
-    		pidl "$prefix$element->{NAME}$postfix";
+		} elsif ($l->{TYPE} eq "DATA") {
+    			pidl "$prefix$element->{NAME}$postfix";
 		}
 	}
-	
-    if (defined $element->{ARRAY_LEN}[0] && util::is_constant($element->{ARRAY_LEN}[0])) {
-	    pidl "[$element->{ARRAY_LEN}[0]]";
-    }
-    pidl ";\n";
+
+	if (defined $element->{ARRAY_LEN}[0] && util::is_constant($element->{ARRAY_LEN}[0])) {
+		pidl "[$element->{ARRAY_LEN}[0]]";
+	}
+	pidl ";\n";
 }
 
 #####################################################################
diff --git a/source4/build/pidl/ndr_parser.pm b/source4/build/pidl/ndr_parser.pm
index be663269f86..a73675159b5 100644
--- a/source4/build/pidl/ndr_parser.pm
+++ b/source4/build/pidl/ndr_parser.pm
@@ -33,11 +33,10 @@ sub append_prefix($$)
 			if (($pointers == 0) and 
 			    (not $l->{IS_FIXED}) and
 			    (not $l->{IS_INLINE})) {
-				return get_value_of($var_name) 
+				return get_value_of($var_name); 
 			}
 		} elsif ($l->{TYPE} eq "DATA") {
-			if ($l->{DATA_TYPE} eq "string" or
-			    $l->{DATA_TYPE} eq "nbt_string") {
+			if (typelist::scalar_is_reference($l->{DATA_TYPE})) {
 				return get_value_of($var_name) unless ($pointers);
 			}
 		}
@@ -63,7 +62,7 @@ sub is_scalar_array($$)
 
 	my $nl = Ndr::GetNextLevel($e,$l);
 	return (($nl->{TYPE} eq "DATA") and 
-	        (Ndr::is_scalar_type($nl->{DATA_TYPE})));
+	        (typelist::is_scalar($nl->{DATA_TYPE})));
 }
 
 sub get_pointer_to($)
@@ -776,7 +775,7 @@ sub ParseElementPrint($$$)
 			unless ($l->{NO_METADATA}){ $var_name = get_pointer_to($var_name); }
 
 		} elsif ($l->{TYPE} eq "DATA") {
-			if (not Ndr::is_scalar_type($l->{DATA_TYPE})) {
+			if (not typelist::is_scalar($l->{DATA_TYPE}) or typelist::scalar_is_reference($l->{DATA_TYPE})) {
 				$var_name = get_pointer_to($var_name);
 			}
 			pidl "ndr_print_$l->{DATA_TYPE}(ndr, \"$e->{NAME}\", $var_name);";
@@ -849,13 +848,12 @@ sub ParseDataPull($$$$$)
 	my $var_name = shift;
 	my $ndr_flags = shift;
 
-	$var_name = get_pointer_to($var_name);
-
-	if ($l->{DATA_TYPE} eq "string" or 
-	    $l->{DATA_TYPE} eq "nbt_string") {
+	if (typelist::scalar_is_reference($l->{DATA_TYPE})) {
 		$var_name = get_pointer_to($var_name);
 	}
 
+	$var_name = get_pointer_to($var_name);
+
 	pidl "NDR_CHECK(ndr_pull_$l->{DATA_TYPE}($ndr, $ndr_flags, $var_name));";
 
 	if (my $range = util::has_property($e, "range")) {
@@ -876,7 +874,7 @@ sub ParseDataPush($$$$$)
 	my $ndr_flags = shift;
 
 	# strings are passed by value rather then reference
-	if (not Ndr::is_scalar_type($l->{DATA_TYPE})) {
+	if (not typelist::is_scalar($l->{DATA_TYPE}) or typelist::scalar_is_reference($l->{DATA_TYPE})) {
 		$var_name = get_pointer_to($var_name);
 	}
 
diff --git a/source4/build/pidl/typelist.pm b/source4/build/pidl/typelist.pm
index f5a06500061..a8600cedbe8 100644
--- a/source4/build/pidl/typelist.pm
+++ b/source4/build/pidl/typelist.pm
@@ -9,6 +9,166 @@ use strict;
 
 my %typedefs = ();
 
+# a list of known scalar types
+my $scalars = {
+	# 0 byte types
+	"void"		=> {
+				C_TYPE		=> "void",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 0
+			},
+
+	# 1 byte types
+	"char"		=> {
+				C_TYPE		=> "char",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 1
+			},
+	"int8"		=> {
+				C_TYPE		=> "int8_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 1
+			},
+	"uint8"		=> {
+				C_TYPE		=> "uint8_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 1
+			},
+
+	# 2 byte types
+	"int16"		=> {
+				C_TYPE		=> "int16_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 2
+			},
+	"uint16"	=> {	C_TYPE		=> "uint16_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 2
+			},
+
+	# 4 byte types
+	"int32"		=> {
+				C_TYPE		=> "int32_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+	"uint32"	=> {	C_TYPE		=> "uint32_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+
+	# 8 byte types
+	"hyper"		=> {
+				C_TYPE		=> "uint64_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 8
+			},
+	"dlong"		=> {
+				C_TYPE		=> "int64_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+	"udlong"	=> {
+				C_TYPE		=> "uint64_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+	"udlongr"	=> {
+				C_TYPE		=> "uint64_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+
+	# DATA_BLOB types
+	"DATA_BLOB"	=> {
+				C_TYPE		=> "DATA_BLOB",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+
+	# string types
+	"string"	=> {
+				C_TYPE		=> "const char *",
+				IS_REFERENCE	=> 1,
+				NDR_ALIGN	=> 4 #???
+			},
+	"string_array"	=> {
+				C_TYPE		=> "const char **",
+				IS_REFERENCE	=> 1,
+				NDR_ALIGN	=> 4 #???
+			},
+
+	# time types
+	"time_t"	=> {
+				C_TYPE		=> "time_t",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+	"NTTIME"	=> {
+				C_TYPE		=> "NTTIME",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+	"NTTIME_1sec"	=> {
+				C_TYPE		=> "NTTIME",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+	"NTTIME_hyper"	=> {
+				C_TYPE		=> "NTTIME",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 8
+			},
+
+
+	# error code types
+	"WERROR"	=> {
+				C_TYPE		=> "WERROR",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+	"NTSTATUS"	=> {
+				C_TYPE		=> "NTSTATUS",
+				IS_REFERENCE	=> 0,
+				NDR_ALIGN	=> 4
+			},
+
+	# special types
+	"nbt_string"	=> {
+				C_TYPE		=> "const char *",
+				IS_REFERENCE	=> 1,
+				NDR_ALIGN	=> 4 #???
+			},
+	"ipv4address"	=> {
+				C_TYPE		=> "const char *",
+				IS_REFERENCE	=> 1,
+				NDR_ALIGN	=> 4
+			}
+};
+
+# map from a IDL type to a C header type
+sub mapScalarType($)
+{
+	my $name = shift;
+
+	# it's a bug when a type is not in the list
+	# of known scalars or has no mapping
+	return $scalars->{$name}{C_TYPE} if defined($scalars->{$name}) and defined($scalars->{$name}{C_TYPE});
+
+	die("Unknown scalar type $name");
+}
+
+sub getScalarAlignment($)
+{
+	my $name = shift;
+
+	# it's a bug when a type is not in the list
+	# of known scalars or has no mapping
+	return $scalars->{$name}{NDR_ALIGN} if defined($scalars->{$name}) and defined($scalars->{$name}{NDR_ALIGN});
+
+	die("Unknown scalar type $name");
+}
+
 sub addType($)
 {
 	my $t = shift;
@@ -38,17 +198,30 @@ sub hasType($)
 	return 0;
 }
 
-sub RegisterPrimitives()
+sub is_scalar($)
 {
-	my @primitives = (
-		"char", "int8", "uint8", "short", "wchar_t", 
-		"int16", "uint16", "long", "int32", "uint32", 
-		"dlong", "udlong", "udlongr", "NTTIME", "NTTIME_1sec", 
-		"time_t", "DATA_BLOB", "error_status_t", "WERROR", 
-		"NTSTATUS", "boolean32", "unsigned32", "ipv4address", 
-		"hyper", "NTTIME_hyper");
-		
-	foreach my $k (@primitives) {
+	my $type = shift;
+
+	return 0 unless(hasType($type));
+
+	if (my $dt = getType($type)->{DATA}->{TYPE}) {
+		return 1 if ($dt eq "SCALAR" or $dt eq "ENUM" or $dt eq "BITMAP");
+	}
+
+	return 0;
+}
+
+sub scalar_is_reference($)
+{
+	my $name = shift;
+
+	return $scalars->{$name}{IS_REFERENCE} if defined($scalars->{$name}) and defined($scalars->{$name}{IS_REFERENCE});
+	return 0;
+}
+
+sub RegisterScalars()
+{
+	foreach my $k (keys %{$scalars}) {
 		$typedefs{$k} = {
 			NAME => $k,
 			TYPE => "TYPEDEF",
@@ -85,53 +258,12 @@ sub bitmap_type_fn($)
 	return "uint32";
 }
 
-# provide mappings between IDL base types and types in our headers
-my %scalar_type_mappings = 
-    (
-     "int8"         => "int8_t",
-     "uint8"        => "uint8_t",
-     "short"        => "int16_t",
-     "wchar_t"      => "uint16_t",
-     "int16"        => "int16_t",
-     "uint16"       => "uint16_t",
-     "int32"        => "int32_t",
-     "uint32"       => "uint32_t",
-     "int64"        => "int64_t",
-     "dlong"        => "int64_t",
-     "udlong"       => "uint64_t",
-     "udlongr"      => "uint64_t",
-     "hyper"        => "uint64_t",
-     "NTTIME"       => "NTTIME",
-     "NTTIME_1sec"  => "NTTIME",
-     "time_t"       => "time_t",
-     "NTTIME_hyper" => "NTTIME",
-     "NTSTATUS"     => "NTSTATUS",
-     "WERROR"       => "WERROR",
-     "DATA_BLOB"    => "DATA_BLOB",
-     "ipv4address"  => "const char *",
-     "nbt_string"   => "const char *"
-     );
-
-# map from a IDL type to a C header type
-sub mapScalarType($)
-{
-	my $name = shift;
-	die("Undef passed to mapScalarType") unless defined($name);
-	if (defined($scalar_type_mappings{$name})) {
-		return $scalar_type_mappings{$name};
-	}
-	die("Tried to map non-scalar type $name");
-}
-
 sub mapType($)
 {
 	my $t = shift;
 	die("Undef passed to mapType") unless defined($t);
 	my $dt;
 
-	return "void" if ($t eq "void");
-	return "const char *" if ($t =~ "string");
-
 	unless ($dt or ($dt = getType($t))) {
 		# Best guess
 		return "struct $t";
@@ -171,7 +303,6 @@ sub LoadIdl($)
 	}
 }
 
-RegisterPrimitives();
-
+RegisterScalars();
 
 1;
-- 
cgit