summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/rocklib_aux.pl
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-07-05 15:33:08 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-07-05 15:33:08 +0000
commitd755a5ac58b8401255eb3a2e7b00e902bc06ad1d (patch)
treedfcbe89f139dbe54ae1e9e37176c78ab6df68a0e /apps/plugins/lua/rocklib_aux.pl
parent9b1c774218e59fbcb7160709687686275ee04c13 (diff)
Lua: add script which wraps not-yet ported C functions to Lua
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21657 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lua/rocklib_aux.pl')
-rwxr-xr-xapps/plugins/lua/rocklib_aux.pl291
1 files changed, 291 insertions, 0 deletions
diff --git a/apps/plugins/lua/rocklib_aux.pl b/apps/plugins/lua/rocklib_aux.pl
new file mode 100755
index 0000000000..b5de1e4544
--- /dev/null
+++ b/apps/plugins/lua/rocklib_aux.pl
@@ -0,0 +1,291 @@
+#!/usr/bin/env perl
+
+sub trim
+{
+ my $text = $_[0];
+ $text =~ s/^\s+//;
+ $text =~ s/\s+$//;
+ return $text;
+}
+
+sub rand_string
+{
+ my @chars=('a'..'z');
+ my $ret;
+ foreach (1..5)
+ {
+ $ret .= $chars[rand @chars];
+ }
+ return $ret;
+}
+
+
+my @functions;
+my @ported_functions;
+my @forbidden_functions = ('^open$',
+ '^close$',
+ '^read$',
+ '^write$',
+ '^lseek$',
+ '^ftruncate$',
+ '^filesize$',
+ '^fdprintf$',
+ '^read_line$',
+ '^[a-z]+dir$',
+ '^__.+$',
+ '^.+_(un)?cached$',
+ '^audio_play$');
+
+my $rocklib = sprintf("%s/rocklib.c", $ARGV[0]);
+open ROCKLIB, "<$rocklib" or die("Couldn't open $rocklib: $!");
+while(<ROCKLIB>)
+{
+ if(/^RB_WRAP\(([^)]+)\)/)
+ {
+ push(@ported_functions, $1);
+ }
+}
+close ROCKLIB;
+
+# Parse plugin.h
+my $start = 0;
+while(<STDIN>)
+{
+ if(/struct plugin_api \{/)
+ {
+ $start = 1;
+ }
+ elsif($start && /\};/)
+ {
+ $start = 0;
+ }
+
+ if($start == 1)
+ {
+ my $line = $_;
+ while($line !~ /;/)
+ {
+ $line .= <STDIN>;
+ }
+
+ $line =~ s/(\n|\r)//g;
+
+ if($line =~ /([a-zA-Z *_]+)?\s?\(\*([^)]+)?\)\(([^)]+)\).*?;/)
+ {
+ $return_type = $1;
+ $name = $2;
+ $arguments = $3;
+
+ $return_type = trim($return_type);
+ $arguments =~ s/\s{2,}/ /g;
+
+ if( !grep($_ eq $name, @ported_functions) &&
+ !grep($name =~ $_, @forbidden_functions))
+ {
+ push(@functions, {'name' => $name, 'return' => $return_type, 'arg' => $arguments});
+ }
+ }
+ }
+}
+
+my $svnrev = '$Revision$';
+
+# Print the header
+print <<EOF
+/* Automatically generated of $svnrev from rocklib.c & plugin.h */
+
+#define lrocklib_c
+#define LUA_LIB
+
+#define _ROCKCONF_H_ /* We don't need strcmp() etc. wrappers */
+#include "lua.h"
+#include "lauxlib.h"
+#include "plugin.h"
+
+EOF
+;
+
+my %in_types = ('void' => \&in_void,
+ 'int' => \&in_int,
+ 'unsigned' => \&in_int,
+ 'unsignedint' => \&in_int,
+ 'signed' => \&in_int,
+ 'signedint' => \&in_int,
+ 'short' => \&in_int,
+ 'unsignedshort' => \&in_int,
+ 'signedshort' => \&in_int,
+ 'long' => \&in_int,
+ 'unsignedlong' => \&in_int,
+ 'signedlong' => \&in_int,
+ 'char' => \&in_int,
+ 'unsignedchar' => \&in_int,
+ 'signedchar' => \&in_int,
+ 'char*' => \&in_string,
+ 'signedchar*' => \&in_string,
+ 'unsignedchar*' => \&in_string,
+ 'bool' => \&in_bool,
+ '_Bool' => \&in_bool
+), %out_types = ('void' => \&out_void,
+ 'int' => \&out_int,
+ 'unsigned' => \&out_int,
+ 'unsignedint' => \&out_int,
+ 'signed' => \&out_int,
+ 'signedint' => \&out_int,
+ 'short' => \&out_int,
+ 'unsignedshort' => \&out_int,
+ 'signedshort' => \&out_int,
+ 'long' => \&out_int,
+ 'unsignedlong' => \&out_int,
+ 'signedlong' => \&out_int,
+ 'char' => \&out_int,
+ 'unsignedchar' => \&out_int,
+ 'signedchar' => \&out_int,
+ 'char*' => \&out_string,
+ 'signedchar*' => \&out_string,
+ 'unsignedchar*' => \&out_string,
+ 'bool' => \&out_bool,
+ '_Bool' => \&out_bool
+);
+
+sub in_void
+{
+ return "\t(void)L;\n";
+}
+
+sub in_int
+{
+ my ($name, $type, $pos) = @_;
+ return sprintf("\t%s %s = (%s) luaL_checkint(L, %d);\n", $type, $name, $type, $pos);
+}
+
+sub in_string
+{
+ my ($name, $type, $pos) = @_;
+ return sprintf("\t%s %s = (%s) luaL_checkstring(L, %d);\n", $type, $name, $type, $pos)
+}
+
+sub in_bool
+{
+ my ($name, $type, $pos) = @_;
+ return sprintf("\tbool %s = luaL_checkboolean(L, %d);\n", $name, $pos)
+}
+
+sub out_void
+{
+ my $name = $_[0];
+ return sprintf("\t%s;\n\treturn 0;\n", $name);
+}
+
+sub out_int
+{
+ my ($name, $type) = @_;
+ return sprintf("\t%s result = %s;\n\tlua_pushinteger(L, result);\n\treturn 1;\n", $type, $name);
+}
+
+sub out_string
+{
+ my ($name, $type) = @_;
+ return sprintf("\t%s result = %s;\n\tlua_pushstring(L, result);\n\treturn 1;\n", $type, $name);
+}
+
+sub out_bool
+{
+ my ($name, $type) = @_;
+ return sprintf("\tbool result = %s;\n\tlua_pushboolean(L, result);\n\treturn 1;\n", $name);
+}
+
+# Print the functions
+my @valid_functions;
+foreach my $function (@functions)
+{
+ my $valid = 1, @arguments = ();
+ # Check for supported arguments
+ foreach my $argument (split(/,/, @$function{'arg'}))
+ {
+ $argument = trim($argument);
+ if($argument !~ /\[.+\]/ && ($argument =~ /^(.+[\s*])([^[*\s]*)/
+ || $argument eq "void"))
+ {
+ my $literal_type, $type, $name;
+ if($argument eq "void")
+ {
+ $literal_type = "void", $type = "void", $name = "";
+ }
+ else
+ {
+ $literal_type = trim($1), $name = trim($2), $type = trim($1);
+ $type =~ s/(\s|const)//g;
+
+ if($name eq "")
+ {
+ $name = rand_string();
+ }
+ }
+
+ #printf "/* %s: %s|%s */\n", @$function{'name'}, $type, $name;
+ if(!defined $in_types{$type})
+ {
+ $valid = 0;
+ break;
+ }
+
+ push(@arguments, {'name' => $name,
+ 'type' => $type,
+ 'literal_type' => $literal_type
+ });
+ }
+ else
+ {
+ $valid = 0;
+ break;
+ }
+ }
+
+ # Check for supported return value
+ my $return = @$function{'return'};
+ $return =~ s/(\s|const)//g;
+ #printf "/* %s: %s [%d] */\n", @$function{'name'}, $return, $valid;
+ if(!defined $out_types{$return})
+ {
+ $valid = 0;
+ }
+
+ if($valid == 1)
+ {
+ # Print the header
+ printf "static int rock_%s(lua_State *L)\n".
+ "{\n",
+ @$function{'name'};
+
+ # Print the arguments
+ my $i = 1;
+ foreach my $argument (@arguments)
+ {
+ print $in_types{@$argument{'type'}}->(@$argument{'name'}, @$argument{'literal_type'}, $i++);
+ }
+
+ # Generate the arguments string
+ my $func_args = $arguments[0]{'name'};
+ for(my $i = 1; $i < $#arguments + 1; $i++)
+ {
+ $func_args .= ", ".$arguments[$i]{'name'};
+ }
+
+ # Print the function call
+ my $func = sprintf("rb->%s(%s)", @$function{'name'}, $func_args);
+
+ # Print the footer
+ print $out_types{$return}->($func, @$function{'return'});
+ print "}\n\n";
+
+ push(@valid_functions, $function);
+ }
+}
+
+# Print the C array
+print "const luaL_Reg rocklib_aux[] =\n{\n";
+foreach my $function (@valid_functions)
+{
+ printf "\t{\"%s\", rock_%s},\n", @$function{'name'}, @$function{'name'};
+}
+print "\t{NULL, NULL}\n};\n\n";