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>
28 scan_str (const char *s1
, const char *s2
)
48 strcspn (const char *s1
, const char *s2
)
52 r
= scan_str (s1
, s2
);
57 strpbrk (const char *s1
, const char *s2
)
61 r
= scan_str (s1
, s2
);
62 return (*r
) ? (char *) r
: 0;
66 memchr (const void *s
, int c
, size_t n
)
68 const unsigned char *p
= s
;
82 static lua_State
*state
;
84 /* Call `grub_error' to report a Lua error. The error message string must be
85 on the top of the Lua stack (at index -1). The error message is popped off
86 the Lua stack before this function returns. */
88 handle_lua_error (const char *error_type
)
90 const char *error_msg
;
91 error_msg
= lua_tostring (state
, -1);
92 if (error_msg
== NULL
)
93 error_msg
= "(error message not a string)";
94 grub_error (GRUB_ERR_BAD_ARGUMENT
, "%s: %s", error_type
, error_msg
);
95 /* Pop the error message. */
100 grub_lua_parse_line (char *line
, grub_reader_getline_t getline
)
105 lua_settop(state
, 0);
108 r
= luaL_loadbuffer (state
, line
, grub_strlen (line
), "=grub");
111 /* No error: Execute the statement. */
112 r
= lua_pcall (state
, 0, 0, 0);
115 handle_lua_error ("Lua");
120 grub_free (old_line
);
125 if (r
== LUA_ERRSYNTAX
)
127 /* Check whether the syntax error is a result of an incomplete
128 statement. If it is, then try to complete the statement by
129 reading more lines. */
131 const char *msg
= lua_tolstring (state
, -1, &lmsg
);
132 const char *tp
= msg
+ lmsg
- (sizeof (LUA_QL ("<eof>")) - 1);
133 if (grub_strstr (msg
, LUA_QL ("<eof>")) == tp
)
138 /* Discard the error message. */
140 /* Try to read another line to complete the statement. */
141 if ((getline (&n
, 1)) || (! n
))
143 grub_error (GRUB_ERR_BAD_ARGUMENT
, "incomplete command");
147 /* More input was available: Add it to the current statement
149 len
= grub_strlen (line
);
150 t
= grub_malloc (len
+ grub_strlen (n
) + 2);
154 grub_strcpy (t
, line
);
156 grub_strcpy (t
+ len
+ 1, n
);
157 grub_free (old_line
);
159 /* Try again to execute the statement now that more input has
163 /* The syntax error was not the result of an incomplete line. */
164 handle_lua_error ("Lua syntax error");
168 /* Handle errors other than syntax errors (out of memory, etc.). */
169 handle_lua_error ("Lua parser failed");
175 grub_free (old_line
);
176 lua_gc (state
, LUA_GCCOLLECT
, 0);
181 static struct grub_parser grub_lua_parser
=
184 .parse_line
= grub_lua_parse_line
194 lua_gc (state
, LUA_GCSTOP
, 0);
195 luaL_openlibs (state
);
196 luaL_register (state
, "grub", grub_lua_lib
);
197 lua_gc (state
, LUA_GCRESTART
, 0);
198 grub_parser_register ("lua", &grub_lua_parser
);
206 grub_parser_unregister (&grub_lua_parser
);