Release 980809
[wine] / tools / make_requests
1 #! /usr/bin/perl
2 #
3 # Build the server/trace.c and include/server/request.h files
4 # from the contents of include/server.h.
5 #
6 # Copyright (C) 1998 Alexandre Julliard
7 #
8
9 %formats =
10 (
11     "int"          => "%d",
12     "unsigned int" => "%08x",
13     "void*"        => "%p"
14 );
15
16 my @requests = ();
17 my %replies = ();
18
19 open(SERVER,"include/server.h") or die "Can't open include/server.h";
20 open(TRACE,">server/trace.c") or die "Can't create server/trace.c";
21 open(REQUESTS,">include/server/request.h") or die "Can't create include/server/request.h";
22
23 ### Generate the header
24
25 print TRACE <<EOF;
26 /* File generated automatically by $0; DO NOT EDIT!! */
27
28 #include <stdio.h>
29 #include <sys/uio.h>
30 #include "server.h"
31 #include "server/thread.h"
32 EOF
33
34 ### Parse server.h to find request/reply structure definitions
35
36 while (<SERVER>)
37 {
38     if (/^struct +(\w+)_request/) { &DO_REQUEST($1); }
39     if (/^struct +(\w+)_reply/)   { &DO_REPLY($1); }
40 }
41
42 ### Output the dumping function tables
43
44 print TRACE<<EOF;
45
46 struct dumper
47 {
48     void (*dump_req)();
49     void (*dump_reply)();
50     unsigned int size;
51 };
52
53 static const struct dumper dumpers[REQ_NB_REQUESTS] =
54 {
55 EOF
56
57 foreach $req (@requests)
58 {
59     $request = $req . "_request";
60     $reply = $replies{$req} ? "dump_${req}_reply" : "0";
61     print TRACE "    { (void(*)())dump_$request,\n";
62     print TRACE "      (void(*)())$reply,\n";
63     print TRACE "      sizeof(struct $request) },\n";
64 }
65
66 print TRACE <<EOF;
67 };
68
69 static const char * const req_names[REQ_NB_REQUESTS] =
70 {
71 EOF
72 foreach $req (@requests)
73 {
74     print TRACE "    \"$req\",\n";
75 }
76
77 ### Output the tracing functions
78
79 print TRACE <<EOF;
80 };
81
82 void trace_request( enum request req, void *data, int len, int fd )
83 {
84     current->last_req = req;
85     printf( "%08x: %s(", (unsigned int)current, req_names[req] );
86     dumpers[req].dump_req( data );
87     if (len > dumpers[req].size)
88     {
89         unsigned char *ptr = (unsigned char *)data + dumpers[req].size;
90         len -= dumpers[req].size;
91         while (len--) printf( ", %02x", *ptr++ );
92     }
93     if (fd != -1) printf( " ) fd=%d\\n", fd );
94     else printf( " )\\n" );
95 }
96
97 void trace_timeout(void)
98 {
99     printf( "%08x: *timeout*\\n", (unsigned int)current );
100 }
101
102 void trace_kill( int exit_code )
103 {
104     printf( "%08x: *killed* exit_code=%d\\n",
105             (unsigned int)current, exit_code );
106 }
107
108 void trace_reply( struct thread *thread, int type, int pass_fd,
109                   struct iovec *vec, int veclen )
110 {
111     if (!thread) return;
112     printf( "%08x: %s() = %d",
113             (unsigned int)thread, req_names[thread->last_req], type );
114     if (veclen)
115     {
116         printf( " {" );
117         if (dumpers[thread->last_req].dump_reply)
118         {
119             dumpers[thread->last_req].dump_reply( vec->iov_base );
120             vec++;
121             veclen--;
122         }
123         for (; veclen; veclen--, vec++)
124         {
125             unsigned char *ptr = vec->iov_base;
126             int len = vec->iov_len;
127             while (len--) printf( ", %02x", *ptr++ );
128         }
129         printf( " }" );
130     }
131     if (pass_fd != -1) printf( " fd=%d\\n", pass_fd );
132     else printf( "\\n" );
133 }
134 EOF
135
136 ### Output the requests list
137
138 print REQUESTS <<EOF;
139 /* File generated automatically by $0; DO NOT EDIT!! */
140
141 #ifndef __WINE_SERVER_REQUEST_H
142 #define __WINE_SERVER_REQUEST_H
143
144 enum request
145 {
146 EOF
147
148 foreach $req (@requests)
149 {
150     print REQUESTS "    REQ_\U$req,\n";
151 }
152
153 print REQUESTS <<EOF;
154     REQ_NB_REQUESTS
155 };
156
157 #ifdef WANT_REQUEST_HANDLERS
158
159 #define DECL_HANDLER(name) \\
160     static void req_##name( struct name##_request *req, void *data, int len, int fd )
161
162 EOF
163
164 foreach $req (@requests) { print REQUESTS "DECL_HANDLER($req);\n"; }
165
166 print REQUESTS <<EOF;
167
168 static const struct handler {
169     void       (*handler)();
170     unsigned int min_size;
171 } req_handlers[REQ_NB_REQUESTS] = {
172 EOF
173
174 foreach $req (@requests)
175 {
176     print REQUESTS "    { (void(*)())req_$req, sizeof(struct ${req}_request) },\n";
177 }
178
179 print REQUESTS <<EOF;
180 };
181 #endif  /* WANT_REQUEST_HANDLERS */
182
183 #endif  /* __WINE_SERVER_REQUEST_H */
184 EOF
185
186 ### Handle a request structure definition
187
188 sub DO_REQUEST
189 {
190     my $name = shift;
191     my @struct = ();
192     while (<SERVER>)
193     {
194         last if /^};$/;
195         next if /^{$/;
196         s!/\*.*\*/!!g;
197         / *(\w+\**( +\w+\**)*) +(\w+);/ or die "Unrecognized syntax $_";
198         my $type = $1;
199         my $var = $3;
200         die "Unrecognized type $type" unless defined($formats{$type});
201         push @struct, $type, $var;
202     }
203     push @requests, $name;
204     &DO_DUMP_FUNC( $name . "_request",@struct);
205 }
206
207 ### Handle a reply structure definition
208
209 sub DO_REPLY
210 {
211     my $name = shift;
212     my @struct = ();
213     while (<SERVER>)
214     {
215         last if /^};$/;
216         next if /^{$/;
217         s!/\*.*\*/!!g;
218         / *(\w+\**( +\w+\**)*) +(\w+);/ or die "Unrecognized syntax $_";
219         my $type = $1;
220         my $var = $3;
221         die "Unrecognized type $type" unless defined($formats{$type});
222         push @struct, $type, $var;
223     }
224     $replies{$name} = 1;
225     &DO_DUMP_FUNC( $name . "_reply" ,@struct);
226 }
227
228 ### Generate a dumping function
229
230 sub DO_DUMP_FUNC
231 {
232     my $name = shift;
233     print TRACE "\nstatic void dump_$name( struct $name *req )\n{\n";
234     while ($#_ >= 0)
235     {
236         my $type = shift;
237         my $var = shift;
238         print TRACE "    printf( \" $var=$formats{$type}";
239         print TRACE "," if ($#_ > 0);
240         print TRACE "\", req->$var );\n";
241         $size .= "+sizeof($type)";
242     }
243     print TRACE "}\n";
244 }