change IntPtr mapping from int to gpointer
[mono.git] / mono / wrapper / genwrapper.pl
1 #!/usr/bin/perl
2
3 # Author:
4 #       Dietmar Maurer (dietmar@ximian.com)
5 #
6 # (C) 2001 Ximian, Inc.
7
8 use Getopt::Long;
9 init();
10
11 if ($ENV{"OSTYPE"} eq "cygwin") {
12 @includes = ("sys/types.h", "sys/stat.h", "unistd.h", "fcntl.h", "glib.h",
13              "errno.h");
14 } else {
15 @includes = ("sys/types.h", "sys/stat.h", "unistd.h", "fcntl.h", "glib.h",
16              "errno.h");
17 }
18
19 $cflags = `glib-config --cflags glib`;
20 $cflags =~ s/\n//;
21
22 $lib = "monowrapper";
23
24 create_struct ("MonoWrapperStat", "stat",
25                "uint", "st_dev",
26                "uint", "st_mode",
27                "uint", "st_nlink",
28                "uint", "st_uid",
29                "uint", "st_gid",
30                "long", "st_size",
31                "uint", "st_atime",
32                "uint", "st_mtime",
33                "uint", "st_ctime",
34                );
35
36 create_func ($lib, "", "seek", "long", 
37              "IntPtr", "fd",
38              "long", "offset",
39              "int", "whence");
40
41 create_func ($lib, "", "read", "int",
42              "IntPtr", "fd",
43              "void *", "buf",
44              "int", "count");
45
46 create_func ($lib, "", "write", "int",
47              "IntPtr", "fd",
48              "void *", "buf",
49              "int", "count");
50
51 create_func ($lib, "", "fstat", "int",
52              "IntPtr", "fd",
53              "stat *", "buf");
54
55 create_func ($lib, "", "ftruncate", "int",
56              "IntPtr", "fd",
57              "long", "length");
58
59 create_func ($lib, "", "open", "IntPtr",
60              "string", "path",
61              "int", "flags",
62              "int", "mode");
63
64 create_func ($lib, "", "close", "int",
65              "IntPtr", "fd");
66
67 create_func ($lib, "", "stat", "int",
68              "string", "path",
69              "stat *", "buf");
70
71 create_func ($lib, "", "unlink", "int",
72              "string", "path");
73
74 create_func ($lib, "", "opendir", "IntPtr",
75              "string", "path");
76
77 create_func ($lib, "", "readdir", "string",
78              "IntPtr", "dir");
79
80 create_func ($lib, "", "closedir", "int",
81              "IntPtr", "dir");
82
83 create_func ($lib, "", "getenv", "IntPtr",
84              "string", "variable");
85
86 create_func ($lib, "", "environ", "IntPtr");
87
88
89 map_const ("int", "%d", "SEEK_SET",
90            "int", "%d", "SEEK_CUR",
91            "int", "%d", "SEEK_END",
92
93            "int", "0x%08x", "O_RDONLY",
94            "int", "0x%08x", "O_WRONLY",
95            "int", "0x%08x", "O_RDWR",
96            "int", "0x%08x", "O_CREAT",
97            "int", "0x%08x", "O_EXCL",
98            "int", "0x%08x", "O_NOCTTY",
99            "int", "0x%08x", "O_TRUNC",
100            "int", "0x%08x", "O_SYNC",
101            "int", "0x%08x", "O_APPEND",
102
103            "int", "0x%08x", "STDIN_FILENO",
104            "int", "0x%08x", "STDOUT_FILENO",
105            "int", "0x%08x", "STDERR_FILENO",
106
107            "int", "0x%08x", "S_IFMT",
108            "int", "0x%08x", "S_IFSOCK",
109            "int", "0x%08x", "S_IFLNK",
110            "int", "0x%08x", "S_IFREG",
111            "int", "0x%08x", "S_IFBLK",
112            "int", "0x%08x", "S_IFDIR",
113            "int", "0x%08x", "S_IFCHR",
114            "int", "0x%08x", "S_IFIFO",
115            "int", "0x%08x", "S_ISUID",
116            "int", "0x%08x", "S_ISGID",
117            "int", "0x%08x", "S_ISVTX",
118            "int", "0x%08x", "S_IRWXU",
119            "int", "0x%08x", "S_IRUSR",
120            "int", "0x%08x", "S_IWUSR",
121            "int", "0x%08x", "S_IXUSR",
122            "int", "0x%08x", "S_IRWXG",
123            "int", "0x%08x", "S_IRGRP",
124            "int", "0x%08x", "S_IWGRP",
125            "int", "0x%08x", "S_IXGRP",
126            "int", "0x%08x", "S_IRWXO",
127            "int", "0x%08x", "S_IROTH",
128            "int", "0x%08x", "S_IWOTH",
129            "int", "0x%08x", "S_IXOTH",
130
131            "int", "%d", "EPERM",
132            "int", "%d", "ENOENT",
133            "int", "%d", "ESRCH",
134            "int", "%d", "EINTR",
135            "int", "%d", "EIO",
136            "int", "%d", "ENXIO",
137            "int", "%d", "E2BIG",
138            "int", "%d", "ENOEXEC",
139            "int", "%d", "EBADF",
140            "int", "%d", "ECHILD",
141            "int", "%d", "EAGAIN",
142            "int", "%d", "ENOMEM",
143            "int", "%d", "EACCES",
144            "int", "%d", "EFAULT",
145            "int", "%d", "ENOTBLK",
146            "int", "%d", "EBUSY",
147            "int", "%d", "EEXIST",
148            "int", "%d", "EXDEV",
149            "int", "%d", "ENODEV",
150            "int", "%d", "EISDIR",
151            "int", "%d", "EINVAL",
152            "int", "%d", "ENFILE",
153            "int", "%d", "EMFILE",
154            "int", "%d", "ENOTTY",
155            "int", "%d", "ETXTBSY",
156            "int", "%d", "EFBIG",
157            "int", "%d", "ENOSPC",
158            "int", "%d", "ESPIPE",
159            "int", "%d", "EROFS",
160            "int", "%d", "EMLINK",
161            "int", "%d", "EPIPE",
162            "int", "%d", "EDOM",
163            "int", "%d", "ERANGE",
164            "int", "%d", "EDEADLK",
165            "int", "%d", "ENAMETOOLONG",
166            "int", "%d", "ENOLCK",
167            "int", "%d", "ENOSYS",
168            "int", "%d", "ENOTEMPTY",
169            "int", "%d", "ELOOP",
170            "int", "%d", "EWOULDBLOCK",
171            "int", "%d", "ENOMSG",
172            "int", "%d", "EIDRM",
173            "int", "%d", "ECHRNG",
174            "int", "%d", "EL2NSYNC",
175            "int", "%d", "EL3HLT",
176            "int", "%d", "EL3RST",
177            "int", "%d", "ELNRNG",
178            "int", "%d", "EUNATCH",
179            "int", "%d", "ENOCSI",
180            "int", "%d", "EL2HLT",
181            "int", "%d", "EBADE",
182            "int", "%d", "EBADR",
183            "int", "%d", "EXFULL",
184            "int", "%d", "ENOANO",
185            "int", "%d", "EBADRQC",
186            "int", "%d", "EBADSLT",
187            "int", "%d", "EDEADLOCK",
188            "int", "%d", "EBFONT",
189            "int", "%d", "ENOSTR",
190            "int", "%d", "ENODATA",
191            "int", "%d", "ETIME",
192            "int", "%d", "ENOSR",
193            "int", "%d", "ENONET",
194            "int", "%d", "ENOPKG",
195            "int", "%d", "EREMOTE",
196            "int", "%d", "ENOLINK",
197            "int", "%d", "EADV",
198            "int", "%d", "ESRMNT",
199            "int", "%d", "ECOMM",
200            "int", "%d", "EPROTO",
201            "int", "%d", "EMULTIHOP",
202            "int", "%d", "EDOTDOT",
203            "int", "%d", "EBADMSG",
204            "int", "%d", "ENOTUNIQ",
205            "int", "%d", "EBADFD",
206            "int", "%d", "EREMCHG",
207            "int", "%d", "ELIBACC",
208            "int", "%d", "ELIBBAD",
209            "int", "%d", "ELIBSCN",
210            "int", "%d", "ELIBMAX",
211            "int", "%d", "ELIBEXEC",
212            "int", "%d", "EUSERS",
213            "int", "%d", "ENOTSOCK",
214            "int", "%d", "EDESTADDRREQ",
215            "int", "%d", "EMSGSIZE",
216            "int", "%d", "EPROTOTYPE",
217            "int", "%d", "ENOPROTOOPT",
218            "int", "%d", "EPROTONOSUPPORT",
219            "int", "%d", "ESOCKTNOSUPPORT",
220            "int", "%d", "EOPNOTSUPP",
221            "int", "%d", "EPFNOSUPPORT",
222            "int", "%d", "EAFNOSUPPORT",
223            "int", "%d", "EADDRINUSE",
224            "int", "%d", "EADDRNOTAVAIL",
225            "int", "%d", "ENETDOWN",
226            "int", "%d", "ENETUNREACH",
227            "int", "%d", "ENETRESET",
228            "int", "%d", "ECONNABORTED",
229            "int", "%d", "ECONNRESET",
230            "int", "%d", "ENOBUFS",
231            "int", "%d", "EISCONN",
232            "int", "%d", "ENOTCONN",
233            "int", "%d", "ESHUTDOWN",
234            "int", "%d", "ETOOMANYREFS",
235            "int", "%d", "ETIMEDOUT",
236            "int", "%d", "ECONNREFUSED",
237            "int", "%d", "EHOSTDOWN",
238            "int", "%d", "EHOSTUNREACH",
239            "int", "%d", "EALREADY",
240            "int", "%d", "EINPROGRESS",
241            "int", "%d", "ESTALE",
242            "int", "%d", "EDQUOT",
243            "int", "%d", "ENOMEDIUM",
244            "int", "%d", "ENOTDIR",
245            );
246
247 sub init {
248
249     $csmode = 0;
250     $defmode = 0;
251
252     GetOptions ("c|csharp" => \$csmode,
253                 "d|defmode" => \$defmode) or die "cant parse options";
254
255     $CC = $env{"CC"};
256
257     if (!$CC) {
258         $CC = "gcc";
259     }
260
261
262     %tmap = ("void" => "void",
263              "IntPtr" => "gpointer",
264              "sbyte" => "gint8",
265              "byte" => "guint8",
266              "short" => "gint16",
267              "ushort" => "guint16",
268              "int" => "gint32",
269              "uint" => "guint32",
270              "long" => "gint64",
271              "ulong" => "guint64",
272              "string" => "const char *",
273              );
274 }
275
276 sub t {
277     my ($name) = @_;
278     my ($rname) = $name;
279
280     if ($name =~ m/(.*)\*\s*$/) {
281         $rname = $1;
282         $rname =~ s/\s+$//; # remove trailing spaces
283         $rval = $tmap{$rname} || die "unable to map type \"$name\"";
284         return "$rval*";
285     }
286
287     $rval = $tmap{$name} || die "unable to map type \"$name\"";
288
289 }
290
291 sub create_func {
292     my (@func) = @_;
293     my ($i) = 0;
294     my ($res) = "";
295
296     if ($func[1] eq "") {
297         $func[1] = "mono_wrapper_$func[2]";
298     }
299
300     if ($defmode) {
301         $dlldef .= "\t$func[1]\n";
302     }
303
304     if ($csmode) {
305
306         $res = "\t[DllImport(\"$func[0]\", EntryPoint=\"$func[1]\", CharSet=CharSet.Ansi)]\n";
307         $res .= "\tpublic unsafe static extern $func[3] $func[2] (";
308         $i +=4;
309         while ($i <= $#func) {
310             if ($i>4) {
311                 $res .= ", ";
312             }
313             $res .= "$func[$i] $func[$i+1]";
314             
315             $i+=2;
316         }
317         $res .= ");\n\n";
318
319         $res_func .= $res;
320
321     } else  {
322         
323         $res = t($func[3]) . "\n$func[1] (";
324         
325         $i +=4;
326         while ($i <= $#func) {
327             if ($i>4) {
328                 $res .= ", ";
329             }
330             $res .= t($func[$i]) . " $func[$i+1]";
331             
332             $i+=2;
333         }
334         $res .= ");\n\n";
335
336         $res_func .= $res;
337     }
338 }
339
340 sub create_struct {
341     my (@str) = @_;
342     my ($i) = 0;
343     my ($res) = "";
344
345     if ($csmode) {
346         $res = "public struct $str[1] {\n";
347         $i +=2;
348         while ($i <= $#str) {
349             $res .= "\tpublic $str[$i] $str[$i+1];\n";
350             $i+=2;
351         }
352         $res .= "};\n\n";
353     } else {
354         $res = "typedef struct {\n";
355         $i += 2;
356         while ($i <= $#str) {
357             $res .= "\t" . t($str[$i]) . " $str[$i+1];\n";
358             $i+=2;
359         }
360         $res .= "} $str[0];\n\n";
361     }
362
363     $tmap{"$str[1]"} = "$str[0]";
364
365     $res_struct .= $res;
366 }
367
368 sub map_const {
369     my (@co) = @_;
370     my ($res) = "";
371     my ($l);
372     my ($space);
373
374     if (!$csmode) {
375         return;
376     }
377
378     my ($tfn) = "/tmp/etypes$$.c";
379
380     open (TFN, ">$tfn") || die (0);
381
382     for ($i = 0; $i <= $#includes; $i++) {
383         print TFN "#include \"$includes[$i]\"\n";
384     }
385     
386     print TFN "\nint main () {\n"; 
387     for ($i = 0; $i <= $#co; $i+=3) {
388
389         $l = 20 - length($co[$i+2]);
390
391         $space = "";
392         for (my ($j) = 0; $j < $l; $j++) {
393             $space = $space . " ";
394         }
395
396         print TFN "printf (\"\\tpublic const %s %s $space= $co[$i+1];\\n\",".
397             " \"$co[$i]\", \"$co[$i+2]\", $co[$i+2]);\n";
398
399     }
400     print TFN "exit (-1);\n";
401     print TFN "}\n";
402
403     close (TFN);
404
405     system ("$CC $cflags $tfn -o conftest.exe") == 0
406         or die "calling c compiler failed";
407
408     system ("rm $tfn");
409
410     $res = `./conftest.exe`;
411
412     if (!$res) {
413         die "calling a.out failde";
414     }
415
416     $res_const = $res_const . $res;
417
418     system ("rm ./conftest.exe");       
419 }
420
421 sub etypes_end {
422
423     @ae = split (/\./, $__class);
424
425     print $res_struct;
426
427     print "public class $ae[$#ae] {\n\n";
428
429     if ($res_const) {
430         print "$res_const\n\n";
431     }
432
433     print "$res_func";
434
435     printf "} // class $ae[$#ae]\n\n";
436
437     for ($i = $#ae - 1; $i >= 0; $i--) {
438         print "} // namescape $ae[$i]\n";
439     }
440
441 }
442
443 print "/*\n * Generated automatically: do not edit this file.\n */\n\n";
444
445
446 if ($csmode) {
447
448     print "using System;\n";
449     print "using System.Runtime.InteropServices;\n\n";
450
451     print "namespace System.Private {\n\n";
452
453     print $res_struct;
454
455     print "public class Wrapper {\n\n";
456
457     if ($res_const) {
458         print "$res_const\n\n";
459     }
460
461     print "$res_func";
462
463     print "}\n";
464
465     print "}\n";
466     
467 } elsif ($defmode) {
468         
469     print "LIBRARY libmonowrapper\n";
470     print "EXPORTS\n";
471     print "\tDllMain\n";
472     print $dlldef;
473
474 } else {
475
476     print "#ifndef _MONO_WRAPPER_H_\n#define _MONO_WRAPPER_H_ 1\n\n";
477
478     for ($i = 0; $i <= $#includes; $i++) {
479         print "#include <$includes[$i]>\n";
480     }
481
482     print "\n";
483
484     print $res_struct;
485
486     print $res_func;
487
488     print "#endif\n";
489 }