Made all 16<->32 HWND conversions use explicit functions instead of
[wine/dcerpc.git] / tools / make_requests
blobb882effd2bf00c1dc300d7991f6d84fa12b47633
1 #! /usr/bin/perl -w
3 # Build the server/trace.c and server/request.h files
4 # from the contents of include/wine/server.h.
6 # Copyright (C) 1998 Alexandre Julliard
9 %formats =
11 "int" => "%d",
12 "char" => "%c",
13 "unsigned char" => "%02x",
14 "unsigned short"=> "%04x",
15 "unsigned int" => "%08x",
16 "void*" => "%p",
17 "time_t" => "%ld",
18 "handle_t" => "%d",
19 "user_handle_t" => "%08x",
22 my @requests = ();
23 my %replies = ();
25 my @trace_lines = ();
27 # Get the server protocol version
28 my $protocol = &GET_PROTOCOL_VERSION;
30 ### Create server_protocol.h and print header
32 open SERVER_PROT, ">include/wine/server_protocol.h" or die "Cannot create include/wine/server_protocol.h";
33 print SERVER_PROT "/*\n * Wine server protocol definitions\n *\n";
34 print SERVER_PROT " * This file is automatically generated; DO NO EDIT!\n";
35 print SERVER_PROT " * Edit server/protocol.def instead and re-run tools/make_requests\n";
36 print SERVER_PROT " */\n\n";
37 print SERVER_PROT "#ifndef __WINE_WINE_SERVER_PROTOCOL_H\n";
38 print SERVER_PROT "#define __WINE_WINE_SERVER_PROTOCOL_H\n";
40 ### Parse requests to find request/reply structure definitions
42 &PARSE_REQUESTS;
44 ### Build the request list
46 print SERVER_PROT "\n\nenum request\n{\n";
47 foreach $req (@requests) { print SERVER_PROT " REQ_$req,\n"; }
48 print SERVER_PROT " REQ_NB_REQUESTS\n};\n\n";
49 print SERVER_PROT "union generic_request\n{\n";
50 print SERVER_PROT " struct request_max_size max_size;\n";
51 print SERVER_PROT " struct request_header header;\n";
52 foreach $req (@requests) { print SERVER_PROT " struct ${req}_request $req;\n"; }
53 print SERVER_PROT "};\n\n";
54 printf SERVER_PROT "#define SERVER_PROTOCOL_VERSION %d\n\n", $protocol + 1;
55 print SERVER_PROT "#endif /* __WINE_WINE_SERVER_PROTOCOL_H */\n";
56 close SERVER_PROT;
58 ### Output the dumping function tables
60 push @trace_lines, "static const dump_func req_dumpers[REQ_NB_REQUESTS] = {\n";
61 foreach $req (@requests)
63 push @trace_lines, " (dump_func)dump_${req}_request,\n";
65 push @trace_lines, "};\n\n";
67 push @trace_lines, "static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {\n";
68 foreach $req (@requests)
70 push @trace_lines, " (dump_func)", $replies{$req} ? "dump_${req}_reply,\n" : "0,\n";
72 push @trace_lines, "};\n\n";
74 push @trace_lines, "static const char * const req_names[REQ_NB_REQUESTS] = {\n";
75 foreach $req (@requests)
77 push @trace_lines, " \"$req\",\n";
79 push @trace_lines, "};\n";
81 REPLACE_IN_FILE( "server/trace.c", @trace_lines );
83 ### Output the request handlers list
85 my @request_lines = ();
87 foreach $req (@requests) { push @request_lines, "DECL_HANDLER($req);\n"; }
88 push @request_lines, "\n#ifdef WANT_REQUEST_HANDLERS\n\n";
89 push @request_lines, "typedef void (*req_handler)( void *req );\n";
90 push @request_lines, "static const req_handler req_handlers[REQ_NB_REQUESTS] =\n{\n";
91 foreach $req (@requests)
93 push @request_lines, " (req_handler)req_$req,\n";
95 push @request_lines, "};\n#endif /* WANT_REQUEST_HANDLERS */\n";
97 REPLACE_IN_FILE( "server/request.h", @request_lines );
99 ### Parse the request definitions
101 sub PARSE_REQUESTS
103 # states: 0 = header 1 = declarations 2 = inside @REQ 3 = inside @REPLY
104 my $state = 0;
105 my $name = "";
106 my @in_struct = ();
107 my @out_struct = ();
109 open(PROTOCOL,"server/protocol.def") or die "Can't open server/protocol.def";
111 while (<PROTOCOL>)
113 my ($type, $var);
114 # strip comments
115 s!/\*.*\*/!!g;
116 # strip white space at end of line
117 s/\s+$//;
119 if (/^\@HEADER/)
121 die "Misplaced \@HEADER" unless $state == 0;
122 $state++;
123 next;
126 # ignore everything while in state 0
127 next if $state == 0;
129 if (/^\@REQ\(\s*(\w+)\s*\)/)
131 $name = $1;
132 die "Misplaced \@REQ" unless $state == 1;
133 # start a new request
134 @in_struct = ();
135 @out_struct = ();
136 print SERVER_PROT "struct ${name}_request\n{\n";
137 print SERVER_PROT " struct request_header __header;\n";
138 $state++;
139 next;
142 if (/^\@REPLY/)
144 die "Misplaced \@REPLY" unless $state == 2;
145 $state++;
146 next;
149 if (/^\@END/)
151 die "Misplaced \@END" unless ($state == 2 || $state == 3);
152 print SERVER_PROT "};\n";
154 # got a complete request
155 push @requests, $name;
156 &DO_DUMP_FUNC( $name, "request", @in_struct);
157 if ($#out_struct >= 0)
159 $replies{$name} = 1;
160 &DO_DUMP_FUNC( $name, "reply", @out_struct);
162 $state = 1;
163 next;
166 if ($state != 1)
168 # skip empty lines (but keep them in output file)
169 if (/^$/)
171 print SERVER_PROT "\n";
172 next;
175 if (/^\s*VARARG\((\w+),(\w+)\)/)
177 $var = $1;
178 $type = "&dump_varargs_" . $2;
179 s!(VARARG\(.*\)\s*;)!/* $1 */!;
181 elsif (/^\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/)
183 $type = $1 . ($4 || "");
184 $var = $3;
185 die "Unrecognized type $type" unless (defined($formats{$type}) || $4);
187 else
189 die "Unrecognized syntax $_";
191 if ($state == 2) { push @in_struct, $type, $var; }
192 if ($state == 3) { push @out_struct, $type, $var; }
195 # Pass it through into the output file
196 print SERVER_PROT $_ . "\n";
198 close PROTOCOL;
201 ### Generate a dumping function
203 sub DO_DUMP_FUNC
205 my $name = shift;
206 my $req = shift;
207 push @trace_lines, "static void dump_${name}_$req( const struct ${name}_request *req )\n{\n";
208 while ($#_ >= 0)
210 my $type = shift;
211 my $var = shift;
212 if (defined($formats{$type}))
214 if ($formats{$type} =~ /^&(.*)/)
216 my $func = $1;
217 push @trace_lines, " fprintf( stderr, \" $var=\" );\n";
218 if ($type =~ /[1]/) { push @trace_lines, " $func( req, req->$var );\n"; }
219 else { push @trace_lines, " $func( req, &req->$var );\n"; }
220 push @trace_lines, " fprintf( stderr, \",\" );\n" if ($#_ > 0);
222 else
224 push @trace_lines, " fprintf( stderr, \" $var=$formats{$type}";
225 push @trace_lines, "," if ($#_ > 0);
226 push @trace_lines, "\", ";
227 push @trace_lines, "req->$var );\n";
230 else # must be some varargs format
232 if ($type =~ /^&(.*)/)
234 my $func = $1;
235 push @trace_lines, " fprintf( stderr, \" $var=\" );\n";
236 push @trace_lines, " cur_pos += $func( req );\n";
237 push @trace_lines, " fputc( ',', stderr );\n" if ($#_ > 0);
239 else
241 push @trace_lines, " fprintf( stderr, \" $var=\" );\n";
242 push @trace_lines, " dump_varargs_${name}_${req}( req );\n";
246 push @trace_lines, "}\n\n";
249 ### Retrieve the server protocol version from the existing server_protocol.h file
251 sub GET_PROTOCOL_VERSION
253 my $protocol = 0;
254 open SERVER_PROT, "include/wine/server_protocol.h" or return 0;
255 while (<SERVER_PROT>)
257 if (/^\#define SERVER_PROTOCOL_VERSION (\d+)/) { $protocol = $1; last; }
259 close SERVER_PROT;
260 return $protocol;
263 ### Replace the contents of a file between ### make_requests ### marks
265 sub REPLACE_IN_FILE
267 my $name = shift;
268 my @data = @_;
269 my @lines = ();
270 open(FILE,$name) or die "Can't open $name";
271 while (<FILE>)
273 push @lines, $_;
274 last if /\#\#\# make_requests begin \#\#\#/;
276 push @lines, "\n", @data;
277 while (<FILE>)
279 if (/\#\#\# make_requests end \#\#\#/) { push @lines, "\n", $_; last; }
281 push @lines, <FILE>;
282 open(FILE,">$name") or die "Can't modify $name";
283 print FILE @lines;
284 close(FILE);