On Wed, Jun 24, 2009 at 6:10 AM, Pavel Roskin<[email protected]> wrote: > On Tue, 2009-06-23 at 17:27 +0800, Bean wrote: >> Hi, >> >> Some bug fix for osdetect.lua, it also detect windows 98/me, freedos, >> msdos and freebsd. > > Why FressDOS and FressBSD? I assume it's typos. Why isn't Linux > capitalized? MS-DOS is written with a dash. "Windows Vista bootmgr" > should be "Windows Vista" and "Windows NT/2000/XP loader" should be > "Windows NT/2000/XP". It's not like we are just booting the loaders. >
Oh, fixed typos now. As for "Windows Vista bootmgr" and "Windows NT/2000/XP loader", I just copy them from 10_windows.in, I guess there is a reason for it there. > inird should be initrd. Please add check for the Fedora style names for > initrd, namely "initrd-KVER.img". Or maybe you just missed ".img" in > the second check? > Add the test for initrd-KVER.img. Is there any distro that uses initrd-KVER ? if not, I can just remove the second test. >> Extend the function of grub.file_exist to allow testing multiple names >> at the same time, this simplify osdetect.lua. > > The change to grub_lua_file_exist() is dubious. It's not clear why the > requirement is that all files exist. Maybe I don't know the style of > lua, but I think it's wrong to hardcode the AND logic just because one > script would benefit from it. As lua can detect the number of parameter quite easily, I just think it'd be a waste not to utilize it. If you always call it with one parameter, then it's equivalent to the previous file_exist. It's just a little more code in c, but it can reduce the number of calls between c and lua. > > If we consider e.g. the wildcard expansion in make, it will return a > non-empty value if any file exists, i.e. the OR logic is used. > We can add a new function that uses OR logic instead of AND, for example, grub.file_exist_any, and the current AND version can be called grub.file_exist_all. > I suggest that you split the lua.mod changes and osdetect.lua. The > later is obviously a bikeshed issue that can be discussed for a long > time. The former needs a more technical consideration. Ok. > > -- > Regards, > Pavel Roskin > > > _______________________________________________ > Grub-devel mailing list > [email protected] > http://lists.gnu.org/mailman/listinfo/grub-devel > -- Bean
diff --git a/conf/common.rmk b/conf/common.rmk
index fbca2e4..dc78df9 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -519,15 +519,14 @@ lua_mod_SOURCES = script/lua/lapi.c script/lua/lcode.c script/lua/ldebug.c \
script/lua/lstate.c script/lua/lstring.c script/lua/ltable.c \
script/lua/ltm.c script/lua/lundump.c script/lua/lvm.c \
script/lua/lzio.c script/lua/lauxlib.c script/lua/lbaselib.c \
- script/lua/linit.c script/lua/ltablib.c \
+ script/lua/linit.c script/lua/ltablib.c script/lua/lstrlib.c \
script/lua/grub_main.c script/lua/grub_lib.c
lua_mod_CFLAGS = $(COMMON_CFLAGS)
lua_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Extra libraries for lua
# script/lua/lmathlib.c script/lua/loslib.c script/lua/liolib.c
-# script/lua/lstrlib.c script/lua/ldblib.c script/lua/ltablib.c
-# script/lua/loadlib.c
+# script/lua/ldblib.c script/lua/loadlib.c
# Common Video Subsystem specific modules.
pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod \
diff --git a/script/lua/grub_lib.c b/script/lua/grub_lib.c
index 0295f0d..9875e8b 100644
--- a/script/lua/grub_lib.c
+++ b/script/lua/grub_lib.c
@@ -24,18 +24,47 @@
#include <grub/env.h>
#include <grub/parser.h>
#include <grub/command.h>
+#include <grub/normal.h>
+#include <grub/file.h>
+#include <grub/device.h>
+
+static int
+save_errno (lua_State *state)
+{
+ int saved_errno;
+
+ saved_errno = grub_errno;
+ grub_errno = 0;
+
+ lua_pushinteger (state, saved_errno);
+ lua_setfield (state, LUA_GLOBALSINDEX, "grub_errno");
+
+ if (saved_errno)
+ lua_pushstring (state, grub_errmsg);
+ else
+ lua_pushnil (state);
+
+ lua_setfield (state, LUA_GLOBALSINDEX, "grub_errmsg");
+
+ return saved_errno;
+}
+
+static int
+push_result (lua_State *state)
+{
+ lua_pushinteger (state, save_errno (state));
+ return 1;
+}
static int
grub_lua_run (lua_State *state)
{
int n;
char **args;
- grub_err_t result;
-
- if (! lua_gettop(state))
- return 0;
+ const char *s;
- if ((! grub_parser_split_cmdline (lua_tostring (state, 1), 0, &n, &args))
+ s = luaL_checkstring (state, 1);
+ if ((! grub_parser_split_cmdline (s, 0, &n, &args))
&& (n >= 0))
{
grub_command_t cmd;
@@ -50,15 +79,7 @@ grub_lua_run (lua_State *state)
grub_free (args);
}
- result = grub_errno;
- grub_errno = 0;
-
- lua_pushinteger(state, result);
-
- if (result)
- lua_pushstring (state, grub_errmsg);
-
- return (result) ? 2 : 1;
+ return push_result (state);
}
static int
@@ -66,12 +87,12 @@ grub_lua_getenv (lua_State *state)
{
int n, i;
- n = lua_gettop(state);
+ n = lua_gettop (state);
for (i = 1; i <= n; i++)
{
const char *name, *value;
- name = lua_tostring (state, i);
+ name = luaL_checkstring (state, i);
value = grub_env_get (name);
if (value)
lua_pushstring (state, value);
@@ -87,11 +108,8 @@ grub_lua_setenv (lua_State *state)
{
const char *name, *value;
- if (lua_gettop(state) != 2)
- return 0;
-
- name = lua_tostring (state, 1);
- value = lua_tostring (state, 2);
+ name = luaL_checkstring (state, 1);
+ value = luaL_checkstring (state, 2);
if (name[0])
grub_env_set (name, value);
@@ -99,10 +117,330 @@ grub_lua_setenv (lua_State *state)
return 0;
}
+static int
+grub_lua_enum_device (lua_State *state)
+{
+ auto int enum_device (const char *name);
+ int enum_device (const char *name)
+ {
+ int result;
+ grub_device_t dev;
+
+ result = 0;
+ dev = grub_device_open (name);
+ if (dev)
+ {
+ grub_fs_t fs;
+
+ fs = grub_fs_probe (dev);
+ if (fs)
+ {
+ lua_pushvalue (state, 1);
+ lua_pushstring (state, name);
+ lua_pushstring (state, fs->name);
+ if (! fs->uuid)
+ lua_pushnil (state);
+ else
+ {
+ int err;
+ char *uuid;
+
+ err = fs->uuid (dev, &uuid);
+ if (err)
+ {
+ grub_errno = 0;
+ lua_pushnil (state);
+ }
+ else
+ {
+ lua_pushstring (state, uuid);
+ grub_free (uuid);
+ }
+ }
+
+ lua_call (state, 3, 1);
+ result = lua_tointeger (state, -1);
+ lua_pop (state, 1);
+ }
+ else
+ grub_errno = 0;
+ grub_device_close (dev);
+ }
+ else
+ save_errno (state);
+
+ return result;
+ }
+
+ luaL_checktype (state, 1, LUA_TFUNCTION);
+ grub_device_iterate (enum_device);
+ return push_result (state);
+}
+
+static int
+grub_lua_enum_file (lua_State *state)
+{
+ char *device_name;
+ const char *arg;
+ grub_device_t dev;
+
+ auto int enum_file (const char *name, const struct grub_dirhook_info *info);
+ int enum_file (const char *name, const struct grub_dirhook_info *info)
+ {
+ int result;
+
+ lua_pushvalue (state, 1);
+ lua_pushstring (state, name);
+ lua_pushinteger (state, info->dir != 0);
+ lua_call (state, 2, 1);
+ result = lua_tointeger (state, -1);
+ lua_pop (state, 1);
+
+ return result;
+ }
+
+ luaL_checktype (state, 1, LUA_TFUNCTION);
+ arg = luaL_checkstring (state, 2);
+ device_name = grub_file_get_device_name (arg);
+ dev = grub_device_open (device_name);
+ if (dev)
+ {
+ grub_fs_t fs;
+ const char *path;
+
+ fs = grub_fs_probe (dev);
+ path = grub_strchr (arg, ')');
+ if (! path)
+ path = arg;
+ else
+ path++;
+
+ if (fs)
+ {
+ (fs->dir) (dev, path, enum_file);
+ }
+
+ grub_device_close (dev);
+ }
+
+ grub_free (device_name);
+
+ return push_result (state);
+}
+
+static int
+grub_lua_file_open (lua_State *state)
+{
+ grub_file_t file;
+ const char *name;
+
+ name = luaL_checkstring (state, 1);
+ file = grub_file_open (name);
+ save_errno (state);
+
+ if (! file)
+ return 0;
+
+ lua_pushlightuserdata (state, file);
+ return 1;
+}
+
+static int
+grub_lua_file_close (lua_State *state)
+{
+ grub_file_t file;
+
+ luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
+ file = lua_touserdata (state, 1);
+ grub_file_close (file);
+
+ return push_result (state);
+}
+
+static int
+grub_lua_file_seek (lua_State *state)
+{
+ grub_file_t file;
+ grub_off_t offset;
+
+ luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
+ file = lua_touserdata (state, 1);
+ offset = luaL_checkinteger (state, 2);
+
+ offset = grub_file_seek (file, offset);
+ save_errno (state);
+
+ lua_pushinteger (state, offset);
+ return 1;
+}
+
+static int
+grub_lua_file_read (lua_State *state)
+{
+ grub_file_t file;
+ luaL_Buffer b;
+ int n;
+
+ luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
+ file = lua_touserdata (state, 1);
+ n = luaL_checkinteger (state, 2);
+
+ luaL_buffinit (state, &b);
+ while (n)
+ {
+ char *p;
+ int nr;
+
+ nr = (n > LUAL_BUFFERSIZE) ? LUAL_BUFFERSIZE : n;
+ p = luaL_prepbuffer (&b);
+
+ nr = grub_file_read (file, p, nr);
+ if (nr <= 0)
+ break;
+
+ luaL_addsize (&b, nr);
+ n -= nr;
+ }
+
+ save_errno (state);
+ luaL_pushresult (&b);
+ return 1;
+}
+
+static int
+grub_lua_file_getline (lua_State *state)
+{
+ grub_file_t file;
+ char *line;
+
+ luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
+ file = lua_touserdata (state, 1);
+
+ line = grub_file_getline (file);
+ save_errno (state);
+
+ if (! line)
+ return 0;
+
+ lua_pushstring (state, line);
+ grub_free (line);
+ return 1;
+}
+
+static int
+grub_lua_file_getsize (lua_State *state)
+{
+ grub_file_t file;
+
+ luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
+ file = lua_touserdata (state, 1);
+
+ lua_pushinteger (state, file->size);
+ return 1;
+}
+
+static int
+grub_lua_file_getpos (lua_State *state)
+{
+ grub_file_t file;
+
+ luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
+ file = lua_touserdata (state, 1);
+
+ lua_pushinteger (state, file->offset);
+ return 1;
+}
+
+static int
+grub_lua_file_eof (lua_State *state)
+{
+ grub_file_t file;
+
+ luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
+ file = lua_touserdata (state, 1);
+
+ lua_pushboolean (state, file->offset >= file->size);
+ return 1;
+}
+
+static int
+grub_lua_file_exist (lua_State *state)
+{
+ int result, i, n;
+
+ result = 1;
+ n = lua_gettop (state);
+ for (i = 1; i <= n; i++)
+ {
+ grub_file_t file;
+ const char *name;
+
+ name = luaL_checkstring (state, i);
+ file = grub_file_open (name);
+ if (file)
+ {
+ grub_file_close (file);
+ }
+ else
+ {
+ result = 0;
+ grub_errno = 0;
+ break;
+ }
+ }
+
+ lua_pushboolean (state, result);
+ return 1;
+}
+
+static int
+grub_lua_add_menu (lua_State *state)
+{
+ int n;
+ const char *source;
+
+ source = luaL_checklstring (state, 1, 0);
+ n = lua_gettop (state) - 1;
+ if (n > 0)
+ {
+ const char *args[sizeof (char *) * n];
+ char *p;
+ int i;
+
+ for (i = 0; i < n; i++)
+ args[i] = luaL_checkstring (state, 2 + i);
+
+ p = grub_strdup (source);
+ if (! p)
+ return push_result (state);
+
+ grub_normal_add_menu_entry (n, args, p);
+ }
+ else
+ {
+ lua_pushstring (state, "not enough parameter");
+ lua_error (state);
+ }
+
+ return push_result (state);
+}
+
luaL_Reg grub_lua_lib[] =
{
{"run", grub_lua_run},
{"getenv", grub_lua_getenv},
{"setenv", grub_lua_setenv},
+ {"enum_device", grub_lua_enum_device},
+ {"enum_file", grub_lua_enum_file},
+ {"file_open", grub_lua_file_open},
+ {"file_close", grub_lua_file_close},
+ {"file_seek", grub_lua_file_seek},
+ {"file_read", grub_lua_file_read},
+ {"file_getline", grub_lua_file_getline},
+ {"file_getsize", grub_lua_file_getsize},
+ {"file_getpos", grub_lua_file_getpos},
+ {"file_eof", grub_lua_file_eof},
+ {"file_exist", grub_lua_file_exist},
+ {"add_menu", grub_lua_add_menu},
{0, 0}
};
diff --git a/script/lua/grub_lua.h b/script/lua/grub_lua.h
index a181b52..d5181f1 100644
--- a/script/lua/grub_lua.h
+++ b/script/lua/grub_lua.h
@@ -77,26 +77,28 @@ iscntrl (int c)
}
static inline int
-strcspn(const char *s1, const char *s2)
+isupper (int c)
{
- int size = 0;
-
- while (*s1)
- {
- const char *p = s2;
+ return ((c >= 'A') && (c <= 'Z'));
+}
- while (*p)
- {
- if (*s1 == *p)
- return size;
- p++;
- }
+static inline int
+islower (int c)
+{
+ return ((c >= 'a') && (c <= 'z'));
+}
- s1++;
- size++;
- }
+static inline int
+ispunct (int c)
+{
+ return ((! isspace (c)) && (! isalnum (c)));
+}
- return size;
+static inline int
+isxdigit (int c)
+{
+ return (isdigit (c) || ((c >= 'a') && (c <= 'f')) ||
+ ((c >= 'A') && (c <= 'F')));
}
static inline int
@@ -105,4 +107,8 @@ abs (int c)
return (c >= 0) ? : -c;
}
+int strcspn (const char *s1, const char *s2);
+char *strpbrk (const char *s1, const char *s2);
+void *memchr (const void *s, int c, size_t n);
+
#endif
diff --git a/script/lua/grub_main.c b/script/lua/grub_main.c
index 03f890a..b39141f 100644
--- a/script/lua/grub_main.c
+++ b/script/lua/grub_main.c
@@ -24,6 +24,61 @@
#include <grub/dl.h>
#include <grub/parser.h>
+static const char *
+scan_str (const char *s1, const char *s2)
+{
+ while (*s1)
+ {
+ const char *p = s2;
+
+ while (*p)
+ {
+ if (*s1 == *p)
+ return s1;
+ p++;
+ }
+
+ s1++;
+ }
+
+ return s1;
+}
+
+int
+strcspn (const char *s1, const char *s2)
+{
+ const char *r;
+
+ r = scan_str (s1, s2);
+ return r - s1;
+}
+
+char *
+strpbrk (const char *s1, const char *s2)
+{
+ const char *r;
+
+ r = scan_str (s1, s2);
+ return (*r) ? (char *) r : 0;
+}
+
+void *
+memchr (const void *s, int c, size_t n)
+{
+ const unsigned char *p = s;
+
+ while (n)
+ {
+ if (*p == c)
+ return (void *) p;
+
+ n--;
+ p++;
+ }
+
+ return 0;
+}
+
static lua_State *state;
/* Call `grub_error' to report a Lua error. The error message string must be
diff --git a/script/lua/linit.c b/script/lua/linit.c
index d034a2f..f920a0b 100644
--- a/script/lua/linit.c
+++ b/script/lua/linit.c
@@ -20,7 +20,7 @@ static const luaL_Reg lualibs[] = {
{LUA_TABLIBNAME, luaopen_table},
// {LUA_IOLIBNAME, luaopen_io},
// {LUA_OSLIBNAME, luaopen_os},
-// {LUA_STRLIBNAME, luaopen_string},
+ {LUA_STRLIBNAME, luaopen_string},
// {LUA_MATHLIBNAME, luaopen_math},
// {LUA_DBLIBNAME, luaopen_debug},
{NULL, NULL}
osdetect.gz
Description: GNU Zip compressed data
_______________________________________________ Grub-devel mailing list [email protected] http://lists.gnu.org/mailman/listinfo/grub-devel
