mirror of
https://github.com/epasveer/seer.git
synced 2026-08-30 00:50:42 +08:00
120 lines
4.2 KiB
C++
120 lines
4.2 KiB
C++
// SPDX-FileCopyrightText: 2021 Ernie Pasveer <epasveer@att.net>
|
|
//
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
#include "SeerAsmWidget.h"
|
|
#include "SeerUtl.h"
|
|
#include <QtCore/QDebug>
|
|
#include <algorithm>
|
|
|
|
SeerAsmWidget::SeerAsmWidget(QWidget* parent) : QWidget(parent) {
|
|
|
|
// Construct the UI.
|
|
setupUi(this);
|
|
|
|
// Setup the widgets
|
|
QFont font;
|
|
font.setFamily("monospace [Consolas]");
|
|
font.setFixedPitch(true);
|
|
font.setStyleHint(QFont::TypeWriter);
|
|
|
|
plainTextEdit->setFont(font);
|
|
plainTextEdit->setFocusPolicy(Qt::StrongFocus);
|
|
plainTextEdit->setTextInteractionFlags(Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse);
|
|
plainTextEdit->setWordWrapMode(QTextOption::NoWrap);
|
|
|
|
// Set text formats.
|
|
_defaultFormat = plainTextEdit->currentCharFormat();
|
|
_grayFormat = _defaultFormat;
|
|
_grayFormat.setBackground(QBrush(Qt::lightGray));
|
|
|
|
// Connect things.
|
|
}
|
|
|
|
SeerAsmWidget::~SeerAsmWidget() {
|
|
}
|
|
|
|
QTextDocument* SeerAsmWidget::document () {
|
|
|
|
return plainTextEdit->document();
|
|
}
|
|
|
|
QString SeerAsmWidget::toPlainText () {
|
|
|
|
return plainTextEdit->toPlainText();
|
|
}
|
|
|
|
void SeerAsmWidget::setData (const QString& data) {
|
|
|
|
|
|
// ^done,asm_insns=[
|
|
// {address="0x000000000040093c",func-name="main()",offset="362",inst="mov $0x400aa9,%edi"},
|
|
// {address="0x0000000000400941",func-name="main()",offset="367",inst="call 0x400680 <puts@plt>"},
|
|
// {address="0x0000000000400946",func-name="main()",offset="372",inst="mov -0x30(%rbp),%rax"}
|
|
// ]
|
|
|
|
// Clear the document.
|
|
plainTextEdit->clear();
|
|
|
|
// Get a cursor
|
|
QTextCursor cursor(plainTextEdit->textCursor());
|
|
|
|
cursor.movePosition(QTextCursor::Start);
|
|
|
|
// Prepare the 'data' for parsing.
|
|
QString asm_insns_text = Seer::parseFirst(data, "asm_insns=", '[', ']', false);
|
|
|
|
QStringList asm_list = Seer::parse(asm_insns_text, "", '{', '}', false);
|
|
|
|
// Loop through the asm list to get maximum field widths.
|
|
int address_width = QString("Address").length();
|
|
int opcode_width = QString("Opcode").length();
|
|
int inst_width = QString("Assembly").length();
|
|
|
|
for ( const auto& asm_text : asm_list ) {
|
|
|
|
QString address_text = Seer::parseFirst(asm_text, "address=", '"', '"', false);
|
|
QString opcodes_text = Seer::parseFirst(asm_text, "opcodes=", '"', '"', false);
|
|
QString inst_text = Seer::parseFirst(asm_text, "inst=", '"', '"', false);
|
|
|
|
address_width = std::max((qsizetype)address_width, (qsizetype)address_text.length());
|
|
opcode_width = std::max((qsizetype)opcode_width, (qsizetype)opcodes_text.length());
|
|
inst_width = std::max((qsizetype)inst_width, (qsizetype)inst_text.length());
|
|
}
|
|
|
|
// Write header.
|
|
cursor.insertText (QString("Address").leftJustified(address_width, ' ', true), _grayFormat);
|
|
cursor.insertText (QString(" "), _defaultFormat);
|
|
cursor.insertText (QString("Opcodes").leftJustified(opcode_width, ' ', true), _defaultFormat);
|
|
cursor.insertText (QString(" | "), _defaultFormat);
|
|
cursor.insertText (QString("Assembly"), _defaultFormat);
|
|
cursor.insertText (QString("\n"), _defaultFormat);
|
|
|
|
// Loop through the asm list and print each line.
|
|
for ( const auto& asm_text : asm_list ) {
|
|
|
|
// Get the strings, with padding.
|
|
QString address_text = Seer::parseFirst(asm_text, "address=", '"', '"', false).leftJustified(address_width, ' ', true);
|
|
QString opcodes_text = Seer::parseFirst(asm_text, "opcodes=", '"', '"', false).leftJustified(opcode_width, ' ', true);
|
|
QString inst_text = Seer::parseFirst(asm_text, "inst=", '"', '"', false).leftJustified(inst_width, ' ', true);
|
|
|
|
// Write the text, with spacers.
|
|
cursor.insertText (address_text, _grayFormat);
|
|
cursor.insertText (QString(" "), _defaultFormat);
|
|
|
|
cursor.insertText (opcodes_text, _defaultFormat);
|
|
cursor.insertText (QString(" | "), _defaultFormat);
|
|
|
|
cursor.insertText (inst_text, _defaultFormat);
|
|
|
|
// Write eol to document.
|
|
cursor.insertText (QString("\n"), _defaultFormat);
|
|
}
|
|
|
|
// Move to the start of the document.
|
|
cursor.movePosition(QTextCursor::Start);
|
|
|
|
plainTextEdit->setTextCursor(cursor);
|
|
}
|
|
|