Add the identifying header
[kugel-rb.git] / apps / plugins / lua / rocklib_aux.pl
blobf536ba3b7803ade25c8a2cad259103a6742e0f08
1 #!/usr/bin/env perl
2 ############################################################################
3 # __________ __ ___.
4 # Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 # \/ \/ \/ \/ \/
9 # $Id$
11 # Copyright (C) 2009 by Maurus Cuelenaere
13 # All files in this archive are subject to the GNU General Public License.
14 # See the file COPYING in the source tree root for full license agreement.
16 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 # KIND, either express or implied.
19 ############################################################################
21 sub trim
23 my $text = $_[0];
24 $text =~ s/^\s+//;
25 $text =~ s/\s+$//;
26 return $text;
29 sub rand_string
31 my @chars=('a'..'z');
32 my $ret;
33 foreach (1..5)
35 $ret .= $chars[rand @chars];
37 return $ret;
41 my @functions;
42 my @ported_functions;
43 my @forbidden_functions = ('^open$',
44 '^close$',
45 '^read$',
46 '^write$',
47 '^lseek$',
48 '^ftruncate$',
49 '^filesize$',
50 '^fdprintf$',
51 '^read_line$',
52 '^[a-z]+dir$',
53 '^__.+$',
54 '^.+_(un)?cached$',
55 '^audio_play$');
57 my $rocklib = sprintf("%s/rocklib.c", $ARGV[0]);
58 open ROCKLIB, "<$rocklib" or die("Couldn't open $rocklib: $!");
59 while(<ROCKLIB>)
61 if(/^RB_WRAP\(([^)]+)\)/)
63 push(@ported_functions, $1);
66 close ROCKLIB;
68 # Parse plugin.h
69 my $start = 0;
70 while(<STDIN>)
72 if(/struct plugin_api \{/)
74 $start = 1;
76 elsif($start && /\};/)
78 $start = 0;
81 if($start == 1)
83 my $line = $_;
84 while($line !~ /;/)
86 $line .= <STDIN>;
89 $line =~ s/(\n|\r)//g;
91 if($line =~ /([a-zA-Z *_]+)?\s?\(\*([^)]+)?\)\(([^)]+)\).*?;/)
93 $return_type = $1;
94 $name = $2;
95 $arguments = $3;
97 $return_type = trim($return_type);
98 $arguments =~ s/\s{2,}/ /g;
100 if( !grep($_ eq $name, @ported_functions) &&
101 !grep($name =~ $_, @forbidden_functions))
103 push(@functions, {'name' => $name, 'return' => $return_type, 'arg' => $arguments});
109 my $svnrev = '$Revision$';
111 # Print the header
112 print <<EOF
113 /* Automatically generated of $svnrev from rocklib.c & plugin.h */
115 #define lrocklib_c
116 #define LUA_LIB
118 #define _ROCKCONF_H_ /* We don't need strcmp() etc. wrappers */
119 #include "lua.h"
120 #include "lauxlib.h"
121 #include "plugin.h"
126 my %in_types = ('void' => \&in_void,
127 'int' => \&in_int,
128 'unsigned' => \&in_int,
129 'unsignedint' => \&in_int,
130 'signed' => \&in_int,
131 'signedint' => \&in_int,
132 'short' => \&in_int,
133 'unsignedshort' => \&in_int,
134 'signedshort' => \&in_int,
135 'long' => \&in_int,
136 'unsignedlong' => \&in_int,
137 'signedlong' => \&in_int,
138 'char' => \&in_int,
139 'unsignedchar' => \&in_int,
140 'signedchar' => \&in_int,
141 'size_t' => \&in_int,
142 'ssize_t' => \&in_int,
143 'off_t' => \&in_int,
144 'char*' => \&in_string,
145 'signedchar*' => \&in_string,
146 'unsignedchar*' => \&in_string,
147 'bool' => \&in_bool,
148 '_Bool' => \&in_bool
149 ), %out_types = ('void' => \&out_void,
150 'int' => \&out_int,
151 'unsigned' => \&out_int,
152 'unsignedint' => \&out_int,
153 'signed' => \&out_int,
154 'signedint' => \&out_int,
155 'short' => \&out_int,
156 'unsignedshort' => \&out_int,
157 'signedshort' => \&out_int,
158 'long' => \&out_int,
159 'unsignedlong' => \&out_int,
160 'signedlong' => \&out_int,
161 'char' => \&out_int,
162 'unsignedchar' => \&out_int,
163 'signedchar' => \&out_int,
164 'size_t' => \&out_int,
165 'ssize_t' => \&out_int,
166 'off_t' => \&out_int,
167 'char*' => \&out_string,
168 'signedchar*' => \&out_string,
169 'unsignedchar*' => \&out_string,
170 'bool' => \&out_bool,
171 '_Bool' => \&out_bool
174 sub in_void
176 return "\t(void)L;\n";
179 sub in_int
181 my ($name, $type, $pos) = @_;
182 return sprintf("\t%s %s = (%s) luaL_checkint(L, %d);\n", $type, $name, $type, $pos);
185 sub in_string
187 my ($name, $type, $pos) = @_;
188 return sprintf("\t%s %s = (%s) luaL_checkstring(L, %d);\n", $type, $name, $type, $pos)
191 sub in_bool
193 my ($name, $type, $pos) = @_;
194 return sprintf("\tbool %s = luaL_checkboolean(L, %d);\n", $name, $pos)
197 sub out_void
199 my $name = $_[0];
200 return sprintf("\t%s;\n\treturn 0;\n", $name);
203 sub out_int
205 my ($name, $type) = @_;
206 return sprintf("\t%s result = %s;\n\tlua_pushinteger(L, result);\n\treturn 1;\n", $type, $name);
209 sub out_string
211 my ($name, $type) = @_;
212 return sprintf("\t%s result = %s;\n\tlua_pushstring(L, result);\n\treturn 1;\n", $type, $name);
215 sub out_bool
217 my ($name, $type) = @_;
218 return sprintf("\tbool result = %s;\n\tlua_pushboolean(L, result);\n\treturn 1;\n", $name);
221 # Print the functions
222 my @valid_functions;
223 foreach my $function (@functions)
225 my $valid = 1, @arguments = ();
226 # Check for supported arguments
227 foreach my $argument (split(/,/, @$function{'arg'}))
229 $argument = trim($argument);
230 if($argument !~ /\[.+\]/ && ($argument =~ /^(.+[\s*])([^[*\s]*)/
231 || $argument eq "void"))
233 my $literal_type, $type, $name;
234 if($argument eq "void")
236 $literal_type = "void", $type = "void", $name = "";
238 else
240 $literal_type = trim($1), $name = trim($2), $type = trim($1);
241 $type =~ s/(\s|const)//g;
243 if($name eq "")
245 $name = rand_string();
249 #printf "/* %s: %s|%s */\n", @$function{'name'}, $type, $name;
250 if(!defined $in_types{$type})
252 $valid = 0;
253 break;
256 push(@arguments, {'name' => $name,
257 'type' => $type,
258 'literal_type' => $literal_type
261 else
263 $valid = 0;
264 break;
268 # Check for supported return value
269 my $return = @$function{'return'};
270 $return =~ s/(\s|const)//g;
271 #printf "/* %s: %s [%d] */\n", @$function{'name'}, $return, $valid;
272 if(!defined $out_types{$return})
274 $valid = 0;
277 if($valid == 1)
279 # Print the header
280 printf "static int rock_%s(lua_State *L)\n".
281 "{\n",
282 @$function{'name'};
284 # Print the arguments
285 my $i = 1;
286 foreach my $argument (@arguments)
288 print $in_types{@$argument{'type'}}->(@$argument{'name'}, @$argument{'literal_type'}, $i++);
291 # Generate the arguments string
292 my $func_args = $arguments[0]{'name'};
293 for(my $i = 1; $i < $#arguments + 1; $i++)
295 $func_args .= ", ".$arguments[$i]{'name'};
298 # Print the function call
299 my $func = sprintf("rb->%s(%s)", @$function{'name'}, $func_args);
301 # Print the footer
302 print $out_types{$return}->($func, @$function{'return'});
303 print "}\n\n";
305 push(@valid_functions, $function);
309 # Print the C array
310 print "const luaL_Reg rocklib_aux[] =\n{\n";
311 foreach my $function (@valid_functions)
313 printf "\t{\"%s\", rock_%s},\n", @$function{'name'}, @$function{'name'};
315 print "\t{NULL, NULL}\n};\n\n";