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