r7161: - Add support for "aliases" for pidls scalar types and add a few aliases.
[samba.git] / source4 / build / pidl / idl.yp
index fb2433ee72550f48c8348fe35152c1fe8ab9c3eb..b556b064b42d495daf468cfd6b915daf340fd754 100644 (file)
 %%
 idl: 
        #empty  { {} }
-    | idl interface { push(@{$_[1]}, $_[2]); $_[1] }
+       | idl interface { push(@{$_[1]}, $_[2]); $_[1] }
        | idl coclass { push(@{$_[1]}, $_[2]); $_[1] }
 ;
 
-coclass: property_list 'coclass' identifier '{' interfaces '}' optional_semicolon
+coclass: property_list 'coclass' identifier '{' interface_names '}' optional_semicolon
           {$_[3] => {
                "TYPE" => "COCLASS", 
-                          "PROPERTIES" => $_[1],
-                      "NAME" => $_[3],
-                      "DATA" => $_[5],
+              "PROPERTIES" => $_[1],
+              "NAME" => $_[3],
+              "DATA" => $_[5],
+                  "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+                  "LINE" => $_[0]->YYData->{LINE},
           }}
 ;
 
-interfaces:
+interface_names:
        #empty { {} }
-       | interfaces interface { push(@{$_[1]}, $_[2]); $_[1] }
+       | interface_names 'interface' identifier ';' { push(@{$_[1]}, $_[2]); $_[1] }
 ;
 
 interface: property_list 'interface' identifier base_interface '{' definitions '}' optional_semicolon
           {$_[3] => {
                "TYPE" => "INTERFACE", 
-                          "PROPERTIES" => $_[1],
-                      "NAME" => $_[3],
-                          "BASE" => $_[4],
-                      "DATA" => $_[6],
+              "PROPERTIES" => $_[1],
+              "NAME" => $_[3],
+              "BASE" => $_[4],
+              "DATA" => $_[6],
+                  "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+                  "LINE" => $_[0]->YYData->{LINE},
           }}
 ;
 
@@ -55,7 +59,7 @@ definitions:
 ;    
 
 
-definition: function | const | typedef
+definition: function | const | typedef | declare
 ;
 
 const: 'const' identifier identifier '=' anytext ';' 
@@ -63,7 +67,9 @@ const: 'const' identifier identifier '=' anytext ';'
                      "TYPE"  => "CONST", 
                     "DTYPE"  => $_[2],
                     "NAME"  => $_[3],
-                    "VALUE" => $_[5]
+                    "VALUE" => $_[5],
+                    "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+                    "LINE" => $_[0]->YYData->{LINE},
         }}
        | 'const' identifier identifier array_len '=' anytext ';' 
         {{
@@ -72,6 +78,8 @@ const: 'const' identifier identifier '=' anytext ';'
                     "NAME"  => $_[3],
                     "ARRAY_LEN" => $_[4],
                     "VALUE" => $_[6],
+                    "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+                    "LINE" => $_[0]->YYData->{LINE},
         }}
 ;
 
@@ -82,27 +90,58 @@ function: property_list type identifier '(' element_list2 ')' ';'
                "NAME" => $_[3],
                "RETURN_TYPE" => $_[2],
                "PROPERTIES" => $_[1],
-               "DATA" => $_[5]
-        }}
+               "ELEMENTS" => $_[5],
+               "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+               "LINE" => $_[0]->YYData->{LINE},
+         }}
+;
+
+declare: 'declare' property_list decl_type identifier';' 
+        {{
+                    "TYPE" => "DECLARE", 
+                     "PROPERTIES" => $_[2],
+                    "NAME" => $_[4],
+                    "DATA" => $_[3],
+                    "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+                    "LINE" => $_[0]->YYData->{LINE},
+        }}
 ;
 
-typedef: 'typedef' type identifier array_len ';' 
+decl_type: decl_enum | decl_bitmap
+;
+
+decl_enum: 'enum' 
         {{
-                     "TYPE" => "TYPEDEF", 
-                    "NAME" => $_[3],
-                    "DATA" => $_[2],
-                    "ARRAY_LEN" => $_[4]
+                     "TYPE" => "ENUM"
         }}
 ;
 
-type:   struct | union | enum | identifier 
+decl_bitmap: 'bitmap' 
+        {{
+                     "TYPE" => "BITMAP"
+        }}
+;
+
+typedef: 'typedef' property_list type identifier array_len ';' 
+        {{
+                    "TYPE" => "TYPEDEF", 
+                     "PROPERTIES" => $_[2],
+                    "NAME" => $_[4],
+                    "DATA" => $_[3],
+                    "ARRAY_LEN" => $_[5],
+                    "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+                    "LINE" => $_[0]->YYData->{LINE},
+        }}
+;
+
+type:   struct | union | enum | bitmap | identifier 
        | void { "void" }
 ;
 
 
 enum: 'enum' '{' enum_elements '}' 
         {{
-                     "TYPE" => "ENUM", 
+             "TYPE" => "ENUM", 
                     "ELEMENTS" => $_[3]
         }}
 ;
@@ -116,50 +155,56 @@ enum_element: identifier
              | identifier '=' anytext { "$_[1]$_[2]$_[3]" }
 ;
 
-struct: property_list 'struct' '{' element_list1 '}' 
+bitmap: 'bitmap' '{' bitmap_elements '}' 
+        {{
+                     "TYPE" => "BITMAP", 
+                    "ELEMENTS" => $_[3]
+        }}
+;
+
+bitmap_elements: 
+      bitmap_element                    { [ $_[1] ] }            
+    | bitmap_elements ',' bitmap_element  { push(@{$_[1]}, $_[3]); $_[1] }
+;
+
+bitmap_element: identifier '=' anytext { "$_[1] ( $_[3] )" }
+;
+
+struct: 'struct' '{' element_list1 '}' 
         {{
                      "TYPE" => "STRUCT", 
-                    "PROPERTIES" => $_[1],
-                    "ELEMENTS" => $_[4]
+                    "ELEMENTS" => $_[3]
         }}
 ;
 
-union: property_list 'union' '{' union_elements '}' 
-        {{
-               "TYPE" => "UNION",
-               "PROPERTIES" => $_[1],
-               "DATA" => $_[4]
+empty_element: property_list ';'
+       {{
+                "NAME" => "",
+                "TYPE" => "EMPTY",
+                "PROPERTIES" => $_[1],
+                "POINTERS" => 0,
+                "ARRAY_LEN" => [],
+                "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+                "LINE" => $_[0]->YYData->{LINE},
         }}
 ;
 
+base_or_empty: base_element ';' | empty_element;
+
+optional_base_element:
+       property_list base_or_empty { $_[2]->{PROPERTIES} = util::FlattenHash([$_[1],$_[2]->{PROPERTIES}]); $_[2] }
+;
+
 union_elements: 
-      union_element                    { [ $_[1] ] }            
-    | union_elements union_element  { push(@{$_[1]}, $_[2]); $_[1] }
+    #empty
+    | union_elements optional_base_element { push(@{$_[1]}, $_[2]); $_[1] }
 ;
 
-union_element: 
-         '[' 'case' '(' anytext ')' ']' base_element ';'
-        {{
-               "TYPE" => "UNION_ELEMENT",
-               "CASE" => $_[4],
-               "DATA" => $_[7]
-        }}
-         | '[' 'case' '(' anytext ')' ']' ';'
-        {{
-               "TYPE" => "EMPTY",
-               "CASE" => $_[4],
-        }}
-         | '[' 'default' ']' base_element ';'
-        {{
-               "TYPE" => "UNION_ELEMENT",
-               "CASE" => "default",
-               "DATA" => $_[4]
-        }}
-         | '[' 'default' ']' ';'
-        {{
-               "TYPE" => "EMPTY",
-               "CASE" => "default",
-        }}
+union: 'union' '{' union_elements '}' 
+        {{
+                     "TYPE" => "UNION", 
+                    "ELEMENTS" => $_[3]
+        }}
 ;
 
 base_element: property_list type pointers identifier array_len
@@ -168,7 +213,9 @@ base_element: property_list type pointers identifier array_len
                           "TYPE" => $_[2],
                           "PROPERTIES" => $_[1],
                           "POINTERS" => $_[3],
-                          "ARRAY_LEN" => $_[5]
+                          "ARRAY_LEN" => $_[5],
+                      "FILE" => $_[0]->YYData->{INPUT_FILENAME},
+                      "LINE" => $_[0]->YYData->{LINE},
               }}
 ;
 
@@ -179,8 +226,6 @@ pointers:
     | pointers '*'  { $_[1]+1 }
 ;
 
-
-
 element_list1: 
     #empty
     | element_list1 base_element ';' { push(@{$_[1]}, $_[2]); $_[1] }
@@ -194,9 +239,9 @@ element_list2:
 ;
 
 array_len: 
-    #empty 
-    | '[' ']'            { "*" }
-    | '[' anytext ']'    { "$_[2]" }
+    #empty                        { [] }
+    | '[' ']' array_len           { push(@{$_[3]}, "*"); $_[3] }
+    | '[' anytext ']' array_len   { push(@{$_[4]}, "$_[2]"); $_[4] }
 ;
 
 
@@ -230,10 +275,12 @@ anytext:  #empty
     | anytext '.' anytext  { "$_[1]$_[2]$_[3]" }
     | anytext '*' anytext  { "$_[1]$_[2]$_[3]" }
     | anytext '>' anytext  { "$_[1]$_[2]$_[3]" }
+    | anytext '<' anytext  { "$_[1]$_[2]$_[3]" }
     | anytext '|' anytext  { "$_[1]$_[2]$_[3]" }
     | anytext '&' anytext  { "$_[1]$_[2]$_[3]" }
     | anytext '/' anytext  { "$_[1]$_[2]$_[3]" }
     | anytext '+' anytext  { "$_[1]$_[2]$_[3]" }
+    | anytext '~' anytext  { "$_[1]$_[2]$_[3]" }
     | anytext '(' commalisttext ')' anytext  { "$_[1]$_[2]$_[3]$_[4]$_[5]" }
     | anytext '{' commalisttext '}' anytext  { "$_[1]$_[2]$_[3]$_[4]$_[5]" }
 ;
@@ -257,10 +304,10 @@ optional_semicolon:
 # start code
 %%
 
-use util;
+use pidl::util;
 
 sub _Error {
-        if (exists $_[0]->YYData->{ERRMSG}) {
+    if (exists $_[0]->YYData->{ERRMSG}) {
                print $_[0]->YYData->{ERRMSG};
                delete $_[0]->YYData->{ERRMSG};
                return;
@@ -313,8 +360,8 @@ again:
                if (s/^([\w_]+)//) {
                        $parser->YYData->{LAST_TOKEN} = $1;
                        if ($1 =~ 
-                           /^(coclass|interface|const|typedef|union
-                             |struct|enum|void|case|default)$/x) {
+                           /^(coclass|interface|const|typedef|declare|union
+                             |struct|enum|bitmap|void)$/x) {
                                return $1;
                        }
                        return('IDENTIFIER',$1);
@@ -337,7 +384,7 @@ sub parse_idl($$)
        if (! defined $cpp) {
                $cpp = "cpp"
        }
-       my $data = `$cpp -xc $filename`;
+       my $data = `$cpp -D__PIDL__ -xc $filename`;
        $/ = $saved_delim;
 
     $self->YYData->{INPUT} = $data;
@@ -346,42 +393,5 @@ sub parse_idl($$)
 
        my $idl = $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error );
 
-       foreach my $x (@{$idl}) {
-               # Add [in] ORPCTHIS *this, [out] ORPCTHAT *that
-               # for 'object' interfaces
-               if (defined($x->{PROPERTIES}->{object})) {
-                       foreach my $e (@{$x->{DATA}}) {
-                               if($e->{TYPE} eq "FUNCTION") {
-                                       $e->{PROPERTIES}->{object} = 1;
-                                       unshift(@{$e->{DATA}}, 
-                        { 'NAME' => 'ORPCthis',
-                          'POINTERS' => 0,
-                          'PROPERTIES' => { 'in' => '1' },
-                          'TYPE' => 'ORPCTHIS'
-                        });
-                                       unshift(@{$e->{DATA}},
-                        { 'NAME' => 'ORPCthat',
-                          'POINTERS' => 0,
-                          'PROPERTIES' => { 'out' => '1' },
-                                                 'TYPE' => 'ORPCTHAT'
-                        });
-                               }
-                       }
-               }
-               
-               # Do the inheritance
-               if (defined($x->{BASE}) and $x->{BASE} ne "") {
-                       my $parent = util::get_interface($idl, $x->{BASE});
-
-                       if(not defined($parent)) { 
-                               die("No such parent interface " . $x->{BASE});
-                       }
-                       
-                       @{$x->{INHERITED_DATA}} = (@{$parent->{INHERITED_DATA}}, @{$x->{DATA}});
-               } else {
-                       $x->{INHERITED_DATA} = $x->{DATA};
-               }
-       }
-
-       return $idl;
+       return util::CleanData($idl);
 }