- Fixed: Rainmeter crashes if the Lua GetStringValue() function returns an invalid value

- Fixed: Rainmeter crashes on initialization if Lua is invalid (e.g. syntax error)
- Fixed: Rainmeter crashes on mouse action if Lua file is not initialized
- Fixed: Measure=SCRIPT tries to process mouse actions even if corresponding function does not exist in the Lua file causing log to fill with 'nil value' warnings
- Mainly cosmetic changes to logging of erros in Measure=SCRIPT
This commit is contained in:
Birunthan Mohanathas 2011-01-30 10:39:10 +00:00
parent 92eafce2dc
commit 4b30714520
5 changed files with 128 additions and 118 deletions

View File

@ -22,7 +22,6 @@ CMeasureScript::CMeasureScript(CMeterWindow* meterWindow) : CMeasure(meterWindow
CMeasureScript::~CMeasureScript()
{
delete m_pLuaScript;
}
void CMeasureScript::Initialize()
@ -92,26 +91,33 @@ const WCHAR* CMeasureScript::GetStringValue(AUTOSCALE autoScale, double scale, i
return CMeasure::GetStringValue(autoScale, scale, decimals, percentual);
}
static void stackDump (lua_State *L) {
static void stackDump(lua_State *L)
{
int i = lua_gettop(L);
LuaManager::LuaLog(" ---------------- Stack Dump ----------------" );
while( i ) {
LuaManager::LuaLog(LOG_DEBUG, " ---------------- Stack Dump ----------------" );
while(i)
{
int t = lua_type(L, i);
switch (t) {
switch (t)
{
case LUA_TSTRING:
LuaManager::LuaLog("%d:`%s'", i, lua_tostring(L, i));
LuaManager::LuaLog(LOG_DEBUG, "%d:`%s'", i, lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
LuaManager::LuaLog("%d: %s",i,lua_toboolean(L, i) ? "true" : "false");
LuaManager::LuaLog(LOG_DEBUG, "%d: %s",i,lua_toboolean(L, i) ? "true" : "false");
break;
case LUA_TNUMBER:
LuaManager::LuaLog("%d: %g", i, lua_tonumber(L, i));
LuaManager::LuaLog(LOG_DEBUG, "%d: %g", i, lua_tonumber(L, i));
break;
default: LuaManager::LuaLog("%d: %s", i, lua_typename(L, t)); break;
default:
LuaManager::LuaLog(LOG_DEBUG, "%d: %s", i, lua_typename(L, t)); break;
}
i--;
}
LuaManager::LuaLog("--------------- Stack Dump Finished ---------------" );
LuaManager::LuaLog(LOG_DEBUG, "--------------- Stack Dump Finished ---------------" );
}
@ -123,7 +129,6 @@ static void stackDump (lua_State *L) {
*/
void CMeasureScript::ReadConfig(CConfigParser& parser, const WCHAR* section)
{
CMeasure::ReadConfig(parser, section);
std::string strScriptFile = ConvertToAscii(parser.ReadString(section, L"ScriptFile", L"").c_str());
@ -131,18 +136,19 @@ void CMeasureScript::ReadConfig(CConfigParser& parser, const WCHAR* section)
if (strScriptFile.empty() == false)
{
if (strTableName.empty() == false)
{
lua_State* L = LuaManager::GetState();
m_pLuaScript = new LuaScript(LuaManager::GetState(), strScriptFile.c_str(), strTableName.c_str());
if (m_pLuaScript->IsInitialized())
{
m_bUpdateDefined = m_pLuaScript->FunctionExists(g_strUpdateFunction);
m_bInitializeDefined = m_pLuaScript->FunctionExists(g_strInitFunction);
m_bGetValueDefined = m_pLuaScript->FunctionExists(g_strGetValueFunction);
m_bGetStringValueDefined = m_pLuaScript->FunctionExists(g_strGetStringValueFunction);
m_pLuaScript->PushTable();
// Push the variable name we want to put a value in.
@ -201,20 +207,19 @@ void CMeasureScript::ReadConfig(CConfigParser& parser, const WCHAR* section)
// Pop the table
lua_pop(L, 1);
}
}
else
{
LuaManager::LuaLog("%s : TableName missing.", m_ANSIName.c_str());
LuaManager::LuaLog(LOG_ERROR, "Script: TableName missing in %s.", m_ANSIName.c_str());
}
}
else
{
LuaManager::LuaLog("%s : ScriptFile missing.", m_ANSIName.c_str());
LuaManager::LuaLog(LOG_ERROR, "Script: ScriptFile missing in %s.", m_ANSIName.c_str());
}
}
void CMeasureScript::RunFunctionWithMeter(const char* p_strFunction, CMeter* p_pMeter)
{
// Get the Lua State
lua_State* L = m_pLuaScript->GetState();
@ -224,6 +229,9 @@ void CMeasureScript::RunFunctionWithMeter(const char* p_strFunction, CMeter* p_p
// Push the function onto the stack
lua_getfield(L, -1, p_strFunction);
// Check if the function exists
if (!lua_isnil(L, -1))
{
// Push the Meter
tolua_pushusertype(L, (void*) p_pMeter, "CMeter");
@ -231,43 +239,53 @@ void CMeasureScript::RunFunctionWithMeter(const char* p_strFunction, CMeter* p_p
{
LuaManager::ReportErrors(L);
}
}
// Clean up
lua_pop(L, 1);
}
void CMeasureScript::MeterMouseEvent(CMeter* p_pMeter, MOUSE p_eMouse)
{
if (m_pLuaScript->IsInitialized())
{
switch (p_eMouse)
{
case MOUSE_LMB_DOWN:
RunFunctionWithMeter("LeftMouseDown", p_pMeter);
break;
case MOUSE_LMB_UP:
RunFunctionWithMeter("LeftMouseUp", p_pMeter);
break;
case MOUSE_LMB_DBLCLK:
RunFunctionWithMeter("LeftMouseDoubleClick", p_pMeter);
break;
case MOUSE_RMB_DOWN:
RunFunctionWithMeter("RightMouseDown", p_pMeter);
break;
case MOUSE_RMB_UP:
RunFunctionWithMeter("RightMouseUp", p_pMeter);
break;
case MOUSE_RMB_DBLCLK:
RunFunctionWithMeter("RightMouseDoubleClick", p_pMeter);
break;
case MOUSE_MMB_DOWN:
RunFunctionWithMeter("MiddleMouseDown", p_pMeter);
break;
case MOUSE_MMB_UP:
RunFunctionWithMeter("MiddleMouseUp", p_pMeter);
break;
case MOUSE_MMB_DBLCLK:
RunFunctionWithMeter("MiddleMouseDoubleClick", p_pMeter);
break;
}
}
}

View File

@ -12,7 +12,6 @@
#include "lua_rainmeter_ext.h"
bool LuaManager::m_bInitialized = false;
lua_State* LuaManager::m_pState = 0;
@ -20,7 +19,6 @@ void LuaManager::Init()
{
if(m_pState == 0)
{
// initialize Lua
m_pState = lua_open();
@ -36,7 +34,6 @@ void LuaManager::Init()
//tolua_meter_image_open(m_pState);
luaopen_rainmeter_ext(m_pState);
}
}
@ -47,13 +44,11 @@ void LuaManager::CleanUp()
void LuaManager::ReportErrors(lua_State * L)
{
LuaLog("Lua Error: %s", lua_tostring(L, -1));
LuaLog(LOG_ERROR, "Script: %s", lua_tostring(L, -1));
lua_pop(L, 1);
}
void LuaManager::LuaLog(const char* format, ... )
void LuaManager::LuaLog(int nLevel, const char* format, ... )
{
char buffer[4096];
va_list args;
@ -66,7 +61,7 @@ void LuaManager::LuaLog(const char* format, ... )
_vsnprintf_s( buffer, _TRUNCATE, format, args );
if (errno != 0)
{
_snprintf_s(buffer, _TRUNCATE, "LuaLog internal error: %s", format);
_snprintf_s(buffer, _TRUNCATE, "Script: LuaLog internal error: %s", format);
}
_set_invalid_parameter_handler(oldHandler);
@ -79,6 +74,6 @@ void LuaManager::LuaLog(const char* format, ... )
std::wstring str = ConvertToWide(buffer);
LSLog(LOG_NOTICE, L"Lua", str.c_str());
LSLog(nLevel, L"Rainmeter", str.c_str());
va_end(args);
}

View File

@ -16,7 +16,7 @@ public:
static void ReportErrors(lua_State * L);
static void LuaLog(const char* format, ... );
static void LuaLog(int nLevel, const char* format, ... );
protected:

View File

@ -41,17 +41,16 @@ LuaScript::LuaScript(lua_State* p_pState, const char* p_strFile, const char* p_s
if (result)
{
m_bInitialized = false;
LuaManager::LuaLog("Lua cannot run file:");
LuaManager::LuaLog("%s", lua_tostring(m_pState, -1) );
LuaManager::LuaLog(LOG_ERROR, "Script: Cannot run file: %s", p_strFile);
LuaManager::LuaLog(LOG_ERROR, "Script: %s", lua_tostring(m_pState, -1));
}
}
else
{
m_bInitialized = false;
LuaManager::LuaLog("Lua cannot run file:");
LuaManager::LuaLog("%s", lua_tostring(m_pState, -1) );
LuaManager::LuaLog(LOG_ERROR, "Script: Cannot run file: %s", p_strFile);
LuaManager::LuaLog(LOG_ERROR, "Script: %s", lua_tostring(m_pState, -1));
}
}
LuaScript::~LuaScript(void)
@ -61,7 +60,6 @@ LuaScript::~LuaScript(void)
void LuaScript::BindVariable(const char* p_strName, void* p_pValue, const char* p_strTypeName)
{
PushTable();
/*
@ -105,7 +103,7 @@ double LuaScript::RunFunctionDouble(const char* p_strFuncName)
{
if (!lua_isnumber(m_pState, -1))
{
LuaManager::LuaLog("Function `%s:%s' must return a number",m_strTableName, p_strFuncName);
LuaManager::LuaLog(LOG_ERROR, "Script: Function '%s:%s' must return a number", m_strTableName, p_strFuncName);
}
double d = lua_tonumber(m_pState, -1);
@ -121,7 +119,6 @@ double LuaScript::RunFunctionDouble(const char* p_strFuncName)
return -1;
}
std::wstring LuaScript::RunFunctionString(const char* p_strFuncName)
{
if( m_bInitialized && p_strFuncName )
@ -140,7 +137,7 @@ std::wstring LuaScript::RunFunctionString(const char* p_strFuncName)
{
if (!lua_isstring(m_pState, -1))
{
LuaManager::LuaLog("Function `%s:%s' must return a string",m_strTableName, p_strFuncName);
LuaManager::LuaLog(LOG_ERROR, "Script: Function '%s:%s' must return a string",m_strTableName, p_strFuncName);
}
const char* str = lua_tostring(m_pState, -1);
@ -153,7 +150,7 @@ std::wstring LuaScript::RunFunctionString(const char* p_strFuncName)
lua_pop(m_pState, 1);
}
return 0;
return L"";
}
void LuaScript::RunFunction(const char* p_strFuncName)

View File

@ -91,7 +91,7 @@ static int AsMeterString(lua_State* tolua_S)
static int staticLuaLog(lua_State* tolua_S)
{
const char* str = tolua_tostring(tolua_S,1,0);
LuaManager::LuaLog(str);
LuaManager::LuaLog(LOG_NOTICE, str);
return 0;
}