Lua_icxx
1.02 (Aug 2011)
|
00001 /* 00002 This file is part of the Lua_icxx library. 00003 Copyright 2010 (c) by Oliver Schoenborn. 00004 License terms in LICENSE.txt. 00005 */ 00006 00007 00008 /* Requires Lua 5.1 */ 00009 00010 #include "LuaInterpreter.h" 00011 #include "LuaFuncRef.h" 00012 #include "LuaTableRef.h" 00013 00014 #include <stdexcept> 00015 using namespace std; 00016 00017 00018 LuaInterpreter::LuaInterpreter() : mLua(lua_open()), mOwner(true) 00019 { 00020 if (mLua == NULL) 00021 throw runtime_error("Could not initialize LUA interpreter"); 00022 00023 luaL_openlibs(mLua); 00024 } 00025 00026 00027 // Call whatever is in top section of stack (function plus arguments) 00028 // and return the result as a LuaResult instance 00029 inline LuaTempResult 00030 getResult(lua_State* lua, int stackTop, const std::string& errMsg) 00031 { 00032 const int nargs = 0, errFnIdx = 0; 00033 const int errCall = lua_pcall(lua, nargs, LUA_MULTRET, errFnIdx); 00034 return LuaTempResult( lua, stackTop, errCall, errMsg ); 00035 } 00036 00037 00038 LuaTempResult 00039 LuaInterpreter::chunkFromString( const std::string& script ) 00040 { 00041 const int stackTop = lua_gettop(mLua); 00042 assert( lua_checkstack(mLua, 1) ); 00043 const int err = luaL_loadstring(mLua, script.c_str()); 00044 return LuaTempResult( mLua, stackTop, err, "Syntax error in" ); 00045 } 00046 00047 00048 LuaTempResult 00049 LuaInterpreter::chunkFromFile( const std::string& filename ) 00050 { 00051 const int stackTop = lua_gettop(mLua); 00052 assert( lua_checkstack(mLua, 1) ); 00053 const int err = luaL_loadfile(mLua, filename.c_str()); 00054 return LuaTempResult(mLua, stackTop, err, "Read error"); 00055 } 00056 00057 00058 LuaTempResult 00059 LuaInterpreter::doFileCommon( const std::string& filename, const LuaTableRef * globalEnv) 00060 { 00061 const int stackTop = lua_gettop(mLua); 00062 00063 assert( lua_checkstack(mLua, 1) ); 00064 const int err = luaL_loadfile(mLua, filename.c_str()); 00065 if (err != LUA_ERR_NONE) 00066 return LuaTempResult(mLua, stackTop, err, "Read error"); 00067 00068 if ( globalEnv != NULL ) 00069 { 00070 globalEnv->pushObj(); 00071 const int ok = lua_setfenv(mLua, -2); 00072 assert(ok == 1); 00073 } 00074 00075 return getResult(mLua, stackTop, "Logic error in"); 00076 } 00077 00078 00079 LuaTempResult 00080 LuaInterpreter::doStringCommon( const std::string& script, const LuaTableRef * globalEnv ) 00081 { 00082 const int stackTop = lua_gettop(mLua); 00083 00084 assert( lua_checkstack(mLua, 1) ); 00085 const int err = luaL_loadstring(mLua, script.c_str()); 00086 if (err != LUA_ERR_NONE) 00087 return LuaTempResult( mLua, stackTop, err, "Syntax error in" ); 00088 00089 if ( globalEnv != NULL ) 00090 { 00091 globalEnv->pushObj(); 00092 const int ok = lua_setfenv(mLua, -2); 00093 assert(ok == 1); 00094 } 00095 00096 return getResult(mLua, stackTop, "Logic error in"); 00097 } 00098 00099 00100 LuaInterpreter::~LuaInterpreter() 00101 { 00102 if (mOwner) 00103 lua_close(mLua); 00104 } 00105 00106 00107 LuaTempResult 00108 LuaInterpreter::openDynLib( const std::string& libPath, const std::string& entryPoint ) 00109 { 00110 LuaFuncRef loadlib = eval("package.loadlib"); 00111 const int prevStackTop = lua_gettop(mLua); 00112 string errMsg; 00113 const int errCode = tryOpenDynLib(loadlib, libPath, entryPoint, errMsg); 00114 assert( prevStackTop == lua_gettop(mLua)) ; 00115 00116 if ( errCode != LUA_ERR_NONE ) 00117 { 00118 assert( lua_checkstack(mLua, 1) ); 00119 lua_pushstring(mLua, errMsg.c_str()); 00120 } 00121 return LuaTempResult(mLua, prevStackTop, errCode, "File error"); 00122 } 00123 00124 00125 LuaErrCode 00126 LuaInterpreter::tryOpenDynLib( 00127 const LuaFuncRef& loadlib, const std::string& libPath, const std::string& entryPoint, 00128 string& errMsg ) 00129 { 00130 LuaErrCode errCode = LUA_ERR_NONE; 00131 LuaTempResult res = loadlib(libPath, entryPoint); 00132 if ( res[1].isNil() ) 00133 { 00134 const string errOper = res[2]; 00135 string errPrefix = "Error opening"; 00136 errCode = LUA_ERR_FILE; 00137 if ( errOper != "open" ) 00138 { 00139 errCode = LUA_ERR_RUN; 00140 if ( errOper == "init" ) 00141 errPrefix = "Error initializing"; 00142 else 00143 errPrefix = "Unknown error in loading"; 00144 } 00145 errMsg = errPrefix + " library " + libPath + ": " + res[1].getAs<string>(); 00146 } 00147 00148 else 00149 { 00150 // lib and its entry point function found; now call it: 00151 LuaFuncRef libEntryFunc = res[1]; 00152 LuaTempResult loadRes = libEntryFunc(); 00153 if ( ! loadRes.ok() ) 00154 { 00155 errCode = (LuaErrCode) loadRes.getErrCode(); 00156 errMsg = "Error running entry point function " + entryPoint + "() for library " 00157 + libPath + ": " + loadRes.getErrMsg(); 00158 } 00159 } 00160 00161 return errCode; 00162 } 00163 00164