void AssertMessage(const char * text, const char * filename, int linenum, const char * format, ...) { // We only want to display the file name filename = clean_filename(filename); SCP_stringstream msgStream; msgStream << "Assert: \"" << text << "\"\n"; msgStream << "File: " << filename << "\n"; msgStream << "Line: " << linenum << "\n"; if (format != nullptr) { SCP_string buffer; va_list args; va_start(args, format); vsprintf(buffer, format, args); va_end(args); msgStream << buffer << "\n"; mprintf(("ASSERTION: \"%s\" at %s:%d\n %s\n", text, filename, linenum, buffer.c_str())); } else { // No additional message mprintf(("ASSERTION: \"%s\" at %s:%d\n", text, filename, linenum)); } if (running_unittests) { throw AssertException(msgStream.str()); } msgStream << "\n"; msgStream << dump_stacktrace(); SCP_string messageText = msgStream.str(); set_clipboard_text(messageText.c_str()); messageText = truncateLines(msgStream, Messagebox_lines); messageText += "\n[ This info is in the clipboard so you can paste it somewhere now ]\n"; messageText += "\n\nUse Debug to break into Debugger, Exit will close the application.\n"; Error(messageText.c_str()); }
void ReleaseWarning(const char* filename, int line, const char* format, ...) { Global_warning_count++; filename = clean_filename(filename); // output to the debug log before anything else (so that we have a complete record) SCP_string formatMessage; va_list args; va_start(args, format); vsprintf(formatMessage, format, args); va_end(args); SCP_string printfString = formatMessage; std::transform(printfString.begin(), printfString.end(), printfString.begin(), replaceNewline); mprintf(("WARNING: \"%s\" at %s:%d\n", printfString.c_str(), filename, line)); // now go for the additional popup window, if we want it ... if (Cmdline_noninteractive) { return; } if (running_unittests) { throw AssertException(printfString); } SCP_stringstream boxMsgStream; boxMsgStream << "Warning: " << formatMessage << "\n"; boxMsgStream << "File: " << filename << "\n"; boxMsgStream << "Line: " << line << "\n"; boxMsgStream << "\n"; boxMsgStream << dump_stacktrace(); set_clipboard_text(boxMsgStream.str().c_str()); SCP_string boxMessage = truncateLines(boxMsgStream, Messagebox_lines); boxMessage += "\n[ This info is in the clipboard so you can paste it somewhere now ]\n"; boxMessage += "\n\nUse Debug to break into Debugger\n"; const SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 2, "Exit" }, { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "Continue" }, { /* .flags, .buttonid, .text */ 0, 0, "Debug" }, }; SDL_MessageBoxData boxData; memset(&boxData, 0, sizeof(boxData)); boxData.buttons = buttons; boxData.numbuttons = 3; boxData.colorScheme = nullptr; boxData.flags = SDL_MESSAGEBOX_WARNING; boxData.message = boxMessage.c_str(); boxData.title = "Warning!"; boxData.window = os::getSDLMainWindow(); gr_activate(0); int buttonId; if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed exit(1); } switch (buttonId) { case 2: exit(1); case 0: Int3(); break; default: break; } gr_activate(1); }
void Error(const char* text) { mprintf(("\n%s\n", text)); if (Cmdline_noninteractive) { abort(); return; } if (running_unittests) { throw ErrorException(text); } SCP_stringstream messageStream; messageStream << text << "\n"; messageStream << dump_stacktrace(); SCP_string fullText = messageStream.str(); set_clipboard_text(fullText.c_str()); fullText = truncateLines(messageStream, Messagebox_lines); fullText += "\n[ This info is in the clipboard so you can paste it somewhere now ]\n"; fullText += "\n\nUse Debug to break into Debugger, Exit will close the application.\n"; const SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Exit" }, { /* .flags, .buttonid, .text */ 0, 0, "Debug" }, }; SDL_MessageBoxData boxData; memset(&boxData, 0, sizeof(boxData)); boxData.buttons = buttons; boxData.numbuttons = 2; boxData.colorScheme = nullptr; boxData.flags = SDL_MESSAGEBOX_ERROR; boxData.message = text; boxData.title = "Error!"; boxData.window = os::getSDLMainWindow(); gr_activate(0); int buttonId; if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed exit(1); } switch (buttonId) { case 1: exit(1); default: Int3(); break; } gr_activate(1); }
void LuaError(lua_State * L, const char * format, ...) { SCP_stringstream msgStream; //WMC - if format is set to NULL, assume this is acting as an //error handler for Lua. if (format == NULL) { msgStream << "LUA ERROR: " << lua_tostring(L, -1); lua_pop(L, -1); } else { SCP_string formatText; va_list args; va_start(args, format); vsprintf(formatText, format, args); va_end(args); msgStream << formatText; } msgStream << "\n"; msgStream << "\n"; msgStream << Separator; msgStream << "ADE Debug:"; msgStream << "\n"; msgStream << Separator; LuaDebugPrint(msgStream, Ade_debug_info); msgStream << Separator; msgStream << "\n"; msgStream << "\n"; msgStream << Separator; // Get the stack via the debug.traceback() function lua_getglobal(L, LUA_DBLIBNAME); if (!lua_isnil(L, -1)) { msgStream << "\n"; lua_getfield(L, -1, "traceback"); lua_remove(L, -2); if (lua_pcall(L, 0, 1, 0) != 0) msgStream << "Error while retrieving stack: " << lua_tostring(L, -1); else msgStream << lua_tostring(L, -1); lua_pop(L, 1); } msgStream << "\n"; msgStream << Separator; char stackText[1024]; stackText[0] = '\0'; scripting::ade_stackdump(L, stackText); msgStream << stackText; msgStream << "\n"; msgStream << Separator; mprintf(("Lua Error: %s\n", msgStream.str().c_str())); if (Cmdline_noninteractive) { exit(1); return; } if (running_unittests) { throw LuaErrorException(msgStream.str()); } set_clipboard_text(msgStream.str().c_str()); // truncate text auto truncatedText = truncateLines(msgStream, Messagebox_lines); SCP_stringstream boxTextStream; boxTextStream << truncatedText << "\n"; boxTextStream << "\n[ This info is in the clipboard so you can paste it somewhere now ]\n"; auto boxText = boxTextStream.str(); const SDL_MessageBoxButtonData buttons[] = { { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 2, "Exit" }, { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "Continue" }, { /* .flags, .buttonid, .text */ 0, 0, "Debug" }, }; SDL_MessageBoxData boxData; memset(&boxData, 0, sizeof(boxData)); boxData.buttons = buttons; boxData.numbuttons = 3; boxData.colorScheme = nullptr; boxData.flags = SDL_MESSAGEBOX_ERROR; boxData.message = boxText.c_str(); boxData.title = "Error!"; boxData.window = os::getSDLMainWindow(); gr_activate(0); int buttonId; if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed buttonId = 1; // No action } switch (buttonId) { case 2: exit(1); case 0: Int3(); break; default: break; } gr_activate(1); }
void Entry::executeCmd(EntryCmd cmd, int unicodeChar, bool shift_pressed) { std::string text = this->text(); int selbeg, selend; getEntryThemeInfo(NULL, NULL, NULL, &selbeg, &selend); switch (cmd) { case EntryCmd::NoOp: break; case EntryCmd::InsertChar: // delete the entire selection if (selbeg >= 0) { text.erase(m_boxes[selbeg].from, m_boxes[selend].to - m_boxes[selbeg].from); m_caret = selbeg; // We set the caret to the beginning of the erased selection, // needed to show the first inserted character in case // m_scroll > m_caret. E.g. we select all text and insert a // new character to replace the whole text, the new inserted // character makes m_caret=1, so m_scroll will be 1 too, but // we need to make m_scroll=0 to show the new inserted char.) // In this way, we first ensure a m_scroll value enough to // show the new inserted character. recalcCharBoxes(text); setCaretPos(m_caret); } // Convert the unicode character -> wstring -> utf-8 string -> insert the utf-8 string if (lastCaretPos() < m_maxsize) { ASSERT(m_caret <= lastCaretPos()); std::wstring unicodeStr; unicodeStr.push_back(unicodeChar); text.insert(m_boxes[m_caret].from, base::to_utf8(unicodeStr)); recalcCharBoxes(text); ++m_caret; } m_select = -1; break; case EntryCmd::BackwardChar: case EntryCmd::BackwardWord: // selection if (shift_pressed) { if (m_select < 0) m_select = m_caret; } else m_select = -1; // backward word if (cmd == EntryCmd::BackwardWord) { backwardWord(); } // backward char else if (m_caret > 0) { m_caret--; } break; case EntryCmd::ForwardChar: case EntryCmd::ForwardWord: // selection if (shift_pressed) { if (m_select < 0) m_select = m_caret; } else m_select = -1; // forward word if (cmd == EntryCmd::ForwardWord) { forwardWord(); } // forward char else if (m_caret < (int)text.size()) { m_caret++; } break; case EntryCmd::BeginningOfLine: // selection if (shift_pressed) { if (m_select < 0) m_select = m_caret; } else m_select = -1; m_caret = 0; break; case EntryCmd::EndOfLine: // selection if (shift_pressed) { if (m_select < 0) m_select = m_caret; } else m_select = -1; m_caret = lastCaretPos(); break; case EntryCmd::DeleteForward: case EntryCmd::Cut: // delete the entire selection if (selbeg >= 0) { // *cut* text! if (cmd == EntryCmd::Cut) set_clipboard_text(selectedText()); // remove text text.erase(m_boxes[selbeg].from, m_boxes[selend].to - m_boxes[selbeg].from); m_caret = selbeg; } // delete the next character else { if (m_caret < (int)text.size()) text.erase(m_boxes[m_caret].from, m_boxes[m_caret].to - m_boxes[m_caret].from); } m_select = -1; break; case EntryCmd::Paste: { std::string clipboard; if (get_clipboard_text(clipboard)) { // delete the entire selection if (selbeg >= 0) { text.erase(m_boxes[selbeg].from, m_boxes[selend].to - m_boxes[selbeg].from); m_caret = selbeg; m_select = -1; } // Paste text recalcCharBoxes(text); int oldBoxes = m_boxes.size(); text.insert(m_boxes[m_caret].from, clipboard); // Remove extra chars that do not fit in m_maxsize recalcCharBoxes(text); if (lastCaretPos() > m_maxsize) { text.erase(m_boxes[m_maxsize].from, text.size() - m_boxes[m_maxsize].from); recalcCharBoxes(text); } int newBoxes = m_boxes.size(); setCaretPos(m_caret+(newBoxes - oldBoxes)); } break; } case EntryCmd::Copy: if (selbeg >= 0) set_clipboard_text(selectedText()); break; case EntryCmd::DeleteBackward: // delete the entire selection if (selbeg >= 0) { text.erase(m_boxes[selbeg].from, m_boxes[selend].to - m_boxes[selbeg].from); m_caret = selbeg; } // delete the previous character else { if (m_caret > 0) { --m_caret; text.erase(m_boxes[m_caret].from, m_boxes[m_caret].to - m_boxes[m_caret].from); } } m_select = -1; break; case EntryCmd::DeleteBackwardWord: m_select = m_caret; backwardWord(); if (m_caret < m_select) { text.erase(m_boxes[m_caret].from, m_boxes[m_select].to - m_boxes[m_caret].from); } m_select = -1; break; case EntryCmd::DeleteForwardToEndOfLine: text.erase(m_boxes[m_caret].from); break; case EntryCmd::SelectAll: selectAllText(); break; } if (text != this->text()) { setText(text); onChange(); } setCaretPos(m_caret); invalidate(); }