lua-users home
lua-l archive

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


Hi.

I would like to be able to redirect the lua prints.

So i added two hooks in the global state, beside the one for allocations. They allow to print standard messages and error messages. I also added some print functions to the api.

Then i changed the luai_write* macros in order to use the lua_print functions.

I join the patches for comments.

Is there any chance to have such a feature in next lua versions ?

Cheers.

Paul.
>From 7132cf203de9ba84a29d066079cf0372273bdcb7 Mon Sep 17 00:00:00 2001
From: Paul Chavent <paul.chavent@fnac.net>
Date: Sat, 26 Oct 2013 19:13:52 +0200
Subject: [PATCH 1/2] Add print function hooks (normal and error).

---
 src/lapi.c   | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lstate.c | 14 ++++++++++++++
 src/lstate.h |  4 ++++
 src/lua.h    | 12 ++++++++++++
 4 files changed, 80 insertions(+)

diff --git a/src/lapi.c b/src/lapi.c
index 791d854..7340b8b 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1172,6 +1172,56 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
 }
 
 
+LUA_API lua_Print lua_getprintf (lua_State *L, void **ud) {
+  lua_Print f;
+  lua_lock(L);
+  if (ud) *ud = G(L)->fprint_ud;
+  f = G(L)->fprint;
+  lua_unlock(L);
+  return f;
+}
+
+
+LUA_API void lua_setprintf (lua_State *L, lua_Print f, void *ud) {
+  lua_lock(L);
+  G(L)->fprint_ud = ud;
+  G(L)->fprint = f;
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_print (lua_State *L, const char * text, size_t size) {
+  lua_lock(L);
+  (*G(L)->fprint)(G(L)->fprint_ud, text, size);
+  lua_unlock(L);
+}
+
+
+LUA_API lua_PrintError lua_getprinterrorf (lua_State *L, void **ud) {
+  lua_PrintError f;
+  lua_lock(L);
+  if (ud) *ud = G(L)->fprinterror_ud;
+  f = G(L)->fprinterror;
+  lua_unlock(L);
+  return f;
+}
+
+
+LUA_API void lua_setprinterrorf (lua_State *L, lua_PrintError f, void *ud) {
+  lua_lock(L);
+  G(L)->fprinterror_ud = ud;
+  G(L)->fprinterror = f;
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_printerror (lua_State *L, const char * format, const char * text) {
+  lua_lock(L);
+  (*G(L)->fprinterror)(G(L)->fprinterror_ud, format, text);
+  lua_unlock(L);
+}
+
+
 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
   Udata *u;
   lua_lock(L);
diff --git a/src/lstate.c b/src/lstate.c
index 207a106..0da9e4a 100644
--- a/src/lstate.c
+++ b/src/lstate.c
@@ -7,6 +7,7 @@
 
 #include <stddef.h>
 #include <string.h>
+#include <stdio.h>
 
 #define lstate_c
 #define LUA_CORE
@@ -258,6 +259,15 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
   luaM_free(L, l);
 }
 
+static void l_print(void *ud, const char * text, size_t size) {
+  FILE * fp = (FILE *)ud;
+  fwrite(text, size, 1, fp);
+}
+static void l_printerror(void *ud, const char * format, const char * text) {
+  FILE * fp = (FILE *)ud;
+  fprintf(fp, format, text);
+  fflush(fp);
+}
 
 LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   int i;
@@ -275,6 +285,10 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   preinit_state(L, g);
   g->frealloc = f;
   g->ud = ud;
+  g->fprint = l_print;
+  g->fprint_ud = (void *)stdout;
+  g->fprinterror = l_printerror;
+  g->fprinterror_ud = (void *)stderr;
   g->mainthread = L;
   g->seed = makeseed(L);
   g->uvhead.u.l.prev = &g->uvhead;
diff --git a/src/lstate.h b/src/lstate.h
index c8a31f5..44d039d 100644
--- a/src/lstate.h
+++ b/src/lstate.h
@@ -112,6 +112,10 @@ typedef struct CallInfo {
 typedef struct global_State {
   lua_Alloc frealloc;  /* function to reallocate memory */
   void *ud;         /* auxiliary data to `frealloc' */
+  lua_Print fprint;  /* function to print messages */
+  void *fprint_ud;   /* auxiliary data to `fprint' */
+  lua_PrintError fprinterror;  /* function to print error messages */
+  void *fprinterror_ud;        /* auxiliary data to `fprinterror' */
   lu_mem totalbytes;  /* number of bytes currently allocated - GCdebt */
   l_mem GCdebt;  /* bytes allocated not yet compensated by the collector */
   lu_mem GCmemtrav;  /* memory traversed by the GC */
diff --git a/src/lua.h b/src/lua.h
index eb0482b..d642bb2 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -69,6 +69,12 @@ typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
 */
 typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
 
+/*
+** prototype for printing functions
+*/
+typedef void (*lua_Print) (void *ud, const char * text, size_t size);
+typedef void (*lua_PrintError) (void *ud, const char * format, const char * text);
+
 
 /*
 ** basic types
@@ -308,7 +314,13 @@ LUA_API void  (lua_len)    (lua_State *L, int idx);
 LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
 LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
 
+LUA_API lua_Print (lua_getprintf) (lua_State *L, void **ud);
+LUA_API void      (lua_setprintf) (lua_State *L, lua_Print f, void *ud);
+LUA_API void      (lua_print) (lua_State *L, const char * text, size_t size);
 
+LUA_API lua_PrintError (lua_getprinterrorf) (lua_State *L, void **ud);
+LUA_API void           (lua_setprinterrorf) (lua_State *L, lua_PrintError f, void *ud);
+LUA_API void           (lua_printerror) (lua_State *L, const char * format, const char * text);
 
 /*
 ** ===============================================================
-- 
1.7.12.1

>From 28a273804fc7507a8b07ebefca03a1743f64162c Mon Sep 17 00:00:00 2001
From: Paul Chavent <paul.chavent@fnac.net>
Date: Sat, 26 Oct 2013 21:55:31 +0200
Subject: [PATCH 2/2] Redefine luai_write function in order to use LuaState
 fprint hooks.

---
 src/lauxlib.c  | 2 +-
 src/lbaselib.c | 6 +++---
 src/ldblib.c   | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/lauxlib.c b/src/lauxlib.c
index 2e989d6..a1e1fd3 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -928,7 +928,7 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
 
 
 static int panic (lua_State *L) {
-  luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
+  lua_printerror(L, "PANIC: unprotected error in call to Lua API (%s)\n",
                    lua_tostring(L, -1));
   return 0;  /* return to Lua to abort */
 }
diff --git a/src/lbaselib.c b/src/lbaselib.c
index 540e9a5..7f16837 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -34,11 +34,11 @@ static int luaB_print (lua_State *L) {
     if (s == NULL)
       return luaL_error(L,
          LUA_QL("tostring") " must return a string to " LUA_QL("print"));
-    if (i>1) luai_writestring("\t", 1);
-    luai_writestring(s, l);
+    if (i>1) lua_print(L, "\t", 1);
+    lua_print(L, s, l);
     lua_pop(L, 1);  /* pop result */
   }
-  luai_writeline();
+  lua_print(L, "\n", 1);
   return 0;
 }
 
diff --git a/src/ldblib.c b/src/ldblib.c
index c022694..6c13a1e 100644
--- a/src/ldblib.c
+++ b/src/ldblib.c
@@ -344,13 +344,13 @@ static int db_gethook (lua_State *L) {
 static int db_debug (lua_State *L) {
   for (;;) {
     char buffer[250];
-    luai_writestringerror("%s", "lua_debug> ");
+    lua_printerror(L, "%s", "lua_debug> ");
     if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
         strcmp(buffer, "cont\n") == 0)
       return 0;
     if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
         lua_pcall(L, 0, 0, 0))
-      luai_writestringerror("%s\n", lua_tostring(L, -1));
+      lua_printerror(L, "%s\n", lua_tostring(L, -1));
     lua_settop(L, 0);  /* remove eventual returns */
   }
 }
-- 
1.7.12.1