LCOV - code coverage report
Current view: top level - ugbase/bindings/lua - info_commands.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 4.8 % 522 25
Test Date: 2025-09-21 23:31:46 Functions: 1.9 % 52 1

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Martin Rupp
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : /**
      34              :  * \file info_commands.cpp
      35              :  *
      36              :  * \author Martin Rupp
      37              :  *
      38              :  * \date 15.10.2010
      39              :  *
      40              :  * Goethe-Center for Scientific Computing 2010.
      41              :  *
      42              :  * Comfort functions for the lua ug shell.
      43              :  * example: TypeInfo("
      44              :  */
      45              : 
      46              : #include <iomanip>
      47              : #include "bindings/lua/lua_util.h"
      48              : #include "bindings/lua/bindings_lua.h"
      49              : #include "bridge/bridge.h"
      50              : #include "bridge/util.h"
      51              : #include "registry/class_helper.h"
      52              : #include "common/util/sort_util.h"
      53              : #include "common/util/string_util.h"
      54              : #include "lua_stack_check.h"
      55              : #include "registry/class_name_provider.h"
      56              : #include "common/util/string_util.h"
      57              : #include "common/util/stringify.h"
      58              : #include "common/util/string_table_stream.h"
      59              : 
      60              : #include "common/profiler/profiler.h"
      61              : #ifdef UG_PLUGINS
      62              :         #include "common/util/plugin_util.h"
      63              : #endif
      64              : 
      65              : #ifdef UG_POSIX
      66              : #include <signal.h>
      67              : #endif
      68              : 
      69              : #ifndef USE_LUAJIT
      70              : extern "C" // default lua
      71              : {
      72              : #include "bindings/lua/externals/lua/lstate.h"
      73              : }
      74              : #else
      75              : // luajit
      76              : #include <lua.hpp>
      77              : #endif
      78              : 
      79              : 
      80              : #include "info_commands.h"
      81              : 
      82              : 
      83              : using namespace std;
      84              : 
      85              : std::string get_gcc_backtrace();
      86              : void lua_backtrace();
      87              : void shiny_backtrace();
      88              : void ug_backtrace();
      89              : 
      90              : namespace ug
      91              : {
      92              : bool useLua2VM=false;
      93              : bool useLuaCompiler=false;
      94              : 
      95              : namespace bridge
      96              : {
      97              : 
      98              : #ifdef UG_POSIX
      99              : void (*oldSIGSEGVhandler)(int);
     100              : void (*oldSIGINThandler)(int);
     101              : 
     102            0 : void signal_callback_handler(int signum)
     103              : {
     104            0 :         cout << "\n##############################################################################################################\n";
     105              :         printf("CAUGHT SIGNAL SIGSEV = Segmentation Violation (Invalid access to storage). Possibly an uninitialized pointer.");
     106            0 :         cout << "\n##############################################################################################################\n\n";
     107            0 :         ug_backtrace();
     108            0 :         UG_THROW("CAUGHT SIGNAL SIGSEV = Segmentation Violation (Invalid access to storage). Possibly an uninitialized pointer.");
     109              :         exit(signum);
     110              : }
     111              : 
     112            0 : void sigint_handler(int signum)
     113              : {
     114            0 :         cout << "\n##############################################################################################################\n";
     115            0 :         cout << "--- Received SIGINT (Ctrl+C) --- \n";
     116            0 :         cout << "\n##############################################################################################################\n\n";
     117              : 
     118            0 :         lua_backtrace();
     119            0 :         shiny_backtrace();
     120            0 :         exit(signum);
     121              : }
     122              : 
     123            0 : void InitSignals()
     124              : {
     125            0 :         oldSIGSEGVhandler = signal(SIGSEGV, signal_callback_handler);
     126            0 :         oldSIGINThandler = signal(SIGINT, sigint_handler);
     127            0 : }
     128              : #else
     129              : void InitSignals()
     130              : {
     131              :         UG_LOG("Signals not available on this system (non-posix).\n");
     132              : }
     133              : #endif
     134              : 
     135            0 : void SetLuaNamespaceInTable(string name, string value)
     136              : {
     137              :         UG_LOGN("SetLuaNamespaceInTable " << name << " str " << value);
     138            0 :         lua_State* L = script::GetDefaultLuaState();
     139              :         LUA_STACK_CHECK(L, 0);
     140            0 :         int dotPos = name.find(".");
     141              : 
     142            0 :         if(dotPos == -1)
     143              :         {
     144            0 :                 lua_pushstring(L, name.c_str()); // key
     145            0 :                 lua_pushstring(L, value.c_str()); // value
     146            0 :                 lua_settable(L, -3);
     147              :         }
     148              :         else
     149              :         {
     150            0 :                 string subname = name.substr(0, dotPos);
     151            0 :                 string restname = name.substr(dotPos+1, name.size());
     152              : 
     153            0 :                 lua_pushstring(L, subname.c_str());
     154            0 :                 lua_rawget(L, -2);
     155            0 :                 if(lua_isnil(L, -1))
     156              :                 {
     157            0 :                         lua_pop(L, 1);
     158              : 
     159            0 :                         lua_newtable(L);
     160            0 :                         SetLuaNamespaceInTable(restname, value);
     161            0 :                         lua_pushstring(L, subname.c_str());
     162            0 :                         lua_insert(L, -2); /* swap uppertable and 0 */
     163            0 :                         lua_settable(L, -3);
     164              :                 }
     165              :                 else
     166              :                 {
     167            0 :                         SetLuaNamespaceInTable(restname.c_str(), value);
     168            0 :                         lua_pop(L, 1);
     169              :                 }
     170              :         }
     171            0 : }
     172            0 : void SetLuaNamespace(string name, string value)
     173              : {
     174              :         UG_LOGN("SetLuaNamespace " << name << " str " << value);
     175            0 :         lua_State* L = script::GetDefaultLuaState();
     176              :         LUA_STACK_CHECK(L, 0);
     177              : 
     178            0 :         int dotPos = name.find(".");
     179              : 
     180            0 :         if(dotPos == -1)
     181              :         {
     182            0 :                 lua_pushstring(L, value.c_str());
     183            0 :                 lua_setglobal(L, name.c_str());
     184              :         }
     185              :         else
     186              :         {
     187            0 :                 string subname = name.substr(0, dotPos);
     188            0 :                 string restname = name.substr(dotPos+1, name.size());
     189            0 :                 lua_getglobal(L, subname.c_str());
     190            0 :                 if(lua_isnil(L, -1))
     191              :                 {
     192            0 :                         lua_pop(L, 1);
     193            0 :                         lua_newtable(L);
     194            0 :                         lua_setglobal(L, subname.c_str());
     195            0 :                         lua_getglobal(L, subname.c_str());
     196              :                 }
     197            0 :                 SetLuaNamespaceInTable(restname, value);
     198            0 :                 lua_pop(L, 1);
     199              : 
     200              :         }
     201            0 : }
     202              : 
     203              : 
     204              : /**
     205              :  * this function also includes all lines before fromline which begin with -- (lua comments)
     206              :  * and adds line numbers
     207              :  * @param filename
     208              :  * @param fromline
     209              :  * @param toline
     210              :  * @return string with lines
     211              :  */
     212            0 : string GetFileLinesLUA(const char *filename, size_t fromline, size_t toline)
     213              : {
     214            0 :         if(GetLogAssistant().is_output_process()) return "";
     215              :         char buf[512];
     216            0 :         fstream file(filename, ios::in);
     217            0 :         if(file.is_open() == false) return string("");
     218              :         stringstream *pss = NULL;
     219            0 :         for(size_t i=0; i<fromline-1 && !file.eof(); i++)
     220              :         {
     221            0 :                 file.getline(buf, 512);
     222            0 :                 if(strncmp(buf+strspn(buf, "\t "), "--", 2)==0)
     223              :                 {
     224            0 :                         if(pss == NULL) pss = new stringstream;
     225            0 :                         *pss << "   \t" << buf+strspn(buf, "-\t ") << '\n';
     226              :                 }
     227            0 :                 else if(pss) { delete pss; pss = NULL; }
     228              : 
     229              :         }
     230            0 :         stringstream ss;
     231            0 :         if(pss != NULL) ss << "\n" << pss->str() << "\n";
     232            0 :         for(; fromline <= toline && !file.eof(); fromline++)
     233              :         {
     234            0 :                 file.getline(buf, 512);
     235            0 :                 ss << fromline << "\t" << buf << "\n";
     236              :         }
     237              :         return ss.str();
     238            0 : }
     239              : 
     240              : 
     241            0 : double LuaGetNumber(lua_State *L, const char *name, double notAvailable)
     242              : {
     243              :         LUA_STACK_CHECK(L, 0);
     244            0 :         if(GetLuaNamespace(L, name)==false || !lua_isnumber(L, -1))
     245              :         {
     246            0 :                 lua_pop(L, 1);
     247            0 :                 return notAvailable;
     248              :         }
     249            0 :         double d = lua_tonumber(L, -1);
     250            0 :         lua_pop(L, 1);
     251            0 :         return d;
     252              : }
     253              : 
     254            0 : string LuaGetString(lua_State *L, const char *name, const char *notAvailable)
     255              : {
     256              :         LUA_STACK_CHECK(L, 0);
     257            0 :         if(GetLuaNamespace(L, name)==false || !lua_isstring(L, -1))
     258              :         {
     259            0 :                 lua_pop(L, 1);
     260            0 :                 return notAvailable;
     261              :         }
     262            0 :         string str = lua_tostring(L, -1);
     263            0 :         lua_pop(L, 1);
     264            0 :         return str;
     265              : }
     266              : 
     267            0 : bool LuaGetBoolean(lua_State *L, const char *name, bool notAvailable)
     268              : {
     269              :         LUA_STACK_CHECK(L, 0);
     270            0 :         if(GetLuaNamespace(L, name)==false || !lua_isboolean(L, -1))
     271              :         {
     272            0 :                 lua_pop(L, 1);
     273            0 :                 return notAvailable;
     274              :         }
     275            0 :         bool b = lua_toboolean(L, -1);
     276            0 :         lua_pop(L, 1);
     277            0 :         return b;
     278              : }
     279              : 
     280              : 
     281              : 
     282              : 
     283              : /**
     284              :  * \brief searches for a namespaces (lists) and pushes it onto the stack
     285              :  * \param L                             the lua state
     286              :  * \param name                  name of the namespace. also nested namespaces are allowed (like struc1.struc2)
     287              :  * \return true if namespace found
     288              :  */
     289            0 : bool GetLuaNamespace(lua_State* L, string name)
     290              : {
     291              :         LUA_STACK_CHECK(L, 1);
     292              :         vector<string> tokens;
     293            0 :         TokenizeString(name, tokens, '.');
     294            0 :         if(tokens.empty())
     295              :         {
     296            0 :                 lua_pushnil(L);
     297              :                 return false;
     298              :         }
     299              : 
     300            0 :         lua_getglobal(L, tokens[0].c_str());
     301            0 :         if(lua_isnil(L, -1))
     302              :         {
     303              :                 return 0;       // global name not found
     304              :         }
     305              : 
     306              :         size_t i=1;
     307            0 :         for(; i<tokens.size(); i++)
     308              :         {
     309            0 :                 lua_pushstring(L, tokens[i].c_str());
     310            0 :                 lua_rawget(L, -2);
     311            0 :                 lua_remove(L, -2); // remove parent table from stack
     312            0 :                 if(lua_isnil(L, -1))
     313              :                         return false;
     314              :         }
     315              : 
     316              :         return true;
     317            0 : }
     318              : 
     319              : 
     320            0 : const ClassNameNode* GetClassNameNode(lua_State *L, int index)
     321              : {
     322              :         LUA_STACK_CHECK(L, 0);
     323              :         const ClassNameNode* classNameNode = NULL;
     324            0 :         if(lua_getmetatable(L, index) != 0)
     325              :         {
     326              :                 // get names
     327            0 :                 lua_pushstring(L, "class_name_node");
     328            0 :                 lua_rawget(L, -2);
     329            0 :                 if(!lua_isnil(L, -1) && lua_isuserdata(L, -1))
     330            0 :                         classNameNode = (const ClassNameNode*) lua_touserdata(L, -1);
     331            0 :                 lua_pop(L, 2); // pop userdata, metatable
     332              :         }
     333            0 :         return classNameNode;
     334              : }
     335              : 
     336              : 
     337            0 : const std::vector<const char*> *GetClassNames(lua_State *L, int index)
     338              : {
     339              :         LUA_STACK_CHECK(L, 0);
     340              :         const std::vector<const char*> *p = NULL;
     341            0 :         if(lua_getmetatable(L, index) != 0)
     342              :         {
     343              :                 // get names
     344            0 :                 lua_pushstring(L, "__names");
     345            0 :                 lua_rawget(L, -2);
     346            0 :                 if(!lua_isnil(L, -1) && lua_isuserdata(L, -1))
     347            0 :                         p = (const std::vector<const char*>*) lua_touserdata(L, -1);
     348            0 :                 lua_pop(L, 2); // pop userdata, metatable
     349              :         }
     350            0 :         return p;
     351              : }
     352              : 
     353            0 : const std::vector<const char*> *GetClassNames(lua_State* L, const char *name)
     354              : {
     355              :         // get the lua object with that name
     356            0 :         lua_getglobal(L, name);
     357            0 :         if(lua_isnil(L, -1))
     358              :         {
     359            0 :                 lua_pop(L, 1);  // remove global from stack
     360            0 :                 return NULL;    // global name not found
     361              :         }
     362              : 
     363            0 :         const std::vector<const char*> *p = GetClassNames(L, -1);
     364            0 :         lua_pop(L, 1); // remove global from stack;
     365            0 :         return p;
     366              : }
     367              : 
     368            0 : string GetLUAScriptFunctionDefined(const char *functionName)
     369              : {
     370              : 
     371            0 :         lua_State* L = script::GetDefaultLuaState();
     372              :         LUA_STACK_CHECK(L, 0);
     373              : 
     374            0 :         string str = functionName;
     375            0 :         GetLuaNamespace(L, str);
     376              : 
     377            0 :         if(lua_isnil(L, -1) || lua_isfunction(L, -1)==false)
     378              :         {
     379              :                 // it is nil
     380            0 :                 lua_pop(L, 1);
     381            0 :                 return "?";
     382              :         }
     383              : 
     384              :         lua_Debug ar;
     385              : 
     386            0 :         if(lua_getinfo(L, ">Snlu", &ar) != 0 && ar.source)
     387              :         {
     388            0 :                 const char *src = ar.source[0]=='@' ? ar.source+1 : ar.source;
     389            0 :                 std::stringstream ss;
     390            0 :                 ss << src << ":" << ar.linedefined << "-" << ar.lastlinedefined;
     391              :                 return ss.str();
     392            0 :         }
     393              :         else
     394              :         {
     395            0 :                 return "?";
     396              :         }
     397              : }
     398              : 
     399            0 : string FunctionInfo(lua_State *L, bool bComplete, const char *functionName)
     400              : {
     401              :         LUA_STACK_CHECK(L, 0);
     402            0 :         lua_pushvalue(L, -1);
     403              :         lua_Debug ar;
     404              : 
     405            0 :         std::stringstream ss;
     406            0 :         if(lua_getinfo(L, ">Snlu", &ar) != 0 && ar.source)
     407              :         {
     408            0 :                 if(bComplete)
     409              :                 {
     410            0 :                         const char *src = ar.source[0]=='@' ? ar.source+1 : ar.source;
     411            0 :                         ss << src << ":" << ar.linedefined << "-" << ar.lastlinedefined << "\n";
     412            0 :                         ss << GetFileLinesLUA(src, ar.linedefined, ar.lastlinedefined) << "\n";
     413              :                 }
     414              :                 else
     415              :                 {
     416            0 :                         ss << GetFileLine(ar.source+1, ar.linedefined) << "\n";
     417              :                 }
     418              :         }
     419              :         else
     420            0 :                 ss << functionName;
     421              : 
     422            0 :         return ss.str();
     423            0 : }
     424              : 
     425            0 : string LuaClassMethodInfo(lua_State *L, int index, const ExportedMethod &thefunc)
     426              : {
     427            0 :         const std::vector<const char*> *names = GetClassNames(L, index);
     428              :         const char *classname = "(unknown class)";
     429            0 :         if(names != NULL)
     430            0 :                 classname = names->at(0);
     431            0 :         return FunctionInfo(thefunc, false, classname);
     432              : }
     433              : 
     434              : 
     435              : /**
     436              :  * \brief Prints info to a lua type
     437              :  * \param       p                       the name of the object in lua.
     438              :  * you can use class names, function names or the names of an object
     439              :  * - TypeInfo("class") prints all member functions+parameters of this class and its parents
     440              :  * - TypeInfo("Function") prints all member functions+parameters
     441              :  * - TypeInfo("variable") prints class information if variable is a object of a ug class, otherwise what type in lua it is
     442              :  */
     443            0 : int UGTypeInfo(const char *p)
     444              : {
     445              :         UG_LOG("\n");
     446            0 :         const bridge::Registry &reg = GetUGRegistry();
     447              : 
     448              :         // check if it is a class
     449            0 :         const ClassGroupDesc *cg = reg.get_class_group(p);
     450              :         const IExportedClass *c=NULL;
     451            0 :         if(cg != NULL)
     452              :         {
     453            0 :                 UG_LOG("ClassGroup " << p << " consisting of classes\n");
     454            0 :                 for(size_t i=0; i<cg->num_classes(); i++)
     455              :                 {
     456            0 :                         if(i != 0) UG_LOG(", ");
     457            0 :                         UG_LOG(cg->get_class(i)->name());
     458              :                 }
     459              :                 c = cg->get_default_class();
     460            0 :                 if(c)
     461            0 :                 {       UG_LOG("\nDefault class is " << c->name() << "\n");  }
     462              :                 else
     463              :                 {
     464              :                         UG_LOG("\nDefault class (not yet?) set, using first class in list.\n");
     465            0 :                         if(cg->num_classes() > 0)
     466              :                                 c = cg->get_class(0);
     467              :                 }
     468              :                 UG_LOG("\n\n");
     469              :         }
     470              :         else
     471            0 :                 c = reg.get_class(p);
     472              : 
     473            0 :         if(c)
     474              :         {
     475            0 :                 const std::vector<const char*> *names = c->class_names();
     476            0 :                 for(size_t i=0; i < names->size(); ++i)
     477            0 :                         UG_LOG(ClassInfo(reg, names->at(i)));
     478              :                 UG_LOG(endl);
     479            0 :                 UG_LOG(ClassHierarchyString(reg, c->name().c_str()));
     480            0 :                 ClassInstantiations(c->name().c_str());
     481              :                 UG_LOG("\n");
     482            0 :                 return true;
     483              :         }
     484              : 
     485              : 
     486            0 :         lua_State* L = script::GetDefaultLuaState();
     487              :         LUA_STACK_CHECK(L, 0);
     488              : 
     489            0 :         string str = p;
     490            0 :         GetLuaNamespace(L, str);
     491              : 
     492            0 :         if(lua_isnil(L, -1))
     493              :         {
     494              :                 // it is nil
     495            0 :                 lua_pop(L, 1);
     496            0 :                 UG_LOG(p << " is neither a global variable nor a class name." << endl);
     497              :                 return false;
     498              :         }
     499              : 
     500            0 :         if(lua_iscfunction(L, -1))
     501              :         {
     502              :                 // it is a cfunction
     503            0 :                 UG_LOG(p << " is a cfunction\n " << FunctionInfo(reg, p) << "\n");
     504              :         }
     505            0 :         else if(lua_isfunction(L, -1))
     506              :         {
     507              :                 // it is a lua function
     508            0 :                 UG_LOG(p << " is a function\n " << FunctionInfo(L, true, p) << "\n");
     509              :         }
     510            0 :         else if(lua_isuserdata(L, -1))
     511              :         {
     512              :                 // it is user data, that is a class object
     513              :                 // names = GetClassNames(L, -1))
     514            0 :                 if(lua_getmetatable(L, -1) == 0)
     515              :                 {
     516            0 :                         UG_LOG(p << " is a global variable which has light user data, but no metatable." << endl);
     517            0 :                         lua_pop(L, 1); // pop globals
     518              :                         return false;
     519              :                 }
     520              : 
     521              :                 // get names
     522            0 :                 lua_pushstring(L, "__names");
     523            0 :                 lua_rawget(L, -2);
     524            0 :                 if(lua_isnil(L, -1) || !lua_isuserdata(L, -1))
     525              :                 {
     526            0 :                         UG_LOG(p << " is a global variable which has a metatable, but cannot access names." << endl);
     527            0 :                         lua_pop(L, 3); // pop metatable, userdata, globals
     528              :                         return false;
     529              :                 }
     530              :                 const std::vector<const char*> *names =
     531            0 :                                 (const std::vector<const char*>*) lua_touserdata(L, -1);
     532            0 :                 lua_pop(L, 2); // pop metatable, userdata
     533            0 :                 UG_LOG("Typeinfo for " << p << ": " << endl);
     534            0 :                 for(size_t i=0; i < names->size(); ++i)
     535            0 :                         UG_LOG(ClassInfo(reg, names->at(i)));
     536            0 :                 if(!names->empty())
     537            0 :                         UG_LOG(ClassHierarchyString(reg, names->at(0)));
     538              :         }
     539            0 :         else if (lua_istable(L, -1))
     540              :         {
     541              :                 // it is a table
     542            0 :                 LuaPrintTable(L, 1);
     543            0 :                 UG_LOG(p << " is a table" << "\n");
     544              :         }
     545              :         else
     546              :         {
     547              :                 // it is something else like number string or boolean
     548            0 :                 UG_LOG(p << ": type is " << GetLuaTypeString(L, -1) << ": " << lua_tostring(L, -1));
     549              :         }
     550            0 :         lua_pop(L, 1);
     551              : 
     552              :         UG_LOG("\n");
     553              :         return 0;
     554              : }
     555              : 
     556              : 
     557              : /**
     558              :  * \brief this function prints all objects which are of a certain class
     559              :  * \param       classname       the class name to be searched
     560              :  * \return true if class found, otherwise false
     561              :  */
     562            0 : bool ClassInstantiations(const char *classname)
     563              : {
     564            0 :         bridge::Registry &reg = GetUGRegistry();
     565              :         // search for the class
     566            0 :         const IExportedClass *c = reg.get_class(classname);
     567            0 :         if(c == NULL)
     568              :         {
     569            0 :                 UG_LOG("Class " << classname << " not found\n");
     570            0 :                 return false;
     571              :         }
     572              : 
     573              :         UG_LOG(endl);
     574            0 :         UG_LOG("Instantiations of Class " << classname << ":\n");
     575              : 
     576            0 :         lua_State* L = script::GetDefaultLuaState();
     577              :         LUA_STACK_CHECK(L, 0);
     578              :         bool bFound = false;
     579              : 
     580              : #ifndef USE_LUAJIT
     581              :         // iterate through all of lua's global string table
     582            0 :         for(int i=0; i<G(L)->strt.size; i++)
     583              :         {
     584              :                 GCObject *obj;
     585            0 :                 for (obj = G(L)->strt.hash[i]; obj != NULL; obj = obj->gch.next)
     586              :                 {
     587              :                         // get the string
     588              :                         TString *ts = rawgco2ts(obj);
     589              :                         if(ts == NULL) continue;
     590              : 
     591            0 :                         const char *luastr = getstr(ts);
     592              :                         // check is of a global variable
     593              : 
     594            0 :                         const std::vector<const char*> *names = GetClassNames(L, luastr);
     595            0 :                         if(names == NULL)
     596            0 :                                 continue;
     597              : 
     598            0 :                         if(ClassNameVecContains(*names, classname))
     599              :                         {
     600              :                                 bFound = true;
     601            0 :                                 UG_LOG(setw(10) << left << luastr);
     602              :                                 UG_LOG(" (");
     603            0 :                                 for(size_t i=0; i<names->size(); i++)
     604              :                                 {
     605            0 :                                         if(i>0) UG_LOG(" :: ");
     606            0 :                                         UG_LOG(names->at(i));
     607              :                                 }
     608              :                                 UG_LOG(")\n");
     609              :                         }
     610              :                 }
     611              :         }
     612              : #else
     613              :         // traversal using API
     614              :         // cf. http://stackoverflow.com/questions/20527659/how-to-filter-out-user-defined-globals-in-lua-from-c
     615              : 
     616              :         lua_pushvalue(L, LUA_GLOBALSINDEX);     //lua_pushglobaltable(L);
     617              :         lua_pushnil(L);
     618              :         while (lua_next(L,-2) != 0)
     619              :         {
     620              :           const char* luastr = lua_tostring(L,-2);
     621              : 
     622              :           if (luastr) {
     623              :                   std::cerr << "Found global: " << luastr << std::endl;
     624              :           }
     625              : 
     626              :           lua_pop(L,1); // pop value
     627              :         }
     628              :         lua_pop(L,1); // pop global table
     629              : 
     630              :         // Check required!
     631              :         UG_ASSERT(0, "ERROR: Implement for LuaJit!");
     632              : 
     633              : #endif
     634            0 :         if(!bFound) UG_LOG("No instantiations of " << classname << " or subclasses found.");
     635              :         UG_LOG(endl);
     636            0 :         return true;
     637              : }
     638              : 
     639              : /**
     640              :  *
     641              :  * \param classname the class to print usage in functions/member functions of (and all its subclasses) .
     642              :  * class in in/out parameters is highlighted with [class].
     643              :  * \return true if class found, otherwise fals
     644              :  */
     645            0 : string ClassUsage(const char *classname)
     646              : {
     647            0 :         bridge::Registry &reg = GetUGRegistry();
     648            0 :         std::stringstream ss;
     649            0 :         ss << "\n";
     650              : 
     651              :         // find class
     652            0 :         const IExportedClass *c = reg.get_class(classname);
     653            0 :         if(c == NULL)
     654              :         {
     655            0 :                 ss << "Class name " << classname << " not found\n";
     656              :                 return ss.str();
     657              :         }
     658              : 
     659              :         // print usages in functions
     660              : 
     661            0 :         ss << "--- Functions returning " << classname << ": ---\n";
     662            0 :         ss << ClassUsageExact(reg, classname, true);
     663              : 
     664            0 :         const std::vector<const char*> *names = c->class_names();
     665            0 :         if(names != NULL && !names->empty())
     666              :         {
     667            0 :                 for(size_t i = 0; i<names->size(); i++)
     668              :                 {
     669            0 :                         ss << "--- Functions using " << names->at(i) << ": ---\n";
     670            0 :                         ss << ClassUsageExact(reg, names->at(i), false);
     671              :                 }
     672              :         }
     673              : 
     674            0 :         ss << ClassInstantiations(classname);
     675              : 
     676            0 :         ss << "\n";
     677              :         return ss.str();
     678            0 : }
     679              : 
     680            0 : string LuaGetScriptFunctionString(lua_State *L, int index)
     681              : {
     682              :         LUA_STACK_CHECK(L, 0);
     683            0 :         lua_pushvalue(L, index);
     684              :         lua_Debug ar;
     685              : 
     686            0 :         if(lua_getinfo(L, ">S", &ar) != 0 && ar.linedefined != -1)
     687              :         {
     688              : 
     689            0 :                 const char *p=GetFileLine(ar.source[0] == '@' ? ar.source+1 : ar.source,
     690              :                                                                   ar.linedefined).c_str();
     691            0 :                 p+=strspn(p, " \t");
     692            0 :                 return p;
     693              :         }
     694            0 :         return "";
     695              : }
     696              : 
     697              : /**
     698              :  * \brief prints the source of a lua script function which is on top of the stack
     699              :  * \param L             the lua state
     700              :  */
     701            0 : void LuaPrintTable(lua_State *L, size_t iSpace, int index)
     702              : {
     703              :         LUA_STACK_CHECK(L, 0);
     704              : 
     705            0 :         if(index != -1)
     706            0 :                 lua_pushvalue(L, index);
     707              : 
     708            0 :         UG_LOG(repeat(' ', iSpace));
     709              :         UG_LOG("{\n");
     710              :         //lua_getglobal(L, "ugargv"); // -2
     711              :         int len=0;
     712            0 :         lua_pushnil( L ); // -1
     713            0 :         while( lua_next( L, (-1-len)*2) )
     714              :         {
     715              :                 // key -2
     716              :                 // val -1
     717            0 :                 lua_pushvalue(L, -2);
     718            0 :                 len++;
     719              :         }
     720              : 
     721              :         std::vector<SortStruct<int, string> > sorted;
     722            0 :         sorted.resize(len);
     723              : 
     724            0 :         for(int i=0; i<len; i++)
     725              :         {
     726            0 :                 sorted[i].index = -2*len+2*i+1; // valueIndex
     727              :                 size_t indexIndex = -2*len+2*i;
     728            0 :                 const char *name = lua_tostring(L, indexIndex);
     729            0 :                 if(name) sorted[i].value = name;
     730            0 :                 else sorted[i].value = GetLuaTypeString(L, indexIndex);
     731              :         }
     732              : 
     733            0 :         sort(sorted.begin(), sorted.end());
     734              : 
     735            0 :         for(int i=0; i<len; i++)
     736              :         {
     737            0 :                 int index2 = sorted[i].index;
     738              : 
     739            0 :                 UG_LOG(repeat(' ', iSpace));
     740              :                 UG_LOG(sorted[i].value);
     741            0 :                 UG_LOG(" (" << GetLuaTypeString(L, index2) << ")");
     742            0 :                 if(lua_isfunction(L, index2))
     743              :                 {
     744            0 :                         UG_LOG(": " << LuaGetScriptFunctionString(L, index2));
     745              :                 }
     746            0 :                 else if(lua_istable(L, index2))
     747              :                 {
     748              :                         UG_LOG(" = \n");
     749            0 :                         LuaPrintTable(L, iSpace+1, index2);
     750              :                 }
     751              :                 else
     752              :                 {
     753            0 :                         const char * value = lua_tostring(L, index2);
     754            0 :                         if(value) { UG_LOG(" = \"" << value << "\"") };
     755              :                 }
     756              :                 UG_LOG("\n");
     757              :         }
     758              : 
     759            0 :         lua_pop(L, 2*len);
     760            0 :         UG_LOG(repeat(' ', iSpace));
     761              :         UG_LOG("}\n");
     762            0 :         if(index != -1)
     763            0 :                 lua_pop(L, 1);
     764            0 : }
     765              : 
     766              : 
     767              : /**
     768              :  * @brief function to list all objects of the default LUA state
     769              :  * @param functions
     770              :  * @param internalFunctions
     771              :  * @param scriptFunctions
     772              :  * @param luaObjects
     773              :  * @param classInstantiations
     774              :  */
     775            0 : void GetLuaGlobals(std::vector<std::string>  *functions,
     776              :                 std::vector<std::string> *internalFunctions,
     777              :                 std::vector<std::string> *scriptFunctions,
     778              :                 std::vector<std::string> *luaObjects,
     779              :                 std::vector<std::string> *classInstantiations)
     780              : {
     781            0 :         bridge::Registry &reg = GetUGRegistry();
     782            0 :         lua_State* L = script::GetDefaultLuaState();
     783              :         LUA_STACK_CHECK(L, 0);
     784              : 
     785              :         // iterate through all of lua's globals
     786              : 
     787            0 :         lua_getglobal(L, "_G");
     788            0 :         lua_pushnil( L ); // -1
     789            0 :         while( lua_next( L, -2 ))
     790              :         {
     791            0 :                 const char *luastr = lua_tostring(L, -2);
     792            0 :                 if(luastr && strcmp(luastr, "_G") != 0 && strcmp(luastr, "package") != 0)
     793              :                 {
     794            0 :                         if(!reg.get_class(luastr))
     795              :                         {
     796            0 :                                 if(FindFunction(reg, luastr))
     797              :                                 {
     798            0 :                                         if(functions) functions->push_back(luastr);
     799              :                                 }
     800            0 :                                 else if(lua_isfunction(L, -1) || lua_iscfunction(L, -1))
     801              :                                 {
     802              :                                         lua_Debug ar;
     803            0 :                                         lua_pushvalue(L, -1);
     804            0 :                                         if(lua_getinfo(L, ">S", &ar) != 0 && ar.linedefined != -1) {
     805            0 :                                                 if(scriptFunctions) scriptFunctions->push_back(luastr);
     806              :                                         }
     807              :                                         else {
     808            0 :                                                 if(internalFunctions) internalFunctions->push_back(luastr);
     809              :                                         }
     810              :                                 }
     811            0 :                                 else if(lua_isuserdata(L, -1)) {
     812            0 :                                         if(classInstantiations) classInstantiations->push_back(luastr);
     813              :                                 }
     814              :                                 else {
     815            0 :                                         if(luaObjects) luaObjects->push_back(luastr);
     816              :                                 }
     817              :                         }
     818              :                 }
     819            0 :                 lua_pop(L, 1); // remove table entry from stack
     820              :         }
     821            0 :         lua_pop(L, 1); // remove global _G from stack
     822              : 
     823            0 :         if(functions) sort(functions->begin(), functions->end());
     824            0 :         if(internalFunctions) sort(internalFunctions->begin(), internalFunctions->end());
     825            0 :         if(scriptFunctions) sort(scriptFunctions->begin(), scriptFunctions->end());
     826            0 :         if(luaObjects) sort(luaObjects->begin(), luaObjects->end());
     827            0 :         if(classInstantiations) sort(classInstantiations->begin(), classInstantiations->end());
     828            0 : }
     829              : 
     830            0 : void GetLuaGlobal_functions(std::vector<std::string> &functions)
     831              : {
     832            0 :         GetLuaGlobals(&functions, NULL, NULL, NULL, NULL);
     833            0 : }
     834              : 
     835            0 : void GetLuaGlobal_internalFunctions(std::vector<std::string> &internalFunctions)
     836              : {
     837            0 :         GetLuaGlobals(NULL, &internalFunctions, NULL, NULL, NULL);
     838            0 : }
     839              : 
     840            0 : void GetLuaGlobal_scriptFunctions(std::vector<std::string> &scriptFunctions)
     841              : {
     842            0 :         GetLuaGlobals(NULL, NULL, &scriptFunctions, NULL, NULL);
     843            0 : }
     844              : 
     845            0 : void GetLuaGlobal_luaObjects(std::vector<std::string> &luaObjects)
     846              : {
     847            0 :         GetLuaGlobals(NULL, NULL, NULL, &luaObjects, NULL);
     848            0 : }
     849              : 
     850            0 : void GetLuaGlobal_classInstantiations(std::vector<std::string> &classInstantiations)
     851              : {
     852            0 :         GetLuaGlobals(NULL, NULL, NULL, NULL, &classInstantiations);
     853            0 : }
     854              : 
     855            0 : void LuaList_classes()
     856              : {
     857            0 :         bridge::Registry &reg = GetUGRegistry();
     858              :         std::vector<std::string> classes;
     859            0 :         classes.reserve(reg.num_classes());
     860            0 :         for(size_t j=0; j<reg.num_classes(); ++j)
     861            0 :                 classes.push_back(reg.get_class(j).name());
     862            0 :         sort(classes.begin(), classes.end());
     863              : 
     864              :         UG_LOG(endl << "--- Classes: --------------------" << endl)
     865            0 :         for(size_t i=0; i<classes.size(); i++)
     866              :                 UG_LOG(classes[i] << endl);
     867            0 : }
     868              : 
     869              : 
     870            0 : void LuaList_cfunctions()
     871              : {
     872            0 :         bridge::Registry &reg = GetUGRegistry();
     873              :         std::vector<std::string> functions;
     874            0 :         GetLuaGlobal_functions(functions);
     875              :         UG_LOG(endl << "--- C Functions: ------------------" << endl)
     876            0 :         for(size_t i=0; i<functions.size(); i++)
     877            0 :                 UG_LOG(FunctionInfo(reg, functions[i].c_str()) << "\n");
     878            0 : }
     879              : 
     880            0 : void LuaList_scriptFunctions()
     881              : {
     882            0 :         lua_State* L = script::GetDefaultLuaState();
     883              : 
     884              :         std::vector<std::string> scriptFunctions;
     885            0 :         GetLuaGlobal_scriptFunctions(scriptFunctions);
     886              :         UG_LOG(endl << "--- Script Functions: ---" << endl)
     887              : 
     888            0 :         if(scriptFunctions.empty())     return;
     889            0 :         int maxLength = (*max_element(scriptFunctions.begin(), scriptFunctions.end(), IsLonger)).size();
     890            0 :         for(size_t i=0; i<scriptFunctions.size(); i++)
     891              :         {
     892            0 :                 lua_getglobal(L, scriptFunctions[i].c_str());  /* get global 'f' */
     893              :                 UG_LOG(left << setw(maxLength) << scriptFunctions[i] << ": ");
     894            0 :                 UG_LOG(LuaGetScriptFunctionString(L));
     895            0 :                 lua_pop(L, 1);
     896              :                 UG_LOG("\n");
     897              :         }
     898            0 : }
     899              : 
     900            0 : void LuaList_internalFunctions()
     901              : {
     902              :         std::vector<std::string> internalFunctions;
     903            0 :         GetLuaGlobal_internalFunctions(internalFunctions);
     904              : 
     905              :         UG_LOG(endl << "--- Internal Functions: ---" << endl)
     906            0 :         for(size_t i=0; i<internalFunctions.size(); i++)
     907              :                 UG_LOG(internalFunctions[i] << endl);
     908            0 : }
     909              : 
     910              : 
     911            0 : void LuaList_luaObjects()
     912              : {
     913            0 :         lua_State* L = script::GetDefaultLuaState();
     914              :         std::vector<std::string> luaObjects;
     915            0 :         GetLuaGlobal_luaObjects(luaObjects);
     916              : 
     917              :         UG_LOG(endl << "--- Lua Objects: ----------------" << endl)
     918            0 :         if(luaObjects.empty()) return;
     919            0 :         int maxLength = (*max_element(luaObjects.begin(), luaObjects.end(), IsLonger)).size();
     920            0 :         for(size_t i=0; i<luaObjects.size(); i++)
     921              :         {
     922            0 :                 if(luaObjects[i].compare("_G") == 0) continue;
     923            0 :                 if(luaObjects[i].compare("package") == 0) continue;
     924            0 :                 lua_getglobal(L, luaObjects[i].c_str());
     925              :                 UG_LOG(left << setw(maxLength) << luaObjects[i]);
     926            0 :                 UG_LOG(" (" << GetLuaTypeString(L, -1) << ")");
     927              :                 /*if(lua_istable(L, -1))
     928              :                 {
     929              :                         UG_LOG(" = \n");
     930              :                         LuaPrintTable(L, 1);
     931              :                 }*/
     932            0 :                 const char *p = lua_tostring(L, -1);
     933            0 :                 if(p) UG_LOG(": " << p)
     934            0 :                 lua_pop(L, 1);
     935              :                 UG_LOG(endl);
     936              :         }
     937            0 : }
     938              : 
     939            0 : void LuaList_classInstantiations()
     940              : {
     941            0 :         lua_State* L = script::GetDefaultLuaState();
     942              :         std::vector<std::string> instantiations;
     943            0 :         GetLuaGlobal_classInstantiations(instantiations);
     944              : 
     945              :         UG_LOG(endl << "--- Class Instantiations: ---------" << endl)
     946            0 :         if(instantiations.empty()) return;
     947            0 :         int maxLength = (*max_element(instantiations.begin(), instantiations.end(), IsLonger)).size();
     948            0 :         for(size_t i=0; i<instantiations.size(); i++)
     949              :         {
     950            0 :                 lua_getglobal(L, instantiations[i].c_str());
     951              : 
     952              :                 const char * type = "UNKNOWN";
     953              :                 int ref = 0;
     954            0 :                 void* ptr = lua_touserdata(L, 1);
     955              :                 
     956              :         //      we perform delete if the user-data is a raw pointer
     957            0 :                 if(((lua::UserDataWrapper*)ptr)->is_raw_ptr()){
     958              :                         type = "raw ptr ";
     959              :                 }
     960            0 :                 else if(((lua::UserDataWrapper*)ptr)->is_smart_ptr()){
     961              : 
     962              :                 //      invalidate the associated smart-pointer
     963            0 :                         if(((lua::UserDataWrapper*)ptr)->is_const())
     964              :                         {
     965              :                                 type = "ConstSmartPtr ";
     966              :                                 ref = ((lua::ConstSmartUserDataWrapper*)ptr)->smartPtr.refcount();
     967              :                         }
     968              :                         else
     969              :                         {
     970              :                                 type = "SmartPtr ";
     971              :                                 ref =  ((lua::SmartUserDataWrapper*)ptr)->smartPtr.refcount();
     972              :                         }
     973              :                 }
     974              : 
     975            0 :                 if(!lua_isuserdata(L, -1)) continue;
     976            0 :                 const std::vector<const char*> *n  = GetClassNames(L, -1);
     977            0 :                 if(n && !n->empty())
     978              :                 {
     979              :                         UG_LOG(left << setw(maxLength) << instantiations[i]);
     980            0 :                         if(ref != 0)
     981            0 :                         {       UG_LOG(" refcount = " << ref << "\t"); }
     982            0 :                         UG_LOG(type);
     983              : //                      for(size_t j = 0; j < n->size(); j++)
     984              : //                      {
     985              : //                              if(j > 0) UG_LOG(", ");
     986              : //                              UG_LOG(n->at(j));
     987              : //                      }
     988              : //                      UG_LOG(endl);
     989            0 :                         UG_LOG(n->at(0));
     990              : 
     991              :                         UG_LOG("\n");
     992              :                 }
     993            0 :                 lua_pop(L, 1);
     994              :         }
     995            0 : }
     996              : 
     997              : 
     998            0 : void LuaList()
     999              : {
    1000            0 :         LuaList_cfunctions();
    1001            0 :         LuaList_classes();
    1002            0 :         LuaList_internalFunctions();
    1003            0 :         LuaList_luaObjects();
    1004            0 :         LuaList_scriptFunctions();
    1005            0 : }
    1006              : 
    1007            0 : string GetLuaTypeString(lua_State* L, int index)
    1008              : {
    1009            0 :         if(lua_isnil(L, index))
    1010            0 :                 return string("nil");
    1011            0 :         string str("");
    1012              :         // somehow lua_typeinfo always prints userdata
    1013            0 :         if(lua_isboolean(L, index)) str.append("boolean/");
    1014            0 :         if(lua_iscfunction(L, index)) str.append("cfunction/");
    1015            0 :         if(lua_isfunction(L, index)) str.append("function/");
    1016            0 :         if(lua_islightuserdata(L, index)) str.append("lightuserdata/");
    1017            0 :         if(lua_isnil(L, index)) str.append("nil/");
    1018            0 :         if(lua_isnone(L, index)) str.append("none/");
    1019            0 :         if(lua_isnumber(L, index))      str.append("number/");
    1020            0 :         if(lua_isstring(L, index)) str.append("string/");
    1021              : 
    1022            0 :         if(lua_istable(L, index)) {
    1023              :                 //lua_pushnil(L);
    1024              :                 //str.append("{");
    1025              :                 /*bool bFirst = true;
    1026              :                 while (lua_next(L, index) != 0) {
    1027              :                         if(bFirst) {bFirst = false;} else {str.append(", ");};
    1028              :                         str.append(GetLuaTypeString(L, -1));
    1029              :                         lua_pop(L, 1);
    1030              :            }*/
    1031            0 :                 str.append("table/");
    1032              :         }
    1033            0 :         if(lua_isthread(L, index)) str.append("thread/");
    1034            0 :         if(lua_isuserdata(L, index))
    1035              :         {
    1036            0 :                 if(((lua::UserDataWrapper*)lua_touserdata(L, index))->is_const()){
    1037            0 :                         str.append("const ");
    1038              :                 }
    1039            0 :                 const ClassNameNode* classNameNode = GetClassNameNode(L, index);
    1040            0 :                 if(classNameNode == NULL || classNameNode->empty()) str.append("userdata/");
    1041              :                 else str.append(classNameNode->name());
    1042            0 :                 str.append("*/");
    1043              :         }
    1044              : 
    1045            0 :         if(lua_type(L, index) == LUA_TNONE)     str.append("none/");
    1046              : 
    1047            0 :         if(str.size() == 0)
    1048            0 :                 return string("unknown type");
    1049              :         else
    1050            0 :                 return str.substr(0, str.size()-1);
    1051              : }
    1052              : 
    1053              : 
    1054              : /**
    1055              :  * @param L
    1056              :  * @param entry (out) returns the lua_Debug entry associated with the deepest call stack level (the "current line")
    1057              :  */
    1058            0 : void LuaGetLastLine(lua_State* L, lua_Debug entry)
    1059              : {
    1060            0 :     for(int depth = 0; lua_getstack(L, depth, &entry); depth++)
    1061              :         {
    1062            0 :         int status = lua_getinfo(L, "Sln", &entry);
    1063            0 :         if(!status || entry.currentline < 0) continue;
    1064              :     }
    1065            0 : }
    1066              : 
    1067              : /**
    1068              :  * @param L
    1069              :  * @return the current line with content
    1070              :  * example:
    1071              :  * @/Users/mrupp/Documents/workspace/ug4svn/apps/amg//setup.lua:576        local dim = p.approxSpace:get_dim()
    1072              :  */
    1073            0 : string LuaCurrentLine(lua_State* L)
    1074              : {
    1075            0 :         std::stringstream ss;
    1076              :         lua_Debug entry;
    1077            0 :         LuaGetLastLine(L, entry);
    1078            0 :         ss << entry.short_src << ":" << entry.currentline;
    1079            0 :         ss << " " << GetFileLine(entry.short_src, entry.currentline) << "\n";
    1080            0 :         return ss.str();
    1081              : 
    1082            0 : }
    1083              : 
    1084              : /**
    1085              :  * this function returns e.g.
    1086              :  * 1  @/Users/mrupp/Documents/workspace/ug4svn/apps/amg//setup.lua:576        local dim = p.approxSpace:get_dim()
    1087              :  * 2  @/Users/mrupp/Documents/workspace/ug4svn/apps/amg//setup.lua:649        amgsetup.CreateApproxSpaceAndDisc()
    1088              :  * 3  @/Users/mrupp/Documents/workspace/ug4svn/apps/amg/famg_laplace.lua:21   amgsetup.LoadStdDomAndApproxSpace()
    1089              :  * @param L
    1090              :  * @param fromLevel  where to start
    1091              :  * @param toLevel  how far we want to go back
    1092              :  * @return a list list
    1093              :  */
    1094            0 : string LuaStackTraceString(lua_State* L, int fromLevel, int toLevel)
    1095              : {
    1096              :         StringTableStream sts;
    1097              :     lua_Debug entry;
    1098              : 
    1099              :     std::vector<string> filenames;
    1100              : 
    1101              :     //sts.table().set_col_alignments("ll");
    1102              :     int luaLevel=0;
    1103            0 :     for(int depth = 0; lua_getstack(L, depth, &entry); depth++)
    1104              :         {
    1105            0 :                 int status = lua_getinfo(L, "Sln", &entry);
    1106            0 :                 if(entry.currentline <0) continue;
    1107            0 :                 if(!status || !entry.source || entry.currentline < 0) continue;
    1108            0 :                 luaLevel++;
    1109            0 :                 if(luaLevel < fromLevel) continue;
    1110              :                 // first col
    1111            0 :                 sts << (Stringify() << " " << luaLevel << "  " << entry.source << ":" << entry.currentline).str();
    1112              :                 // second col
    1113            0 :                 sts << TrimString(GetFileLine(entry.source, entry.currentline));
    1114              :                 // next row
    1115            0 :                 sts << "\n";
    1116            0 :                 if(luaLevel == toLevel) break;
    1117              :         }
    1118              : 
    1119            0 :     return sts.to_string();
    1120            0 : }
    1121              : 
    1122              : /// returns the current file and line ( \sa LuaStackTrace ).
    1123            0 : bool GetLuaFileAndLine(lua_State* L, std::string &file, size_t &line)
    1124              : {
    1125              :         file = "unknown";
    1126            0 :         line = -1;
    1127              :         lua_Debug entry;
    1128            0 :         for(int depth = 0; lua_getstack(L, depth, &entry); depth++)
    1129              :         {
    1130            0 :                 int status = lua_getinfo(L, "Sln", &entry);
    1131            0 :                 if(!status || !entry.source || entry.currentline <0) continue;
    1132              :                 file = entry.source;
    1133            0 :                 line = entry.currentline;
    1134            0 :                 return true;
    1135              :         }
    1136              :         return false;
    1137              : }
    1138              : 
    1139              : /// returns the current file and line ( \sa LuaStackTrace ).
    1140            0 : std::string GetLuaFileAndLine(lua_State* L)
    1141              : {
    1142              :         PROFILE_FUNC();
    1143              :         string file; size_t line;
    1144            0 :         if(GetLuaFileAndLine(L, file, line) == false) return "[LUA File could not be determined]";
    1145            0 :         std::stringstream ss;
    1146            0 :         if(GetLogAssistant().is_output_process())
    1147            0 :                 ss << file << ":" << line << " " << GetFileLine(file.c_str(), line);
    1148              :         else
    1149            0 :                 ss << file << ":" << line;
    1150              : 
    1151              :         return ss.str();
    1152            0 : }
    1153              : 
    1154            0 : std::string GetLuaFileAndLineNumber(lua_State* L)
    1155              : {
    1156              :         string file; size_t line;
    1157            0 :         if(GetLuaFileAndLine(L, file, line) == false) return "[ --unknown file -- ]";
    1158            0 :         std::stringstream ss;
    1159            0 :         ss << file << ":" << line;
    1160              :         return ss.str();
    1161            0 : }
    1162              : 
    1163            0 : std::string GetLuaLine(lua_State* L)
    1164              : {
    1165              :         PROFILE_FUNC();
    1166              :         string file; size_t line;
    1167            0 :         if(GetLuaFileAndLine(L, file, line) == false) return "[ --unknown script line -- ]";
    1168            0 :         if(GetLogAssistant().is_output_process())
    1169            0 :                 return GetFileLine(file.c_str(), line);
    1170              :         else
    1171            0 :                 return Stringify() << file << ":" << line;
    1172              : }
    1173              : 
    1174            0 : std::string LuaStackTraceString()
    1175              : {
    1176            0 :         return LuaStackTraceString(script::GetDefaultLuaState(), 0, -1);
    1177              : }
    1178              : 
    1179            0 : void LuaStackTrace(int fromLevel)
    1180              : {
    1181            0 :         UG_LOG(LuaStackTraceString(script::GetDefaultLuaState(), fromLevel, -1));
    1182            0 : }
    1183              : 
    1184            0 : void ScriptPrintClassHierarchy(const char *classname)
    1185              : {
    1186            0 :         UG_LOG(ClassHierarchyString(GetUGRegistry(), classname));
    1187            0 : }
    1188              : 
    1189              :         
    1190            0 : bool ScriptHasClass(const char *classname)
    1191              : {
    1192            0 :         const Registry &reg = GetUGRegistry();
    1193            0 :         return reg.get_class(classname) != NULL;
    1194              : }
    1195              : 
    1196            0 : bool ScriptHasClassGroup(const char *classname)
    1197              : {
    1198            0 :         const Registry &reg = GetUGRegistry();
    1199            0 :         return reg.get_class_group(classname) != NULL;
    1200              : }
    1201              : 
    1202            0 : void ScriptPrintClassUsage(const char *classname)
    1203              : {
    1204            0 :         UG_LOG(ClassUsage(classname));
    1205            0 : }
    1206              : 
    1207              : #ifdef UG_PLUGINS
    1208            0 : bool PluginRequired(const char *name)
    1209              : {
    1210            0 :         if(PluginLoaded(name) == false)
    1211              :         {
    1212            0 :                 string msg = string("plugin ") + name + string(" not loaded. Please use 'cmake -D") + name + string("=ON .' in your build directory.");           
    1213              :                 std::string file; size_t line;
    1214            0 :                 if(GetLuaFileAndLine(script::GetDefaultLuaState(), file, line))
    1215            0 :                         throw UGError(msg.c_str(), file.c_str(), line);
    1216              :                 else
    1217            0 :                         throw UGError(msg.c_str());
    1218              :                 return false;
    1219              :         }
    1220              :         return true;
    1221              : }
    1222              : #endif
    1223              : 
    1224            0 : void EnableLUA2C(bool b)
    1225              : {
    1226              : #ifndef USE_LUA2C
    1227              :         UG_LOG("Warning: LUA2C not enabled. Enable with \"cmake -DUSE_LUA2C=ON ..\"\n")
    1228              : #else
    1229              :         useLuaCompiler=b;
    1230              :         useLua2VM=false;
    1231              : #endif
    1232            0 : }
    1233              : 
    1234            0 : void EnableLUA2VM(bool b)
    1235              : {
    1236            0 :         useLuaCompiler=b;
    1237            0 :         useLua2VM=b;
    1238            0 : }
    1239              : 
    1240              : bool RegisterSerializationCommands(Registry &reg, const char* parentGroup);
    1241              : 
    1242            1 : bool RegisterInfoCommands(Registry &reg, const char* parentGroup)
    1243              : {
    1244            1 :         RegisterSerializationCommands(reg, parentGroup);
    1245            1 :         stringstream grpSS; grpSS << parentGroup << "/Info";
    1246              :         std::string grp = grpSS.str();
    1247              : 
    1248              :         try
    1249              :         {
    1250            2 :                 reg.add_function("ls", &LuaList, grp.c_str(), 
    1251              :                                  "", "", "list all objects");
    1252            2 :                 reg.add_function("list_cfunctions", &LuaList_cfunctions, grp.c_str(), 
    1253              :                                  "", "", "list all cfunctions");
    1254            2 :                 reg.add_function("list_classes", &LuaList_classes, grp.c_str(), 
    1255              :                                  "", "", "list all classes");
    1256            2 :                 reg.add_function("list_internalFunctions", &LuaList_internalFunctions, grp.c_str(), 
    1257              :                                  "", "", "list all of LUAs internal functions");
    1258            2 :                 reg.add_function("list_luaObjects", &LuaList_luaObjects, grp.c_str(), 
    1259              :                                  "", "", "list all created LUA objects");
    1260            2 :                 reg.add_function("list_scriptFunctions", LuaList_scriptFunctions, grp.c_str(), 
    1261              :                                  "", "", "list all LUA script functions");
    1262            2 :                 reg.add_function("list_objects", LuaList_classInstantiations, grp.c_str(),
    1263              :                                                  "", "", "list all LUA class objects");
    1264              : 
    1265            2 :                 reg.add_function("TypeInfo", &UGTypeInfo, grp.c_str(), 
    1266              :                                  "", "typeName", "print information about a type");
    1267            2 :                 reg.add_function("ClassUsage", &ScriptPrintClassUsage, grp.c_str(),
    1268              :                                  "", "typeName", "print information about the usage of a type");
    1269            2 :                 reg.add_function("ClassInstantiations" ,&ClassInstantiations, grp.c_str(), 
    1270              :                                  "", "typeName", "print all objects of the type");
    1271            2 :                 reg.add_function("ClassHierarchy" ,&ScriptPrintClassHierarchy, grp.c_str(), 
    1272              :                                  "", "typeName", "print the class hierachy of type");
    1273            2 :                 reg.add_function("Stacktrace", &LuaStackTrace, grp.c_str(),
    1274              :                                  "", "", "prints the LUA function stack, that is which functions are called up to this point");
    1275            2 :                 reg.add_function("HasClass", &ScriptHasClass, grp.c_str(), 
    1276              :                                  "true if class exists", "className", "use only if you know that you're not using a class group, otherwise HasClassGroup");
    1277            2 :                 reg.add_function("HasClassGroup", &ScriptHasClassGroup, grp.c_str(), 
    1278              :                                  "true if class oder classGroup exists", "classGroupName", "can be used before instantiating a class");
    1279              : #ifdef UG_PLUGINS
    1280            2 :                 reg.add_function("PluginLoaded", &PluginLoaded, grp.c_str(), 
    1281              :                                  "true if plugin loaded", "pluginName", "pluginName as listed when using cmake ..");
    1282              : 
    1283            2 :                 reg.add_function("PluginRequired", &PluginRequired, grp.c_str(),
    1284              :                                  "true if plugin loaded", "pluginName", "throws an error if plugin not loaded, displays help string how to enable plugins via cmake -DpluginName=ON ..");
    1285            2 :                 reg.add_function("GetLoadedPlugins", &GetLoadedPlugins, grp.c_str(), 
    1286              :                                  "list of loaded plugins names", "", "");
    1287              : #endif
    1288            2 :                 reg.add_function("EnableLUA2C", &EnableLUA2C, grp.c_str(), 
    1289              :                                  "", "bEnable", "");
    1290            2 :                 reg.add_function("EnableLUA2VM", &EnableLUA2VM, grp.c_str(),
    1291              :                                 "", "bEnable", "");
    1292            2 :                 reg.add_function("InitSignals", &InitSignals, grp.c_str());
    1293              :         }
    1294            0 :         UG_REGISTRY_CATCH_THROW(grp);
    1295              : 
    1296            1 :         return true;
    1297            1 : }
    1298              : 
    1299              : 
    1300              : } // namespace bridge
    1301              : 
    1302              : } // namespace ug
        

Generated by: LCOV version 2.0-1