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