1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 Dan Everton (safetydan)
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
27 #include "rockmalloc.h"
32 static const luaL_Reg lualibs
[] = {
34 {LUA_TABLIBNAME
, luaopen_table
},
35 {LUA_STRLIBNAME
, luaopen_string
},
36 {LUA_OSLIBNAME
, luaopen_os
},
37 {LUA_ROCKLIBNAME
, luaopen_rock
},
38 {LUA_BITLIBNAME
, luaopen_bit
},
39 {LUA_IOLIBNAME
, luaopen_io
},
40 {LUA_LOADLIBNAME
, luaopen_package
},
41 {LUA_MATHLIBNAME
, luaopen_math
},
42 {LUA_DIRLIBNAME
, luaopen_luadir
},
46 static void rocklua_openlibs(lua_State
*L
) {
47 const luaL_Reg
*lib
= lualibs
;
48 for (; lib
->func
; lib
++) {
49 lua_pushcfunction(L
, lib
->func
);
50 lua_pushstring(L
, lib
->name
);
56 static lua_State
*getthread (lua_State
*L
, int *arg
) {
57 if (lua_isthread(L
, 1)) {
59 return lua_tothread(L
, 1);
67 #define LEVELS1 12 /* size of the first part of the stack */
68 #define LEVELS2 10 /* size of the second part of the stack */
70 static int db_errorfb (lua_State
*L
) {
72 int firstpart
= 1; /* still before eventual `...' */
74 lua_State
*L1
= getthread(L
, &arg
);
76 if (lua_isnumber(L
, arg
+2)) {
77 level
= (int)lua_tointeger(L
, arg
+2);
81 level
= (L
== L1
) ? 1 : 0; /* level 0 may be this own function */
82 if (lua_gettop(L
) == arg
)
83 lua_pushliteral(L
, "");
84 else if (!lua_isstring(L
, arg
+1)) return 1; /* message is not a string */
85 else lua_pushliteral(L
, "\n");
86 lua_pushliteral(L
, "stack traceback:");
87 while (lua_getstack(L1
, level
++, &ar
)) {
88 if (level
> LEVELS1
&& firstpart
) {
89 /* no more than `LEVELS2' more levels? */
90 if (!lua_getstack(L1
, level
+LEVELS2
, &ar
))
91 level
--; /* keep going */
93 lua_pushliteral(L
, "\n\t..."); /* too many levels */
94 while (lua_getstack(L1
, level
+LEVELS2
, &ar
)) /* find last levels */
100 lua_pushliteral(L
, "\n\t");
101 lua_getinfo(L1
, "Snl", &ar
);
102 lua_pushfstring(L
, "%s:", ar
.short_src
);
103 if (ar
.currentline
> 0)
104 lua_pushfstring(L
, "%d:", ar
.currentline
);
105 if (*ar
.namewhat
!= '\0') /* is there a name? */
106 lua_pushfstring(L
, " in function " LUA_QS
, ar
.name
);
108 if (*ar
.what
== 'm') /* main? */
109 lua_pushfstring(L
, " in main chunk");
110 else if (*ar
.what
== 'C' || *ar
.what
== 't')
111 lua_pushliteral(L
, " ?"); /* C function or tail call */
113 lua_pushfstring(L
, " in function <%s:%d>",
114 ar
.short_src
, ar
.linedefined
);
116 lua_concat(L
, lua_gettop(L
) - arg
);
118 lua_concat(L
, lua_gettop(L
) - arg
);
123 static int traceback (lua_State
*L
) {
124 lua_pushcfunction(L
, db_errorfb
);
125 lua_pushvalue(L
, 1); /* pass error message */
126 lua_pushinteger(L
, 2); /* skip this function and traceback */
127 lua_call(L
, 2, 1); /* call debug.traceback */
131 static int docall (lua_State
*L
) {
133 int base
= lua_gettop(L
); /* function index */
134 lua_pushcfunction(L
, traceback
); /* push traceback function */
135 lua_insert(L
, base
); /* put it under chunk and args */
136 status
= lua_pcall(L
, 0, 0, base
);
137 lua_remove(L
, base
); /* remove traceback function */
138 /* force a complete garbage collection in case of errors */
139 if (status
!= 0) lua_gc(L
, LUA_GCCOLLECT
, 0);
144 /***************** Plugin Entry Point *****************/
145 enum plugin_status
plugin_start(const void* parameter
)
147 const char* filename
;
150 if (parameter
== NULL
)
152 rb
->splash(HZ
, "Play a .lua file!");
157 filename
= (char*) parameter
;
159 lua_State
*L
= luaL_newstate();
162 status
= luaL_loadfile(L
, filename
);
164 rb
->lcd_clear_display();
171 DEBUGF("%s\n", lua_tostring(L
, -1));
172 rb
->splashf(5 * HZ
, "%s", lua_tostring(L
, -1));