From 89a17e60a14783e8560d3babc8a9a328adc3c94c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher 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') diff --git a/source4/build/pidl/com_header.pm b/source4/build/pidl/com_header.pm index 1e178eed85..3300d84092 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 43ed8b841a..a285dacf23 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 98e3d2b4bc..aa1a557dd1 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 576361260f..dfc20389ea 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 be663269f8..a73675159b 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 f5a0650006..a8600cedbe 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