void wxLuaConsole::DisplayStack(const wxLuaState& wxlState) { wxCHECK_RET(wxlState.Ok(), wxT("Invalid wxLuaState")); int nIndex = 0; lua_Debug luaDebug = INIT_LUA_DEBUG; wxString buffer; lua_State* L = wxlState.GetLuaState(); while (lua_getstack(L, nIndex, &luaDebug) != 0) { if (lua_getinfo(L, "Sln", &luaDebug)) { wxString what (luaDebug.what ? lua2wx(luaDebug.what) : wxString(wxT("?"))); wxString nameWhat(luaDebug.namewhat ? lua2wx(luaDebug.namewhat) : wxString(wxT("?"))); wxString name (luaDebug.name ? lua2wx(luaDebug.name) : wxString(wxT("?"))); buffer += wxString::Format(wxT("[%d] %s '%s' '%s' (line %d)\n Line %d src='%s'\n"), nIndex, what.c_str(), nameWhat.c_str(), name.c_str(), luaDebug.linedefined, luaDebug.currentline, lua2wx(luaDebug.short_src).c_str()); } nIndex++; } if (!buffer.empty()) { AppendText(wxT("\n-----------------------------------------------------------") wxT("\n- Backtrace") wxT("\n-----------------------------------------------------------\n") + buffer + wxT("\n-----------------------------------------------------------\n\n")); } }
bool wxLuaSocketBase::ReadDebugData(wxLuaDebugData& value) { wxLuaDebugData debugData(true); wxInt32 idx, idxMax = 0; bool ok = ReadInt32(idxMax); wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::ReadDebugData"), wxString::Format(wxT("items %d"), idxMax)); for (idx = 0; ok && (idx < idxMax); ++idx) { wxInt32 bufferLength = 0; ok = Read((char*)&bufferLength, sizeof(wxInt32)) == sizeof(wxInt32); if (ok && (bufferLength > 0)) { char *pBuffer = new char[bufferLength]; char *pMemory = pBuffer; ok = Read(pMemory, bufferLength) == bufferLength; if (!ok) break; wxInt32 nReference = *(wxInt32 *) pMemory; pMemory += sizeof(wxInt32); wxInt32 nIndex = *(wxInt32 *) pMemory; pMemory += sizeof(wxInt32); wxInt32 flag = *(wxInt32 *) pMemory; pMemory += sizeof(wxInt32); wxInt32 keyType = *(wxInt32 *) pMemory; pMemory += sizeof(wxInt32); wxInt32 valueType = *(wxInt32 *) pMemory; pMemory += sizeof(wxInt32); const char *pKeyPtr = pMemory; pMemory += strlen(pKeyPtr) + 1; const char *pValuePtr = pMemory; pMemory += strlen(pValuePtr) + 1; const char *pSourcePtr = pMemory; wxLuaDebugItem *pItem = new wxLuaDebugItem(lua2wx(pKeyPtr), keyType, lua2wx(pValuePtr), valueType, lua2wx(pSourcePtr), nReference, nIndex, flag); debugData.Add(pItem); delete[] pBuffer; } } if (ok) value = debugData; return ok; }
wxString wxLuaSocketCmdEventMsg(int val) { if (val <= 0) return wxString::Format(wxT("INVALID SOCKET CMD/EVENT (%d), SOCKET ERROR?"), val); if ((val >= wxLUASOCKET_DEBUGGEE_EVENT_BREAK) && (val <= wxLUASOCKET_DEBUGGEE_EVENT__COUNT)) return lua2wx(s_wxlsocket_event[val]); if ((val >= wxLUASOCKET_DEBUGGER_CMD_ADD_BREAKPOINT) && (val <= wxLUASOCKET_DEBUGGER_CMD_ENABLE_BREAKPOINT)) return lua2wx(s_wxlsocket_cmd[val - wxLUASOCKET_DEBUGGER_CMD_ADD_BREAKPOINT + 1]); return wxString::Format(wxT("INVALID SOCKET CMD/EVENT (%d), SOCKET ERROR?"), val); }
wxLuaDebugData *wxLuaDebugIO::ReadDebugData(wxLuaSocket *pSocket) { wxLuaDebugData *pSortedList = new wxLuaDebugData(); try { size_t idx, idxMax; pSocket->Read((char *) &idxMax, sizeof(idxMax)); for (idx = 0; idx < idxMax; ++idx) { int bufferLength; pSocket->Read((char *) &bufferLength, sizeof(bufferLength)); if (bufferLength > 0) { char *pBuffer = new char[bufferLength]; char *pMemory = pBuffer; pSocket->Read(pMemory, bufferLength); int nReference = *(int *) pMemory; pMemory += sizeof(int); int nIndex = *(int *) pMemory; pMemory += sizeof(int); bool fExpanded = (0 != *pMemory++); const char *pNamePtr = pMemory; pMemory += strlen(pNamePtr) + 1; const char *pTypePtr = pMemory; pMemory += strlen(pTypePtr) + 1; const char *pValuePtr = pMemory; wxLuaDebugDataItem *pItem = new wxLuaDebugDataItem(lua2wx(pNamePtr), lua2wx(pTypePtr), lua2wx(pValuePtr), wxEmptyString, // FIXME! What goes here!? nReference, nIndex, fExpanded); pSortedList->Add(pItem); delete[] pBuffer; } } } catch(wxLuaSocketException & /*e*/) { delete pSortedList; pSortedList = NULL; } return pSortedList; }
int wxLuaDebugData::EnumerateStackEntry(lua_State* L, int stack_frame, wxArrayInt& references) { wxCHECK_MSG(L, 0, wxT("Invalid lua_State")); wxCHECK_MSG(M_DEBUGREFDATA != NULL, 0, wxT("Invalid ref data")); lua_Debug luaDebug = INIT_LUA_DEBUG; int count = 0; if (lua_getstack(L, stack_frame, &luaDebug) != 0) { int stack_idx = 1; wxString name(lua2wx(lua_getlocal(L, &luaDebug, stack_idx))); while (!name.IsEmpty()) { //wxPrintf(wxT("%s lua_getlocal :%s\n"), lua_Debug_to_wxString(luaDebug).c_str(), name.c_str()); int wxl_valuetype = WXLUA_TNONE; wxString value; wxString source(lua2wx(luaDebug.source)); int lua_value_type = GetTypeValue(L, -1, &wxl_valuetype, value); int val_flag_type = 0; int val_ref = LUA_NOREF; if (lua_value_type == LUA_TTABLE) { val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references); } else if (lua_value_type == LUA_TUSERDATA) { if (lua_getmetatable(L, -1)) // doesn't push anything if nil { val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references); lua_pop(L, 1); } } Add(new wxLuaDebugItem(name, WXLUA_TNONE, value, wxl_valuetype, source, val_ref, 0, val_flag_type)); ++count; lua_pop(L, 1); // remove variable value name = lua2wx(lua_getlocal(L, &luaDebug, ++stack_idx)); } } return count; }
void wxLuaConsole::DisplayStack(const wxLuaState& wxlState) { wxCHECK_RET(wxlState.Ok(), wxT("Invalid wxLuaState")); int nIndex = 0; lua_Debug luaDebug; wxString buffer; m_debugListBox->Clear(); lua_State* L = wxlState.GetLuaState(); while (lua_getstack(L, nIndex, &luaDebug) != 0) { buffer.Empty(); if (lua_getinfo(L, "Sln", &luaDebug)) { int lineNumber = luaDebug.currentline; if (lineNumber == -1) { if (luaDebug.name != NULL) buffer.Printf(wxT("function %s"), lua2wx(luaDebug.name).c_str()); else buffer.Printf(wxT("{global}")); } else { if (luaDebug.name != NULL) buffer.Printf(wxT("function %s line %d"), lua2wx(luaDebug.name).c_str(), lineNumber); else buffer.Printf(wxT("{global} line %d"), lineNumber); } // skip over ourselves on the stack if (nIndex > 0) m_debugListBox->Append(buffer, (void *)(long) nIndex); } nIndex++; } // only show the listbox if it has anything in it if (m_debugListBox->GetCount() && !m_splitter->IsSplit()) { m_splitter->SplitHorizontally( m_textCtrl, m_debugListBox, 150); m_splitter->SetMinimumPaneSize(50); } }
wxString wxLuaBindClassString(wxLuaBindClass* wxlClass) { wxCHECK_MSG(wxlClass, wxEmptyString, wxT("Invalid wxLuaBindClass")); wxString baseClasses; if (wxlClass->baseclassNames) { for (size_t i = 0; wxlClass->baseclassNames[i]; ++i) baseClasses += lua2wx(wxlClass->baseclassNames[i]) + wxT(","); } return wxString::Format(wxT(" (%s, wxluatype=%d, classinfo=%s, baseclass=%s, methods=%d, enums=%d)"), lua2wx(wxlClass->name).c_str(), *wxlClass->wxluatype, wxString(wxlClass->classInfo ? wxlClass->classInfo->GetClassName() : wxEmptyString).c_str(), baseClasses.c_str(), wxlClass->wxluamethods_n, wxlClass->enums_n); }
int LUACALL wxLuaDebugTarget::LuaPrint(lua_State *L) { int idx; wxString stream; int n = lua_gettop(L); /* number of arguments */ lua_getglobal(L, "tostring"); for (idx = 1; idx <= n; idx++) { lua_pushvalue(L, -1); /* function to be called */ lua_pushvalue(L, idx); /* value to print */ lua_call(L, 1, 1); wxString s = lua2wx(lua_tostring(L, -1)); /* get result */ if (s.IsEmpty()) return luaL_error(L, "`tostring' must return a string to `print'"); if (idx > 1) stream.Append(wxT("\t")); stream.Append(s); lua_pop(L, 1); /* pop result */ } wxLuaDebugTarget *pTarget = GetDebugTarget(L); if (pTarget != NULL) pTarget->NotifyPrint(stream); return 0; }
wxString wxLuaEventCallback::GetInfo() const { return wxString::Format(wxT("%s(%d) -> wxLuaEventCallback(%p, ids %d, %d)|wxEvtHandler(%p) -> %s : %s"), lua2wx(m_wxlBindEvent ? m_wxlBindEvent->name : "?NULL?").c_str(), (int)GetEventType(), this, m_id, m_last_id, m_evtHandler, m_evtHandler ? m_evtHandler->GetClassInfo()->GetClassName() : wxT("?NULL?"), m_wxlState.GetwxLuaTypeName(m_wxlBindEvent ? *m_wxlBindEvent->wxluatype : WXLUA_TUNKNOWN).c_str()); }
bool wxLuaSocketBase::ReadLong(long& value_) { long value = 0; // make sure that long really works for 32 and 64 bit platforms, use a string char buf[65] = { 0 }; memset(buf, 0, 65); bool ok = Read(buf, 64) == 64; if (ok) ok = lua2wx(buf).ToLong(&value); wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::ReadLong"), wxString::Format(wxT("ok %d val %ld '%s'"), (int)ok, value, lua2wx(buf).c_str())); if (ok) value_ = value; return ok; }
bool wxLuaCSocket::Connect(const wxString &addr, u_short port_number) { m_port_number = port_number; hostent *pHost = NULL; if (m_sockstate != SOCKET_CLOSED) { AddErrorMessage(wxString::Format(wxT("Unable to connect to addr '%s' socket already open."), addr.c_str())); return false; } m_sock = ::socket(AF_INET, SOCK_STREAM, 0); if (m_sock == INVALID_SOCKET) { AddErrorMessage(wxString::Format(wxT("Unable to create client socket for addr '%s'."), addr.c_str())); return false; } unsigned long address = ::inet_addr(wx2lua(addr)); if (address != INADDR_NONE) pHost = ::gethostbyaddr((const char*) &address, 4, AF_INET); else pHost = ::gethostbyname(wx2lua(addr)); if (pHost == NULL) { AddErrorMessage(wxString::Format(wxT("Unable to get hostbyaddr or gethostbyname for addr '%s'."), addr.c_str())); return false; } if (pHost->h_addrtype != AF_INET) { AddErrorMessage(wxString::Format(wxT("Socket for addr '%s' is wrong type, isn't AF_INET."), addr.c_str())); return false; } memset(&m_sockaddress, 0, sizeof(m_sockaddress)); memcpy(&(m_sockaddress.sin_addr), pHost->h_addr_list[0], pHost->h_length); m_sockaddress.sin_family = AF_INET; m_sockaddress.sin_port = htons(port_number); m_address = lua2wx(inet_ntoa(m_sockaddress.sin_addr)); m_port_number = ntohs(m_sockaddress.sin_port); if (::connect(m_sock, (sockaddr *) &m_sockaddress, sizeof(m_sockaddress)) == SOCKET_ERROR) { AddErrorMessage(wxString::Format(wxT("Unable to connect socket to addr '%s'."), addr.c_str())); return false; } m_sockstate = SOCKET_CONNECTED; return true; }
wxString wxLuaCSocket::GetLastErrorMsg() const { wxString str; int errnum = 0; #ifdef WIN32 errnum = ::WSAGetLastError(); switch(errnum) { case WSANOTINITIALISED: str = _("A successful WSAStartup must occur before using this function."); break; case WSAENETDOWN: str = _("The network subsystem or the associated service provider has failed."); break; case WSAEAFNOSUPPORT: str = _("The specified address family is not supported."); break; case WSAEINPROGRESS: str = _("A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function."); break; case WSAEMFILE: str = _("No more socket descriptors are available."); break; case WSAENOBUFS: str = _("No buffer space is available. The socket cannot be created."); break; case WSAEPROTONOSUPPORT: str = _("The specified protocol is not supported."); break; case WSAEPROTOTYPE: str = _("The specified protocol is the wrong type for this socket."); break; case WSAESOCKTNOSUPPORT: str = _("The specified socket type is not supported in this address family."); break; } #else // a unix type system str = lua2wx(strerror(errno)); errnum = errno; //wxPrintf(wxT("ERRNO %d '%s' code: %d msg: '%s'\n"), errno, m_description.c_str(), code, m_msg.c_str()); #endif //WIN32 if (str.IsEmpty()) str = _("Unknown Socket Error."); str = wxString::Format(wxT("Socket Error %d : '%s'"), errnum, str.c_str()); return str; }
int wxLuaDebugData::EnumerateStack(lua_State* L) { wxCHECK_MSG(L, 0, wxT("Invalid lua_State")); wxCHECK_MSG(M_DEBUGREFDATA != NULL, 0, wxT("Invalid ref data")); lua_Debug luaDebug = INIT_LUA_DEBUG; int stack_frame = 0; int count = 0; while (lua_getstack(L, stack_frame, &luaDebug) != 0) { if (lua_getinfo(L, "Sln", &luaDebug)) { //wxPrintf(wxT("%s\n"), lua_Debug_to_wxString(luaDebug).c_str()); // skip stack frames that do not have line number, always add first int currentLine = luaDebug.currentline; if ((count == 0) || (currentLine != -1)) { wxString name; wxString source(lua2wx(luaDebug.source)); if (currentLine == -1) currentLine = 0; if (luaDebug.name != NULL) name.Printf(_("function %s line %d"), lua2wx(luaDebug.name).c_str(), currentLine); else name.Printf(_("line %d"), currentLine); Add(new wxLuaDebugItem(name, WXLUA_TNONE, wxEmptyString, WXLUA_TNONE, source, LUA_NOREF, stack_frame, WXLUA_DEBUGITEM_LOCALS)); ++count; } } ++stack_frame; } return count; }
wxString wxLuaDebugData::GetUserDataInfo(lua_State *L, int stack_idx, bool full_userdata) { wxCHECK_MSG(L, wxEmptyString, wxT("Invalid lua_State")); void* udata = lua_touserdata(L, stack_idx); wxString s(wxString::Format(wxT("%p"), udata)); if (!full_userdata) { // Convert our known keys to something more readable if ((udata == &wxlua_lreg_types_key) || (udata == &wxlua_lreg_refs_key) || (udata == &wxlua_lreg_debug_refs_key) || (udata == &wxlua_lreg_classes_key) || (udata == &wxlua_lreg_derivedmethods_key) || (udata == &wxlua_lreg_wxluastate_key) || (udata == &wxlua_lreg_wxluabindings_key) || (udata == &wxlua_lreg_weakobjects_key) || (udata == &wxlua_lreg_gcobjects_key) || (udata == &wxlua_lreg_evtcallbacks_key) || (udata == &wxlua_lreg_windestroycallbacks_key) || (udata == &wxlua_lreg_callbaseclassfunc_key) || (udata == &wxlua_lreg_wxeventtype_key) || (udata == &wxlua_lreg_wxluastatedata_key) || (udata == &wxlua_lreg_regtable_key) || (udata == &wxlua_metatable_type_key) || (udata == &wxlua_lreg_topwindows_key) || (udata == &wxlua_metatable_wxluabindclass_key)) { const char* ss = *(const char**)udata; s += wxString::Format(wxT(" (%s)"), lua2wx(ss).c_str()); } } else // is full userdata { int wxl_type = wxluaT_type(L, stack_idx); if (wxlua_iswxuserdatatype(wxl_type)) { s += wxString::Format(wxT(" (wxltype %d)"), wxl_type); wxString wxltypeName(wxluaT_typename(L, wxl_type)); if (!wxltypeName.IsEmpty()) s += wxString::Format(wxT(" '%s'"), wxltypeName.c_str()); } } return s; }
wxString wxLuaDebugIO::ReadString(wxLuaSocket *pSocket) { wxString value; unsigned int length = ReadInt(pSocket); if (length > 0) { char *buffer = new char[length + 1]; pSocket->Read(buffer, length); buffer[length] = 0; value = lua2wx(buffer); delete[] buffer; } return value; }
// Redefine task.post to use wx events in secondary threads // task.post(id, data, flags) int task_post(lua_State * L) { // Get params long id = (long)luaL_checknumber(L, 1); wxString data = lua2wx(luaL_checkstring(L, 2)); long flags = (long)luaL_optinteger(L, 3, 0); // Don't bother with the id, and assume it will always be 1 wxCommandEvent * evt = new wxCommandEvent(EVT_LUATASK); evt->SetInt(flags); evt->SetString(data.c_str()); if (wxTheApp) wxTheApp->QueueEvent(evt); // Always return 0, as this should never fail lua_pushnumber(L, 0); return 1; };
bool wxLuaSocketBase::ReadString(wxString& value_) { wxString value; wxUint32 length = 0; bool ok = Read((char *) &length, sizeof(wxUint32)) == sizeof(wxUint32); if (ok && (length > 0)) { char *buffer = new char[length + 1]; memset(buffer, 0, length+1); ok = Read(buffer, length) == (int)length; buffer[length] = 0; if (ok) value = lua2wx(buffer); delete[] buffer; } wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::ReadString"), wxString::Format(wxT("ok %d len %u val '%s'"), (int)ok, length, value.c_str())); if (ok) value_ = value; return ok; }
int wxLuaDebugData::GetTypeValue(lua_State *L, int stack_idx, int* wxl_type_, wxString& value) { wxCHECK_MSG(L, 0, wxT("Invalid lua_State")); int l_type = lua_type(L, stack_idx); int wxl_type = wxlua_luatowxluatype(l_type); switch (l_type) { case LUA_TNONE: { value = wxEmptyString; break; } case LUA_TNIL: { value = wxT("nil"); break; } case LUA_TBOOLEAN: { value = (lua_toboolean(L, stack_idx) != 0) ? wxT("true") : wxT("false"); break; } case LUA_TLIGHTUSERDATA: { value = GetUserDataInfo(L, stack_idx, false); break; } case LUA_TNUMBER: { double num = lua_tonumber(L, stack_idx); if ((long)num == num) value.Printf(wxT("%ld (0x%lx)"), (long)num, (unsigned long)num); else value.Printf(wxT("%g"), num); break; } case LUA_TSTRING: { value = lua2wx(lua_tostring(L, stack_idx)); break; } case LUA_TTABLE: { value = GetTableInfo(L, stack_idx); break; } case LUA_TFUNCTION: { value.Printf(wxT("%p"), lua_topointer(L, stack_idx)); if (lua_iscfunction(L, stack_idx)) wxl_type = WXLUA_TCFUNCTION; break; } case LUA_TUSERDATA: { value = GetUserDataInfo(L, stack_idx, true); break; } case LUA_TTHREAD: { value.Printf(wxT("%p"), lua_topointer(L, stack_idx)); break; } default : { value = wxEmptyString; break; } } if (wxl_type_) *wxl_type_ = wxl_type; return l_type; }
int wxLuaDebugData::EnumerateTable(lua_State* L, int tableRef, int nIndex, wxArrayInt& references) { wxCHECK_MSG(L, 0, wxT("Invalid lua_State")); wxCHECK_MSG(M_DEBUGREFDATA != NULL, 0, wxT("Invalid ref data")); int count = 0; int wxl_keytype = WXLUA_TNONE; int wxl_valuetype = WXLUA_TNONE; wxString value; wxString name; if (tableRef == LUA_GLOBALSINDEX) { lua_pushglobaltable(L); GetTypeValue(L, -1, &wxl_valuetype, value); int flag_type = 0; int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references); lua_pop(L, 1); // pop globals table Add(new wxLuaDebugItem(wxT("Globals"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type)); } #if LUA_VERSION_NUM < 502 // LUA_ENVIRONINDEX is no longer in 5.2 else if (tableRef == LUA_ENVIRONINDEX) { lua_pushvalue(L, LUA_ENVIRONINDEX); GetTypeValue(L, -1, &wxl_valuetype, value); int flag_type = 0; int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references); lua_pop(L, 1); // pop environment table Add(new wxLuaDebugItem(wxT("Environment"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type)); } #endif // LUA_VERSION_NUM < 502 else if (tableRef == LUA_REGISTRYINDEX) { lua_pushvalue(L, LUA_REGISTRYINDEX); GetTypeValue(L, -1, &wxl_valuetype, value); int flag_type = 0; int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references); lua_pop(L, 1); // pop registry table Add(new wxLuaDebugItem(wxT("Registry"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type)); } else { // push the table onto the stack to iterate through if (wxluaR_getref(L, tableRef, &wxlua_lreg_debug_refs_key)) { if (lua_isnil(L, -1)) { // assert so we don't crash mysteriously inside Lua on nil lua_pop(L, 1); // pop nil wxFAIL_MSG(wxT("Invalid wxLua debug reference")); return count; } // Check to see if this is a wxLua LUA_REGISTRYINDEX table void *lightuserdata_reg_key = NULL; lua_pushlightuserdata(L, &wxlua_lreg_regtable_key); // push key lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, -2); // push value (table we're iterating) lua_rawget(L, -2); lightuserdata_reg_key = lua_touserdata(L, -1); // returns NULL for nil lua_pop(L, 2); // pop wxlua_lreg_regtable_key table and (nil or lightuserdata) // Check if this table/userdata has a metatable if (lua_getmetatable(L, -1)) // if no metatable then nothing is pushed { // get the type and value GetTypeValue(L, -1, &wxl_valuetype, value); int flag_type = 0; int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references); // leading space so it's first when sorted Add(new wxLuaDebugItem(wxT(" __metatable"), WXLUA_TTABLE, value, wxl_valuetype, wxEmptyString, val_ref, nIndex, flag_type)); ++count; lua_pop(L, 1); // pop metatable } // start iterating if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2) != 0) { // value at -1, key at -2, table at -3 // get the key type and value int lua_key_type = GetTypeValue(L, -2, &wxl_keytype, name); // get the value type and value int lua_value_type = GetTypeValue(L, -1, &wxl_valuetype, value); // Handle items within the wxLua LUA_REGISTRYINDEX tables to give more information if (lightuserdata_reg_key != NULL) { if (lightuserdata_reg_key == &wxlua_lreg_types_key) { value += wxString::Format(wxT(" (%s)"), wxluaT_typename(L, (int)lua_tonumber(L, -2)).c_str()); } else if (lightuserdata_reg_key == &wxlua_lreg_classes_key) { wxLuaBindClass* wxlClass = (wxLuaBindClass*)lua_touserdata(L, -1); value += wxLuaBindClassString(wxlClass); } else if (lightuserdata_reg_key == &wxlua_lreg_wxluabindings_key) { wxLuaBinding* binding = (wxLuaBinding*)lua_touserdata(L, -2); name = wxString::Format(wxT("wxLuaBinding(%s) -> %s"), name.c_str(), binding->GetBindingName().c_str()); value += wxT(" = ") + binding->GetLuaNamespace(); } else if (lightuserdata_reg_key == &wxlua_lreg_evtcallbacks_key) { wxLuaEventCallback* wxlCallback = (wxLuaEventCallback*)lua_touserdata(L, -2); wxCHECK_MSG(wxlCallback, count, wxT("Invalid wxLuaEventCallback")); wxString s(wxlCallback->GetInfo()); name = s.BeforeFirst(wxT('|')); value = s.AfterFirst(wxT('|')); } else if (lightuserdata_reg_key == &wxlua_lreg_windestroycallbacks_key) { // only handle t[wxWindow*] = wxLuaWinDestroyCallback* wxLuaWinDestroyCallback* wxlDestroyCallBack = (wxLuaWinDestroyCallback*)lua_touserdata(L, -1); wxCHECK_MSG(wxlDestroyCallBack, count, wxT("Invalid wxLuaWinDestroyCallback")); wxString s(wxlDestroyCallBack->GetInfo()); name = s.BeforeFirst(wxT('|')); value = s.AfterFirst(wxT('|')); } else if (lightuserdata_reg_key == &wxlua_lreg_topwindows_key) { wxWindow* win = (wxWindow*)lua_touserdata(L, -2); name += wxT(" ") + wxString(win->GetClassInfo()->GetClassName()); } else if (lightuserdata_reg_key == &wxlua_lreg_gcobjects_key) { int wxl_type_ = (int)lua_tonumber(L, -1); name = wxString::Format(wxT("%s(%s)"), wxluaT_typename(L, wxl_type_).c_str(), name.c_str()); } else if (lightuserdata_reg_key == &wxlua_lreg_weakobjects_key) { wxString names_weak; // iterate the table of userdata lua_pushnil(L); while (lua_next(L, -2) != 0) { // value = -1, key = -2, table = -3 int wxl_type_weak = (int)lua_tonumber(L, -2); if (!names_weak.IsEmpty()) names_weak += wxT(", "); names_weak += wxString::Format(wxT("%s(%d)"), wxluaT_typename(L, wxl_type_weak).c_str(), wxl_type_weak); lua_pop(L, 1); // pop value, lua_next will pop key at end } name = wxString::Format(wxT("%s (%s)"), names_weak.c_str(), name.c_str()); } } // For these keys we know what is in the value to give more information if (lua_key_type == LUA_TLIGHTUSERDATA) { void* key = lua_touserdata(L, -2); if (key == &wxlua_lreg_wxeventtype_key) { wxEventType eventType = (wxEventType)lua_tonumber(L, -1); const wxLuaBindEvent* wxlEvent = wxLuaBinding::FindBindEvent(eventType); if (wxlEvent != NULL) { value = wxString::Format(wxT("%d = %s : %s"), eventType, lua2wx(wxlEvent->name).c_str(), wxluaT_typename(L, *wxlEvent->wxluatype).c_str()); } } else if (key == &wxlua_metatable_type_key) { value += wxString::Format(wxT(" (%s)"), wxluaT_typename(L, (int)lua_tonumber(L, -1)).c_str()); } else if (key == &wxlua_metatable_wxluabindclass_key) { wxLuaBindClass* wxlClass = (wxLuaBindClass*)lua_touserdata(L, -1); value += wxLuaBindClassString(wxlClass); } else if (key == &wxlua_lreg_debug_refs_key) { value += wxT(" Note: You cannot traverse refed tables"); } } // ---------------------------------------------------------- // Handle the key int key_flag_type = 0; int key_ref = LUA_NOREF; // don't ref anything in this table since it's already refed if ((lua_key_type == LUA_TTABLE) && (lightuserdata_reg_key != &wxlua_lreg_debug_refs_key)) { key_ref = RefTable(L, -2, &key_flag_type, WXLUA_DEBUGITEM_KEY_REF, references); } else if (lua_key_type == LUA_TUSERDATA) { if (lua_getmetatable(L, -2)) // doesn't push anything if nil { key_ref = RefTable(L, -2, &key_flag_type, WXLUA_DEBUGITEM_KEY_REF, references); lua_pop(L, 1); } } // only add the key if we refed it so it can be viewed in the stack dialog if (key_flag_type != 0) { Add(new wxLuaDebugItem(name, wxl_keytype, value, wxl_valuetype, wxEmptyString, key_ref, nIndex, key_flag_type)); ++count; } // ---------------------------------------------------------- // Handle the value int val_flag_type = 0; int val_ref = LUA_NOREF; // don't ref anything in this table since it's already refed if ((lua_value_type == LUA_TTABLE) && (lightuserdata_reg_key != &wxlua_lreg_debug_refs_key)) { val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references); } else if (lua_value_type == LUA_TUSERDATA) { if (lua_getmetatable(L, -1)) // doesn't push anything if nil { val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references); lua_pop(L, 1); } } // Add the value, but not if the value doesn't expand and the key was already added if ((key_flag_type == 0) || ((key_flag_type != 0) && (val_flag_type != 0))) { Add(new wxLuaDebugItem(name, wxl_keytype, value, wxl_valuetype, wxEmptyString, val_ref, nIndex, val_flag_type)); ++count; } lua_pop(L, 1); // pop value, leave key } } lua_pop(L, 1); // remove reference } } return count; }
wxLuaCSocket::wxLuaCSocket(socket_type socket, sockaddr_in address) :m_sock(socket), m_sockaddress(address), m_sockstate(SOCKET_ACCEPTED) { m_address = lua2wx(inet_ntoa(m_sockaddress.sin_addr)); m_port_number = ntohs(m_sockaddress.sin_port); }
wxString wxLuaFreezeApp::LoadScript(const wxString& filename, bool only_check) { // lots of debugging to make sure that everything is ok wxFile f; if (!f.Open(filename, wxFile::read)) { OutputPrint(wxString::Format(wxT("Unable to open this executable file '%s' in read-only mode.\n"), filename.c_str())); return wxEmptyString; } // end of file is : "<wxLuaFreeze:%010d>", script_len #define END_TAG_LEN 24 if (f.Seek(-END_TAG_LEN, wxFromEnd) == wxInvalidOffset) { f.Close(); OutputPrint(wxString::Format(wxT("Unable to seek to last %d bytes at end of '%s'.\n"), END_TAG_LEN, filename.c_str())); return wxEmptyString; } // do some sanity checking before reading the script length char tag_buf[END_TAG_LEN+2] = {0}; memset(tag_buf, 0, sizeof(char)*(END_TAG_LEN+2)); long script_len = 0; if (f.Read((void*)tag_buf, END_TAG_LEN) == wxInvalidOffset) { f.Close(); OutputPrint(wxString::Format(wxT("Unable to read wxLuaFreeze tag info at end of '%s'.\n"), filename.c_str())); return wxEmptyString; } if (sscanf(tag_buf, "<wxLuaFreeze:%ld>", &script_len) != 1) { f.Close(); // they only wanted to know if the script exists, assume it's valid if (only_check) return LOADSCRIPT_MISSING; OutputPrint(wxString::Format(wxT("Expecting '<wxLuaFreeze:[script length]>' at end of '%s'.\n") wxT("Did you forget to run wxluafreeze.lua to attach your script?\n"), filename.c_str())); return wxEmptyString; } else if (f.Seek(-END_TAG_LEN - script_len, wxFromEnd) == wxInvalidOffset) { f.Close(); OutputPrint(wxString::Format(wxT("Unable to seek to beginning of wxLua script at end of '%s'.\n"), filename.c_str())); return wxEmptyString; } // size should be valid from Seek statement char *script = (char*)malloc(script_len+2); if (script) { memset(script, 0, sizeof(script_len+2)); f.Read(script, script_len); script[script_len] = 0; } f.Close(); // we finally have our script! wxString scriptStr(lua2wx(script)); free(script); return scriptStr; }
bool wxLuaDebugTarget::EvaluateExpr(int exprRef, const wxString &strExpr) // FIXME - check this code { wxString strResult(wxT("Error")); int nReference = LUA_NOREF; EnterLuaCriticalSection(); { lua_State* L = m_wxlState.GetLuaState(); if (wxStrpbrk(strExpr.c_str(), wxT(" ~=<>+-*/%(){}[]:;,.\"'")) != NULL) { // an expression int nOldTop = lua_gettop(L); wxLuaCharBuffer charbuf(strExpr); int nResult = luaL_loadbuffer(L, charbuf.GetData(), charbuf.Length(), "debug"); if (nResult == 0) nResult = lua_pcall(L, 0, LUA_MULTRET, 0); // call main if (nResult != 0) wxlua_pushwxString(L, wxlua_LUA_ERR_msg(nResult)); else if (lua_gettop(L) == nOldTop) lua_pushliteral(L, "OK"); nReference = m_wxlState.wxluaR_Ref(-1, &wxlua_lreg_refs_key); lua_settop(L, nOldTop); // throw out all return values } else { lua_Debug ar = INIT_LUA_DEBUG; int iLevel = 0; bool fFound = false; while (lua_getstack(L, iLevel++, &ar) != 0) { int iIndex = 0; wxString name = lua2wx(lua_getlocal(L, &ar, ++iIndex)); if (!name.IsEmpty()) { if (strExpr == name) { nReference = m_wxlState.wxluaR_Ref(-1, &wxlua_lreg_refs_key); fFound = true; break; } lua_pop(L, 1); } if (fFound) break; name = lua2wx(lua_getlocal(L, &ar, ++iIndex)); } if (!fFound) { int nOldTop = lua_gettop(L); lua_pushvalue(L, LUA_GLOBALSINDEX); lua_pushnil(L); while (lua_next(L, -2) != 0) { if (lua_type(L, -2) == LUA_TSTRING) { wxString name = lua2wx(lua_tostring(L, -2)); if (strExpr == name) { nReference = m_wxlState.wxluaR_Ref(-1, &wxlua_lreg_refs_key); // reference value lua_pop(L, 2); // pop key and value fFound = true; break; } } lua_pop(L, 1); // removes 'value'; } lua_settop(L, nOldTop); // the table of globals. } } if (m_wxlState.wxluaR_GetRef(nReference, &wxlua_lreg_refs_key)) { m_wxlState.wxluaR_Unref(nReference, &wxlua_lreg_refs_key); int wxl_type = 0; wxString value; wxLuaDebugData::GetTypeValue(L, -1, &wxl_type, value); strResult.Printf(wxT("%s : %s"), wxluaT_typename(L, wxl_type).c_str(), value.c_str()); lua_pop(L, 1); } } LeaveLuaCriticalSection(); return NotifyEvaluateExpr(exprRef, strResult); }
bool wxLuaDebugTarget::DebugHook(int event) { bool fWait = false; m_fStopped = true; int lineNumber = 0; wxString fileName; if (!(m_forceBreak && m_resetRequested)) { lua_Debug luaDebug = INIT_LUA_DEBUG; lua_getstack(m_wxlState.GetLuaState(), 0, &luaDebug); lua_getinfo(m_wxlState.GetLuaState(), "Sln", &luaDebug); lineNumber = luaDebug.currentline - 1; fileName = lua2wx(luaDebug.source); if (!fileName.IsEmpty() && (fileName[0] == wxT('@'))) fileName = fileName.Mid(1); } if (m_forceBreak) { if (m_resetRequested) { fWait = true; m_fExiting = true; wxExit(); } if (!m_fExiting) { if (NotifyBreak(fileName, lineNumber)) fWait = true; } } else { if (event == LUA_HOOKCALL) // call m_nFramesUntilBreak++; else if ((event == LUA_HOOKRET) || (event == LUA_HOOKTAILRET)) // return { if (m_nFramesUntilBreak > 0) m_nFramesUntilBreak--; } else if (event == LUA_HOOKLINE) // line { switch (m_nextOperation) { case DEBUG_STEP: { if (NotifyBreak(fileName, lineNumber)) fWait = true; break; } case DEBUG_STEPOVER: { if ((m_nFramesUntilBreak == 0) && NotifyBreak(fileName, lineNumber)) fWait = true; break; } case DEBUG_GO: default: { if (AtBreakPoint(fileName, lineNumber) && NotifyBreak(fileName, lineNumber)) fWait = true; break; } } } } if (fWait) { // release the critical section so // the other thread can access LUA LeaveLuaCriticalSection(); // Wait for a command m_debugCondition.Wait(); // acquire the critical section again EnterLuaCriticalSection(); } m_fStopped = false; return fWait; }