r9459: Move pidl up one level (to prevent too much nesting)
[sfrench/samba-autobuild/.git] / source / pidl / Parse / Pidl / Samba / NDR / Header.pm
1 ###################################################
2 # create C header files for an IDL structure
3 # Copyright tridge@samba.org 2000
4 # Copyright jelmer@samba.org 2005
5 # released under the GNU GPL
6
7 package Parse::Pidl::Samba::NDR::Header;
8
9 use strict;
10 use Parse::Pidl::Typelist qw(mapType);
11 use Parse::Pidl::Util qw(has_property is_constant);
12 use Parse::Pidl::NDR qw(GetNextLevel GetPrevLevel);
13 use Parse::Pidl::Samba::NDR::Parser;
14
15 my($res);
16 my($tab_depth);
17
18 sub pidl ($)
19 {
20         $res .= shift;
21 }
22
23 sub tabs()
24 {
25         my $res = "";
26         $res .="\t" foreach (1..$tab_depth);
27         return $res;
28 }
29
30 #####################################################################
31 # prototype a typedef
32 sub HeaderTypedefProto($)
33 {
34     my($d) = shift;
35
36         my $tf = Parse::Pidl::Samba::NDR::Parser::get_typefamily($d->{DATA}{TYPE});
37
38     if (has_property($d, "gensize")) {
39                 my $size_args = $tf->{SIZE_FN_ARGS}->($d);
40                 pidl "size_t ndr_size_$d->{NAME}($size_args);\n";
41     }
42
43     return unless has_property($d, "public");
44
45         unless (has_property($d, "nopush")) {
46                 pidl "NTSTATUS ndr_push_$d->{NAME}(struct ndr_push *ndr, int ndr_flags, " . $tf->{DECL}->($d, "push") . ");\n";
47         }
48         unless (has_property($d, "nopull")) {
49             pidl "NTSTATUS ndr_pull_$d->{NAME}(struct ndr_pull *ndr, int ndr_flags, " . $tf->{DECL}->($d, "pull") . ");\n";
50         }
51     unless (has_property($d, "noprint")) {
52             pidl "void ndr_print_$d->{NAME}(struct ndr_print *ndr, const char *name, " . $tf->{DECL}->($d, "print") . ");\n";
53     }
54 }
55
56 #####################################################################
57 # output prototypes for a IDL function
58 sub HeaderFnProto($$)
59 {
60         my ($interface,$fn) = @_;
61         my $name = $fn->{NAME};
62
63         pidl "void ndr_print_$name(struct ndr_print *ndr, const char *name, int flags, const struct $name *r);\n";
64
65         unless (has_property($fn, "noopnum")) {
66                 pidl "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
67                 pidl "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
68         }
69
70         return unless has_property($fn, "public");
71
72         pidl "NTSTATUS ndr_push_$name(struct ndr_push *ndr, int flags, const struct $name *r);\n";
73         pidl "NTSTATUS ndr_pull_$name(struct ndr_pull *ndr, int flags, struct $name *r);\n";
74
75         pidl "\n";
76 }
77
78 #####################################################################
79 # parse the interface definitions
80 sub HeaderInterface($)
81 {
82         my($interface) = shift;
83
84         if (defined $interface->{PROPERTIES}->{depends}) {
85                 my @d = split / /, $interface->{PROPERTIES}->{depends};
86                 foreach my $i (@d) {
87                         pidl "#include \"librpc/gen_ndr/ndr_$i\.h\"\n";
88                 }
89         }
90
91         my $count = 0;
92
93         pidl "#ifndef _HEADER_NDR_$interface->{NAME}\n";
94         pidl "#define _HEADER_NDR_$interface->{NAME}\n\n";
95
96         if (defined $interface->{PROPERTIES}->{uuid}) {
97                 my $name = uc $interface->{NAME};
98                 pidl "#define DCERPC_$name\_UUID " . 
99                 Parse::Pidl::Util::make_str($interface->{PROPERTIES}->{uuid}) . "\n";
100
101                 if(!defined $interface->{PROPERTIES}->{version}) { $interface->{PROPERTIES}->{version} = "0.0"; }
102                 pidl "#define DCERPC_$name\_VERSION $interface->{PROPERTIES}->{version}\n";
103
104                 pidl "#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n";
105
106                 if(!defined $interface->{PROPERTIES}->{helpstring}) { $interface->{PROPERTIES}->{helpstring} = "NULL"; }
107                 pidl "#define DCERPC_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}\n";
108
109                 pidl "\nextern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
110                 pidl "NTSTATUS dcerpc_server_$interface->{NAME}_init(void);\n\n";
111         }
112
113         foreach my $d (@{$interface->{DATA}}) {
114                 next if $d->{TYPE} ne "FUNCTION";
115                 next if has_property($d, "noopnum");
116                 next if grep(/$d->{NAME}/,@{$interface->{INHERITED_FUNCTIONS}});
117                 my $u_name = uc $d->{NAME};
118                 pidl "#define DCERPC_$u_name (";
119         
120                 if (defined($interface->{BASE})) {
121                         pidl "DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT + ";
122                 }
123
124                 pidl sprintf("0x%02x", $count) . ")\n";
125                 $count++;
126         }
127
128         pidl "\n#define DCERPC_" . uc $interface->{NAME} . "_CALL_COUNT (";
129         
130         if (defined($interface->{BASE})) {
131                 pidl "DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT + ";
132         }
133         
134         pidl "$count)\n\n";
135
136         foreach my $d (@{$interface->{DATA}}) {
137                 next if ($d->{TYPE} ne "TYPEDEF");
138                 HeaderTypedefProto($d);
139         }
140
141         foreach my $d (@{$interface->{DATA}}) {
142                 next if ($d->{TYPE} ne "FUNCTION");
143                 HeaderFnProto($interface, $d);
144         }
145
146         pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
147 }
148
149 #####################################################################
150 # parse a parsed IDL into a C header
151 sub Parse($$)
152 {
153     my($idl,$basename) = @_;
154     $tab_depth = 0;
155
156         $res = "";
157     pidl "/* header auto-generated by pidl */\n";
158         pidl "#include \"librpc/gen_ndr/$basename\.h\"\n\n";
159
160     foreach my $x (@{$idl}) {
161             ($x->{TYPE} eq "INTERFACE") && HeaderInterface($x);
162     }
163     return $res;
164 }
165
166 1;