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 ® = 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 ® = 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 ® = 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 ® = 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 ® = 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 ® = 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 ® = GetUGRegistry();
1193 0 : return reg.get_class(classname) != NULL;
1194 : }
1195 :
1196 0 : bool ScriptHasClassGroup(const char *classname)
1197 : {
1198 0 : const Registry ® = 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 ®, const char* parentGroup);
1241 :
1242 1 : bool RegisterInfoCommands(Registry ®, 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
|