Port to new grub_pci_iterate signature as of 2013-01-13, removing nested functions.
[grub-extras.git] / grub_main.c
blobc28349302e0c54885381ad4cab9003036d5adb29
1 /*
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/>.
19 #include "lua.h"
20 #include "lauxlib.h"
21 #include "lualib.h"
22 #include "grub_lib.h"
24 #include <grub/dl.h>
25 #include <grub/command.h>
26 #include <grub/i18n.h>
27 #include <grub/misc.h>
28 #include <grub/normal.h>
30 GRUB_MOD_LICENSE("GPLv3+");
32 static const char *
33 scan_str (const char *s1, const char *s2)
35 while (*s1)
37 const char *p = s2;
39 while (*p)
41 if (*s1 == *p)
42 return s1;
43 p++;
46 s1++;
49 return s1;
52 int
53 strcspn (const char *s1, const char *s2)
55 const char *r;
57 r = scan_str (s1, s2);
58 return r - s1;
61 char *
62 strpbrk (const char *s1, const char *s2)
64 const char *r;
66 r = scan_str (s1, s2);
67 return (*r) ? (char *) r : 0;
70 static lua_State *state;
72 /* Call `grub_error' to report a Lua error. The error message string must be
73 on the top of the Lua stack (at index -1). The error message is popped off
74 the Lua stack before this function returns. */
75 static void
76 handle_lua_error (const char *error_type)
78 const char *error_msg;
79 error_msg = lua_tostring (state, -1);
80 if (error_msg == NULL)
81 error_msg = "(error message not a string)";
82 grub_error (GRUB_ERR_BAD_ARGUMENT, "%s: %s", error_type, error_msg);
83 /* Pop the error message. */
84 lua_pop (state, 1);
87 /* Taken from lua.c */
88 static int
89 incomplete (lua_State * L, int status)
91 if (status == LUA_ERRSYNTAX)
93 size_t lmsg;
94 const char *msg = lua_tolstring (L, -1, &lmsg);
95 const char *tp = msg + lmsg - (sizeof (LUA_QL ("<eof>")) - 1);
96 if (strstr (msg, LUA_QL ("<eof>")) == tp)
98 lua_pop (L, 1);
99 return 1;
102 return 0; /* else... */
105 static grub_err_t
106 interactive (void)
108 char *ps1 = "lua> ";
109 char *ps2 = "lua>> ";
110 char *prompt = ps1;
111 char *line;
112 char *chunk = NULL;
113 size_t len;
114 size_t oldlen = 0;
115 int r;
117 grub_printf ("%s", N_ ("Welcome to lua, press the escape key to exit."));
119 while ((line = grub_cmdline_get (prompt)) != NULL)
121 /* len = lenght of chunk + line + newline character */
122 len = oldlen + grub_strlen (line) + 1;
123 chunk = grub_realloc (chunk, len + 1);
124 grub_strcpy (chunk + oldlen , line);
125 chunk[len - 1] = '\n';
126 chunk[len] = '\0';
127 grub_free (line);
129 r = luaL_loadbuffer (state, chunk, len, "stdin");
130 if (!r)
132 /* No error: Execute this chunk and prepare to read another */
133 r = lua_pcall (state, 0, 0, 0);
134 if (r)
136 handle_lua_error ("Lua");
137 grub_print_error ();
140 grub_free (chunk);
141 chunk = NULL;
142 len = 0;
143 prompt = ps1;
145 else if (incomplete (state, r))
147 /* Chunk is incomplete, try reading another line */
148 prompt = ps2;
150 else if (r == LUA_ERRSYNTAX)
152 handle_lua_error ("Lua");
153 grub_print_error ();
155 /* This chunk is garbage, try starting another one */
156 grub_free (chunk);
157 chunk = NULL;
158 len = 0;
159 prompt = ps1;
161 else
163 /* Handle errors other than syntax errors (out of memory, etc.) */
164 grub_free (chunk);
165 handle_lua_error ("Lua parser failed");
166 return grub_errno;
169 oldlen = len;
172 grub_free (chunk);
173 lua_gc (state, LUA_GCCOLLECT, 0);
175 return grub_errno;
178 static grub_err_t
179 grub_cmd_lua (grub_command_t cmd __attribute__ ((unused)),
180 int argc, char **args)
182 if (argc == 1)
184 if (luaL_loadfile (state, args[0]))
186 handle_lua_error ("Lua");
188 else if (lua_pcall (state, 0, 0, 0))
190 handle_lua_error ("Lua");
193 else if (argc == 0)
195 return interactive ();
197 else
199 return grub_error (GRUB_ERR_BAD_ARGUMENT, "1 or 0 arguments expected");
202 return grub_errno;
205 static grub_command_t cmd;
207 GRUB_MOD_INIT (lua)
209 (void) mod;
211 state = lua_open ();
212 if (state)
214 lua_gc (state, LUA_GCSTOP, 0);
215 luaL_openlibs (state);
216 luaL_register (state, "grub", grub_lua_lib);
217 lua_gc (state, LUA_GCRESTART, 0);
218 cmd = grub_register_command ("lua", grub_cmd_lua, N_("[FILE]"),
219 N_ ("Run lua script FILE or start interactive lua shell"));
223 GRUB_MOD_FINI (lua)
225 if (state)
227 lua_close (state);
228 grub_unregister_command (cmd);