From fed34d05863eb47419686bbe339b8f0b9ffca2df Mon Sep 17 00:00:00 2001 From: mcuelenaere Date: Sun, 5 Jul 2009 15:33:08 +0000 Subject: [PATCH] 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 --- apps/plugins/lua/lua.make | 12 +- apps/plugins/lua/rocklib.c | 363 +--------------------------------------- apps/plugins/lua/rocklib_aux.pl | 291 ++++++++++++++++++++++++++++++++ 3 files changed, 303 insertions(+), 363 deletions(-) create mode 100755 apps/plugins/lua/rocklib_aux.pl diff --git a/apps/plugins/lua/lua.make b/apps/plugins/lua/lua.make index 1232ddf04..7272118bc 100644 --- a/apps/plugins/lua/lua.make +++ b/apps/plugins/lua/lua.make @@ -30,15 +30,21 @@ else ROCKS += $(LUA_BUILDDIR)/lua.rock endif -$(LUA_BUILDDIR)/lua.rock: $(LUA_OBJ) $(LUA_BUILDDIR)/actions.lua $(LUA_BUILDDIR)/buttons.lua +$(LUA_BUILDDIR)/lua.rock: $(LUA_OBJ) $(LUA_BUILDDIR)/actions.lua $(LUA_BUILDDIR)/buttons.lua $(LUA_BUILDDIR)/rocklib_aux.o -$(LUA_BUILDDIR)/actions.lua: $(LUA_OBJ) +$(LUA_BUILDDIR)/actions.lua: $(call PRINTS,GEN $(@F))$(CC) $(INCLUDES) -E $(APPSDIR)/action.h | $(LUA_SRCDIR)/action_helper.pl > $(LUA_BUILDDIR)/actions.lua -$(LUA_BUILDDIR)/buttons.lua: $(LUA_OBJ) +$(LUA_BUILDDIR)/buttons.lua: $(SILENT)$(CC) $(INCLUDES) -dM -E -include button-target.h - < /dev/null | $(LUA_SRCDIR)/button_helper.pl | $(HOSTCC) -fno-builtin $(INCLUDES) -x c -o $(LUA_BUILDDIR)/button_helper - $(call PRINTS,GEN $(@F))$(LUA_BUILDDIR)/button_helper > $(LUA_BUILDDIR)/buttons.lua +$(LUA_BUILDDIR)/rocklib_aux.c: $(APPSDIR)/plugin.h + $(call PRINTS,GEN $(@F))$(CC) $(CFLAGS) $(INCLUDES) -E -include plugin.h - < /dev/null | $(LUA_SRCDIR)/rocklib_aux.pl $(LUA_SRCDIR) > $(LUA_BUILDDIR)/rocklib_aux.c + +$(LUA_BUILDDIR)/rocklib_aux.o: $(LUA_BUILDDIR)/rocklib_aux.c + $(call PRINTS,CC $(splash(ticks, s); - return 0; -} - -RB_WRAP(lcd_update) -{ - (void)L; - rb->lcd_update(); - return 0; -} - -RB_WRAP(lcd_update_rect) -{ - int x = luaL_checkint(L, 1); - int y = luaL_checkint(L, 2); - int width = luaL_checkint(L, 3); - int height = luaL_checkint(L, 4); - rb->lcd_update_rect(x, y, width, height); - return 0; -} - -RB_WRAP(lcd_clear_display) -{ - (void)L; - rb->lcd_clear_display(); - return 0; -} - -RB_WRAP(lcd_putsxy) -{ - int x = luaL_checkint(L, 1); - int y = luaL_checkint(L, 2); - const char* string = luaL_checkstring(L, 3); - rb->lcd_putsxy(x, y, string); - return 0; -} - -RB_WRAP(lcd_puts) -{ - int x = luaL_checkint(L, 1); - int y = luaL_checkint(L, 2); - const char* string = luaL_checkstring(L, 3); - rb->lcd_puts(x, y, string); - return 0; -} - -RB_WRAP(lcd_puts_scroll) -{ - int x = luaL_checkint(L, 1); - int y = luaL_checkint(L, 2); - const char* string = luaL_checkstring(L, 3); - rb->lcd_puts_scroll(x, y, string); - return 0; -} - -RB_WRAP(lcd_stop_scroll) -{ - (void)L; - rb->lcd_stop_scroll(); - return 0; -} - #ifdef HAVE_LCD_BITMAP RB_WRAP(lcd_framebuffer) { @@ -331,89 +265,6 @@ RB_WRAP(lcd_framebuffer) return 1; } -RB_WRAP(lcd_set_drawmode) -{ - int drawmode = luaL_checkint(L, 1); - rb->lcd_set_drawmode(drawmode); - return 0; -} - -RB_WRAP(lcd_get_drawmode) -{ - int result = rb->lcd_get_drawmode(); - lua_pushinteger(L, result); - return 1; -} - -RB_WRAP(lcd_setfont) -{ - int font = luaL_checkint(L, 1); - rb->lcd_setfont(font); - return 0; -} - -RB_WRAP(lcd_drawpixel) -{ - int x = luaL_checkint(L, 1); - int y = luaL_checkint(L, 2); - - rb->lcd_drawpixel(x, y); - return 0; -} - -RB_WRAP(lcd_drawline) -{ - int x1 = luaL_checkint(L, 1); - int y1 = luaL_checkint(L, 2); - int x2 = luaL_checkint(L, 3); - int y2 = luaL_checkint(L, 4); - - rb->lcd_drawline(x1, y1, x2, y2); - return 0; -} - -RB_WRAP(lcd_hline) -{ - int x1 = luaL_checkint(L, 1); - int x2 = luaL_checkint(L, 2); - int y = luaL_checkint(L, 3); - - rb->lcd_hline(x1, x2, y); - return 0; -} - -RB_WRAP(lcd_vline) -{ - int x = luaL_checkint(L, 1); - int y1 = luaL_checkint(L, 2); - int y2 = luaL_checkint(L, 3); - - rb->lcd_vline(x, y1, y2); - return 0; -} - -RB_WRAP(lcd_drawrect) -{ - int x = luaL_checkint(L, 1); - int y = luaL_checkint(L, 2); - int width = luaL_checkint(L, 3); - int height = luaL_checkint(L, 4); - - rb->lcd_drawrect(x, y, width, height); - return 0; -} - -RB_WRAP(lcd_fillrect) -{ - int x = luaL_checkint(L, 1); - int y = luaL_checkint(L, 2); - int width = luaL_checkint(L, 3); - int height = luaL_checkint(L, 4); - - rb->lcd_fillrect(x, y, width, height); - return 0; -} - RB_WRAP(lcd_mono_bitmap_part) { struct rocklua_image *src = rli_checktype(L, 1); @@ -442,34 +293,6 @@ RB_WRAP(lcd_mono_bitmap) } #if LCD_DEPTH > 1 -RB_WRAP(lcd_set_foreground) -{ - unsigned foreground = luaL_checkint(L, 1); - rb->lcd_set_foreground(foreground); - return 0; -} - -RB_WRAP(lcd_get_foreground) -{ - unsigned result = rb->lcd_get_foreground(); - lua_pushinteger(L, result); - return 1; -} - -RB_WRAP(lcd_set_background) -{ - unsigned background = luaL_checkint(L, 1); - rb->lcd_set_background(background); - return 0; -} - -RB_WRAP(lcd_get_background) -{ - unsigned result = rb->lcd_get_background(); - lua_pushinteger(L, result); - return 1; -} - RB_WRAP(lcd_bitmap_part) { struct rocklua_image *src = rli_checktype(L, 1); @@ -541,76 +364,12 @@ RB_WRAP(lcd_bitmap_transparent) #endif /* defined(LCD_BITMAP) */ -RB_WRAP(yield) -{ - (void)L; - rb->yield(); - return 0; -} - -RB_WRAP(sleep) -{ - int ticks = luaL_checkint(L, 1); - rb->sleep(ticks); - return 0; -} - RB_WRAP(current_tick) { lua_pushinteger(L, *rb->current_tick); return 1; } -RB_WRAP(button_get) -{ - bool block = luaL_checkboolean(L, 1); - long result = rb->button_get(block); - lua_pushinteger(L, result); - return 1; -} - -RB_WRAP(button_get_w_tmo) -{ - int ticks = luaL_checkint(L, 1); - long result = rb->button_get_w_tmo(ticks); - lua_pushinteger(L, result); - return 1; -} - -RB_WRAP(button_status) -{ - int result = rb->button_status(); - lua_pushinteger(L, result); - return 1; -} - -#ifdef HAVE_BUTTON_DATA -RB_WRAP(button_get_data) -{ - int result = rb->button_get_data(); - lua_pushinteger(L, result); - return 1; -} -#endif - -#ifdef HAS_BUTTON_HOLD -RB_WRAP(button_hold) -{ - bool result = rb->button_hold(); - lua_pushboolean(L, result); - return 1; -} -#endif - -RB_WRAP(get_action) -{ - int context = luaL_checkint(L, 1); - int timeout = luaL_checkint(L, 2); - int result = rb->get_action(context, timeout); - lua_pushinteger(L, result); - return 1; -} - #ifdef HAVE_TOUCHSCREEN RB_WRAP(action_get_touchscreen_press) { @@ -624,14 +383,6 @@ RB_WRAP(action_get_touchscreen_press) } #endif -RB_WRAP(action_userabort) -{ - int timeout = luaL_checkint(L, 1); - bool result = rb->action_userabort(timeout); - lua_pushboolean(L, result); - return 1; -} - RB_WRAP(kbd_input) { luaL_Buffer b; @@ -655,69 +406,6 @@ RB_WRAP(touchscreen_set_mode) } #endif -RB_WRAP(backlight_on) -{ - (void)L; - rb->backlight_on(); - return 0; -} - -RB_WRAP(backlight_off) -{ - (void)L; - rb->backlight_off(); - return 0; -} - -RB_WRAP(backlight_set_timeout) -{ - int val = luaL_checkint(L, 1); - rb->backlight_set_timeout(val); - return 0; -} - -#ifdef HAVE_BACKLIGHT_BRIGHTNESS -RB_WRAP(backlight_set_brightness) -{ - int val = luaL_checkint(L, 1); - rb->backlight_set_brightness(val); - return 0; -} -#endif - -RB_WRAP(creat) -{ - const char* pathname = luaL_checkstring(L, 1); - int result = rb->creat(pathname); - lua_pushinteger(L, result); - return 1; -} - -RB_WRAP(remove) -{ - const char* pathname = luaL_checkstring(L, 1); - int result = rb->remove(pathname); - lua_pushinteger(L, result); - return 1; -} - -RB_WRAP(rename) -{ - const char* path = luaL_checkstring(L, 1); - const char* newname = luaL_checkstring(L, 2); - int result = rb->rename(path, newname); - lua_pushinteger(L, result); - return 1; -} - -RB_WRAP(file_exists) -{ - const char* path = luaL_checkstring(L, 1); - bool result = rb->file_exists(path); - lua_pushboolean(L, result); - return 1; -} - RB_WRAP(font_getstringsize) { const unsigned char* str = luaL_checkstring(L, 1); @@ -796,32 +484,11 @@ RB_WRAP(current_path) static const luaL_Reg rocklib[] = { /* Graphics */ - R(lcd_clear_display), - R(lcd_update), - R(lcd_update_rect), - R(lcd_puts), - R(lcd_putsxy), - R(lcd_puts_scroll), - R(lcd_stop_scroll), - R(splash), #ifdef HAVE_LCD_BITMAP R(lcd_framebuffer), - R(lcd_set_drawmode), - R(lcd_get_drawmode), - R(lcd_setfont), - R(lcd_drawline), - R(lcd_drawpixel), - R(lcd_hline), - R(lcd_vline), - R(lcd_drawrect), - R(lcd_fillrect), R(lcd_mono_bitmap_part), R(lcd_mono_bitmap), #if LCD_DEPTH > 1 - R(lcd_set_foreground), - R(lcd_get_foreground), - R(lcd_set_background), - R(lcd_get_background), R(lcd_get_backdrop), R(lcd_bitmap_part), R(lcd_bitmap), @@ -836,43 +503,16 @@ static const luaL_Reg rocklib[] = R(lcd_rgbunpack), #endif - /* File handling */ - R(creat), - R(remove), - R(rename), - R(file_exists), - /* Kernel */ - R(sleep), - R(yield), R(current_tick), /* Buttons */ - R(button_get), - R(button_get_w_tmo), - R(button_status), -#ifdef HAVE_BUTTON_DATA - R(button_get_data), -#endif -#ifdef HAS_BUTTON_HOLD - R(button_hold), -#endif - R(get_action), - R(action_userabort), #ifdef HAVE_TOUCHSCREEN R(action_get_touchscreen_press), R(touchscreen_set_mode), #endif R(kbd_input), - /* Hardware */ - R(backlight_on), - R(backlight_off), - R(backlight_set_timeout), -#ifdef HAVE_BACKLIGHT_BRIGHTNESS - R(backlight_set_brightness), -#endif - R(font_getstringsize), R(read_bmp_file), R(set_viewport), @@ -884,6 +524,8 @@ static const luaL_Reg rocklib[] = {NULL, NULL} }; #undef R +extern const luaL_Reg rocklib_aux[]; + #define RB_CONSTANT(x) lua_pushinteger(L, x); lua_setfield(L, -2, #x); /* @@ -892,6 +534,7 @@ static const luaL_Reg rocklib[] = LUALIB_API int luaopen_rock(lua_State *L) { luaL_register(L, LUA_ROCKLIBNAME, rocklib); + luaL_register(L, LUA_ROCKLIBNAME, rocklib_aux); RB_CONSTANT(HZ); diff --git a/apps/plugins/lua/rocklib_aux.pl b/apps/plugins/lua/rocklib_aux.pl new file mode 100755 index 000000000..b5de1e454 --- /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() +{ + if(/^RB_WRAP\(([^)]+)\)/) + { + push(@ported_functions, $1); + } +} +close ROCKLIB; + +# Parse plugin.h +my $start = 0; +while() +{ + if(/struct plugin_api \{/) + { + $start = 1; + } + elsif($start && /\};/) + { + $start = 0; + } + + if($start == 1) + { + my $line = $_; + while($line !~ /;/) + { + $line .= ; + } + + $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 < \&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"; -- 2.11.4.GIT