Lua_icxx  1.02 (Aug 2011)
LuaInterpreter.cpp
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