All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] File access library for lua
@ 2009-06-21 11:33 Bean
  2009-06-22  0:42 ` Pavel Roskin
  0 siblings, 1 reply; 31+ messages in thread
From: Bean @ 2009-06-21 11:33 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 1065 bytes --]

Hi,

I've added a few function in the lua grub library to access files:

enum_device - enumerate devices
enum_file - enumerate files
file_open - open file
file_close - close file
file_seek - seek file
file_read - read n bytes
file_getline - read a line
file_getsize - get file size
file_getpos - get current read position

Here is an example:

#!lua

function enum_device (name)
  print (name)
  return 0
end

function enum_file (name, is_dir)
  print (is_dir, name)
  return 0
end

grub.enum_device (enum_device)
grub.enum_file ("/boot/grub", enum_file)
f = grub.file_open ("/boot/grub/grub.cfg")
print (grub.file_getsize (f))
print (grub.file_getline (f))
print (grub.file_getline (f))
print (grub.file_seek (f, 0))
print (grub.file_read (f, 10))
print (grub.file_getpos (f))
grub.file_close (f);

And now after file operation, the result is saved in global variable
grub_errno and grub_errmsg (lua variable), for example:
f = grub.file_open ("/abcde")
if (f == nil) then
  print (grub_errno, grub_errmsg)
fi

I also enable the string library from lua.

-- 
Bean

[-- Attachment #2: lua_file.diff --]
[-- Type: text/x-diff, Size: 9256 bytes --]

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..f3c8812 100644
--- a/script/lua/grub_lib.c
+++ b/script/lua/grub_lib.c
@@ -24,13 +24,43 @@
 #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;
@@ -50,15 +80,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
@@ -99,10 +121,236 @@ 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;
+
+    lua_pushvalue (state, -1);
+    lua_pushstring (state, name);
+    lua_call (state, 1, 1);
+    result = lua_tointeger (state, -1);
+    lua_pop (state, 1);
+
+    return result;
+  }
+
+  if (lua_gettop (state) != 1)
+    return 0;
+
+  grub_device_iterate (enum_device);
+  return push_result (state);
+}
+
+static int
+grub_lua_enum_file (lua_State *state)
+{
+
+  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;
+  }
+
+  if (lua_gettop (state) != 2)
+    return 0;
+  else
+    {
+      char *device_name, *arg;
+      grub_device_t dev;
+
+      arg = (char *) lua_tostring (state, 1);
+      device_name = grub_file_get_device_name (arg);
+      dev = grub_device_open (device_name);
+      if (dev)
+	{
+	  grub_fs_t fs;
+	  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;
+
+  if (lua_gettop(state) != 1)
+    return 0;
+
+  name = lua_tostring (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;
+
+  if (lua_gettop(state) != 1)
+    return 0;
+
+  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;
+
+  if (lua_gettop(state) != 2)
+    return 0;
+
+  file = lua_touserdata (state, 1);
+  offset = lua_tointeger (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;
+
+  if (lua_gettop(state) != 2)
+    return 0;
+
+  file = lua_touserdata (state, 1);
+  n = lua_tointeger (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;
+
+  if (lua_gettop(state) != 1)
+    return 0;
+
+  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;
+
+  if (lua_gettop(state) != 1)
+    return 0;
+
+  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;
+
+  if (lua_gettop(state) != 1)
+    return 0;
+
+  file = lua_touserdata (state, 1);
+
+  lua_pushinteger (state, file->offset);
+  return 1;
+}
+
 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},
     {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..b6d496d 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}

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-21 11:33 [PATCH] File access library for lua Bean
@ 2009-06-22  0:42 ` Pavel Roskin
  2009-06-22  3:38   ` Bean
  0 siblings, 1 reply; 31+ messages in thread
From: Pavel Roskin @ 2009-06-22  0:42 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2009-06-21 at 19:33 +0800, Bean wrote:

> I've added a few function in the lua grub library to access files:
...
> I also enable the string library from lua.

The patch doesn't introduce any compiler warnings, and that's good.

It makes lua.mod bigger by about 10%, but it's very little compared to
the added functionality.

Please don't add trailing whitespace.  STGit detects it in two places.

There are several cases of missing spaces before parentheses.

We probably need NESTED_FUNC_ATTR in the dir definition in struct
grub_fs, as it takes two arguments.  But is a separate issue.

I'm feeling uneasy about having a parser in GRUB that is not used by
default, but it's not related to the quality of the patch.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22  0:42 ` Pavel Roskin
@ 2009-06-22  3:38   ` Bean
  2009-06-22  3:45     ` Pavel Roskin
  2009-06-22  9:44     ` Robert Millan
  0 siblings, 2 replies; 31+ messages in thread
From: Bean @ 2009-06-22  3:38 UTC (permalink / raw)
  To: The development of GRUB 2

Hi,

On Mon, Jun 22, 2009 at 8:42 AM, Pavel Roskin<proski@gnu.org> wrote:
> On Sun, 2009-06-21 at 19:33 +0800, Bean wrote:
>
>> I've added a few function in the lua grub library to access files:
> ...
>> I also enable the string library from lua.
>
> The patch doesn't introduce any compiler warnings, and that's good.
>
> It makes lua.mod bigger by about 10%, but it's very little compared to
> the added functionality.

This is probably due to the enable of string library, the file access
function itself should be quite small.

>
> Please don't add trailing whitespace.  STGit detects it in two places.
>
> There are several cases of missing spaces before parentheses.
>
> We probably need NESTED_FUNC_ATTR in the dir definition in struct
> grub_fs, as it takes two arguments.  But is a separate issue.
>
> I'm feeling uneasy about having a parser in GRUB that is not used by
> default, but it's not related to the quality of the patch.

Actually, this is about to change. The file function here can be used
in a script osdetect.lua to generate menu items at runtime, and I also
plans to integrate lua with menu viewer.

>
> --
> Regards,
> Pavel Roskin
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Bean



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22  3:38   ` Bean
@ 2009-06-22  3:45     ` Pavel Roskin
  2009-06-22  9:44     ` Robert Millan
  1 sibling, 0 replies; 31+ messages in thread
From: Pavel Roskin @ 2009-06-22  3:45 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2009-06-22 at 11:38 +0800, Bean wrote:

> Actually, this is about to change. The file function here can be used
> in a script osdetect.lua to generate menu items at runtime, and I also
> plans to integrate lua with menu viewer.

OK, that sounds interesting!

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22  3:38   ` Bean
  2009-06-22  3:45     ` Pavel Roskin
@ 2009-06-22  9:44     ` Robert Millan
  2009-06-22 10:26       ` Bean
  1 sibling, 1 reply; 31+ messages in thread
From: Robert Millan @ 2009-06-22  9:44 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 11:38:35AM +0800, Bean wrote:
> >
> > I'm feeling uneasy about having a parser in GRUB that is not used by
> > default, but it's not related to the quality of the patch.
> 
> Actually, this is about to change.

I don't mind LUA being supported if it's useful for some users, but I'm
not satisfied with ditching GRUB scripting engine with something external.

We really should discuss it with Marco or Okuji before changing the
default parser to something else.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22  9:44     ` Robert Millan
@ 2009-06-22 10:26       ` Bean
  2009-06-22 10:59         ` Robert Millan
  0 siblings, 1 reply; 31+ messages in thread
From: Bean @ 2009-06-22 10:26 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 5:44 PM, Robert Millan<rmh@aybabtu.com> wrote:
> On Mon, Jun 22, 2009 at 11:38:35AM +0800, Bean wrote:
>> >
>> > I'm feeling uneasy about having a parser in GRUB that is not used by
>> > default, but it's not related to the quality of the patch.
>>
>> Actually, this is about to change.
>
> I don't mind LUA being supported if it's useful for some users, but I'm
> not satisfied with ditching GRUB scripting engine with something external.
>
> We really should discuss it with Marco or Okuji before changing the
> default parser to something else.

Hi,

No need to change the default parser, with the #! syntax, we can call
the lua script from main grub.cfg, and the parser will switch back to
sh on return, something like this:

grub.cfg:
source osdetect.lua
...

osdetect.lua:
#!lua
...

>
> --
> Robert Millan
>
>  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
>  how) you may access your data; but nobody's threatening your freedom: we
>  still allow you to remove your data and not access it at all."
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Bean



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 10:26       ` Bean
@ 2009-06-22 10:59         ` Robert Millan
  2009-06-22 17:37           ` Bean
  0 siblings, 1 reply; 31+ messages in thread
From: Robert Millan @ 2009-06-22 10:59 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 06:26:02PM +0800, Bean wrote:
> On Mon, Jun 22, 2009 at 5:44 PM, Robert Millan<rmh@aybabtu.com> wrote:
> > On Mon, Jun 22, 2009 at 11:38:35AM +0800, Bean wrote:
> >> >
> >> > I'm feeling uneasy about having a parser in GRUB that is not used by
> >> > default, but it's not related to the quality of the patch.
> >>
> >> Actually, this is about to change.
> >
> > I don't mind LUA being supported if it's useful for some users, but I'm
> > not satisfied with ditching GRUB scripting engine with something external.
> >
> > We really should discuss it with Marco or Okuji before changing the
> > default parser to something else.
> 
> Hi,
> 
> No need to change the default parser, with the #! syntax, we can call
> the lua script from main grub.cfg, and the parser will switch back to
> sh on return, something like this:

Ok, that's nice.  I was more thinking about our grub.cfg-generation scripts
though.  I think those should stay with the current parser.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 10:59         ` Robert Millan
@ 2009-06-22 17:37           ` Bean
  2009-06-22 18:31             ` Pavel Roskin
  2009-07-31  8:07             ` Marco Gerards
  0 siblings, 2 replies; 31+ messages in thread
From: Bean @ 2009-06-22 17:37 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 506 bytes --]

Hi,

Update for this patch:

1, enum_device now pass fs and uuid as well
2, enum_file change parameter order, now the callback function is the
first, path is the second
3, add parameter checking for library function
4, add three function

file_eof - test if eof is encounter for a file
file_exist - test if a file exists
add_menu - add menu item

I also add a script osdetect.lua which can detect Windows
2K/NT/XP/Vista and linux at runtime, to use it, add this in grub.cfg:

source osdetect.lua

-- 
Bean

[-- Attachment #2: lua_file_2.diff --]
[-- Type: text/x-patch, Size: 14857 bytes --]

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..8561dd0 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,322 @@ 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);
+	  }
+	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)
+{
+  grub_file_t file;
+  const char *name;
+  int result;
+
+  name = luaL_checkstring (state, 1);
+  file = grub_file_open (name);
+  if (file)
+    {
+      result = 1;
+      grub_file_close (file);
+    }
+  else
+    {
+      result = 0;
+      grub_errno = 0;
+    }
+
+  lua_pushboolean (state, result);
+  return 1;
+}
+
+static int
+grub_lua_add_menu (lua_State *state)
+{   
+  int len, n;
+  const char *source;
+
+  source = luaL_checklstring (state, 1, &len);
+  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}
diff --git a/util/osdetect.lua b/util/osdetect.lua
new file mode 100644
index 0000000..ff6b613
--- /dev/null
+++ b/util/osdetect.lua
@@ -0,0 +1,84 @@
+#!lua
+--
+-- Copyright (C) 2009  Free Software Foundation, Inc.
+--
+-- GRUB is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- GRUB is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+--
+
+function enum_device (device, fs, uuid)
+  local root
+  local title
+  local source
+  local kernels = {}
+  local kernel_num = 0
+
+  local function enum_file (name)
+    local version
+
+    version = string.match (name, "vmlinuz%-(.*)")
+    if (version ~= nil) then
+      table.insert (kernels, version)
+      kernel_num = kernel_num + 1
+    end
+  end
+
+  local function sort_kernel (first, second)
+    local a1, a2, a3, a4, b1, b2, b3, b4
+    
+    a1, a2, a3, a4 = string.match (first, "(%d+)%.?(%d*).?(%d*)%-?(%d*)")
+    b1, b2, b3, b4 = string.match (second, "(%d+)%.?(%d*).?(%d*)%-?(%d*)")
+    return (a1 > b1) or (a2 > b2) or (a3 > b3) or (a4 > b4);
+  end
+
+  root = "(" .. device .. ")/"
+  source = "root " .. device .. "\nchainloader +1"
+  title = "Other OS"
+  if (grub.file_exist (root .. "bootmgr") and
+      grub.file_exist (root .. "boot/bcd")) then
+    title = "Windows Vista bootmgr"
+  elseif (grub.file_exist (root .. "ntldr") and
+          grub.file_exist (root .. "ntdetect.com") and
+          grub.file_exist (root .. "boot.ini")) then
+    title = "Windows NT/2000/XP loader"
+  else
+    grub.enum_file (enum_file, root .. "boot")
+    if kernel_num ~= 0 then
+      table.sort (kernels, sort_kernel)
+      for i = 1, kernel_num do
+	local initrd
+
+	title = "linux " .. kernels[i]
+	source = "root " .. device ..
+	  "\nlinux /boot/vmlinuz-" .. kernels[i] ..
+	  " root=UUID=" .. uuid .. " ro"
+
+	if grub.file_exist (root .. "boot/initrd.img-" .. kernels[i]) then
+	  initrd = "\ninird /boot/initrd.img-" .. kernels[i]
+	else
+	  initrd = ""
+	end
+
+	grub.add_menu (source .. initrd, title)
+	grub.add_menu (source .. " single" .. initrd,
+	               title .. " (single-user mode)")
+      end
+      return 0
+    end    
+  end
+
+  grub.add_menu (source, title)
+  return 0
+end
+
+grub.enum_device (enum_device)

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 17:37           ` Bean
@ 2009-06-22 18:31             ` Pavel Roskin
  2009-06-22 18:49               ` Bean
  2009-07-31  8:07             ` Marco Gerards
  1 sibling, 1 reply; 31+ messages in thread
From: Pavel Roskin @ 2009-06-22 18:31 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, 2009-06-23 at 01:37 +0800, Bean wrote:
> Hi,
> 
> Update for this patch:
> 
> 1, enum_device now pass fs and uuid as well
> 2, enum_file change parameter order, now the callback function is the
> first, path is the second
> 3, add parameter checking for library function
> 4, add three function
> 
> file_eof - test if eof is encounter for a file
> file_exist - test if a file exists
> add_menu - add menu item

The new patch introduces a warning:

script/lua/grub_lib.c: In function 'grub_lua_add_menu':
script/lua/grub_lib.c:394: warning: pointer targets in passing argument
3 of 'luaL_checklstring' differ in signedness
script/lua/lauxlib.h:51: note: expected 'size_t *' but argument is of
type 'int *'

Fix:

diff --git a/script/lua/grub_lib.c b/script/lua/grub_lib.c
index 8561dd0..bcff3db 100644
--- a/script/lua/grub_lib.c
+++ b/script/lua/grub_lib.c
@@ -388,7 +388,8 @@ grub_lua_file_exist (lua_State *state)
 static int
 grub_lua_add_menu (lua_State *state)
 {   
-  int len, n;
+  int n;
+  size_t len;
   const char *source;
 
   source = luaL_checklstring (state, 1, &len);

> I also add a script osdetect.lua which can detect Windows
> 2K/NT/XP/Vista and linux at runtime, to use it, add this in grub.cfg:
> 
> source osdetect.lua

It didn't find Linux for me, but it found the "Other OS", which is
actually FreeDOS.

-- 
Regards,
Pavel Roskin



^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 18:31             ` Pavel Roskin
@ 2009-06-22 18:49               ` Bean
  2009-06-22 18:59                 ` Pavel Roskin
  0 siblings, 1 reply; 31+ messages in thread
From: Bean @ 2009-06-22 18:49 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, Jun 23, 2009 at 2:31 AM, Pavel Roskin<proski@gnu.org> wrote:
> On Tue, 2009-06-23 at 01:37 +0800, Bean wrote:
>> Hi,
>>
>> Update for this patch:
>>
>> 1, enum_device now pass fs and uuid as well
>> 2, enum_file change parameter order, now the callback function is the
>> first, path is the second
>> 3, add parameter checking for library function
>> 4, add three function
>>
>> file_eof - test if eof is encounter for a file
>> file_exist - test if a file exists
>> add_menu - add menu item
>
> The new patch introduces a warning:
>
> script/lua/grub_lib.c: In function 'grub_lua_add_menu':
> script/lua/grub_lib.c:394: warning: pointer targets in passing argument
> 3 of 'luaL_checklstring' differ in signedness
> script/lua/lauxlib.h:51: note: expected 'size_t *' but argument is of
> type 'int *'
>
> Fix:
>
> diff --git a/script/lua/grub_lib.c b/script/lua/grub_lib.c
> index 8561dd0..bcff3db 100644
> --- a/script/lua/grub_lib.c
> +++ b/script/lua/grub_lib.c
> @@ -388,7 +388,8 @@ grub_lua_file_exist (lua_State *state)
>  static int
>  grub_lua_add_menu (lua_State *state)
>  {
> -  int len, n;
> +  int n;
> +  size_t len;
>   const char *source;
>
>   source = luaL_checklstring (state, 1, &len);
>
>> I also add a script osdetect.lua which can detect Windows
>> 2K/NT/XP/Vista and linux at runtime, to use it, add this in grub.cfg:
>>
>> source osdetect.lua
>
> It didn't find Linux for me, but it found the "Other OS", which is
> actually FreeDOS.

What's the name of kernel and initrd.img ?

>
> --
> Regards,
> Pavel Roskin
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Bean



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 18:49               ` Bean
@ 2009-06-22 18:59                 ` Pavel Roskin
  2009-06-22 19:15                   ` Bean
  0 siblings, 1 reply; 31+ messages in thread
From: Pavel Roskin @ 2009-06-22 18:59 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, 2009-06-23 at 02:49 +0800, Bean wrote:

> What's the name of kernel and initrd.img ?

vmlinuz-2.6.30-wl and initrd-2.6.30-wl.img

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 18:59                 ` Pavel Roskin
@ 2009-06-22 19:15                   ` Bean
  2009-06-22 19:28                     ` Pavel Roskin
  0 siblings, 1 reply; 31+ messages in thread
From: Bean @ 2009-06-22 19:15 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 455 bytes --]

On Tue, Jun 23, 2009 at 2:59 AM, Pavel Roskin<proski@gnu.org> wrote:
> On Tue, 2009-06-23 at 02:49 +0800, Bean wrote:
>
>> What's the name of kernel and initrd.img ?
>
> vmlinuz-2.6.30-wl and initrd-2.6.30-wl.img

Hi,

Oh, find the bug now, try this one.

>
> --
> Regards,
> Pavel Roskin
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Bean

[-- Attachment #2: lua_file_2.diff --]
[-- Type: text/x-patch, Size: 15071 bytes --]

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..7f738c9 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,324 @@ 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)
+{
+  grub_file_t file;
+  const char *name;
+  int result;
+
+  name = luaL_checkstring (state, 1);
+  file = grub_file_open (name);
+  if (file)
+    {
+      result = 1;
+      grub_file_close (file);
+    }
+  else
+    {
+      result = 0;
+      grub_errno = 0;
+    }
+
+  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}
diff --git a/util/osdetect.lua b/util/osdetect.lua
new file mode 100644
index 0000000..af1d491
--- /dev/null
+++ b/util/osdetect.lua
@@ -0,0 +1,94 @@
+#!lua
+--
+-- Copyright (C) 2009  Free Software Foundation, Inc.
+--
+-- GRUB is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- GRUB is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+--
+
+function enum_device (device, fs, uuid)
+  local root
+  local title
+  local source
+  local kernels = {}
+  local kernel_num = 0
+
+  local function enum_file (name)
+    local version
+
+    version = string.match (name, "vmlinuz%-(.*)")
+    if (version ~= nil) then
+      table.insert (kernels, version)
+      kernel_num = kernel_num + 1
+    end
+  end
+
+  local function sort_kernel (first, second)
+    local a1, a2, a3, a4, b1, b2, b3, b4
+    
+    a1, a2, a3, a4 = string.match (first, "(%d+)%.?(%d*).?(%d*)%-?(%d*)")
+    b1, b2, b3, b4 = string.match (second, "(%d+)%.?(%d*).?(%d*)%-?(%d*)")
+    return (a1 > b1) or (a2 > b2) or (a3 > b3) or (a4 > b4);
+  end
+
+  root = "(" .. device .. ")/"
+  source = "root " .. device .. "\nchainloader +1"
+  title = nil
+  if (grub.file_exist (root .. "bootmgr") and
+      grub.file_exist (root .. "boot/bcd")) then
+    title = "Windows Vista bootmgr"
+  elseif (grub.file_exist (root .. "ntldr") and
+          grub.file_exist (root .. "ntdetect.com") and
+          grub.file_exist (root .. "boot.ini")) then
+    title = "Windows NT/2000/XP loader"
+  else
+    grub.enum_file (enum_file, root .. "boot")
+    if kernel_num ~= 0 then
+      table.sort (kernels, sort_kernel)
+      for i = 1, kernel_num do
+	local initrd
+
+	title = "linux " .. kernels[i]
+	source = "root " .. device ..
+	  "\nlinux /boot/vmlinuz-" .. kernels[i] ..
+	  " root=UUID=" .. uuid .. " ro"
+
+	if grub.file_exist (root .. "boot/initrd.img-" .. kernels[i]) then
+	  initrd = "\ninird /boot/initrd.img-" .. kernels[i]
+	else
+	  initrd = ""
+	end
+
+	grub.add_menu (source .. initrd, title)
+	grub.add_menu (source .. " single" .. initrd,
+	               title .. " (single-user mode)")
+      end
+      return 0
+    end
+  end
+
+  if title == nil then
+    local partition = string.match (device, ".*,(%d+)")
+
+    if (partition ~= nil) and (tonumber (partition) > 4) then
+      return 0
+    end
+
+    title = "Other OS"
+  end
+
+  grub.add_menu (source, title)
+  return 0
+end
+
+grub.enum_device (enum_device)

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 19:15                   ` Bean
@ 2009-06-22 19:28                     ` Pavel Roskin
  2009-06-22 19:50                       ` Bean
  0 siblings, 1 reply; 31+ messages in thread
From: Pavel Roskin @ 2009-06-22 19:28 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, 2009-06-23 at 03:15 +0800, Bean wrote:

> Oh, find the bug now, try this one.

This one fails to find anything:

sh:grub> source /boot/grub/osdetect.lua
error: Lua: grub:1: attempt to call field 'enum_device' (a nil value)
sh:grub>

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 19:28                     ` Pavel Roskin
@ 2009-06-22 19:50                       ` Bean
  2009-06-22 20:06                         ` Pavel Roskin
  0 siblings, 1 reply; 31+ messages in thread
From: Bean @ 2009-06-22 19:50 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, Jun 23, 2009 at 3:28 AM, Pavel Roskin<proski@gnu.org> wrote:
> On Tue, 2009-06-23 at 03:15 +0800, Bean wrote:
>
>> Oh, find the bug now, try this one.
>
> This one fails to find anything:
>
> sh:grub> source /boot/grub/osdetect.lua
> error: Lua: grub:1: attempt to call field 'enum_device' (a nil value)
> sh:grub>

Hi,

strange, it's working here, what's the device list ?

>
> --
> Regards,
> Pavel Roskin
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Bean



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 19:50                       ` Bean
@ 2009-06-22 20:06                         ` Pavel Roskin
  2009-06-23  9:27                           ` Bean
  2009-06-25 22:39                           ` Vladimir 'phcoder' Serbinenko
  0 siblings, 2 replies; 31+ messages in thread
From: Pavel Roskin @ 2009-06-22 20:06 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, 2009-06-23 at 03:50 +0800, Bean wrote:

> strange, it's working here, what's the device list ?

My mistake.  I installed an unpatched GRUB.

The entries are created now.  However, the initrd is not picked up.  The
old kernel (vmlinuz-2.6.30-wl.old) goes before the new one
(vmlinuz-2.6.30-wl).  And most importantly, the syntax for the root
command is wrong.

"root hd0,3" has not effect.  "root (hd0,3)" and "root=hd0,3" work.
Yes, that's a bug in the root command.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 20:06                         ` Pavel Roskin
@ 2009-06-23  9:27                           ` Bean
  2009-06-23 22:10                             ` Pavel Roskin
  2009-06-25 22:39                           ` Vladimir 'phcoder' Serbinenko
  1 sibling, 1 reply; 31+ messages in thread
From: Bean @ 2009-06-23  9:27 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 1015 bytes --]

Hi,

Some bug fix for osdetect.lua, it also detect windows 98/me, freedos,
msdos and freebsd.

Extend the function of grub.file_exist to allow testing multiple names
at the same time, this simplify osdetect.lua.

On Tue, Jun 23, 2009 at 4:06 AM, Pavel Roskin<proski@gnu.org> wrote:
> On Tue, 2009-06-23 at 03:50 +0800, Bean wrote:
>
>> strange, it's working here, what's the device list ?
>
> My mistake.  I installed an unpatched GRUB.
>
> The entries are created now.  However, the initrd is not picked up.  The
> old kernel (vmlinuz-2.6.30-wl.old) goes before the new one
> (vmlinuz-2.6.30-wl).  And most importantly, the syntax for the root
> command is wrong.
>
> "root hd0,3" has not effect.  "root (hd0,3)" and "root=hd0,3" work.
> Yes, that's a bug in the root command.
>
> --
> Regards,
> Pavel Roskin
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Bean

[-- Attachment #2: lua_file_3.diff --]
[-- Type: text/x-diff, Size: 15646 bytes --]

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}
diff --git a/util/osdetect.lua b/util/osdetect.lua
new file mode 100644
index 0000000..33d86d7
--- /dev/null
+++ b/util/osdetect.lua
@@ -0,0 +1,105 @@
+#!lua
+--
+-- Copyright (C) 2009  Free Software Foundation, Inc.
+--
+-- GRUB is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- GRUB is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+--
+
+function enum_device (device, fs, uuid)
+  local roo
+  local title
+  local source
+  local kernels = {}
+  local kernel_num = 0
+
+  local function enum_file (name)
+    local version
+
+    version = string.match (name, "vmlinuz%-(.*)")
+    if (version ~= nil) then
+      table.insert (kernels, version)
+      kernel_num = kernel_num + 1
+    end
+  end
+
+  local function sort_kernel (first, second)
+    local a1, a2, a3, a4, b1, b2, b3, b4
+
+    a1, a2, a3, a4 = string.match (first, "(%d+)%.?(%d*).?(%d*)%-?(%d*)")
+    b1, b2, b3, b4 = string.match (second, "(%d+)%.?(%d*).?(%d*)%-?(%d*)")
+    return (a1 > b1) or (a2 > b2) or (a3 > b3) or (a4 < b4);
+  end
+
+  root = "(" .. device .. ")/"
+  source = "root (" .. device .. ")\nchainloader +1"
+  title = nil
+  if grub.file_exist (root .. "bootmgr", root .. "boot/bcd") then
+    title = "Windows Vista bootmgr"
+  elseif grub.file_exist (root .. "ntldr", root .. "ntdetect.com",
+			  root .. "boot.ini") then
+    title = "Windows NT/2000/XP loader"
+  elseif grub.file_exist (root .. "windows/win.com") then
+    title = "Windows 98/ME"
+  elseif grub.file_exist (root .. "io.sys", root .. "command.com") then
+    title = "MSDOS"
+  elseif grub.file_exist (root .. "kernel.sys") then
+    title = "FressDOS"
+  elseif grub.file_exist (root .. "boot/loader",
+			  root .. "boot/devices.hints") then
+    source = "root (" .. device .. ")\nfreebsd /boot/loader" ..
+      "\nfreebsd_loadenv /boot/device.hints"
+    title = "FressBSD"
+  else
+    grub.enum_file (enum_file, root .. "boot")
+    if kernel_num ~= 0 then
+      table.sort (kernels, sort_kernel)
+      for i = 1, kernel_num do
+	local initrd
+
+	title = "linux " .. kernels[i]
+	source = "root (" .. device ..
+	  ")\nlinux /boot/vmlinuz-" .. kernels[i] ..
+	  " root=UUID=" .. uuid .. " ro"
+
+	if grub.file_exist (root .. "boot/initrd.img-" .. kernels[i]) then
+	  initrd = "\ninird /boot/initrd.img-" .. kernels[i]
+	elseif grub.file_exist (root .. "boot/initrd-" .. kernels[i]) then
+	  initrd = "\ninird /boot/initrd-" .. kernels[i]
+	else
+	  initrd = ""
+	end
+
+	grub.add_menu (source .. initrd, title)
+	grub.add_menu (source .. " single" .. initrd,
+	               title .. " (single-user mode)")
+      end
+      return 0
+    end
+  end
+
+  if title == nil then
+    local partition = string.match (device, ".*,(%d+)")
+
+    if (partition ~= nil) and (tonumber (partition) > 4) then
+      return 0
+    end
+
+    title = "Other OS"
+  end
+
+  grub.add_menu (source, title)
+  return 0
+end
+
+grub.enum_device (enum_device)

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-23  9:27                           ` Bean
@ 2009-06-23 22:10                             ` Pavel Roskin
  2009-06-23 22:50                               ` Robert Millan
  2009-06-24  4:41                               ` Bean
  0 siblings, 2 replies; 31+ messages in thread
From: Pavel Roskin @ 2009-06-23 22:10 UTC (permalink / raw)
  To: The development of GRUB 2

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.

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?

> 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.

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.

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.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-23 22:10                             ` Pavel Roskin
@ 2009-06-23 22:50                               ` Robert Millan
  2009-06-26 23:25                                 ` Pavel Roskin
  2009-06-24  4:41                               ` Bean
  1 sibling, 1 reply; 31+ messages in thread
From: Robert Millan @ 2009-06-23 22:50 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, Jun 23, 2009 at 06:10:36PM -0400, Pavel Roskin 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.

But when we're booting a kernel (Linux) we just say that.  Shouldn't we
be consistent and say "bootmgr" and "ntldr" too?

Btw, to make this even more interesting, there's also freeldr, which can
be used to boot either Windows NT/2000/XP or ReactOS.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-23 22:10                             ` Pavel Roskin
  2009-06-23 22:50                               ` Robert Millan
@ 2009-06-24  4:41                               ` Bean
  2009-06-24  5:58                                 ` Bean
  2009-06-27  0:22                                 ` Pavel Roskin
  1 sibling, 2 replies; 31+ messages in thread
From: Bean @ 2009-06-24  4:41 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 2401 bytes --]

On Wed, Jun 24, 2009 at 6:10 AM, Pavel Roskin<proski@gnu.org> 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
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>

-- 
Bean

[-- Attachment #2: lua_file_3.diff --]
[-- Type: text/x-diff, Size: 12205 bytes --]

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}

[-- Attachment #3: osdetect.gz --]
[-- Type: application/x-gzip, Size: 1249 bytes --]

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-24  4:41                               ` Bean
@ 2009-06-24  5:58                                 ` Bean
  2009-06-27  0:22                                 ` Pavel Roskin
  1 sibling, 0 replies; 31+ messages in thread
From: Bean @ 2009-06-24  5:58 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 95 bytes --]

Hi,

Oh, found a small bug in the previous osdetect.lua, here is an updated version.

-- 
Bean

[-- Attachment #2: osdetect.gz --]
[-- Type: application/x-gzip, Size: 1249 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 20:06                         ` Pavel Roskin
  2009-06-23  9:27                           ` Bean
@ 2009-06-25 22:39                           ` Vladimir 'phcoder' Serbinenko
  2009-06-26 23:45                             ` Pavel Roskin
  1 sibling, 1 reply; 31+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-06-25 22:39 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 22, 2009 at 10:06 PM, Pavel Roskin<proski@gnu.org> wrote:
> On Tue, 2009-06-23 at 03:50 +0800, Bean wrote:
>
>> strange, it's working here, what's the device list ?
>
> My mistake.  I installed an unpatched GRUB.
>
> The entries are created now.  However, the initrd is not picked up.  The
> old kernel (vmlinuz-2.6.30-wl.old) goes before the new one
> (vmlinuz-2.6.30-wl).  And most importantly, the syntax for the root
> command is wrong.
>
> "root hd0,3" has not effect.  "root (hd0,3)" and "root=hd0,3" work.
> Yes, that's a bug in the root command.
Can't root command be ditched altogether? It sounds like completely
redundant to me and just taking precious kernel space
>
> --
> Regards,
> Pavel Roskin
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Regards
Vladimir 'phcoder' Serbinenko

Personal git repository: http://repo.or.cz/w/grub2/phcoder.git



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-23 22:50                               ` Robert Millan
@ 2009-06-26 23:25                                 ` Pavel Roskin
  0 siblings, 0 replies; 31+ messages in thread
From: Pavel Roskin @ 2009-06-26 23:25 UTC (permalink / raw)
  To: The development of GRUB 2

On Wed, 2009-06-24 at 00:50 +0200, Robert Millan wrote:
> On Tue, Jun 23, 2009 at 06:10:36PM -0400, Pavel Roskin 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.
> 
> But when we're booting a kernel (Linux) we just say that.  Shouldn't we
> be consistent and say "bootmgr" and "ntldr" too?

The difference is that we are using chainloader to boot Windows, so we
treat is as one system.  If we were loading ntldr from GRUB, then it
would be appropriate to mention it.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-25 22:39                           ` Vladimir 'phcoder' Serbinenko
@ 2009-06-26 23:45                             ` Pavel Roskin
  0 siblings, 0 replies; 31+ messages in thread
From: Pavel Roskin @ 2009-06-26 23:45 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, 2009-06-26 at 00:39 +0200, Vladimir 'phcoder' Serbinenko wrote:
> On Mon, Jun 22, 2009 at 10:06 PM, Pavel Roskin<proski@gnu.org> wrote:

> > "root hd0,3" has not effect.  "root (hd0,3)" and "root=hd0,3" work.
> > Yes, that's a bug in the root command.
> Can't root command be ditched altogether? It sounds like completely
> redundant to me and just taking precious kernel space

Fine with me.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-24  4:41                               ` Bean
  2009-06-24  5:58                                 ` Bean
@ 2009-06-27  0:22                                 ` Pavel Roskin
  2009-06-27  3:53                                   ` Bean
  1 sibling, 1 reply; 31+ messages in thread
From: Pavel Roskin @ 2009-06-27  0:22 UTC (permalink / raw)
  To: The development of GRUB 2

On Wed, 2009-06-24 at 12:41 +0800, Bean wrote:

> 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.

I don't think so.

> > 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.

Actually, I think SUSE uses initrd-KVER (no SUSE around, but Google
seems to confirm it), Fedora uses initrd-KVER.img and Debian uses
initrd.img-KVER, so we need to support all three.

> >> 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.

I think it's not nice to add bells and whistles to a basic function
checking existence of a file.  Imagine if libc did is, and stat() would
take a list of files.

> > 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.

Can we implement them in lua?  I think it would be better than to
implement them in C.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-27  0:22                                 ` Pavel Roskin
@ 2009-06-27  3:53                                   ` Bean
  2009-06-27  4:04                                     ` Pavel Roskin
  0 siblings, 1 reply; 31+ messages in thread
From: Bean @ 2009-06-27  3:53 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, Jun 27, 2009 at 8:22 AM, Pavel Roskin<proski@gnu.org> wrote:
> On Wed, 2009-06-24 at 12:41 +0800, Bean wrote:
>
>> 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.
>
> I don't think so.

Fine with me.

> Can we implement them in lua?  I think it would be better than to
> implement them in C.

Yes, actually it's just a bunch of file_exist AND or OR together, but
I think if we use this kind of test often enough, implement it in c
would be more efficient.


-- 
Bean



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-27  3:53                                   ` Bean
@ 2009-06-27  4:04                                     ` Pavel Roskin
  2009-06-27  4:14                                       ` Bean
  0 siblings, 1 reply; 31+ messages in thread
From: Pavel Roskin @ 2009-06-27  4:04 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, 2009-06-27 at 11:53 +0800, Bean wrote:

> Yes, actually it's just a bunch of file_exist AND or OR together, but
> I think if we use this kind of test often enough, implement it in c
> would be more efficient.

So far, we only have one file.

I checked the Lua reference manual, and no file related functions take
lists of filenames:

http://www.lua.org/manual/5.1/

If it was ineffective, I think Lua developers would have designed the
file access differently.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-27  4:04                                     ` Pavel Roskin
@ 2009-06-27  4:14                                       ` Bean
  2009-07-05  9:59                                         ` Bean
  0 siblings, 1 reply; 31+ messages in thread
From: Bean @ 2009-06-27  4:14 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, Jun 27, 2009 at 12:04 PM, Pavel Roskin<proski@gnu.org> wrote:
> On Sat, 2009-06-27 at 11:53 +0800, Bean wrote:
>
>> Yes, actually it's just a bunch of file_exist AND or OR together, but
>> I think if we use this kind of test often enough, implement it in c
>> would be more efficient.
>
> So far, we only have one file.
>
> I checked the Lua reference manual, and no file related functions take
> lists of filenames:
>
> http://www.lua.org/manual/5.1/
>
> If it was ineffective, I think Lua developers would have designed the
> file access differently.

All right then, I'd change it back to single parameter. Actually it's
not a big deal, but I just hate long lines, :)

-- 
Bean



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-27  4:14                                       ` Bean
@ 2009-07-05  9:59                                         ` Bean
  2009-07-05 13:11                                           ` Duboucher Thomas
  0 siblings, 1 reply; 31+ messages in thread
From: Bean @ 2009-07-05  9:59 UTC (permalink / raw)
  To: The development of GRUB 2

Committed.

On Sat, Jun 27, 2009 at 12:14 PM, Bean<bean123ch@gmail.com> wrote:
> On Sat, Jun 27, 2009 at 12:04 PM, Pavel Roskin<proski@gnu.org> wrote:
>> On Sat, 2009-06-27 at 11:53 +0800, Bean wrote:
>>
>>> Yes, actually it's just a bunch of file_exist AND or OR together, but
>>> I think if we use this kind of test often enough, implement it in c
>>> would be more efficient.
>>
>> So far, we only have one file.
>>
>> I checked the Lua reference manual, and no file related functions take
>> lists of filenames:
>>
>> http://www.lua.org/manual/5.1/
>>
>> If it was ineffective, I think Lua developers would have designed the
>> file access differently.
>
> All right then, I'd change it back to single parameter. Actually it's
> not a big deal, but I just hate long lines, :)
>
> --
> Bean
>



-- 
Bean



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-07-05  9:59                                         ` Bean
@ 2009-07-05 13:11                                           ` Duboucher Thomas
  2009-07-05 14:28                                             ` Bean
  0 siblings, 1 reply; 31+ messages in thread
From: Duboucher Thomas @ 2009-07-05 13:11 UTC (permalink / raw)
  To: The development of GRUB 2

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

	I was reading the code and now I have a question. You are creating a
grub librairy writen in C including useful functions such as
'grub.file_open'. But in your implementation, you removed base libraries
such as 'os' and 'io'. So why don't you just rewrite 'io.open' instead
of creating 'grub.file_open'?

	Thomas.

Bean a écrit :
> Committed.
> 
> On Sat, Jun 27, 2009 at 12:14 PM, Bean<bean123ch@gmail.com> wrote:
>> On Sat, Jun 27, 2009 at 12:04 PM, Pavel Roskin<proski@gnu.org> wrote:
>>> On Sat, 2009-06-27 at 11:53 +0800, Bean wrote:
>>>
>>>> Yes, actually it's just a bunch of file_exist AND or OR together, but
>>>> I think if we use this kind of test often enough, implement it in c
>>>> would be more efficient.
>>> So far, we only have one file.
>>>
>>> I checked the Lua reference manual, and no file related functions take
>>> lists of filenames:
>>>
>>> http://www.lua.org/manual/5.1/
>>>
>>> If it was ineffective, I think Lua developers would have designed the
>>> file access differently.
>> All right then, I'd change it back to single parameter. Actually it's
>> not a big deal, but I just hate long lines, :)
>>
>> --
>> Bean
>>
> 
> 
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkpQpmcACgkQBV7eXqefhqjZkgCfdigjl2N7DFu3xxNCLDbyMerP
AyEAoKzDcOW6ebJtdEIUcNSB9q57q64G
=fJix
-----END PGP SIGNATURE-----



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-07-05 13:11                                           ` Duboucher Thomas
@ 2009-07-05 14:28                                             ` Bean
  0 siblings, 0 replies; 31+ messages in thread
From: Bean @ 2009-07-05 14:28 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jul 5, 2009 at 9:11 PM, Duboucher Thomas<thomas@duboucher.eu> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
>        I was reading the code and now I have a question. You are creating a
> grub librairy writen in C including useful functions such as
> 'grub.file_open'. But in your implementation, you removed base libraries
> such as 'os' and 'io'. So why don't you just rewrite 'io.open' instead
> of creating 'grub.file_open'?

Hi,

The io library uses many stdio function, such as fopen, which doesn't
exist in grub.

-- 
Bean



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] File access library for lua
  2009-06-22 17:37           ` Bean
  2009-06-22 18:31             ` Pavel Roskin
@ 2009-07-31  8:07             ` Marco Gerards
  1 sibling, 0 replies; 31+ messages in thread
From: Marco Gerards @ 2009-07-31  8:07 UTC (permalink / raw)
  To: The development of GRUB 2

Bean <bean123ch@gmail.com> writes:

> Hi,
>
> Update for this patch:
>
> 1, enum_device now pass fs and uuid as well
> 2, enum_file change parameter order, now the callback function is the
> first, path is the second
> 3, add parameter checking for library function
> 4, add three function
>
> file_eof - test if eof is encounter for a file
> file_exist - test if a file exists
> add_menu - add menu item
>
> I also add a script osdetect.lua which can detect Windows
> 2K/NT/XP/Vista and linux at runtime, to use it, add this in grub.cfg:
>
> source osdetect.lua

Can you please comment on what Robert said?

Personally, I do not mind supporting lua.  But I prefer that scripts
included with GRUB are written using the default scripting language.
Some good reasons for this:

- I do not know lua, I assume Okuji doesn't either.
- Only using one script already requires the user to use lua: slowdown
- Personally, I hope people improve on the default scripting language

--
Marco




^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2009-07-31  8:07 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-21 11:33 [PATCH] File access library for lua Bean
2009-06-22  0:42 ` Pavel Roskin
2009-06-22  3:38   ` Bean
2009-06-22  3:45     ` Pavel Roskin
2009-06-22  9:44     ` Robert Millan
2009-06-22 10:26       ` Bean
2009-06-22 10:59         ` Robert Millan
2009-06-22 17:37           ` Bean
2009-06-22 18:31             ` Pavel Roskin
2009-06-22 18:49               ` Bean
2009-06-22 18:59                 ` Pavel Roskin
2009-06-22 19:15                   ` Bean
2009-06-22 19:28                     ` Pavel Roskin
2009-06-22 19:50                       ` Bean
2009-06-22 20:06                         ` Pavel Roskin
2009-06-23  9:27                           ` Bean
2009-06-23 22:10                             ` Pavel Roskin
2009-06-23 22:50                               ` Robert Millan
2009-06-26 23:25                                 ` Pavel Roskin
2009-06-24  4:41                               ` Bean
2009-06-24  5:58                                 ` Bean
2009-06-27  0:22                                 ` Pavel Roskin
2009-06-27  3:53                                   ` Bean
2009-06-27  4:04                                     ` Pavel Roskin
2009-06-27  4:14                                       ` Bean
2009-07-05  9:59                                         ` Bean
2009-07-05 13:11                                           ` Duboucher Thomas
2009-07-05 14:28                                             ` Bean
2009-06-25 22:39                           ` Vladimir 'phcoder' Serbinenko
2009-06-26 23:45                             ` Pavel Roskin
2009-07-31  8:07             ` Marco Gerards

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.