Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-python
[ira/wip.git] / source / pidl / lib / Parse / Pidl / Samba4 / Header.pm
index 76034109b733120913dcfcb9f33acba14c239392..2b3a9df80f3b128a4701143a67c3c631aa290022 100644 (file)
@@ -6,10 +6,16 @@
 
 package Parse::Pidl::Samba4::Header;
 
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
+
 use strict;
+use Parse::Pidl qw(fatal);
 use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
-use Parse::Pidl::Util qw(has_property is_constant);
-use Parse::Pidl::Samba4 qw(is_intree);
+use Parse::Pidl::Util qw(has_property is_constant unmake_str ParseExpr);
+use Parse::Pidl::Samba4 qw(is_intree ElementStars ArrayBrackets choose_header);
 
 use vars qw($VERSION);
 $VERSION = '0.01';
@@ -62,25 +68,10 @@ sub HeaderElement($)
                } else {
                        HeaderType($element, $element->{TYPE}, "");
                }
-               pidl " ";
-               my $numstar = $element->{POINTERS};
-               if ($numstar >= 1) {
-                       $numstar-- if (scalar_is_reference($element->{TYPE}));
-               }
-               foreach (@{$element->{ARRAY_LEN}})
-               {
-                       next if is_constant($_) and 
-                               not has_property($element, "charset");
-                       $numstar++;
-               }
-               pidl "*" foreach (1..$numstar);
+               pidl " ".ElementStars($element);
        }
        pidl $element->{NAME};
-       foreach (@{$element->{ARRAY_LEN}}) {
-               next unless (is_constant($_) and 
-                       not has_property($element, "charset"));
-               pidl "[$_]";
-       }
+       pidl ArrayBrackets($element);
 
        pidl ";";
        if (defined $element->{PROPERTIES}) {
@@ -121,43 +112,49 @@ sub HeaderEnum($$)
        my($enum,$name) = @_;
        my $first = 1;
 
-       pidl "#ifndef USE_UINT_ENUMS\n";
-       pidl "enum $name {\n";
-       $tab_depth++;
-       foreach my $e (@{$enum->{ELEMENTS}}) {
-               unless ($first) { pidl ",\n"; }
-               $first = 0;
-               pidl tabs();
-               pidl $e;
-       }
-       pidl "\n";
-       $tab_depth--;
-       pidl "}\n";
-       pidl "#else\n";
-       my $count = 0;
-       pidl "enum $name { __donnot_use_enum_$name=0x7FFFFFFF}\n";
-       my $with_val = 0;
-       my $without_val = 0;
-       foreach my $e (@{$enum->{ELEMENTS}}) {
-               my $t = "$e";
-               my $name;
-               my $value;
-               if ($t =~ /(.*)=(.*)/) {
-                       $name = $1;
-                       $value = $2;
-                       $with_val = 1;
-                       die ("you can't mix enum member with values and without values when using --uint-enums!")
-                               unless ($without_val == 0);
-               } else {
-                       $name = $t;
-                       $value = $count++;
-                       $without_val = 1;
-                       die ("you can't mix enum member with values and without values when using --uint-enums!")
-                               unless ($with_val == 0);
+       pidl "enum $name";
+       if (defined($enum->{ELEMENTS})) {
+               pidl "\n#ifndef USE_UINT_ENUMS\n";
+               pidl " {\n";
+               $tab_depth++;
+               foreach my $e (@{$enum->{ELEMENTS}}) {
+                       unless ($first) { pidl ",\n"; }
+                       $first = 0;
+                       pidl tabs();
+                       pidl $e;
                }
-               pidl "#define $name ( $value )\n";
+               pidl "\n";
+               $tab_depth--;
+               pidl "}";
+               pidl "\n";
+               pidl "#else\n";
+               my $count = 0;
+               my $with_val = 0;
+               my $without_val = 0;
+               if (defined($enum->{ELEMENTS})) {
+                       pidl " { __donnot_use_enum_$name=0x7FFFFFFF}\n";
+                       foreach my $e (@{$enum->{ELEMENTS}}) {
+                               my $t = "$e";
+                               my $name;
+                               my $value;
+                               if ($t =~ /(.*)=(.*)/) {
+                                       $name = $1;
+                                       $value = $2;
+                                       $with_val = 1;
+                                       fatal($e->{ORIGINAL}, "you can't mix enum member with values and without values!")
+                                               unless ($without_val == 0);
+                               } else {
+                                       $name = $t;
+                                       $value = $count++;
+                                       $without_val = 1;
+                                       fatal($e->{ORIGINAL}, "you can't mix enum member with values and without values!")
+                                               unless ($with_val == 0);
+                               }
+                               pidl "#define $name ( $value )\n";
+                       }
+               }
+               pidl "#endif\n";
        }
-       pidl "#endif\n";
 }
 
 #####################################################################
@@ -166,6 +163,8 @@ sub HeaderBitmap($$)
 {
        my($bitmap,$name) = @_;
 
+       return unless defined($bitmap->{ELEMENTS});
+
        pidl "/* bitmap $name */\n";
        pidl "#define $_\n" foreach (@{$bitmap->{ELEMENTS}});
        pidl "\n";
@@ -223,7 +222,7 @@ sub HeaderType($$$)
 sub HeaderTypedef($)
 {
        my($typedef) = shift;
-       HeaderType($typedef, $typedef->{DATA}->{ORIGINAL}, $typedef->{NAME});
+       HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME}) if defined ($typedef->{DATA});
 }
 
 #####################################################################
@@ -257,7 +256,7 @@ sub HeaderFunctionInOut($$)
        return unless defined($fn->{ELEMENTS});
 
        foreach my $e (@{$fn->{ELEMENTS}}) {
-               HeaderElement($e->{ORIGINAL}) if (ElementDirection($e) eq $prop);
+               HeaderElement($e) if (ElementDirection($e) eq $prop);
        }
 }
 
@@ -334,7 +333,7 @@ sub HeaderImport
        foreach (@imports) {
                s/\.idl\"$//;
                s/^\"//;
-               pidl "#include \"librpc/gen_ndr/$_\.h\"\n";
+               pidl choose_header("librpc/gen_ndr/$_\.h", "gen_ndr/$_.h") . "\n";
        }
 }
 
@@ -355,21 +354,21 @@ sub HeaderInterface($)
        pidl "#ifndef _HEADER_$interface->{NAME}\n";
        pidl "#define _HEADER_$interface->{NAME}\n\n";
 
-       foreach my $d (@{$interface->{CONSTS}}) {
-               HeaderConst($d);
+       foreach my $c (@{$interface->{CONSTS}}) {
+               HeaderConst($c);
        }
 
-       foreach my $d (@{$interface->{TYPES}}) {
-               HeaderTypedef($d) if ($d->{TYPE} eq "TYPEDEF");
-               HeaderStruct($d->{ORIGINAL}, $d->{NAME}) if ($d->{TYPE} eq "STRUCT");
-               HeaderUnion($d->{ORIGINAL}, $d->{NAME}) if ($d->{TYPE} eq "UNION");
-               HeaderEnum($d->{ORIGINAL}, $d->{NAME}) if ($d->{TYPE} eq "ENUM");
-               HeaderBitmap($d->{ORIGINAL}, $d->{NAME}) if ($d->{TYPE} eq "BITMAP");
-               pidl ";\n\n" if ($d->{TYPE} eq "BITMAP" or 
-                                $d->{TYPE} eq "STRUCT" or 
-                                $d->{TYPE} eq "TYPEDEF" or 
-                                $d->{TYPE} eq "UNION" or 
-                                $d->{TYPE} eq "ENUM");
+       foreach my $t (@{$interface->{TYPES}}) {
+               HeaderTypedef($t) if ($t->{TYPE} eq "TYPEDEF");
+               HeaderStruct($t, $t->{NAME}) if ($t->{TYPE} eq "STRUCT");
+               HeaderUnion($t, $t->{NAME}) if ($t->{TYPE} eq "UNION");
+               HeaderEnum($t, $t->{NAME}) if ($t->{TYPE} eq "ENUM");
+               HeaderBitmap($t, $t->{NAME}) if ($t->{TYPE} eq "BITMAP");
+               pidl ";\n\n" if ($t->{TYPE} eq "BITMAP" or 
+                                $t->{TYPE} eq "STRUCT" or 
+                                $t->{TYPE} eq "TYPEDEF" or 
+                                $t->{TYPE} eq "UNION" or 
+                                $t->{TYPE} eq "ENUM");
        }
 
        foreach my $fn (@{$interface->{FUNCTIONS}}) {
@@ -379,6 +378,13 @@ sub HeaderInterface($)
        pidl "#endif /* _HEADER_$interface->{NAME} */\n";
 }
 
+sub HeaderQuote($)
+{
+       my($quote) = shift;
+
+       pidl unmake_str($quote->{DATA}) . "\n";
+}
+
 #####################################################################
 # parse a parsed IDL into a C header
 sub Parse($)
@@ -390,12 +396,13 @@ sub Parse($)
        %headerstructs = ();
        pidl "/* header auto-generated by pidl */\n\n";
        if (!is_intree()) {
-               pidl "#include <core.h>\n";
+               pidl "#include <util/data_blob.h>\n";
        }
        pidl "#include <stdint.h>\n";
        pidl "\n";
 
        foreach (@{$ndr}) {
+               ($_->{TYPE} eq "CPP_QUOTE") && HeaderQuote($_);
                ($_->{TYPE} eq "INTERFACE") && HeaderInterface($_);
                ($_->{TYPE} eq "IMPORT") && HeaderImport(@{$_->{PATHS}});
                ($_->{TYPE} eq "INCLUDE") && HeaderInclude(@{$_->{PATHS}});
@@ -404,4 +411,66 @@ sub Parse($)
        return $res;
 }
 
+sub GenerateStructEnv($$)
+{
+       my ($x, $v) = @_;
+       my %env;
+
+       foreach my $e (@{$x->{ELEMENTS}}) {
+               $env{$e->{NAME}} = "$v->$e->{NAME}";
+       }
+
+       $env{"this"} = $v;
+
+       return \%env;
+}
+
+sub EnvSubstituteValue($$)
+{
+       my ($env,$s) = @_;
+
+       # Substitute the value() values in the env
+       foreach my $e (@{$s->{ELEMENTS}}) {
+               next unless (defined(my $v = has_property($e, "value")));
+               
+               $env->{$e->{NAME}} = ParseExpr($v, $env, $e);
+       }
+
+       return $env;
+}
+
+sub GenerateFunctionInEnv($;$)
+{
+       my ($fn, $base) = @_;
+       my %env;
+
+       $base = "r->" unless defined($base);
+
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               if (grep (/in/, @{$e->{DIRECTION}})) {
+                       $env{$e->{NAME}} = $base."in.$e->{NAME}";
+               }
+       }
+
+       return \%env;
+}
+
+sub GenerateFunctionOutEnv($;$)
+{
+       my ($fn, $base) = @_;
+       my %env;
+
+       $base = "r->" unless defined($base);
+
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               if (grep (/out/, @{$e->{DIRECTION}})) {
+                       $env{$e->{NAME}} = $base."out.$e->{NAME}";
+               } elsif (grep (/in/, @{$e->{DIRECTION}})) {
+                       $env{$e->{NAME}} = $base."in.$e->{NAME}";
+               }
+       }
+
+       return \%env;
+}
+
 1;