lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I would like to propose here a small series of 4 patches that can
improve life for Lua developers and users alike.

[1/4] Add -u flag to interpreter. Forces unbuffered standard streams.
This idea is calqued from the Python interpreter's own -u flag of the
same purpose and implementation, and is useful for prompt output in
situations where a Lua script's output is executed in a batch context
and/or its output piped into another program. In that case Glibc
automatically decides to buffer by blocks, making the output fail to
appear promptly (or at all, should the program be killed).

Although this can be solved by :setvbuf("no"), much as in Python it's
very handy to have that as a single-letter flag.

--- a/lua.c
+++ b/lua.c
@@ -265,6 +265,8 @@ static int handle_script (lua_State *L, char **argv) {
 #define has_v          4       /* -v */
 #define has_e          8       /* -e */
 #define has_E          16      /* -E */
+#define has_W          32      /* -W */
+#define has_u          64      /* -u */


 /*
@@ -305,6 +307,12 @@ static int collectargs (char **argv, int *first) {
       case 'W':
         if (argv[i][2] != '\0')  /* extra characters? */
           return has_error;  /* invalid option */
+        args |= has_W;
+        break;
+      case 'u':
+        if (argv[i][2] != '\0')  /* extra characters? */
+          return has_error;  /* invalid option */
+        args |= has_u;
         break;
       case 'i':
         args |= has_i;  /* (-i implies -v) *//* FALLTHROUGH */
@@ -625,6 +633,11 @@ static int pmain (lua_State *L) {
     print_usage(argv[script]);  /* 'script' has index of bad arg. */
     return 0;
   }
+  if (args & has_u) {  /* option '-u'? */
+    setbuf(stdin,  (char *)NULL);
+    setbuf(stdout, (char *)NULL);
+    setbuf(stderr, (char *)NULL);
+  }
   if (args & has_v)  /* option '-v'? */
     print_version();
   if (args & has_E) {  /* option '-E'? */
diff --git a/manual/manual.of b/manual/manual.of
index 15f207fa..c0ca5cbc 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -8931,6 +8931,7 @@ The options are:
 @item{@T{-v}| print version information;}
 @item{@T{-E}| ignore environment variables;}
 @item{@T{-W}| turn warnings on;}
+@item{@T{-u}| force standard streams to be unbuffered;}
 @item{@T{--}| stop handling options;}
 @item{@T{-}| execute @id{stdin} as a file and stop handling options.}
 }



[2/4] Allow renaming main() function of Lua interpreter. In case Lua
is embedded within a larger program, the following allows redefining
the C function name main() to something else through the preprocessor.
One useful application of this is to combine lua and luac in one
binary that dispatches on argv[0]. This is generally smaller than lua
and luac separately due to code sharing.


--- a/lua.c
+++ b/lua.c
@@ -671,7 +671,10 @@ static int pmain (lua_State *L) {
 }


-int main (int argc, char **argv) {
+#ifndef main_lua
+#define main_lua main
+#endif
+int main_lua (int argc, char **argv) {
   int status, result;
   lua_State *L = luaL_newstate();  /* create state */
   if (L == NULL) {


[3/4] Put one searcher per line. Although this appears purely
cosmetic, this array is an obvious target for patching, and currently
requires a +1-1 diff even for an addition. By spreading the array one
entry per line, an addition at any position in the array can be made
with a +1 diff only, reducing the chance of conflicts.


--- a/loadlib.c
+++ b/loadlib.c
@@ -708,8 +708,13 @@ static const luaL_Reg ll_funcs[] = {


 static void createsearcherstable (lua_State *L) {
-  static const lua_CFunction searchers[] =
-    {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
+  static const lua_CFunction searchers[] = {
+    searcher_preload,
+    searcher_Lua,
+    searcher_C,
+    searcher_Croot,
+    NULL
+  };
   int i;
   /* create 'searchers' table */
   lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);


[4/4] Add a dummy static searcher, and its entry in the searcher table
modified according to patch 3. This reduces the size of a diff that
adds statically-linked packages, and serves as a constructive example
of adding a new searcher.


--- a/loadlib.c
+++ b/loadlib.c
@@ -621,6 +621,12 @@ static int searcher_preload (lua_State *L) {
 }


+static int searcher_static (lua_State* L) {
+  const char *name = luaL_checkstring(L, 1);
+  lua_pushfstring(L, "no module '%s' statically linked in", name);
+  return 1;
+}
+
 static void findloader (lua_State *L, const char *name) {
   int i;
   luaL_Buffer msg;  /* to build error message */
@@ -710,6 +716,7 @@ static const luaL_Reg ll_funcs[] = {
 static void createsearcherstable (lua_State *L) {
   static const lua_CFunction searchers[] = {
     searcher_preload,
+    searcher_static,
     searcher_Lua,
     searcher_C,
     searcher_Croot,


Any of these patches can be applied independently (except that 4/4
currently depends on 3/4, though not critically). I would be extremely
grateful if they could be applied in mainline Lua.


Sincerely,


Olexa Bilaniuk