libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo is the group of objects and functions that executes the basic operations of Moldeo 1.0 Platform.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
moLuaBase.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  moLuaBase.cpp
4 
5  ****************************************************************************
6  * *
7  * This source is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This code is distributed in the hope that it will be useful, but *
13  * WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * General Public License for more details. *
16  * *
17  * A copy of the GNU General Public License is available on the World *
18  * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
19  * obtain it by writing to the Free Software Foundation, *
20  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  * *
22  ****************************************************************************
23 
24  Copyright (C) 2006 Fabricio Costa
25 
26  Authors:
27  Fabricio Costa
28  Andrés Colubri
29 
30  Description:
31  Classes for Lua scripting. Based in the Lua article and VC project by Richard
32  Shephard, available online at:
33  http://www.codeproject.com/cpp/luaincpp.asp?msg=1741798
34 
35 *******************************************************************************/
36 
37 #include "moLuaBase.h"
38 #include <assert.h>
39 #include <string.h>
40 #include <stdio.h>
41 #include "moDebugManager.h"
42 
43 //============================================================================
44 // int printMessage
45 //---------------------------------------------------------------------------
46 // Prints a message to the console
47 //
48 // Parameter Dir Description
49 // --------- --- -----------
50 // lua IN State variable
51 //
52 // Return
53 // ------
54 // Number of return varaibles on the stack
55 //
56 //============================================================================
57 static int printMessage (lua_State *lua)
58 {
59  assert (lua_isstring (lua,1));
60 
61  const char *msg = lua_tostring (lua, 1);
62 
63  // get caller
64  lua_Debug ar;
65  memset (&ar, 0, sizeof(ar));
66  lua_getstack (lua, 1, &ar);
67  lua_getinfo (lua, "Snl", &ar);
68 
69  // debug output
70  const char *str = ar.source;
71  printf ("script: %s -- at %s(%d)\n", msg, str, ar.currentline);
72  return 0;
73 }
74 
75 //============================================================================
76 // moLuaVirtualMachine::moLuaVirtualMachine
77 //---------------------------------------------------------------------------
78 // Constructor. Setups the default VM state
79 //
80 // Parameter Dir Description
81 // --------- --- -----------
82 //
83 //
84 // Return
85 // ------
86 // None.
87 //
88 //============================================================================
89 moLuaVirtualMachine::moLuaVirtualMachine (void) : m_pState (NULL), m_pDbg (NULL)
90 {
91  m_fIsOk = false;
92 }
93 
94 //============================================================================
95 // moLuaVirtualMachine::moLuaVirtualMachine
96 //---------------------------------------------------------------------------
97 // Destructor. Closes the VM
98 //
99 // Parameter Dir Description
100 // --------- --- -----------
101 //
102 //
103 // Return
104 // ------
105 // None.
106 //
107 //============================================================================
109 {
110  FinaliseVM();
111 }
112 
113 //============================================================================
114 // moLuaVirtualMachine::Panic
115 //---------------------------------------------------------------------------
116 // When things in Lua go wrong (ever called in protected mode??)
117 //
118 // Parameter Dir Description
119 // --------- --- -----------
120 // lua IN State variable
121 //
122 // Return
123 // ------
124 // None.
125 //
126 //============================================================================
127 void moLuaVirtualMachine::Panic (lua_State *lua)
128 {
129  lua_Debug ar;
130  lua_getstack (lua, 0, &ar);
131  moDebugManager::Error("moLuaVirtualMachine::Panic > " );
132 }
133 
134 //============================================================================
135 // bool moLuaVirtualMachine::InitialiseVM
136 //---------------------------------------------------------------------------
137 // Initialises the VM, open lua, makes sure things are OK
138 //
139 // Parameter Dir Description
140 // --------- --- -----------
141 // None.
142 //
143 // Return
144 // ------
145 // Success.
146 //
147 //============================================================================
149 {
150  // Open Lua!
151  if (Ok ()) FinaliseVM ();
152 
153  m_pState = luaL_newstate ();
154 
155  if (m_pState)
156  {
157  m_fIsOk = true;
158 
159  // Load util libs into lua
160  luaL_openlibs (m_pState);
161 
162  // setup global printing (trace)
163  lua_pushcclosure (m_pState, printMessage, 0);
164  lua_setglobal (m_pState, "trace");
165 
166  lua_atpanic (m_pState, (lua_CFunction) moLuaVirtualMachine::Panic);
167 
168  return true;
169  }
170 
171  return false;
172 }
173 
174 //============================================================================
175 // bool moLuaVirtualMachine::FinaliseVM
176 //---------------------------------------------------------------------------
177 // Clears the current Lua state
178 //
179 // Parameter Dir Description
180 // --------- --- -----------
181 // None.
182 //
183 // Return
184 // ------
185 // Success.
186 //
187 //============================================================================
189 {
190  if (m_pState)
191  {
192  lua_close (m_pState);
193  m_pState = NULL;
194  m_fIsOk = false;
195  }
196  return true;
197 }
198 
199 
200 //============================================================================
201 // bool moLuaVirtualMachine::RunFile
202 //---------------------------------------------------------------------------
203 // Compiles and runs a lua script file
204 //
205 // Parameter Dir Description
206 // --------- --- -----------
207 // strFilename IN Filename to compile and run
208 //
209 // Return
210 // ------
211 // Success.
212 //
213 //============================================================================
214 bool moLuaVirtualMachine::RunFile (const char *strFilename)
215 {
216  bool fSuccess = false;
217  int iErr = 0;
218 
219  if ((iErr = luaL_loadfile (m_pState, strFilename)) == 0)
220  {
221  // Call main...
222  if ((iErr = lua_pcall (m_pState, 0, LUA_MULTRET, 0)) == 0)
223  {
224  fSuccess = true;
225  }
226  }
227 
228  if (fSuccess == false)
229  {
230  if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr);
231  }
232 
233  return fSuccess;
234 }
235 
236 //============================================================================
237 // bool moLuaVirtualMachine::RunBuffer
238 //---------------------------------------------------------------------------
239 // Compiles and runs a pre-compiled data buffer
240 //
241 // Parameter Dir Description
242 // --------- --- -----------
243 // pbBuffer IN Buffer to run
244 // szLen IN Length of buffer
245 // strName IN Name of Buffer
246 //
247 // Return
248 // ------
249 // Success.
250 //
251 //============================================================================
252 bool moLuaVirtualMachine::RunBuffer (const unsigned char *pbBuffer, size_t szLen, const char *strName /* = NULL */)
253 {
254  bool fSuccess = false;
255  int iErr = 0;
256 
257  if (strName == NULL)
258  {
259  strName = "Temp";
260  }
261 
262  if ((iErr = luaL_loadbuffer (m_pState, (const char *) pbBuffer, szLen, strName)) == 0)
263  {
264  // Call main...
265  if ((iErr = lua_pcall (m_pState, 0, LUA_MULTRET, 0)) == 0)
266  {
267  fSuccess = true;
268  }
269  }
270 
271  if (fSuccess == false)
272  {
273  if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr);
274  }
275 
276  return fSuccess;
277 
278 }
279 
280 //============================================================================
281 // moLuaVirtualMachine::CallFunction
282 //---------------------------------------------------------------------------
283 // Calls a function that is already on the stack
284 //
285 // Parameter Dir Description
286 // --------- --- -----------
287 // nArgs IN Args that are aleady on the stack
288 // nReturns IN Number of expected returns (will be on the stack)
289 //
290 // Return
291 // ------
292 // Success.
293 //
294 //============================================================================
295 bool moLuaVirtualMachine::CallFunction (int nArgs, int nReturns /* = 0 */)
296 {
297  bool fSuccess = false;
298 
299  if (lua_isfunction (m_pState, -nArgs-1))
300  {
301  int iErr = 0;
302  iErr = lua_pcall (m_pState, nArgs, nReturns, 0);
303 
304  if (iErr == 0)
305  {
306  fSuccess = true;
307  }
308  else
309  {
310  if (m_pDbg != NULL) m_pDbg->ErrorRun (iErr);
311  }
312  }
313 
314  return fSuccess;
315 }
316 
317 // typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
318 static void LuaHookCall (lua_State *lua)
319 {
320 
321  printf ("---- Call Stack ----\n");
322 // printf ("[Level] [Function] [# args] [@line] [src]\n");
323 
324  lua_Debug ar;
325 
326  // Look at call stack
327  for (int iLevel = 0; lua_getstack (lua, iLevel, &ar) != 0; ++iLevel)
328  {
329  if (lua_getinfo (lua, "Snlu", &ar) != 0)
330  {
331  printf ("%d %s %s %d @%d %s\n", iLevel, ar.namewhat, ar.name, ar.nups, ar.linedefined, ar.short_src);
332  }
333  }
334 }
335 
336 static void LuaHookRet (lua_State *lua)
337 {
338  printMessage( lua );
339 }
340 
341 static void LuaHookLine (lua_State *lua)
342 {
343  lua_Debug ar;
344  lua_getstack (lua, 0, &ar);
345 
346 
347  if (lua_getinfo (lua, "Sl", &ar) != 0)
348  {
349  printf ("exe %s on line %d\n", ar.short_src, ar.currentline);
350  }
351 }
352 
353 static void LuaHookCount (lua_State *lua)
354 {
355  LuaHookLine (lua);
356 }
357 
358 static void LuaHook (lua_State *lua, lua_Debug *ar)
359 {
360  // Handover to the correct hook
361  switch (ar->event)
362  {
363  case LUA_HOOKCALL:
364  #ifdef LUA_HOOKTAILCALL
365  case LUA_HOOKTAILCALL:
366  #endif
367  LuaHookCall (lua);
368  break;
369  case LUA_HOOKRET:
370  LuaHookRet (lua);
371  break;
372  case LUA_HOOKLINE:
373  LuaHookLine (lua);
374  break;
375  case LUA_HOOKCOUNT:
376  LuaHookCount (lua);
377  break;
378  }
379 }
380 
381 moLuaDebugger::moLuaDebugger (moLuaVirtualMachine& vm) : m_iCountMask (10), m_vm (vm)
382 {
383 }
384 
386 {
387  FinaliseDBG();
388 }
389 
391 {
392 
393  // Clear all current hooks and attach debugger to vm.
394  if (m_vm.Ok ())
395  {
396  m_vm.AttachDebugger (this);
397  lua_sethook ((lua_State *) m_vm, LuaHook, 0, m_iCountMask);
398  }
399 }
400 
402 {
403  // Clear all current hooks
404  if (m_vm.Ok ())
405  {
406  lua_sethook ((lua_State *) m_vm, LuaHook, 0, m_iCountMask);
407  }
408 }
409 
411 {
412  // Set hooks
413  lua_sethook ((lua_State *) m_vm, LuaHook, iMask, m_iCountMask);
414 }
415 
416 void moLuaDebugger::ErrorRun (int iErrorCode)
417 {
418  switch (iErrorCode)
419  {
420  case LUA_ERRRUN:
421  printf ("LUA_ERRRUN\n");
422  if (MODebug2 != NULL) MODebug2->Error("LUA_ERRRUN");
423  break;
424  case LUA_ERRMEM:
425  printf ("LUA_ERRMEM\n");
426  if (MODebug2 != NULL) MODebug2->Error("LUA_ERRMEM");
427  break;
428  case LUA_ERRERR:
429  printf ("LUA_ERRERR\n");
430  if (MODebug2 != NULL) MODebug2->Error("LUA_ERRERR");
431  break;
432  }
433 
434  // Get the error string that appears on top of stack when a function
435  // fails to run
436  printf ("LUA Error: %s\n", lua_tostring ((lua_State *) m_vm, -1));
437  if (MODebug2!= NULL) MODebug2->Error(moText("LUA Error: ") + moText((char*)lua_tostring ((lua_State *) m_vm, -1)));
438 }
439 
bool InitialiseVM(void)
Definition: moLuaBase.cpp:148
virtual bool Ok(void)
Definition: moLuaBase.h:129
void Error(moText p_text)
Anuncia y registra un error.
Definition: moAbstract.cpp:79
moLuaVirtualMachine & m_vm
Definition: moLuaBase.h:187
static void Error(moText p_text)
Anuncia un error.
void InitaliseDBG()
Definition: moLuaBase.cpp:390
lua_State * m_pState
Definition: moLuaBase.h:137
bool FinaliseVM(void)
Definition: moLuaBase.cpp:188
void SetHooksFlag(int iMask)
Definition: moLuaBase.cpp:410
moLuaDebugger * m_pDbg
Definition: moLuaBase.h:139
moText0 moText
Definition: moText.h:291
moLuaDebugger(moLuaVirtualMachine &vm)
Definition: moLuaBase.cpp:381
int m_iCountMask
Definition: moLuaBase.h:186
void AttachDebugger(moLuaDebugger *dbg)
Definition: moLuaBase.h:135
void ErrorRun(int iErrorCode)
Definition: moLuaBase.cpp:416
bool CallFunction(int nArgs, int nReturns=0)
Definition: moLuaBase.cpp:295
static moDebug * MODebug2
Clase de impresión de errores para depuración
Definition: moAbstract.h:225
bool RunBuffer(const unsigned char *pbBuffer, size_t szLen, const char *strName=NULL)
Definition: moLuaBase.cpp:252
virtual ~moLuaVirtualMachine(void)
Definition: moLuaBase.cpp:108
static void Panic(lua_State *lua)
Definition: moLuaBase.cpp:127
bool RunFile(const char *strFilename)
Definition: moLuaBase.cpp:214
virtual ~moLuaDebugger(void)
Definition: moLuaBase.cpp:385
void FinaliseDBG(void)
Definition: moLuaBase.cpp:401