Fawkes API  Fawkes Development Version
context.cpp
1 
2 /***************************************************************************
3  * context.cpp - Fawkes Lua Context
4  *
5  * Created: Fri May 23 15:53:54 2008
6  * Copyright 2006-2009 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include <lua/context.h>
24 #include <lua/context_watcher.h>
25 #include <core/threading/mutex.h>
26 #include <core/threading/mutex_locker.h>
27 #include <core/exceptions/system.h>
28 #include <core/exceptions/software.h>
29 #include <logging/liblogger.h>
30 
31 #include <algorithm>
32 #include <tolua++.h>
33 #include <cstdlib>
34 #include <cstring>
35 #include <unistd.h>
36 
37 #ifndef lua_objlen
38 #define lua_objlen(L,i) lua_rawlen(L, (i))
39 #endif
40 
41 #if LUA_VERSION_NUM < 502
42 # define lua_getuservalue lua_getfenv
43 # define lua_setuservalue lua_setfenv
44 #endif
45 
46 namespace fawkes {
47 #if 0 /* just to make Emacs auto-indent happy */
48 }
49 #endif
50 
51 /** @class LuaContext <lua/context.h>
52  * Lua C++ wrapper.
53  * This thin wrapper allows for easy integration of Fawkes into other
54  * applications. It provides convenience methods to some Lua and
55  * tolua++ features like setting global variables or pushing/popping
56  * values.
57  *
58  * It allows raw access to the Lua state since this class does not and
59  * should not provide all the features Lua provides. If you use this
60  * make sure that you lock the Lua context to avoid multi-threading
61  * problems (if that is a possible concern in your application).
62  *
63  * LuaContext can use a FileAlterationMonitor on all added package and
64  * C package directories. If anything changes in these directories the
65  * Lua instance is then automatically restarted (closed, re-opened and
66  * re-initialized).
67  *
68  * @author Tim Niemueller
69  */
70 
71 /** Constructor.
72  * @param enable_tracebacks if true an error function is installed at the top
73  * of the stackand used for pcalls where errfunc is 0.
74  */
75 LuaContext::LuaContext(bool enable_tracebacks)
76 {
77  __owns_L = true;
78  __enable_tracebacks = enable_tracebacks;
79  __fam = NULL;
80  __fam_thread = NULL;
81 
82  __lua_mutex = new Mutex();
83 
84  __start_script = NULL;
85  __L = init_state();
86 }
87 
88 /** Wrapper contstructor.
89  * This wraps around an existing Lua state. It does not initialize the state in
90  * the sense that it would add variables etc. It only provides convenient access
91  * to the state methods via a C++ interface. It's mainly intended to be used to
92  * create a LuaContext to be passed to LuaContextWatcher::lua_restarted(). The
93  * state is not closed on destruction as is done when using the other ctor.
94  * @param L Lua state to wrap
95  */
96 LuaContext::LuaContext(lua_State *L)
97 {
98  __owns_L = false;
99  __L = L;
100  __lua_mutex = new Mutex();
101  __start_script = NULL;
102  __fam = NULL;
103  __fam_thread = NULL;
104 }
105 
106 /** Destructor. */
107 LuaContext::~LuaContext()
108 {
109  __lua_mutex->lock();
110  if (__fam_thread) {
111  __fam_thread->cancel();
112  __fam_thread->join();
113  delete __fam_thread;
114  }
115  delete __lua_mutex;
116  if ( __start_script ) free(__start_script);
117  if ( __owns_L) {
118  lua_close(__L);
119  }
120 }
121 
122 
123 /** Setup file alteration monitor.
124  * Setup an internal file alteration monitor that can react to changes
125  * on Lua files and packages.
126  * @param auto_restart automatically restart the Lua context in case
127  * of an event
128  * @param conc_thread true to run a concurrent thread for event
129  * processing. If and only if you set this to false, ensure that
130  * process_fam_events() periodically.
131  */
132 void
133 LuaContext::setup_fam(bool auto_restart, bool conc_thread)
134 {
135  __fam = new FileAlterationMonitor();
136  __fam->add_filter("^[^.].*\\.lua$");
137  if (auto_restart) {
138  __fam->add_listener(this);
139  }
140  if (conc_thread) {
141  __fam_thread = new FamThread(__fam);
142  __fam_thread->start();
143  }
144 }
145 
146 
147 /** Get file alteration monitor.
148  * @return reference counted pointer to file alteration monitor. Note
149  * that the pointer might be invalid if setup_fam() has not been called.
150  */
152 LuaContext::get_fam() const
153 {
154  return __fam;
155 }
156 
157 
158 /** Initialize Lua state.
159  * Initializes the state and makes all necessary initializations.
160  * @return fresh initialized Lua state
161  */
162 lua_State *
163 LuaContext::init_state()
164 {
165  lua_State *L = luaL_newstate();
166  luaL_openlibs(L);
167 
168  if (__enable_tracebacks) {
169  lua_getglobal(L, "debug");
170  lua_getfield(L, -1, "traceback");
171  lua_remove(L, -2);
172  }
173 
174  // Add package paths
175  for (__slit = __package_dirs.begin(); __slit != __package_dirs.end(); ++__slit) {
176  do_string(L, "package.path = package.path .. \";%s/?.lua;%s/?/init.lua\"", __slit->c_str(), __slit->c_str());
177  }
178 
179  for (__slit = __cpackage_dirs.begin(); __slit != __cpackage_dirs.end(); ++__slit) {
180  do_string(L, "package.cpath = package.cpath .. \";%s/?.so\"", __slit->c_str());
181  }
182 
183  // load base packages
184  for (__slit = __packages.begin(); __slit != __packages.end(); ++__slit) {
185  do_string(L, "require(\"%s\")", __slit->c_str());
186  }
187 
188  for ( __utit = __usertypes.begin(); __utit != __usertypes.end(); ++__utit) {
189  tolua_pushusertype(L, __utit->second.first, __utit->second.second.c_str());
190  lua_setglobal(L, __utit->first.c_str());
191  }
192 
193  for ( __strings_it = __strings.begin(); __strings_it != __strings.end(); ++__strings_it) {
194  lua_pushstring(L, __strings_it->second.c_str());
195  lua_setglobal(L, __strings_it->first.c_str());
196  }
197 
198  for ( __booleans_it = __booleans.begin(); __booleans_it != __booleans.end(); ++__booleans_it) {
199  lua_pushboolean(L, __booleans_it->second);
200  lua_setglobal(L, __booleans_it->first.c_str());
201  }
202 
203  for ( __numbers_it = __numbers.begin(); __numbers_it != __numbers.end(); ++__numbers_it) {
204  lua_pushnumber(L, __numbers_it->second);
205  lua_setglobal(L, __numbers_it->first.c_str());
206  }
207 
208  for ( __integers_it = __integers.begin(); __integers_it != __integers.end(); ++__integers_it) {
209  lua_pushinteger(L, __integers_it->second);
210  lua_setglobal(L, __integers_it->first.c_str());
211  }
212 
213  for ( __cfuncs_it = __cfuncs.begin(); __cfuncs_it != __cfuncs.end(); ++__cfuncs_it)
214  {
215  lua_pushcfunction(L, __cfuncs_it->second);
216  lua_setglobal(L, __cfuncs_it->first.c_str());
217  }
218 
219  LuaContext *tmpctx = new LuaContext(L);
220  MutexLocker(__watchers.mutex());
221  LockList<LuaContextWatcher *>::iterator i;
222  for (i = __watchers.begin(); i != __watchers.end(); ++i) {
223  try {
224  (*i)->lua_restarted(tmpctx);
225  } catch (...) {
226  delete tmpctx;
227  lua_close(L);
228  throw;
229  }
230  }
231  delete tmpctx;
232 
233  if ( __start_script ) {
234  if (access(__start_script, R_OK) == 0) {
235  // it's a file and we can access it, execute it!
236  do_file(L, __start_script);
237  } else {
238  do_string(L, "require(\"%s\")", __start_script);
239  }
240  }
241 
242  return L;
243 }
244 
245 
246 /** Set start script.
247  * The script will be executed once immediately in this method, make
248  * sure you call this after all other init-relevant routines like
249  * add_* if you need to access these in the start script!
250  * @param start_script script to execute now and on restart(). If the
251  * string is the path and name of an accessible file it is loaded via
252  * do_file(), otherwise it is considered to be the name of a module and
253  * loaded via Lua's require(). Note however, that if you use a module,
254  * special care has to be taken to correctly modify the global
255  * environment!
256  */
257 void
258 LuaContext::set_start_script(const char *start_script)
259 {
260  if ( __start_script ) free(__start_script);
261  if ( start_script ) {
262  __start_script = strdup(start_script);
263  if (access(__start_script, R_OK) == 0) {
264  // it's a file and we can access it, execute it!
265  do_file(__start_script);
266  } else {
267  do_string("require(\"%s\")", __start_script);
268  }
269  } else {
270  __start_script = NULL;
271  }
272 }
273 
274 
275 /** Restart Lua.
276  * Creates a new Lua state, initializes it, anf if this went well the
277  * current state is swapped with the new state.
278  */
279 void
280 LuaContext::restart()
281 {
282  MutexLocker lock(__lua_mutex);
283  try {
284  lua_State *L = init_state();
285  lua_State *tL = __L;
286  __L = L;
287  lua_close(tL);
288 
289  } catch (Exception &e) {
290  LibLogger::log_error("LuaContext", "Could not restart Lua instance, an error "
291  "occured while initializing new state. Keeping old state.");
292  LibLogger::log_error("LuaContext", e);
293  }
294 }
295 
296 
297 /** Add a Lua package directory.
298  * The directory is added to the search path for lua packages. Files with
299  * a .lua suffix will be considered as Lua modules.
300  * @param path path to add
301  */
302 void
303 LuaContext::add_package_dir(const char *path)
304 {
305  MutexLocker lock(__lua_mutex);
306 
307  do_string(__L, "package.path = package.path .. \";%s/?.lua;%s/?/init.lua\"", path, path);
308 
309  __package_dirs.push_back(path);
310  if ( __fam ) __fam->watch_dir(path);
311 }
312 
313 
314 /** Add a Lua C package directory.
315  * The directory is added to the search path for lua C packages. Files
316  * with a .so suffix will be considered as Lua modules.
317  * @param path path to add
318  */
319 void
320 LuaContext::add_cpackage_dir(const char *path)
321 {
322  MutexLocker lock(__lua_mutex);
323 
324  do_string(__L, "package.cpath = package.cpath .. \";%s/?.so\"", path);
325 
326  __cpackage_dirs.push_back(path);
327  if ( __fam ) __fam->watch_dir(path);
328 }
329 
330 
331 /** Add a default package.
332  * Packages that are added this way are automatically loaded now and
333  * on restart().
334  * @param package package to add
335  */
336 void
337 LuaContext::add_package(const char *package)
338 {
339  MutexLocker lock(__lua_mutex);
340  if (find(__packages.begin(), __packages.end(), package) == __packages.end()) {
341  do_string(__L, "require(\"%s\")", package);
342 
343  __packages.push_back(package);
344  }
345 }
346 
347 
348 /** Get Lua state.
349  * Allows for raw modification of the used Lua state. Remember proper
350  * locking!
351  * @return Currently used Lua state
352  */
353 lua_State *
354 LuaContext::get_lua_state()
355 {
356  return __L;
357 }
358 
359 
360 /** Lock Lua state. */
361 void
362 LuaContext::lock()
363 {
364  __lua_mutex->lock();
365 }
366 
367 
368 /** Try to lock the Lua state.
369  * @return true if the state has been locked, false otherwise.
370  */
371 bool
372 LuaContext::try_lock()
373 {
374  return __lua_mutex->try_lock();
375 }
376 
377 
378 /** Unlock Lua state. */
379 void
380 LuaContext::unlock()
381 {
382  __lua_mutex->unlock();
383 }
384 
385 
386 /** Execute file.
387  * @param filename filet to load and excute.
388  */
389 void
390 LuaContext::do_file(const char *filename)
391 {
392  MutexLocker lock(__lua_mutex);
393  do_file(__L, filename);
394 }
395 
396 
397 /** Execute file on a specific Lua state.
398  * @param L Lua state to execute the file in.
399  * @param filename filet to load and excute.
400  */
401 void
402 LuaContext::do_file(lua_State *L, const char *filename)
403 {
404  // Load initialization code
405  int err = 0;
406  std::string errmsg;
407  if ( (err = luaL_loadfile(L, filename)) != 0) {
408  errmsg = lua_tostring(L, -1);
409  lua_pop(L, 1);
410  switch (err) {
411  case LUA_ERRSYNTAX:
412  throw SyntaxErrorException("Lua syntax error in file %s: %s", filename, errmsg.c_str());
413 
414  case LUA_ERRMEM:
415  throw OutOfMemoryException("Could not load Lua file %s", filename);
416 
417  case LUA_ERRFILE:
418  throw CouldNotOpenFileException(filename, errmsg.c_str());
419  }
420  }
421 
422  int errfunc = __enable_tracebacks ? 1 : 0;
423  if ( (err = lua_pcall(L, 0, LUA_MULTRET, errfunc)) != 0 ) {
424  // There was an error while executing the initialization file
425  errmsg = lua_tostring(L, -1);
426  lua_pop(L, 1);
427  switch (err) {
428  case LUA_ERRRUN:
429  throw LuaRuntimeException("do_file", errmsg.c_str());
430 
431  case LUA_ERRMEM:
432  throw OutOfMemoryException("Could not execute Lua file %s", filename);
433 
434  case LUA_ERRERR:
435  throw LuaErrorException("do_file", errmsg.c_str());
436 
437  default:
438  throw LuaErrorException("do_file/unknown error", errmsg.c_str());
439  }
440  }
441 
442 }
443 
444 
445 /** Execute string on a specific Lua state.
446  * @param L Lua state to execute the string in
447  * @param format format of string to execute, arguments can be the same as
448  * for vasprintf.
449  */
450 void
451 LuaContext::do_string(lua_State *L, const char *format, ...)
452 {
453  va_list arg;
454  va_start(arg, format);
455  char *s;
456  if (vasprintf(&s, format, arg) == -1) {
457  throw Exception("LuaContext::do_string: Could not form string");
458  }
459 
460  int rv = 0;
461  int errfunc = __enable_tracebacks ? 1 : 0;
462  rv = (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, errfunc));
463 
464  free(s);
465  va_end(arg);
466 
467  if (rv != 0) {
468  std::string errmsg = lua_tostring(L, -1);
469  lua_pop(L, 1);
470  throw LuaRuntimeException("do_string", errmsg.c_str());
471  }
472 }
473 
474 
475 /** Execute string.
476  * @param format format of string to execute, arguments can be the same as
477  * for vasprintf.
478  */
479 void
480 LuaContext::do_string(const char *format, ...)
481 {
482  MutexLocker lock(__lua_mutex);
483  va_list arg;
484  va_start(arg, format);
485  char *s;
486  if (vasprintf(&s, format, arg) == -1) {
487  throw Exception("LuaContext::do_string: Could not form string");
488  }
489 
490  int rv = 0;
491  int errfunc = __enable_tracebacks ? 1 : 0;
492  rv = (luaL_loadstring(__L, s) || lua_pcall(__L, 0, LUA_MULTRET, errfunc));
493 
494  free(s);
495  va_end(arg);
496 
497  if ( rv != 0 ) {
498  std::string errmsg = lua_tostring(__L, -1);
499  lua_pop(__L, 1);
500  throw LuaRuntimeException("do_string", errmsg.c_str());
501  }
502 }
503 
504 
505 /** Load Lua string.
506  * Loads the Lua string and places it as a function on top of the stack.
507  * @param s string to load
508  */
509 void
510 LuaContext::load_string(const char *s)
511 {
512  int err;
513  if ( (err = luaL_loadstring(__L, s)) != 0 ) {
514  std::string errmsg = lua_tostring(__L, -1);
515  lua_pop(__L, 1);
516  switch (err) {
517  case LUA_ERRSYNTAX:
518  throw SyntaxErrorException("Lua syntax error in string '%s': %s",
519  s, errmsg.c_str());
520 
521  case LUA_ERRMEM:
522  throw OutOfMemoryException("Could not load Lua string '%s'", s);
523  }
524  }
525 }
526 
527 
528 /** Protected call.
529  * Calls the function on top of the stack. Errors are handled gracefully.
530  * @param nargs number of arguments
531  * @param nresults number of results
532  * @param errfunc stack index of an error handling function
533  * @exception Exception thrown for generic runtime error or if the
534  * error function could not be executed.
535  * @exception OutOfMemoryException thrown if not enough memory was available
536  */
537 void
538 LuaContext::pcall(int nargs, int nresults, int errfunc)
539 {
540  int err = 0;
541  if ( ! errfunc && __enable_tracebacks ) errfunc = 1;
542  if ( (err = lua_pcall(__L, nargs, nresults, errfunc)) != 0 ) {
543  std::string errmsg = lua_tostring(__L, -1);
544  lua_pop(__L, 1);
545  switch (err) {
546  case LUA_ERRRUN:
547  throw LuaRuntimeException("pcall", errmsg.c_str());
548 
549  case LUA_ERRMEM:
550  throw OutOfMemoryException("Could not execute Lua chunk via pcall");
551 
552  case LUA_ERRERR:
553  throw LuaErrorException("pcall", errmsg.c_str());
554  }
555  }
556 }
557 
558 
559 /** Assert that the name is unique.
560  * Checks the internal context structures if the name has been used
561  * already. It will accept a value that has already been set that is of the same
562  * type as the one supplied. Pass the empty string to avoid this.
563  * @param name name to check
564  * @param type type of value
565  * @exception Exception thrown if name is not unique
566  */
567 void
568 LuaContext::assert_unique_name(const char *name, std::string type)
569 {
570  if ( (type == "usertype") && (__usertypes.find(name) != __usertypes.end()) ) {
571  throw Exception("User type entry already exists for name %s", name);
572  }
573  if ( (type == "string") && (__strings.find(name) != __strings.end()) ) {
574  throw Exception("String entry already exists for name %s", name);
575  }
576  if ( (type == "boolean") && (__booleans.find(name) != __booleans.end()) ) {
577  throw Exception("Boolean entry already exists for name %s", name);
578  }
579  if ( (type == "number") && (__numbers.find(name) != __numbers.end()) ) {
580  throw Exception("Number entry already exists for name %s", name);
581  }
582  if ( (type == "integer") && (__integers.find(name) != __integers.end()) ) {
583  throw Exception("Integer entry already exists for name %s", name);
584  }
585  if ( (type == "cfunction") && (__cfuncs.find(name) != __cfuncs.end()) ) {
586  throw Exception("C function entry already exists for name %s", name);
587  }
588 }
589 
590 
591 /** Assign usertype to global variable.
592  * @param name name of global variable to assign the value to
593  * @param data usertype data
594  * @param type_name type name of the data
595  * @param name_space C++ namespace of type, prepended to type_name
596  */
597 void
598 LuaContext::set_usertype(const char *name, void *data,
599  const char *type_name, const char *name_space)
600 {
601  MutexLocker lock(__lua_mutex);
602 
603  std::string type_n = type_name;
604  if ( name_space ) {
605  type_n = std::string(name_space) + "::" + type_name;
606  }
607 
608  assert_unique_name(name, "usertype");
609 
610  __usertypes[name] = std::make_pair(data, type_n);
611 
612  tolua_pushusertype(__L, data, type_n.c_str());
613  lua_setglobal(__L, name);
614 }
615 
616 
617 /** Assign string to global variable.
618  * @param name name of global variable to assign the value to
619  * @param value value to assign
620  */
621 void
622 LuaContext::set_string(const char *name, const char *value)
623 {
624  MutexLocker lock(__lua_mutex);
625  assert_unique_name(name, "string");
626 
627  __strings[name] = value;
628 
629  lua_pushstring(__L, value);
630  lua_setglobal(__L, name);
631 }
632 
633 
634 /** Assign boolean to global variable.
635  * @param name name of global variable to assign the value to
636  * @param value value to assign
637  */
638 void
639 LuaContext::set_boolean(const char *name, bool value)
640 {
641  MutexLocker lock(__lua_mutex);
642  assert_unique_name(name, "boolean");
643 
644  __booleans[name] = value;
645 
646  lua_pushboolean(__L, value ? 1 : 0);
647  lua_setglobal(__L, name);
648 }
649 
650 
651 /** Assign number to global variable.
652  * @param name name of global variable to assign the value to
653  * @param value value to assign
654  */
655 void
656 LuaContext::set_number(const char *name, lua_Number value)
657 {
658  MutexLocker lock(__lua_mutex);
659  assert_unique_name(name, "number");
660 
661  __numbers[name] = value;
662 
663  lua_pushnumber(__L, value);
664  lua_setglobal(__L, name);
665 }
666 
667 
668 /** Assign integer to global variable.
669  * @param name name of global variable to assign the value to
670  * @param value value to assign
671  */
672 void
673 LuaContext::set_integer(const char *name, lua_Integer value)
674 {
675  MutexLocker lock(__lua_mutex);
676  assert_unique_name(name, "integer");
677 
678  __integers[name] = value;
679 
680  lua_pushinteger(__L, value);
681  lua_setglobal(__L, name);
682 }
683 
684 
685 /** Assign cfunction to global variable.
686  * @param name name of global variable to assign the value to
687  * @param f function
688  */
689 void
690 LuaContext::set_cfunction(const char *name, lua_CFunction f)
691 {
692  MutexLocker lock(__lua_mutex);
693  assert_unique_name(name, "cfunction");
694 
695  __cfuncs[name] = f;
696 
697  lua_pushcfunction(__L, f);
698  lua_setglobal(__L, name);
699 }
700 
701 
702 /** Push boolean on top of stack.
703  * @param value value to push
704  */
705 void
706 LuaContext::push_boolean(bool value)
707 {
708  MutexLocker lock(__lua_mutex);
709  lua_pushboolean(__L, value ? 1 : 0);
710 }
711 
712 
713 /** Push formatted string on top of stack.
714  * @param format string format
715  * @see man 3 sprintf
716  */
717 void
718 LuaContext::push_fstring(const char *format, ...)
719 {
720  MutexLocker lock(__lua_mutex);
721  va_list arg;
722  va_start(arg, format);
723  lua_pushvfstring(__L, format, arg);
724  va_end(arg);
725 }
726 
727 
728 /** Push integer on top of stack.
729  * @param value value to push
730  */
731 void
732 LuaContext::push_integer(lua_Integer value)
733 {
734  MutexLocker lock(__lua_mutex);
735  lua_pushinteger(__L, value);
736 }
737 
738 
739 /** Push light user data on top of stack.
740  * @param p pointer to light user data to push
741  */
742 void
743 LuaContext::push_light_user_data(void *p)
744 {
745  MutexLocker lock(__lua_mutex);
746  lua_pushlightuserdata(__L, p);
747 }
748 
749 
750 /** Push substring on top of stack.
751  * @param s string to push
752  * @param len length of string to push
753  */
754 void
755 LuaContext::push_lstring(const char *s, size_t len)
756 {
757  MutexLocker lock(__lua_mutex);
758  lua_pushlstring(__L, s, len);
759 }
760 
761 
762 /** Push nil on top of stack.
763  */
764 void
765 LuaContext::push_nil()
766 {
767  MutexLocker lock(__lua_mutex);
768  lua_pushnil(__L);
769 }
770 
771 
772 /** Push number on top of stack.
773  * @param value value to push
774  */
775 void
776 LuaContext::push_number(lua_Number value)
777 {
778  MutexLocker lock(__lua_mutex);
779  lua_pushnumber(__L, value);
780 }
781 
782 
783 /** Push string on top of stack.
784  * @param value value to push
785  */
786 void
787 LuaContext::push_string(const char *value)
788 {
789  MutexLocker lock(__lua_mutex);
790  lua_pushstring(__L, value);
791 }
792 
793 
794 /** Push thread on top of stack.
795  */
796 void
797 LuaContext::push_thread()
798 {
799  MutexLocker lock(__lua_mutex);
800  lua_pushthread(__L);
801 }
802 
803 
804 /** Push a copy of the element at the given index on top of the stack.
805  * @param idx index of the value to copy
806  */
807 void
808 LuaContext::push_value(int idx)
809 {
810  MutexLocker lock(__lua_mutex);
811  lua_pushvalue(__L, idx);
812 }
813 
814 
815 /** Push formatted string on top of stack.
816  * @param format string format
817  * @param arg variadic argument list
818  * @see man 3 sprintf
819  */
820 void
821 LuaContext::push_vfstring(const char *format, va_list arg)
822 {
823  MutexLocker lock(__lua_mutex);
824  lua_pushvfstring(__L, format, arg);
825 }
826 
827 
828 /** Push usertype on top of stack.
829  * @param data usertype data
830  * @param type_name type name of the data
831  * @param name_space C++ namespace of type, prepended to type_name
832  */
833 void
834 LuaContext::push_usertype(void *data, const char *type_name,
835  const char *name_space)
836 {
837  MutexLocker lock(__lua_mutex);
838 
839  std::string type_n = type_name;
840  if ( name_space ) {
841  type_n = std::string(name_space) + "::" + type_name;
842  }
843 
844  tolua_pushusertype(__L, data, type_n.c_str());
845 }
846 
847 
848 /** Push C function on top of stack.
849  * @param f C Function to push
850  */
851 void
852 LuaContext::push_cfunction(lua_CFunction f)
853 {
854  MutexLocker lock(__lua_mutex);
855  lua_pushcfunction(__L, f);
856 }
857 
858 
859 /** Pop value(s) from stack.
860  * @param n number of values to pop
861  */
862 void
863 LuaContext::pop(int n)
864 {
865  MutexLocker lock(__lua_mutex);
866  if (__enable_tracebacks && (n >= stack_size())) {
867  throw LuaRuntimeException("pop", "Cannot pop traceback function, invalid n");
868  }
869  lua_pop(__L, n);
870 }
871 
872 /** Remove value from stack.
873  * @param idx index of element to remove
874  */
875 void
876 LuaContext::remove(int idx)
877 {
878  MutexLocker lock(__lua_mutex);
879  if (__enable_tracebacks && ((idx == 1) || (idx == -stack_size()))) {
880  throw LuaRuntimeException("pop", "Cannot remove traceback function");
881  }
882  lua_remove(__L, idx);
883 }
884 
885 
886 /** Get size of stack.
887  * @return number of elements on the stack
888  */
889 int
890 LuaContext::stack_size()
891 {
892  return lua_gettop(__L);
893 }
894 
895 
896 /** Create a table on top of the stack.
897  * @param narr number of array elements
898  * @param nrec number of non-array elements
899  */
900 void
901 LuaContext::create_table(int narr, int nrec)
902 {
903  lua_createtable(__L, narr, nrec);
904 }
905 
906 
907 /** Set value of a table.
908  * Sets value t[k] = v. t is the table at the given index, by default it is the
909  * third-last entry (index is -3). v is the value at the top of the stack, k
910  * is the element just below the top.
911  * @param t_index index of the table on the stack
912  */
913 void
914 LuaContext::set_table(int t_index)
915 {
916  lua_settable(__L, t_index);
917 }
918 
919 
920 /** Set field of a table. Does the equivalent to t[k] = v, where t is
921  * the value at the given valid index and v is the value at the top of
922  * the stack. This function pops the value from the stack. As in Lua,
923  * this function may trigger a metamethod for the "newindex" event.
924  * @param key key of the field to set @param t_index index of the
925  * table on the stack, defaults to the element just below the value to
926  * set (-2, second last element on the stack).
927  */
928 void
929 LuaContext::set_field(const char *key, int t_index)
930 {
931  lua_setfield(__L, t_index, key);
932 }
933 
934 
935 /** Set a global value.
936  * Sets the global variable with the given name to the value currently on top
937  * of the stack. No check whatsoever regarding the name is done.
938  * @param name name of the variable to assign
939  */
940 void
941 LuaContext::set_global(const char *name)
942 {
943  lua_setglobal(__L, name);
944 }
945 
946 
947 /** Get value from table.
948  * Assumes that an index k is at the top of the stack. Then t[k] is retrieved,
949  * where t is a table at the given index idx. The resulting value is pushed
950  * onto the stack, while the key k is popped from the stack, thus the value
951  * replaces the key.
952  * @param idx index of the table on the stack
953  */
954 void
955 LuaContext::get_table(int idx)
956 {
957  lua_gettable(__L, idx);
958 }
959 
960 
961 /** Get named value from table.
962  * Retrieves the t[k], where k is the given key and t is a table at the given
963  * index idx. The value is pushed onto the stack.
964  * @param idx index of the table
965  * @param k key of the table entry
966  */
967 void
968 LuaContext::get_field(int idx, const char *k)
969 {
970  lua_getfield(__L, idx, k);
971 }
972 
973 
974 /** Set value without invoking meta methods.
975  * Similar to set_table(), but does raw access, i.e. without invoking meta-methods.
976  * @param idx index of the table
977  */
978 void
979 LuaContext::raw_set(int idx)
980 {
981  lua_rawset(__L, idx);
982 }
983 
984 
985 /** Set indexed value without invoking meta methods.
986  * Sets t[n]=v, where t is a table at index idx and v is the value at the
987  * top of the stack.
988  * @param idx index of the table
989  * @param n index in the table
990  */
991 void
992 LuaContext::raw_seti(int idx, int n)
993 {
994  lua_rawseti(__L, idx, n);
995 }
996 
997 
998 /** Get value without invoking meta methods.
999  * Similar to get_table(), but does raw access, i.e. without invoking meta-methods.
1000  * @param idx index of the table
1001  */
1002 void
1003 LuaContext::raw_get(int idx)
1004 {
1005  lua_rawget(__L, idx);
1006 }
1007 
1008 
1009 /** Get indexed value without invoking meta methods.
1010  * Pushes t[n] onto the stack, where t is a table at index idx.
1011  * @param idx index of the table
1012  * @param n index in the table
1013  */
1014 void
1015 LuaContext::raw_geti(int idx, int n)
1016 {
1017  lua_rawgeti(__L, idx, n);
1018 }
1019 
1020 
1021 /** Get global variable.
1022  * @param name name of the global variable
1023  */
1024 void
1025 LuaContext::get_global(const char *name)
1026 {
1027  lua_getglobal(__L, name);
1028 }
1029 
1030 
1031 /** Remove global variable.
1032  * Assigns nil to the given variable and removes it from internal
1033  * assignment maps.
1034  * @param name name of value to remove
1035  */
1036 void
1037 LuaContext::remove_global(const char *name)
1038 {
1039  MutexLocker lock(__lua_mutex);
1040 
1041  __usertypes.erase(name);
1042  __strings.erase(name);
1043  __booleans.erase(name);
1044  __numbers.erase(name);
1045  __integers.erase(name);
1046  __cfuncs.erase(name);
1047 
1048  lua_pushnil(__L);
1049  lua_setglobal(__L, name);
1050 }
1051 
1052 
1053 /** Retrieve stack value as number.
1054  * @param idx stack index of value
1055  * @return value as number
1056  */
1057 lua_Number
1058 LuaContext::to_number(int idx)
1059 {
1060  return lua_tonumber(__L, idx);
1061 }
1062 
1063 
1064 /** Retrieve stack value as integer.
1065  * @param idx stack index of value
1066  * @return value as integer
1067  */
1068 lua_Integer
1069 LuaContext::to_integer(int idx)
1070 {
1071  return lua_tointeger(__L, idx);
1072 }
1073 
1074 
1075 /** Retrieve stack value as boolean.
1076  * @param idx stack index of value
1077  * @return value as boolean
1078  */
1079 bool
1080 LuaContext::to_boolean(int idx)
1081 {
1082  return lua_toboolean(__L, idx);
1083 }
1084 
1085 
1086 /** Retrieve stack value as string.
1087  * @param idx stack index of value
1088  * @return value as string
1089  */
1090 const char *
1091 LuaContext::to_string(int idx)
1092 {
1093  return lua_tostring(__L, idx);
1094 }
1095 
1096 
1097 /** Check if stack value is a boolean.
1098  * @param idx stack index of value
1099  * @return true if value is a boolean, false otherwise
1100  */
1101 bool
1102 LuaContext::is_boolean(int idx)
1103 {
1104  return lua_isboolean(__L, idx);
1105 }
1106 
1107 
1108 /** Check if stack value is a C function.
1109  * @param idx stack index of value
1110  * @return true if value is a C function, false otherwise
1111  */
1112 bool
1113 LuaContext::is_cfunction(int idx)
1114 {
1115  return lua_iscfunction(__L, idx);
1116 }
1117 
1118 
1119 /** Check if stack value is a function.
1120  * @param idx stack index of value
1121  * @return true if value is a function, false otherwise
1122  */
1123 bool
1124 LuaContext::is_function(int idx)
1125 {
1126  return lua_isfunction(__L, idx);
1127 }
1128 
1129 
1130 /** Check if stack value is light user data.
1131  * @param idx stack index of value
1132  * @return true if value is light user data , false otherwise
1133  */
1134 bool
1135 LuaContext::is_light_user_data(int idx)
1136 {
1137  return lua_islightuserdata(__L, idx);
1138 }
1139 
1140 
1141 /** Check if stack value is nil.
1142  * @param idx stack index of value
1143  * @return true if value is nil, false otherwise
1144  */
1145 bool
1146 LuaContext::is_nil(int idx)
1147 {
1148  return lua_isnil(__L, idx);
1149 }
1150 
1151 
1152 /** Check if stack value is a number.
1153  * @param idx stack index of value
1154  * @return true if value is a number, false otherwise
1155  */
1156 bool
1157 LuaContext::is_number(int idx)
1158 {
1159  return lua_isnumber(__L, idx);
1160 }
1161 
1162 
1163 /** Check if stack value is a string.
1164  * @param idx stack index of value
1165  * @return true if value is a string, false otherwise
1166  */
1167 bool
1168 LuaContext::is_string(int idx)
1169 {
1170  return lua_isstring(__L, idx);
1171 }
1172 
1173 
1174 /** Check if stack value is a table.
1175  * @param idx stack index of value
1176  * @return true if value is a table, false otherwise
1177  */
1178 bool
1179 LuaContext::is_table(int idx)
1180 {
1181  return lua_istable(__L, idx);
1182 }
1183 
1184 
1185 /** Check if stack value is a thread.
1186  * @param idx stack index of value
1187  * @return true if value is a thread, false otherwise
1188  */
1189 bool
1190 LuaContext::is_thread(int idx)
1191 {
1192  return lua_isthread(__L, idx);
1193 }
1194 
1195 
1196 /** Get object length
1197  * @param idx stack index of value
1198  * @return size of object
1199  */
1200 size_t
1201 LuaContext::objlen(int idx)
1202 {
1203  return lua_objlen(__L, idx);
1204 }
1205 
1206 
1207 /** Set function environment.
1208  * Sets the table on top of the stack as environment of the function
1209  * at the given stack index.
1210  * @param idx stack index of function
1211  */
1212 void
1213 LuaContext::setfenv(int idx)
1214 {
1215  lua_setuservalue(__L, idx);
1216 }
1217 
1218 
1219 /** Add a context watcher.
1220  * @param watcher watcher to add
1221  */
1222 void
1223 LuaContext::add_watcher(fawkes::LuaContextWatcher *watcher)
1224 {
1225  __watchers.push_back_locked(watcher);
1226 }
1227 
1228 
1229 /** Remove a context watcher.
1230  * @param watcher watcher to remove
1231  */
1232 void
1233 LuaContext::remove_watcher(fawkes::LuaContextWatcher *watcher)
1234 {
1235  __watchers.remove_locked(watcher);
1236 }
1237 
1238 
1239 
1240 /** Process FAM events. */
1241 void
1242 LuaContext::process_fam_events()
1243 {
1244  if ( __fam) __fam->process_events();
1245 }
1246 
1247 
1248 void
1249 LuaContext::fam_event(const char *filename, unsigned int mask)
1250 {
1251  restart();
1252 }
1253 
1254 
1255 } // end of namespace fawkes
File could not be opened.
Definition: system.h:53
Lua context watcher.
Fawkes library namespace.
Mutex locking helper.
Definition: mutex_locker.h:33
Base class for exceptions in Fawkes.
Definition: exception.h:36
Monitors files for changes.
Definition: fam.h:71
RefPtr<> is a reference-counting shared smartpointer.
Definition: refptr.h:49
Lua runtime exception.
Definition: exceptions.h:30
Lua error exception.
Definition: exceptions.h:36
FileAlterationMonitor thread wrapper.
Definition: fam_thread.h:35
Mutex mutual exclusion lock.
Definition: mutex.h:32
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32