Added some useful variables to java.make
[nativez] / src / notzed.nativez / jni / nativez-gen
1 #!/usr/bin/perl
2
3 # usage [ options ]* def-file.def
4 #  -b basedir   Base directory for any 'header' sections.
5 #  -I incdir    Extra include directory
6 #  -Iincdir     Extra include directory
7 #  --func-name  Function table variable name.  Default is `fn'.
8 #  --java-name  Java table variable name.  Default is 'java'.
9 #  -J           Create #defines to map java names to the variable name.
10 #  --java-long  Create long java names for object types.  Sort of like mangled jni names.
11
12 $args = "$0 ".join " ", @ARGV;
13 $java_name = "java";
14 $func_name = "fn";
15 $doJ = 0;
16 $doLong = 0;
17
18 while ($#ARGV >= 0) {
19     my $cmd = shift;
20     if ($cmd eq "-b") {
21         $basedir = shift;
22         $includes.=" '-I${basedir}'";
23     } elsif ($cmd eq "-I") {
24         my $dir = shift;
25         $includes.= " '-I$dir'";
26     } elsif ($cmd =~ m/^-I/) {
27         $includes.= " '$cmd'";
28     } elsif ($cmd eq "--func-name") {
29         $func_name = shift;
30     } elsif ($cmd eq "--java-name") {
31         $java_name = shift;
32     } elsif ($cmd eq "-J") {
33         $doJ = 1;
34     } elsif ($cmd eq "--java-long") {
35         $doLong = 1;
36     } else {
37         $def = $cmd;
38     }
39 }
40
41 #die ("`$def': input file doesn't exist") if ! -f $def;
42 #die ("`$basedir': doesn't exist") if ! -d $basedir;
43
44 $header = "";
45 $librart = "";
46 @functions = ();
47 @headers = ();
48 %proto = ();
49 $last_library = "";
50 $mode = "";
51
52 open IN,"<$def";
53
54 while (<IN>) {
55     chop;
56     s/#.*$//;
57     if (m/^header (.*) (.*) \{/) {
58         $library = $1;
59         $header = $2;
60         push @headers, $header;
61
62         -f "$basedir/$header" || die ("header $header not found");
63         
64         %proto = ();
65         open PROTO, "cproto -q -x ${includes} $basedir/$header|";
66         
67         while (<PROTO>) {
68             chop;
69             $cproto = $_;
70             if (m/([a-zA-Z0-9_]*)\(/) {
71                 $func = $1;
72                 $proto{$func} = $cproto;
73             }
74         }
75         close PROTO;
76
77         if ($library ne $last_library) {
78             push @functions, "#$library";
79             $last_library = $library;
80         }
81         $mode = "proto";
82     } elsif (m/^java (.*) (.*) \{/) {
83         $name = $1;
84         $class = $2;
85         $mode = "java";
86         push @classes,"#$name:$class";
87     } elsif (m/^}$/) {
88         $mode = "";
89     } elsif ($mode eq "proto") {
90         if (m/\s*([a-zA-Z0-9_]+)/) {
91             my $func= $1;
92             my $cproto = $proto{$func};
93             
94             die ("No function $func in $header") if !defined($cproto);
95             
96             push @functions, $cproto;
97         }
98     } elsif ($mode eq "java") {
99         # maps to strict "[static|],name,(arguments)"
100         if (m/(static)? *([\w<>]*) *, *([\[\w<>\(\)\/;]*)/) {
101             push @classes,"$1,$2,$3";
102         }
103     }
104 }
105 close IN;
106
107 $date = `date`;
108 chop $date;
109 print "/* This file was autogenerated on $date: */\n";
110 print "/* $args */\n";
111
112 if ($#headers >= 0) {
113     # Handle C prototype mappings
114     foreach $h (@headers) {
115         print "#include <$h>\n";
116     }
117
118     print "static struct functable {\n";
119     foreach $func (@functions) {
120         if ($func =~ m/^\#(.+)/) {
121             print "\t/* lib$1 */\n";
122         } else {
123             $dfunc = $func;
124             $dfunc =~ s/([a-zA-Z0-9_]*)(\(.*;)/(*\1)\2/;
125             print "\t$dfunc\n";
126         }
127     }
128     print "} ${func_name};\n";
129     print "static const char *${func_name}_names =\n";
130     foreach $func (@functions) {
131         if ($func =~ m/^(\#.+)/) {
132             print "\t\"$func\\0\"\n";
133         } else {
134             $func =~ m/([a-zA-Z0-9_]*)\(/;
135             print "\t\"$1\\0\"\n";
136         }
137     }
138     print "\t;\n";
139 }
140
141 if ($#classes >= 0) {
142     # Handle java defines
143     $name = "";
144     $class = "";
145     print "static struct {\n";
146     foreach $func (@classes) {
147         if ($func =~ m/^#(.+):(.+)/) {
148             $name = $1;
149             $class = $2;
150             print "\t// $class\n";
151             print "\tjclass $name"."_classid;\n";
152             printf "#define $name"."_classid ${java_name}.$name"."_classid\n" if $doJ;
153         } elsif ($func =~ m/(.*),(.+),\((.*)\).*/) {
154             my $method = $2;
155             my $args = $3;
156
157             if ($doLong) {
158                 while ($args =~ m/(.*)L([^;]*);(.*)/) {
159                     my $a = $1;
160                     my $b = $2;
161                     my $c = $3;
162
163                     $b =~ s,/,_,g;
164                     $args = $a."_".$b."_".$c;
165                 }               
166             } else {
167                 $args =~ s/L[^;]*;/l/g;
168                 $args =~ tr/A-Z/a-z/;
169             }
170             $args =~ s/\[/_/g;
171
172             $method =~ s/<init>/new/;
173             
174             print "\tjmethodID $name"."_$method"."_$args;\n";
175             print "#define $name"."_$method"."_$args ${java_name}.$name"."_$method"."_$args\n" if $doJ;
176         } elsif ($func =~ m/(.*),(.+),(.+)/) {
177             my $field = $2;
178             my $type = $3;
179
180             print "\tjfieldID $name"."_$field;\n";
181             print "#define $name"."_$field ${java_name}.$name"."_$field\n" if $doJ;
182         } else {
183             die("can't parse java signature $func");
184         }
185     }
186     print "} ${java_name};\n";
187     print "static const char *${java_name}_names =\n";
188     foreach $func (@classes) {
189         if ($func =~ m/^#(.+):(.+)/) {
190             $name = $1;
191             $class = $2;
192
193             print "\t\"#$class\\0\"\n";
194         } elsif ($func =~ m/static,(.*),(.*\(.*\).*)/) {
195             print "\t\":$1\\0$2\\0\"\n";
196         } elsif ($func =~ m/,(.*),(.*\(.*\).*)/) {
197             print "\t\".$1\\0$2\\0\"\n";
198         } elsif ($func =~ m/static,(.*),(.*)/) {
199             print "\t\";$1\\0$2\\0\"\n";
200         } elsif ($func =~ m/,(.*),(.*)/) {
201             print "\t\",$1\\0$2\\0\"\n";
202         }
203     }
204     print "\t;\n";    
205 }