1
0
Fork 0

Merge pull request #3133 from Bluefissure/log-commands

Add Commands: LogSave, LogRedirect, LogRedirectStop
This commit is contained in:
Duncan Ogilvie 2023-08-01 13:47:49 +02:00 committed by GitHub
commit 17621d845c
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 152 additions and 40 deletions

View File

@ -1361,6 +1361,21 @@ BRIDGE_IMPEXP void GuiLogClear()
_gui_sendmessage(GUI_CLEAR_LOG, 0, 0);
}
BRIDGE_IMPEXP void GuiLogSave(const char* filename)
{
_gui_sendmessage(GUI_SAVE_LOG, (void*)filename, 0);
}
BRIDGE_IMPEXP void GuiLogRedirect(const char* filename)
{
_gui_sendmessage(GUI_REDIRECT_LOG, (void*)filename, 0);
}
BRIDGE_IMPEXP void GuiLogRedirectStop()
{
_gui_sendmessage(GUI_STOP_REDIRECT_LOG, 0, 0);
}
BRIDGE_IMPEXP void GuiUpdateEnable(bool updateNow)
{
bDisableGUIUpdate = false;

View File

@ -1276,6 +1276,9 @@ typedef enum
GUI_ADD_MSG_TO_LOG_HTML, // param1=(const char*)msg, param2=unused
GUI_IS_LOG_ENABLED, // param1=unused, param2=unused
GUI_IS_DEBUGGER_FOCUSED, // param1=unused, param2=unused
GUI_SAVE_LOG, // param1=const char* file name,param2=unused
GUI_REDIRECT_LOG, // param1=const char* file name,param2=unused
GUI_STOP_REDIRECT_LOG, // param1=unused, param2=unused
} GUIMSG;
//GUI Typedefs
@ -1345,6 +1348,9 @@ BRIDGE_IMPEXP void GuiSetDebugStateFast(DBGSTATE state);
BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg);
BRIDGE_IMPEXP void GuiAddLogMessageHtml(const char* msg);
BRIDGE_IMPEXP void GuiLogClear();
BRIDGE_IMPEXP void GuiLogSave(const char* filename);
BRIDGE_IMPEXP void GuiLogRedirect(const char* filename);
BRIDGE_IMPEXP void GuiLogRedirectStop();
BRIDGE_IMPEXP void GuiUpdateAllViews();
BRIDGE_IMPEXP void GuiUpdateRegisterView();
BRIDGE_IMPEXP void GuiUpdateDisassemblyView();

View File

@ -50,6 +50,29 @@ static bool cbClearLog(int argc, char* argv[])
return true;
}
static bool cbSaveLog(int argc, char* argv[])
{
if(argc < 2)
GuiLogSave(nullptr);
else
GuiLogSave(argv[1]);
return true;
}
static bool cbRedirectLog(int argc, char* argv[])
{
if(IsArgumentsLessThan(argc, 2))
return false;
GuiLogRedirect(argv[1]);
return true;
}
static bool cbStopRedirectLog(int argc, char* argv[])
{
GuiLogRedirectStop();
return true;
}
static bool cbPrintf(int argc, char* argv[])
{
if(argc < 2)
@ -406,6 +429,9 @@ static void registercommands()
dbgcmdnew("EnableLog,LogEnable", cbInstrEnableLog, false); //enable log
dbgcmdnew("DisableLog,LogDisable", cbInstrDisableLog, false); //disable log
dbgcmdnew("ClearLog,cls,lc,lclr", cbClearLog, false); //clear the log
dbgcmdnew("SaveLog,LogSave", cbSaveLog, false); //save the log
dbgcmdnew("RedirectLog,LogRedirect", cbRedirectLog, false); //redirect the log
dbgcmdnew("StopRedirectLog,LogRedirectStop", cbStopRedirectLog, false); //stop redirecting the log
dbgcmdnew("AddFavouriteTool", cbInstrAddFavTool, false); //add favourite tool
dbgcmdnew("AddFavouriteCommand", cbInstrAddFavCmd, false); //add favourite command
dbgcmdnew("AddFavouriteToolShortcut,SetFavouriteToolShortcut", cbInstrSetFavToolShortcut, false); //set favourite tool shortcut

View File

@ -127,6 +127,21 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
emit clearLog();
break;
case GUI_SAVE_LOG:
if(!param1)
emit saveLog();
else
emit saveLogToFile(QString((const char*)param1));
break;
case GUI_REDIRECT_LOG:
emit redirectLogToFile(QString((const char*)param1));
break;
case GUI_STOP_REDIRECT_LOG:
emit redirectLogStop();
break;
case GUI_UPDATE_REGISTER_VIEW:
emit updateRegisters();
break;

View File

@ -53,6 +53,10 @@ signals:
void addMsgToLog(QByteArray msg);
void addMsgToLogHtml(QByteArray msg);
void clearLog();
void saveLog();
void saveLogToFile(QString file);
void redirectLogStop();
void redirectLogToFile(QString filename);
void shutdown();
void updateRegisters();
void updateBreakpoints();

View File

@ -36,8 +36,12 @@ LogView::LogView(QWidget* parent) : QTextBrowser(parent), logRedirection(NULL)
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateStyle()));
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateStyle()));
connect(Bridge::getBridge(), SIGNAL(addMsgToLog(QByteArray)), this, SLOT(addMsgToLogSlot(QByteArray)));
connect(Bridge::getBridge(), SIGNAL(addMsgToLogHtml(QByteArray)), this, SLOT(addMsgToLogSlotHtml(QByteArray)));
connect(Bridge::getBridge(), SIGNAL(addMsgToLogHtml(QByteArray)), this, SLOT(addMsgToLogHtmlSlot(QByteArray)));
connect(Bridge::getBridge(), SIGNAL(clearLog()), this, SLOT(clearLogSlot()));
connect(Bridge::getBridge(), SIGNAL(saveLog()), this, SLOT(saveSlot()));
connect(Bridge::getBridge(), SIGNAL(saveLogToFile(QString)), this, SLOT(saveToFileSlot(QString)));
connect(Bridge::getBridge(), SIGNAL(redirectLogToFile(QString)), this, SLOT(redirectLogToFileSlot(QString)));
connect(Bridge::getBridge(), SIGNAL(redirectLogStop()), this, SLOT(stopRedirectLogSlot()));
connect(Bridge::getBridge(), SIGNAL(setLogEnabled(bool)), this, SLOT(setLoggingEnabled(bool)));
connect(Bridge::getBridge(), SIGNAL(flushLog()), this, SLOT(flushLogSlot()));
connect(this, SIGNAL(anchorClicked(QUrl)), this, SLOT(onAnchorClicked(QUrl)));
@ -56,9 +60,9 @@ LogView::LogView(QWidget* parent) : QTextBrowser(parent), logRedirection(NULL)
*/
LogView::~LogView()
{
if(logRedirection != NULL)
if(logRedirection != nullptr)
fclose(logRedirection);
logRedirection = NULL;
logRedirection = nullptr;
}
void LogView::updateStyle()
@ -148,7 +152,7 @@ void LogView::contextMenuEvent(QContextMenuEvent* event)
wMenu.addAction(actionFindInLog);
wMenu.addAction(actionFindNext);
wMenu.addAction(actionFindPrevious);
if(logRedirection == NULL)
if(logRedirection == nullptr)
actionRedirectLog->setText(tr("&Redirect Log..."));
else
actionRedirectLog->setText(tr("Stop &Redirection"));
@ -230,10 +234,10 @@ void LogView::linkify(QString & msg)
}
/**
* @brief LogView::addMsgToLogSlotHtml Adds a HTML message to the log view. This function is a slot for Bridge::addMsgToLogHtml.
* @brief LogView::addMsgToLogHtmlSlot Adds a HTML message to the log view. This function is a slot for Bridge::addMsgToLogHtml.
* @param msg The log message (Which is assumed to contain HTML)
*/
void LogView::addMsgToLogSlotHtml(QByteArray msg)
void LogView::addMsgToLogHtmlSlot(QByteArray msg)
{
LogView::addMsgToLogSlotRaw(msg, false);
}
@ -265,7 +269,7 @@ void LogView::addMsgToLogSlotRaw(QByteArray msg, bool encodeHTML)
// redirect the log
QString msgUtf16;
bool redirectError = false;
if(logRedirection != NULL)
if(logRedirection != nullptr)
{
if(utf16Redirect)
{
@ -274,7 +278,7 @@ void LogView::addMsgToLogSlotRaw(QByteArray msg, bool encodeHTML)
if(!fwrite(msgUtf16.utf16(), msgUtf16.length(), 2, logRedirection))
{
fclose(logRedirection);
logRedirection = NULL;
logRedirection = nullptr;
redirectError = true;
}
}
@ -306,7 +310,7 @@ void LogView::addMsgToLogSlotRaw(QByteArray msg, bool encodeHTML)
if(!fwrite(data, buffersize, 1, logRedirection))
{
fclose(logRedirection);
logRedirection = NULL;
logRedirection = nullptr;
redirectError = true;
}
if(loggingEnabled)
@ -375,30 +379,56 @@ void LogView::clearLogSlot()
this->clear();
}
void LogView::redirectLogSlot()
void LogView::stopRedirectLogSlot()
{
if(logRedirection != NULL)
if(logRedirection != nullptr)
{
fclose(logRedirection);
logRedirection = NULL;
logRedirection = nullptr;
GuiAddLogMessage(tr("Log redirection is stopped.\n").toUtf8().constData());
}
else
{
GuiAddLogMessage(tr("Log is not redirected.\n").toUtf8().constData());
}
}
void LogView::redirectLogToFileSlot(QString filename)
{
if(logRedirection != nullptr)
{
fclose(logRedirection);
logRedirection = nullptr;
GuiAddLogMessage(tr("Log redirection is stopped.\n").toUtf8().constData());
}
logRedirection = _wfopen(filename.toStdWString().c_str(), L"ab");
if(logRedirection == nullptr)
GuiAddLogMessage(tr("_wfopen() failed. Log will not be redirected to %1.\n").arg(QString::fromWCharArray(BridgeUserDirectory())).toUtf8().constData());
else
{
if(utf16Redirect && ftell(logRedirection) == 0)
{
unsigned short BOM = 0xfeff;
fwrite(&BOM, 2, 1, logRedirection);
}
GuiAddLogMessage(tr("Log will be redirected to %1.\n").arg(filename).toUtf8().constData());
}
}
void LogView::redirectLogSlot()
{
if(logRedirection != nullptr)
{
fclose(logRedirection);
logRedirection = nullptr;
GuiAddLogMessage(tr("Log redirection is stopped.\n").toUtf8().constData());
}
else
{
BrowseDialog browse(this, tr("Redirect log to file"), tr("Enter the file to which you want to redirect log messages."), tr("Log files (*.txt);;All files (*.*)"), QString::fromWCharArray(BridgeUserDirectory()), true);
if(browse.exec() == QDialog::Accepted)
{
logRedirection = _wfopen(browse.path.toStdWString().c_str(), L"ab");
if(logRedirection == NULL)
GuiAddLogMessage(tr("_wfopen() failed. Log will not be redirected to %1.\n").arg(browse.path).toUtf8().constData());
else
{
if(utf16Redirect && ftell(logRedirection) == 0)
{
unsigned short BOM = 0xfeff;
fwrite(&BOM, 2, 1, logRedirection);
}
GuiAddLogMessage(tr("Log will be redirected to %1.\n").arg(browse.path).toUtf8().constData());
}
redirectLogToFileSlot(browse.path);
}
}
}
@ -427,13 +457,8 @@ void LogView::autoScrollSlot()
autoScroll = !autoScroll;
}
/**
* @brief LogView::saveSlot Called by "save" action
*/
void LogView::saveSlot()
void LogView::saveToFileSlot(QString fileName)
{
QString fileName;
fileName = QString("log-%1.txt").arg(QDateTime::currentDateTime().toString().replace(QChar(':'), QChar('-')));
QFile savedLog(fileName);
savedLog.open(QIODevice::Append | QIODevice::Text);
if(savedLog.error() != QFile::NoError)
@ -448,6 +473,16 @@ void LogView::saveSlot()
}
}
/**
* @brief LogView::saveSlot Called by "save" action
*/
void LogView::saveSlot()
{
QString fileName;
fileName = QString("log-%1.txt").arg(isoDateTime());
saveToFileSlot(fileName);
}
void LogView::toggleLoggingSlot()
{
setLoggingEnabled(!getLoggingEnabled());

View File

@ -21,7 +21,9 @@ public slots:
void refreshShortcutsSlot();
void updateStyle();
void addMsgToLogSlot(QByteArray msg); /* Non-HTML Log Function*/
void addMsgToLogSlotHtml(QByteArray msg); /* HTML accepting Log Function */
void addMsgToLogHtmlSlot(QByteArray msg); /* HTML accepting Log Function */
void stopRedirectLogSlot();
void redirectLogToFileSlot(QString filename);
void redirectLogSlot();
void setLoggingEnabled(bool enabled);
void autoScrollSlot();
@ -35,6 +37,7 @@ public slots:
void onAnchorClicked(const QUrl & link);
void clearLogSlot();
void saveToFileSlot(QString filename);
void saveSlot();
void toggleLoggingSlot();
void flushTimerSlot();

View File

@ -374,15 +374,7 @@ QString getDbPath(const QString & filename, bool addDateTimeSuffix)
{
extensionIdx = path.length();
}
auto now = QDateTime::currentDateTime();
auto suffix = QString().sprintf("-%04d%02d%02d-%02d%02d%02d",
now.date().year(),
now.date().month(),
now.date().day(),
now.time().hour(),
now.time().minute(),
now.time().second()
);
auto suffix = "-" + isoDateTime();
path.insert(extensionIdx, suffix);
}
}

View File

@ -219,6 +219,19 @@ QString GetDataTypeString(const void* buffer, duint size, ENCODETYPE type)
}
}
QString isoDateTime()
{
auto now = QDateTime::currentDateTime();
return QString().sprintf("%04d%02d%02d-%02d%02d%02d",
now.date().year(),
now.date().month(),
now.date().day(),
now.time().hour(),
now.time().minute(),
now.time().second()
);
}
QString ToDateString(const QDate & date)
{
static const char* months[] =

View File

@ -104,6 +104,9 @@ inline QString ToDoubleString(const void* buffer, int precision = std::numeric_l
QString ToLongDoubleString(const void* buffer);
// yyyyMMdd-HHmmss (useful for file suffix)
QString isoDateTime();
QString ToDateString(const QDate & date);
QString fillValue(const char* value, int valsize = 2, bool bFpuRegistersLittleEndian = false);