- Minor API files update.
[wine] / tools / make_X11wrappers
1 #!/usr/bin/perl -w
2
3 # Create threads safe wrappers around X11 calls.
4 #
5 # Copyright 1998 Kristian Nielsen.
6 #
7
8 # FIXME: This does not do full C prototype parsing, but relies on
9 # knowledge on how the X11 include files are formatted. It will
10 # probably need to be modified for new include files. It also fails
11 # for certain prototypes (notably those with function pointer
12 # arguments or results), so these must be added manually. And it
13 # relies on a fixed location of X11 includes (/usr/X11R6/include/).
14 #
15 # This program expects to be run from Wine's main directory.
16
17 $X11_include_dir = "/usr/X11/include";
18 $outdir = "tsx11";
19 $wantfile = "$outdir/X11_calls";
20 @dolist = ("Xlib", "Xresource", "Xutil", "xpm", "XShm", "xf86dga", "xf86dga2", "xf86vmode", "shape", "xvideo");
21
22 # First read list of wanted function names.
23
24 open(WANT, $wantfile) || die "open";
25 while(<WANT>) {
26     next if /^\s*\#/;           # Skip comment lines.
27     next if /^\s*$/;            # Skip empty lines.
28     if(/^\s*([a-zA-Z0-9_]+)\s*$/) {
29         $want{$1} = 1;
30     } else {
31         die "syntax error in file '$wantfile', in line '$_'";
32     }
33 }
34 close(WANT);
35
36 foreach $name (@dolist) {
37
38     $ucname = uc $name;
39     $lcname = lc $name;
40
41     $outfile = "/ts_$lcname";
42     open(OUTC, ">$outdir/$outfile.c") || die "open";
43     open(OUTH, ">include/$outfile.h") || die "open";
44
45     $x11_incl = "";
46     $extensions_dir = "";
47     $pre_file = "";
48     $post_file = "";
49     $inc_name = $name;
50     if($name eq "Xutil" || $name eq "Xresource" || $name eq "XShm") {
51         $x11_incl = "#include <X11/Xlib.h>\n";
52         # For Xutil, we need X11/Xresource.h for XUniqueContext().
53         $x11_incl .= "#include <X11/Xresource.h>\n" if $name eq "Xutil";
54     }
55     if($name eq "xf86dga")  {
56         $x11_incl = "#include <X11/Xlib.h>\n";
57         $extensions_dir = "extensions/";
58         $pre_file = "#ifdef HAVE_LIBXXF86DGA\n";
59         $post_file = "#endif /* defined(HAVE_LIBXXF86DGA) */\n";
60     }
61     if($name eq "xf86dga2")  {
62         $x11_incl = "#include <X11/Xlib.h>\n";
63         $extensions_dir = "extensions/";
64         $pre_file = "#ifdef HAVE_LIBXXF86DGA2\n";
65         $post_file = "#endif /* defined(HAVE_LIBXXF86DGA2) */\n";
66         $inc_name = "xf86dga";
67     }
68     if($name eq "XShm") {
69         $extensions_dir = "extensions/";
70         $pre_file = "#ifdef HAVE_LIBXXSHM\n";
71         $post_file = "#endif /* defined(HAVE_LIBXXSHM) */\n";
72     }
73     if($name eq "xpm") {
74         $pre_file = "#ifdef HAVE_LIBXXPM\n";
75         $post_file = "#endif /* defined(HAVE_LIBXXPM) */\n";
76     }
77     if($name eq "xf86vmode") {
78         $x11_incl = "#include <X11/Xlib.h>\n";
79         $extensions_dir = "extensions/";
80         $pre_file = "#include \"windef.h\"\n#ifdef HAVE_LIBXXF86VM\n#define XMD_H\n#include \"basetsd.h\"\n";
81         $post_file = "#endif /* defined(HAVE_LIBXXF86VM) */\n";
82     }
83     if($name eq "shape") {
84         $extensions_dir = "extensions/";
85         $pre_file = "#ifdef HAVE_LIBXSHAPE\n#include <X11/IntrinsicP.h>\n";
86         $post_file = "#endif /* defined(HAVE_LIBXSHAPE) */\n";
87         $inc_name = "shape";
88     }
89     if($name eq "xvideo")  {
90         $x11_incl = "#include <X11/Xlib.h>\n#include <X11/extensions/Xv.h>\n#include <X11/extensions/XShm.h>\n";
91         $extensions_dir = "extensions/";
92         $pre_file = "#ifdef HAVE_XVIDEO\n";
93         $post_file = "#endif /* defined(HAVE_XVIDEO) */\n";
94         $inc_name = "Xvlib";
95     }
96
97
98     print OUTH <<END;
99 /*
100  * Thread safe wrappers around $name calls.
101  * Always include this file instead of <X11/$name.h>.
102  * This file was generated automatically by tools/make_X11wrappers
103  *
104  * Copyright 1998 Kristian Nielsen
105  */
106
107 #ifndef __WINE_TS_$ucname\_H
108 #define __WINE_TS_$ucname\_H
109
110 #include "config.h"
111
112 $pre_file
113 $x11_incl#include <X11/$extensions_dir$inc_name.h>
114
115 extern void (*wine_tsx11_lock)(void);
116 extern void (*wine_tsx11_unlock)(void);
117
118 END
119
120     print OUTC <<END;
121 /*
122  * Thread safe wrappers around $name calls.
123  * This file was generated automatically by tools/make_X11wrappers
124  * DO NOT EDIT!
125  */
126
127 #include "config.h"
128
129 $pre_file
130 $x11_incl#include <X11/$extensions_dir$inc_name.h>
131
132 #include "ts_$lcname.h"
133
134 END
135
136     if($name eq "xpm") {        # Handle as special case.
137         output_fn("XpmCreatePixmapFromData", "int",
138                   "Display *, Drawable, char **, Pixmap *, Pixmap *, XpmAttributes *",
139                   "Display *a0, Drawable a1, char **a2, Pixmap *a3, Pixmap *a4, XpmAttributes *a5",
140                   "a0, a1, a2, a3, a4, a5");
141         output_fn("XpmAttributesSize", "int", "void", "void", "");
142     } elsif($name eq "XShm") {
143         output_fn("XShmQueryExtension", "Bool",
144                   "Display *", "Display *a0", "a0");
145         output_fn("XShmQueryVersion", "Bool",
146                   "Display *, int *, int *, Bool *", 
147                   "Display *a0, int *a1, int *a2, Bool *a3", "a0, a1, a2, a3");
148         output_fn("XShmPixmapFormat", "int",
149                   "Display *", "Display *a0", "a0");
150         output_fn("XShmAttach", Status,
151                   "Display *, XShmSegmentInfo *",
152                   "Display *a0, XShmSegmentInfo *a1", "a0, a1");
153         output_fn("XShmDetach", Status,
154                   "Display *, XShmSegmentInfo *",
155                   "Display *a0, XShmSegmentInfo *a1", "a0, a1");
156         output_fn("XShmPutImage", Status,
157                   "Display *, Drawable, GC, XImage *, int, int, int, int, unsigned int, unsigned int, Bool",
158                   "Display *a0, Drawable a1, GC a2, XImage *a3, int a4, int a5, int a6, int a7, unsigned int a8, unsigned int a9, Bool a10", "a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10");
159         output_fn("XShmGetImage", Status,
160                   "Display *, Drawable, XImage *, int, int, unsigned long",
161                   "Display *a0, Drawable a1, XImage *a2, int a3, int a4, unsigned long a5", 
162                   "a0, a1, a2, a3, a4, a5");
163         output_fn("XShmCreateImage", "XImage *",
164                   "Display *, Visual *, unsigned int, int, char *, XShmSegmentInfo *, unsigned int, unsigned int",
165                   "Display *a0, Visual *a1, unsigned int a2, int a3, char *a4, XShmSegmentInfo *a5, unsigned int a6, unsigned int a7",
166                   "a0, a1, a2, a3, a4, a5, a6, a7");
167         output_fn("XShmCreatePixmap", "Pixmap",
168                   "Display *, Drawable, char *, XShmSegmentInfo *, unsigned int, unsigned int, unsigned int",
169                   "Display *a0, Drawable a1, char *a2, XShmSegmentInfo *a3, unsigned int a4, unsigned int a5, unsigned int a6",
170                   "a0, a1, a2, a3, a4, a5, a6");
171     } elsif($name eq "xf86dga") {
172         output_fn("XF86DGAQueryVersion",Bool,
173                 "Display*,int*,int*",
174                 "Display*a0,int*a1,int*a2",
175                 "a0,a1,a2"
176         );
177         output_fn("XF86DGAQueryExtension",Bool,
178                 "Display*,int*,int*",
179                 "Display*a0,int*a1,int*a2",
180                 "a0,a1,a2"
181         );
182         output_fn("XF86DGAGetVideo",Status,
183                 "Display*,int,char**,int*,int*,int*",
184                 "Display*a0,int a1,char**a2,int*a3,int*a4,int*a5",
185                 "a0,a1,a2,a3,a4,a5"
186         );
187         output_fn("XF86DGADirectVideo",Status,
188                 "Display*,int,int",
189                 "Display*a0,int a1,int a2",
190                 "a0,a1,a2"
191         );
192         output_fn("XF86DGAGetViewPortSize",Status,
193                 "Display*,int,int*,int*",
194                 "Display*a0,int a1,int *a2,int *a3",
195                 "a0,a1,a2,a3"
196         );
197         output_fn("XF86DGASetViewPort",Status,
198                 "Display*,int,int,int",
199                 "Display*a0,int a1,int a2,int a3",
200                 "a0,a1,a2,a3"
201         );
202         output_fn("XF86DGAInstallColormap",Status,
203                 "Display*,int,Colormap",
204                 "Display*a0,int a1,Colormap a2",
205                 "a0,a1,a2"
206         );
207         output_fn("XF86DGAQueryDirectVideo",Status,
208                 "Display*,int,int*",
209                 "Display*a0,int a1,int *a2",
210                 "a0,a1,a2"
211         );
212         output_fn("XF86DGAViewPortChanged",Status,
213                 "Display*,int,int",
214                 "Display*a0,int a1,int a2",
215                 "a0,a1,a2"
216         );
217     } elsif($name eq "xf86dga2") {
218         output_fn_short("Bool", "XDGAQueryVersion", "Display*" ,"int*","int*");
219         output_fn_short("Bool", "XDGAQueryExtension", "Display*" ,"int*","int*");
220         output_fn_short("XDGAMode*", "XDGAQueryModes", "Display*" ,"int", "int*");
221         output_fn_short("XDGADevice*", "XDGASetMode", "Display*" ,"int","int");
222         output_fn_short("Bool", "XDGAOpenFramebuffer", "Display*" ,"int");
223         output_fn_short("void", "XDGACloseFramebuffer", "Display*" ,"int");
224         output_fn_short("void", "XDGASetViewport", "Display*" ,"int", "int", "int", "int");
225         output_fn_short("void", "XDGAInstallColormap", "Display*" , "int", "Colormap");
226         output_fn_short("Colormap", "XDGACreateColormap", "Display*" ,"int", "XDGADevice*", "int");
227         output_fn_short("void", "XDGASelectInput", "Display*" ,"int", "long");
228         output_fn_short("void", "XDGAFillRectangle", "Display*" ,"int", "int", "int", "unsigned int", "unsigned int", "unsigned long");
229         output_fn_short("void", "XDGACopyArea", "Display*" ,"int", "int", "int", "unsigned int", "unsigned int", "int", "int");
230         output_fn_short("void", "XDGACopyTransparentArea", "Display*" ,"int", "int", "int", "unsigned int", "unsigned int", "int", "int", "unsigned long");
231         output_fn_short("int", "XDGAGetViewportStatus", "Display*" ,"int");
232         output_fn_short("void", "XDGASync", "Display*" ,"int");
233         output_fn_short("Bool", "XDGASetClientVersion", "Display*");
234         output_fn_short("void", "XDGAChangePixmapMode", "Display*" ,"int", "int*", "int*", "int");
235         output_fn_short("void", "XDGAKeyEventToXKeyEvent", "XDGAKeyEvent*" ,"XKeyEvent*");
236     } elsif ($name eq "xvideo") {
237         output_fn_short("int", "XvQueryExtension", "Display*", "unsigned int*", "unsigned int*", "unsigned int*", "unsigned int*", "unsigned int*");
238         output_fn_short("int", "XvQueryAdaptors", "Display*", "Window", "unsigned int*", "XvAdaptorInfo**");
239         output_fn_short("int", "XvQueryEncodings", "Display*", "XvPortID", "unsigned int*", "XvEncodingInfo**");
240         output_fn_short("int", "XvPutVideo", "Display*", "XvPortID", "Drawable", "GC", "int", "int", "unsigned int", "unsigned int", "int", "int", "unsigned int", "unsigned int");
241         output_fn_short("int", "XvPutStill", "Display*", "XvPortID", "Drawable", "GC", "int", "int", "unsigned int", "unsigned int", "int", "int", "unsigned int", "unsigned int");
242         output_fn_short("int", "XvGetVideo", "Display*", "XvPortID", "Drawable", "GC", "int", "int", "unsigned int", "unsigned int", "int", "int", "unsigned int", "unsigned int");
243         output_fn_short("int", "XvGetStill", "Display*", "XvPortID", "Drawable", "GC", "int", "int", "unsigned int", "unsigned int", "int", "int", "unsigned int", "unsigned int");
244         output_fn_short("int", "XvStopVideo", "Display*", "XvPortID", "Drawable");
245         output_fn_short("int", "XvGrabPort", "Display*", "XvPortID", "Time");
246         output_fn_short("int", "XvUngrabPort", "Display*", "XvPortID", "Time");
247         output_fn_short("int", "XvSelectVideoNotify", "Display*", "Drawable", "Bool");
248         output_fn_short("int", "XvSelectPortNotify", "Display*", "XvPortID", "Bool");
249         output_fn_short("int", "XvSetPortAttribute", "Display*", "XvPortID", "Atom", "int");
250         output_fn_short("int", "XvGetPortAttribute", "Display*", "XvPortID", "Atom", "int*");
251         output_fn_short("int", "XvQueryBestSize", "Display*", "XvPortID", "Bool", "unsigned int", "unsigned int", "unsigned int", "unsigned int", "unsigned int*", "unsigned int*");
252         output_fn_short("XvAttribute*", "XvQueryPortAttributes", "Display*", "XvPortID", "int*");
253         output_fn_short("void", "XvFreeAdaptorInfo", "XvAdaptorInfo*");
254         output_fn_short("void", "XvFreeEncodingInfo", "XvEncodingInfo*");
255         output_fn_short("XvImageFormatValues *", "XvListImageFormats", "Display*", "XvPortID", "int*");
256         output_fn_short("XvImage *", "XvCreateImage", "Display*", "XvPortID", "int", "char*", "int", "int");
257         output_fn_short("int", "XvPutImage", "Display*", "XvPortID", "Drawable", "GC", "XvImage*", "int", "int", "unsigned int", "unsigned int", "int", "int", "unsigned int", "unsigned int");
258         output_fn_short("int", "XvShmPutImage", "Display*", "XvPortID", "Drawable", "GC", "XvImage*", "int", "int", "unsigned int", "unsigned int", "int", "int", "unsigned int", "unsigned int", "Bool");
259 output_fn_short("XvImage *", "XvShmCreateImage", "Display*", "XvPortID", "int", "char*", "int", "int", "XShmSegmentInfo*");
260     } elsif($name eq "xf86vmode") {
261         output_fn("XF86VidModeQueryVersion",Bool,
262                 "Display*,int*,int*",
263                 "Display*a0,int*a1,int*a2",
264                 "a0,a1,a2"
265         );
266         output_fn("XF86VidModeQueryExtension",Bool,
267                 "Display*,int*,int*",
268                 "Display*a0,int*a1,int*a2",
269                 "a0,a2,a2"
270         );
271         output_fn("XF86VidModeGetModeLine",Bool,
272                 "Display*,int,int*,XF86VidModeModeLine*",
273                 "Display*a0,int a1,int*a2,XF86VidModeModeLine*a3",
274                 "a0,a1,a2,a3"
275         );
276         output_fn("XF86VidModeGetAllModeLines",Bool,
277                 "Display*,int,int*,XF86VidModeModeInfo***",
278                 "Display*a0,int a1,int*a2,XF86VidModeModeInfo***a3",
279                 "a0,a1,a2,a3"
280         );
281         output_fn("XF86VidModeAddModeLine",Bool,
282                 "Display*,int,XF86VidModeModeInfo*,XF86VidModeModeInfo*",
283                 "Display*a0,int a1,XF86VidModeModeInfo*a2,XF86VidModeModeInfo*a3",
284                 "a0,a1,a2,a3"
285         );
286         output_fn("XF86VidModeDeleteModeLine",Bool,
287                 "Display*,int,XF86VidModeModeInfo*",
288                 "Display*a0,int a1,XF86VidModeModeInfo*a2",
289                 "a0,a1,a2"
290         );
291         output_fn("XF86VidModeModModeLine",Bool,
292                 "Display*,int,XF86VidModeModeLine*",
293                 "Display*a0,int a1,XF86VidModeModeLine*a2",
294                 "a0,a1,a2"
295         );
296         output_fn("XF86VidModeValidateModeLine",Status,
297                 "Display*,int,XF86VidModeModeInfo*",
298                 "Display*a0,int a1,XF86VidModeModeInfo*a2",
299                 "a0,a1,a2"
300         );
301         output_fn("XF86VidModeSwitchMode",Bool,
302                 "Display*,int,int",
303                 "Display*a0,int a1,int a2",
304                 "a0,a1,a2"
305         );
306         output_fn("XF86VidModeSwitchToMode",Bool,
307                 "Display*,int,XF86VidModeModeInfo*",
308                 "Display*a0,int a1,XF86VidModeModeInfo*a2",
309                 "a0,a1,a2"
310         );
311         output_fn("XF86VidModeLockModeSwitch",Bool,
312                 "Display*,int,int",
313                 "Display*a0,int a1,int a2",
314                 "a0,a1,a2"
315         );
316         output_fn("XF86VidModeGetMonitor",Bool,
317                 "Display*,int,XF86VidModeMonitor*",
318                 "Display*a0,int a1,XF86VidModeMonitor*a2",
319                 "a0,a1,a2"
320         );
321         output_fn("XF86VidModeGetViewPort",Bool,
322                 "Display*,int,int*,int*",
323                 "Display*a0,int a1,int*a2,int*a3",
324                 "a0,a1,a2,a3"
325         );
326         output_fn("XF86VidModeSetViewPort",Bool,
327                 "Display*,int,int,int",
328                 "Display*a0,int a1,int a2,int a3",
329                 "a0,a1,a2,a3"
330         );      
331     } else {
332         open(IN, 
333              "echo \"$x11_incl#include <X11/$extensions_dir$name.h>\" | " . 
334              "gcc -L$X11_include_dir -DNeedFunctionPrototypes -E - | " .
335              "grep -v '^[ \t]*\$)' |"
336              ) || die "open";
337
338       PROTO: while(<IN>) {
339           if(m'extern\s+([^()]*)\b([a-zA-Z0-9_]+)\s*\(') {
340               $result_type = $1;
341               $fn_name = $2;
342               $result_type = "int" if $result_type =~ /^\s*$/;
343               @args = ();
344               while(<IN>) {
345                   last if m'\)\s*;';
346                   # Give up on vararg functions and function pointer args.
347                   if(m'\.\.\.|\(\*\)') {
348                       undef $fn_name;
349                       last;
350                   }
351                   if(m'\s*([^,]*[^, \t])\s*(,?\n)') {
352                       $args[$#args+1] = $1;
353                       if ($1 =~ /char\s*\[/) { # small hack for XQueryKeymap
354                         $args[$#args] = "char*";
355                       }
356                   }
357               }
358               # Skip if vararg, function pointer arg, or not needed.
359               next unless $fn_name;
360               next unless $want{$fn_name} && $want{$fn_name} == 1;
361
362               # Special case for no arguments (which is specified as "void").
363               if($#args == 0 && $args[0] eq "void") {
364                   @args = ();
365               }
366               $proto = "";
367               $formals = "";
368               $actuals = "";
369               for($i = 0; $i <= $#args; $i++) {
370                   $comma = $i < $#args ? ", " : "";
371                   $proto .= "$args[$i]$comma";
372                   $formals .= "$args[$i] a$i$comma";
373                   $actuals .= "a$i$comma";
374               }
375               $proto = $formals = "void" if $#args == -1;
376               output_fn($fn_name, $result_type, $proto, $formals, $actuals);
377           }
378       }
379     }
380
381     if($name eq "Xlib") {
382         raw_output_fn("XSynchronize", "int (*r)(Display *)",
383                   "int (*TSXSynchronize(Display *, Bool))(Display *)",
384                   "int (*TSXSynchronize(Display *a0, Bool a1))(Display *)",
385                   "a0, a1");
386         print OUTC "\nextern void _XInitImageFuncPtrs(XImage *);\n";
387         output_fn("_XInitImageFuncPtrs", "void", "XImage *", "XImage *a0", "a0");
388     } elsif($name eq "Xutil") {
389         output_fn("XDestroyImage", "int",
390                   "struct _XImage *", "struct _XImage *a0", "a0");
391         output_fn("XGetPixel", "unsigned long",
392                   "struct _XImage *, int, int",
393                   "struct _XImage *a0, int a1, int a2",
394                   "a0, a1, a2");
395         output_fn("XPutPixel", "int",
396                   "struct _XImage *, int, int, unsigned long",
397                   "struct _XImage *a0, int a1, int a2, unsigned long a3",
398                   "a0, a1, a2, a3");
399         output_fn("XSubImage", "struct _XImage *",
400                   "struct _XImage *, int, int, unsigned int, unsigned int",
401                   "struct _XImage *a0, int a1, int a2, unsigned int a3, unsigned int a4",
402                   "a0, a1, a2, a3, a4");
403         output_fn("XAddPixel", "int",
404                   "struct _XImage *, long",
405                   "struct _XImage *a0, long a1", "a0, a1");
406         output_fn("XUniqueContext", "XContext", "void", "void", "");
407     }
408
409     print OUTH <<END;
410
411 $post_file
412 #endif /* __WINE_TS_$ucname\_H */
413 END
414     print OUTC <<END;
415
416 $post_file
417 END
418
419
420
421 }
422
423 foreach $i (keys %want) {
424     if($want{$i} == 1) {
425         print "Unresolved: $i\n";
426     }
427 }
428
429
430 sub output_fn {
431     # Example call:
432     # output_fn("main", "int", "int, char **", "int a0, char **a1", "a0, a1")
433     #
434
435     my ($fn_name, $result_type, $protos, $formals, $actuals) = @_;
436
437     return raw_output_fn($fn_name,
438                          $result_type =~ /^\s*void\s*$/ ? "" : "$result_type r",
439                          "$result_type TS$fn_name($protos)",
440                          "$result_type TS$fn_name($formals)",
441                          $actuals);
442 }
443
444 sub output_fn_short {
445     # Example call:
446     # output_fn_sort("Bool", "XDGAQueryExtension", "Display *", "int *", "int *");
447     #
448     my ($result_type, $fn_name, @args) = @_;
449     
450     my ($i, $proto, $formals, $actuals) = (0, 
451                                            "$result_type TS$fn_name(",
452                                            "$result_type TS$fn_name(",
453                                            "");
454     while ($val = shift @args) {
455         $proto = $proto . $val;
456         $formals = $formals . $val . " a$i";
457         $actuals = $actuals . " a$i";
458         $i++;
459         if (@args) {
460             $proto = $proto . ", ";
461             $formals = $formals . ", ";
462             $actuals = $actuals . ", ";
463         }
464     }
465     $proto = $proto . ")";
466     $formals = $formals . ")";
467
468
469     raw_output_fn($fn_name,
470                   $result_type =~ /^\s*void\s*$/ ? "" : "$result_type r",
471                   $proto,
472                   $formals,
473                   $actuals);
474 }
475
476 sub raw_output_fn {
477     # Example call:
478     # output_fn("main", "int r", "int main(int, char **)", "int main(int a0, char **a1)", "a0, a1")
479     #
480
481     my ($fn_name, $resultdecl, $protodecl, $defdecl, $actuals) = @_;
482
483     return undef unless $want{$fn_name} && $want{$fn_name} == 1;
484
485     print OUTC "\n$defdecl\n";
486     print OUTH "extern $protodecl;\n";
487 #    print OUTH "#define $fn_name TS$fn_name\n";
488     print OUTC "{\n";
489     print OUTC "  $resultdecl;\n" if $resultdecl;
490     print OUTC "  wine_tsx11_lock();\n";
491     print OUTC "  ";
492     print OUTC "r = " if $resultdecl;
493     print OUTC "$fn_name($actuals);\n";
494     print OUTC "  wine_tsx11_unlock();\n";
495     print OUTC "  return r;\n" if $resultdecl;
496     print OUTC "}\n";
497     $want{$fn_name} = 2;
498     return 1;
499 }