Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2005:
[Freeciv-Dev] (PR#13023) more error messages for scripts
Home

[Freeciv-Dev] (PR#13023) more error messages for scripts

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#13023) more error messages for scripts
From: "Vasco Alexandre da Silva Costa" <vasco.costa@xxxxxxxxx>
Date: Sun, 20 Nov 2005 07:16:34 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13023 >

> [jdorje - Tue May 10 06:22:37 2005]:
> 
> Now I get a message like:
> 
> [string "..."]:55: `=' expected near `size'
> 
> which is slightly useful but doesn't really tell where the error is.
> Line 55 is the error but in a scenario script this isn't very helpful
> since it doesn't correspond to file line numbers at all.
> 
> Is it possible to output the line of lua code itself in this case?  I
> think that would be sufficient to track down all script errors.

This patch should provide improved script error reporting. I will commit
it ASAP.

Index: script.c
===================================================================
--- script.c    (revision 11252)
+++ script.c    (working copy)
@@ -42,6 +42,65 @@
 
 
 /**************************************************************************
+  Report a lua error.
+**************************************************************************/
+static int script_report(lua_State *L, int status)
+{
+  if (status) {
+    const char *msg;
+
+    if (!(msg = lua_tostring(L, -1))) {
+      msg = "(error with no message)";
+    }
+    freelog(LOG_ERROR, "\nlua error:\n\t%s", msg);
+    lua_pop(L, 1);
+  }
+  return status;
+}
+
+/**************************************************************************
+  Call a Lua function.
+**************************************************************************/
+static int script_call(lua_State *L, int narg, int nret)
+{
+  int status;
+  int base = lua_gettop(L) - narg;  /* Function index */
+
+  lua_pushliteral(L, "_TRACEBACK");
+  lua_rawget(L, LUA_GLOBALSINDEX);  /* Get traceback function */
+  lua_insert(L, base);  /* Put it under chunk and args */
+  status = lua_pcall(L, narg, nret, base);
+  lua_remove(L, base);  /* Remove traceback function */
+  if (status) {
+    script_report(state, status);
+  }
+  return status;
+}
+
+/**************************************************************************
+  Executes a piece of Lua code from a buffer.
+**************************************************************************/
+static int script_dobuffer(lua_State *L, const char *buf, size_t size, const 
char *name)
+{
+  int status;
+
+  status = luaL_loadbuffer(L, buf, size, name);
+  if (status) {
+    script_report(state, status);
+  }
+  status = script_call(L, 0, LUA_MULTRET);
+  return status;
+}
+
+/**************************************************************************
+  lua_dostring replacement with error message showing on errors.
+**************************************************************************/
+static int script_dostring(lua_State *L, const char *str, const char *name)
+{
+  return script_dobuffer(L, str, strlen(str), name);
+}
+
+/**************************************************************************
   Internal api error function.
   Invoking this will cause Lua to stop executing the current context and
   throw an exception, so to speak.
@@ -127,26 +186,16 @@
   /* The function name */
   lua_getglobal(state, callback_name);
 
+  if (!lua_isfunction(state, -1)) {
+    freelog(LOG_ERROR, "lua error: Unknown callback '%s'", callback_name);
+    lua_pop(state, 1);
+    return FALSE;
+  }
+
   script_callback_push_args(nargs, args);
 
   /* Call the function with nargs arguments, return 1 results */
-  if (lua_pcall(state, nargs, 1, 0) != 0) {
-    freelog(LOG_ERROR, "Error in script function \"%s\":", callback_name);
-
-    nres = lua_gettop(state);
-
-    /* Output error message. */
-    if (nres == 1) {
-      if (lua_isstring(state, -1)) {
-       const char *msg;
-
-       msg = lua_tostring(state, -1);
-
-       freelog(LOG_ERROR, "%s", msg);
-      }
-    }
-
-    lua_pop(state, nres);
+  if (script_call(state, nargs, 1)) {
     return FALSE;
   }
 
@@ -190,9 +239,10 @@
 {
   if (state) {
     const char *vars;
+    const char *section = "script.vars";
 
-    vars = secfile_lookup_str_default(file, "", "script.vars");
-    lua_dostring(state, vars);
+    vars = secfile_lookup_str_default(file, "", section);
+    script_dostring(state, vars, section);
   }
 }
 
@@ -242,10 +292,11 @@
 {
   if (!script_code) {
     const char *code;
+    const char *section = "script.code";
 
-    code = secfile_lookup_str_default(file, "", "script.code");
+    code = secfile_lookup_str_default(file, "", section);
     script_code = mystrdup(code);
-    lua_dostring(state, script_code);
+    script_dostring(state, script_code, section);
   }
 }
 
@@ -300,6 +351,7 @@
 
     script_signals_free();
 
+    lua_setgcthreshold(state, 0); /* Collected garbage */
     lua_close(state);
     state = NULL;
   }

[Prev in Thread] Current Thread [Next in Thread]