LCOV - code coverage report
Current view: top level - src/script/common - c_internal.cpp (source / functions) Hit Total Coverage
Test: report Lines: 3 68 4.4 %
Date: 2015-07-11 18:23:49 Functions: 3 8 37.5 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #include "common/c_internal.h"
      21             : #include "debug.h"
      22             : #include "log.h"
      23             : #include "settings.h"
      24             : 
      25           0 : std::string script_get_backtrace(lua_State *L)
      26             : {
      27           0 :         std::string s;
      28           0 :         lua_getglobal(L, "debug");
      29           0 :         if(lua_istable(L, -1)){
      30           0 :                 lua_getfield(L, -1, "traceback");
      31           0 :                 if(lua_isfunction(L, -1)) {
      32           0 :                         lua_call(L, 0, 1);
      33           0 :                         if(lua_isstring(L, -1)){
      34           0 :                                 s = lua_tostring(L, -1);
      35             :                         }
      36             :                 }
      37           0 :                 lua_pop(L, 1);
      38             :         }
      39           0 :         lua_pop(L, 1);
      40           0 :         return s;
      41             : }
      42             : 
      43           0 : int script_error_handler(lua_State *L) {
      44           0 :         lua_getglobal(L, "debug");
      45           0 :         if (!lua_istable(L, -1)) {
      46           0 :                 lua_pop(L, 1);
      47           0 :                 return 1;
      48             :         }
      49           0 :         lua_getfield(L, -1, "traceback");
      50           0 :         if (!lua_isfunction(L, -1)) {
      51           0 :                 lua_pop(L, 2);
      52           0 :                 return 1;
      53             :         }
      54           0 :         lua_pushvalue(L, 1);
      55           0 :         lua_pushinteger(L, 2);
      56           0 :         lua_call(L, 2, 1);
      57           0 :         return 1;
      58             : }
      59             : 
      60         120 : int script_exception_wrapper(lua_State *L, lua_CFunction f)
      61             : {
      62             :         try {
      63         120 :                 return f(L);  // Call wrapped function and return result.
      64           0 :         } catch (const char *s) {  // Catch and convert exceptions.
      65           0 :                 lua_pushstring(L, s);
      66           0 :         } catch (std::exception &e) {
      67           0 :                 lua_pushstring(L, e.what());
      68             :         }
      69           0 :         return lua_error(L);  // Rethrow as a Lua error.
      70             : }
      71             : 
      72           0 : void script_error(lua_State *L)
      73             : {
      74           0 :         const char *s = lua_tostring(L, -1);
      75           0 :         std::string str(s ? s : "");
      76           0 :         throw LuaError(str);
      77             : }
      78             : 
      79             : // Push the list of callbacks (a lua table).
      80             : // Then push nargs arguments.
      81             : // Then call this function, which
      82             : // - runs the callbacks
      83             : // - replaces the table and arguments with the return value,
      84             : //     computed depending on mode
      85           0 : void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
      86             : {
      87           0 :         FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments");
      88             : 
      89             :         // Insert error handler
      90           0 :         lua_pushcfunction(L, script_error_handler);
      91           0 :         int errorhandler = lua_gettop(L) - nargs - 1;
      92           0 :         lua_insert(L, errorhandler);
      93             : 
      94             :         // Insert run_callbacks between error handler and table
      95           0 :         lua_getglobal(L, "core");
      96           0 :         lua_getfield(L, -1, "run_callbacks");
      97           0 :         lua_remove(L, -2);
      98           0 :         lua_insert(L, errorhandler + 1);
      99             : 
     100             :         // Insert mode after table
     101           0 :         lua_pushnumber(L, (int) mode);
     102           0 :         lua_insert(L, errorhandler + 3);
     103             : 
     104             :         // Stack now looks like this:
     105             :         // ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n>
     106             : 
     107           0 :         if (lua_pcall(L, nargs + 2, 1, errorhandler)) {
     108           0 :                 script_error(L);
     109             :         }
     110             : 
     111           0 :         lua_remove(L, -2); // Remove error handler
     112           0 : }
     113             : 
     114           0 : void log_deprecated(lua_State *L, std::string message)
     115             : {
     116             :         static bool configured = false;
     117             :         static bool dolog      = false;
     118             :         static bool doerror    = false;
     119             : 
     120             :         // performance optimization to not have to read and compare setting for every logline
     121           0 :         if (!configured) {
     122           0 :                 std::string value = g_settings->get("deprecated_lua_api_handling");
     123           0 :                 if (value == "log") {
     124           0 :                         dolog = true;
     125             :                 }
     126           0 :                 if (value == "error") {
     127           0 :                         dolog = true;
     128           0 :                         doerror = true;
     129             :                 }
     130             :         }
     131             : 
     132           0 :         if (doerror) {
     133           0 :                 if (L != NULL) {
     134           0 :                         script_error(L);
     135             :                 } else {
     136           0 :                         FATAL_ERROR("Can't do a scripterror for this deprecated message, so exit completely!");
     137             :                 }
     138             :         }
     139             : 
     140           0 :         if (dolog) {
     141             :                 /* abusing actionstream because of lack of file-only-logged loglevel */
     142           0 :                 actionstream << message << std::endl;
     143           0 :                 if (L != NULL) {
     144           0 :                         actionstream << script_get_backtrace(L) << std::endl;
     145             :                 }
     146             :         }
     147           3 : }
     148             : 

Generated by: LCOV version 1.11