2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2009 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
25 #include <grub/parser.h>
27 static lua_State
*state
;
29 /* Call `grub_error' to report a Lua error. The error message string must be
30 on the top of the Lua stack (at index -1). The error message is popped off
31 the Lua stack before this function returns. */
33 handle_lua_error (const char *error_type
)
35 const char *error_msg
;
36 error_msg
= lua_tostring (state
, -1);
37 if (error_msg
== NULL
)
38 error_msg
= "(error message not a string)";
39 grub_error (GRUB_ERR_BAD_ARGUMENT
, "%s: %s", error_type
, error_msg
);
40 /* Pop the error message. */
45 grub_lua_parse_line (char *line
, grub_reader_getline_t getline
)
53 r
= luaL_loadbuffer (state
, line
, grub_strlen (line
), "=grub");
56 /* No error: Execute the statement. */
57 r
= lua_pcall (state
, 0, 0, 0);
60 handle_lua_error ("Lua");
70 if (r
== LUA_ERRSYNTAX
)
72 /* Check whether the syntax error is a result of an incomplete
73 statement. If it is, then try to complete the statement by
74 reading more lines. */
76 const char *msg
= lua_tolstring (state
, -1, &lmsg
);
77 const char *tp
= msg
+ lmsg
- (sizeof (LUA_QL ("<eof>")) - 1);
78 if (grub_strstr (msg
, LUA_QL ("<eof>")) == tp
)
83 /* Discard the error message. */
85 /* Try to read another line to complete the statement. */
86 if ((getline (&n
, 1)) || (! n
))
88 grub_error (GRUB_ERR_BAD_ARGUMENT
, "incomplete command");
92 /* More input was available: Add it to the current statement
94 len
= grub_strlen (line
);
95 t
= grub_malloc (len
+ grub_strlen (n
) + 2);
99 grub_strcpy (t
, line
);
101 grub_strcpy (t
+ len
+ 1, n
);
102 grub_free (old_line
);
104 /* Try again to execute the statement now that more input has
108 /* The syntax error was not the result of an incomplete line. */
109 handle_lua_error ("Lua syntax error");
113 /* Handle errors other than syntax errors (out of memory, etc.). */
114 handle_lua_error ("Lua parser failed");
120 grub_free (old_line
);
121 lua_gc (state
, LUA_GCCOLLECT
, 0);
126 static struct grub_parser grub_lua_parser
=
129 .parse_line
= grub_lua_parse_line
139 lua_gc (state
, LUA_GCSTOP
, 0);
140 luaL_openlibs (state
);
141 luaL_register (state
, "grub", grub_lua_lib
);
142 lua_gc (state
, LUA_GCRESTART
, 0);
143 grub_parser_register ("lua", &grub_lua_parser
);
151 grub_parser_unregister (&grub_lua_parser
);