2009-05-18 Colin D Bennett <colin@gibibit.com>

Display error messages when parsing a Lua statement fails.  Previously,
	executing a syntactically invalid statement like ")foo" or "bar;" would
	silently fail.

	* script/lua/grub_main.c (handle_lua_error): New function.
	(grub_lua_parse_line): Improved reporting of Lua parser and execution
	errors.
This commit is contained in:
cbennett 2009-05-18 21:53:09 +00:00
parent 18f547ad4d
commit 33db90156a
2 changed files with 56 additions and 12 deletions

View file

@ -1,3 +1,13 @@
2009-05-18 Colin D Bennett <colin@gibibit.com>
Display error messages when parsing a Lua statement fails. Previously,
executing a syntactically invalid statement like ")foo" or "bar;" would
silently fail.
* script/lua/grub_main.c (handle_lua_error): New function.
(grub_lua_parse_line): Improved reporting of Lua parser and execution
errors.
2009-05-17 Vladimir Serbinenko <phcoder@gmail.com> 2009-05-17 Vladimir Serbinenko <phcoder@gmail.com>
Remove -Werror which causes build to fail on some systems Remove -Werror which causes build to fail on some systems

View file

@ -26,6 +26,21 @@
static lua_State *state; static lua_State *state;
/* Call `grub_error' to report a Lua error. The error message string must be
on the top of the Lua stack (at index -1). The error message is popped off
the Lua stack before this function returns. */
static void
handle_lua_error (const char *error_type)
{
const char *error_msg;
error_msg = lua_tostring (state, -1);
if (error_msg == NULL)
error_msg = "(error message not a string)";
grub_error (GRUB_ERR_BAD_ARGUMENT, "%s: %s", error_type, error_msg);
/* Pop the error message. */
lua_pop (state, 1);
}
static grub_err_t static grub_err_t
grub_lua_parse_line (char *line, grub_reader_getline_t getline) grub_lua_parse_line (char *line, grub_reader_getline_t getline)
{ {
@ -35,37 +50,47 @@ grub_lua_parse_line (char *line, grub_reader_getline_t getline)
lua_settop(state, 0); lua_settop(state, 0);
while (1) while (1)
{ {
r = luaL_loadbuffer (state, line, grub_strlen (line), "grub"); r = luaL_loadbuffer (state, line, grub_strlen (line), "=grub");
if (! r) if (! r)
{ {
/* No error: Execute the statement. */
r = lua_pcall (state, 0, 0, 0); r = lua_pcall (state, 0, 0, 0);
if (r) if (r)
grub_error (GRUB_ERR_BAD_ARGUMENT, "lua command fails"); {
handle_lua_error ("Lua");
break;
}
else else
{ {
grub_free (old_line); grub_free (old_line);
return grub_errno; return grub_errno;
} }
break;
} }
if (r == LUA_ERRSYNTAX) if (r == LUA_ERRSYNTAX)
{ {
/* Check whether the syntax error is a result of an incomplete
statement. If it is, then try to complete the statement by
reading more lines. */
size_t lmsg; size_t lmsg;
const char *msg = lua_tolstring(state, -1, &lmsg); const char *msg = lua_tolstring (state, -1, &lmsg);
const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1); const char *tp = msg + lmsg - (sizeof (LUA_QL ("<eof>")) - 1);
if (grub_strstr(msg, LUA_QL("<eof>")) == tp) if (grub_strstr (msg, LUA_QL ("<eof>")) == tp)
{ {
char *n, *t; char *n, *t;
int len; int len;
lua_pop(state, 1); /* Discard the error message. */
lua_pop (state, 1);
/* Try to read another line to complete the statement. */
if ((getline (&n, 1)) || (! n)) if ((getline (&n, 1)) || (! n))
{ {
grub_error (GRUB_ERR_BAD_ARGUMENT, "incomplete command"); grub_error (GRUB_ERR_BAD_ARGUMENT, "incomplete command");
break; break;
} }
/* More input was available: Add it to the current statement
contents. */
len = grub_strlen (line); len = grub_strlen (line);
t = grub_malloc (len + grub_strlen (n) + 2); t = grub_malloc (len + grub_strlen (n) + 2);
if (! t) if (! t)
@ -76,8 +101,17 @@ grub_lua_parse_line (char *line, grub_reader_getline_t getline)
grub_strcpy (t + len + 1, n); grub_strcpy (t + len + 1, n);
grub_free (old_line); grub_free (old_line);
line = old_line = t; line = old_line = t;
/* Try again to execute the statement now that more input has
been appended. */
continue; continue;
} }
/* The syntax error was not the result of an incomplete line. */
handle_lua_error ("Lua syntax error");
}
else
{
/* Handle errors other than syntax errors (out of memory, etc.). */
handle_lua_error ("Lua parser failed");
} }
break; break;
@ -102,10 +136,10 @@ GRUB_MOD_INIT(lua)
state = lua_open (); state = lua_open ();
if (state) if (state)
{ {
lua_gc(state, LUA_GCSTOP, 0); lua_gc (state, LUA_GCSTOP, 0);
luaL_openlibs(state); luaL_openlibs (state);
luaL_register(state, "grub", grub_lua_lib); luaL_register (state, "grub", grub_lua_lib);
lua_gc(state, LUA_GCRESTART, 0); lua_gc (state, LUA_GCRESTART, 0);
grub_parser_register ("lua", &grub_lua_parser); grub_parser_register ("lua", &grub_lua_parser);
} }
} }
@ -115,6 +149,6 @@ GRUB_MOD_FINI(lua)
if (state) if (state)
{ {
grub_parser_unregister (&grub_lua_parser); grub_parser_unregister (&grub_lua_parser);
lua_close(state); lua_close (state);
} }
} }