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

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.