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