Discern between internally and externally compiles ELF files
Externally compiles elf files does not have any source code attached
to them (within ripes). Hence, the editor must be disabled.
This is not the case for internally compiled ELF files, wherein we
want to have the editor visible.
MODIFY
src/ccmanager.cpp
src/ccmanager.cpp
@@ -38,8 +38,8 @@ CCManager::CCManager() {
}
}
-bool CCManager::hasValidCC() const {
- return !m_currentCC.isEmpty();
+bool CCManager::hasValidCC() {
+ return !get().m_currentCC.isEmpty();
}
QString CCManager::tryAutodetectCC() {
@@ -71,7 +71,10 @@ bool CCManager::trySetCC(const QString& CC) {
CCManager::CCRes CCManager::compileRaw(const QString& rawsource, QString outname) {
// Write program to temporary file with a .c extension
- QTemporaryFile tmpSrcFile(QDir::tempPath() + QDir::separator() + QCoreApplication::applicationName() + ".XXXXXX.c");
+ const auto tempFileTemplate =
+ QString(QDir::tempPath() + QDir::separator() + QCoreApplication::applicationName() + ".XXXXXX.c");
+ QTemporaryFile tmpSrcFile = QTemporaryFile(tempFileTemplate);
+ tmpSrcFile.setAutoRemove(false);
if (tmpSrcFile.open()) {
QTextStream stream(&tmpSrcFile);
stream << rawsource;
@@ -80,14 +83,15 @@ CCManager::CCRes CCManager::compileRaw(const QString& rawsource, QString outname
return compile(tmpSrcFile.fileName(), outname);
}
-CCManager::CCRes CCManager::compile(const QTextDocument& source, QString outname) {
- return compileRaw(source.toRawText(), outname);
+CCManager::CCRes CCManager::compile(const QTextDocument* source, QString outname) {
+ return compileRaw(source->toPlainText(), outname);
}
CCManager::CCRes CCManager::compile(const QString& filename, QString outname) {
CCRes res;
if (outname.isEmpty()) {
- outname = QDir::tempPath() + QDir::separator() + QCoreApplication::applicationName() + ".XXXXXX.out";
+ outname = QDir::tempPath() + QDir::separator() + QCoreApplication::applicationName() + ".temp.out";
+ QFile::remove(outname); // Remove any previously compiled file
}
res.inFile = filename;
@@ -106,6 +110,10 @@ CCManager::CCRes CCManager::compile(const QString& filename, QString outname) {
return res;
}
+QString CCManager::getError() {
+ return get().m_process.readAllStandardError();
+}
+
QString CCManager::createCompileCommand(const QString& filename, const QString& outname) const {
const auto& currentISA = ProcessorHandler::get()->currentISA();

MODIFY
src/ccmanager.h
src/ccmanager.h
@@ -32,8 +32,10 @@ public:
return manager;
}
- bool hasValidCC() const;
- const QString& currentCC() const { return m_currentCC; }
+ static bool hasValidCC();
+ static const QString& currentCC() { return get().m_currentCC; }
+
+ static QString getError();
/**
* @brief compile
@@ -42,7 +44,7 @@ public:
* output file will be placed in a temporary directory.
*/
CCRes compile(const QString& filename, QString outname = QString());
- CCRes compile(const QTextDocument& source, QString outname = QString());
+ CCRes compile(const QTextDocument* source, QString outname = QString());
CCRes compileRaw(const QString& rawsource, QString outname = QString());
signals:

MODIFY
src/edittab.cpp
src/edittab.cpp
@@ -59,9 +59,14 @@ void EditTab::loadFile(const LoadFileParams& fileParams) {
case SourceType::FlatBinary:
success &= loadFlatBinaryFile(loadedProgram, file, fileParams.binaryEntryPoint, fileParams.binaryLoadAt);
break;
- case SourceType::Executable:
+ case SourceType::InternalELF:
success &= loadElfFile(loadedProgram, file);
break;
+ case SourceType::ExternalELF:
+ success &= loadElfFile(loadedProgram, file);
+ // Since there is no related source code for an externally compiled ELF, the editor is disabled
+ disableEditor();
+ break;
}
if (success) {
@@ -125,6 +130,7 @@ void EditTab::sourceCodeChanged() {
assemble();
break;
case SourceType::C:
+ compile();
break;
default:
// Do nothing, some external program is loaded
@@ -146,6 +152,26 @@ void EditTab::assemble() {
}
}
+void EditTab::compile() {
+ // We don't care about asking our editor for syntax accepted, since there is no C-syntax checking in Ripes.
+ auto res = CCManager::get().compile(m_ui->codeEditor->document());
+ if (res.success) {
+ // Compilation successful; load file through standard file loading functions
+ LoadFileParams params;
+ params.filepath = res.outFile;
+ params.type = SourceType::InternalELF;
+ loadFile(params);
+ // Clean up temporary source and output files
+ } else {
+ QMessageBox compileErrorMsg(this);
+ compileErrorMsg.setWindowTitle("Compile error");
+ compileErrorMsg.setText("Compilation failed. View detailed text for compiler output.");
+ compileErrorMsg.setDetailedText(CCManager::getError());
+ compileErrorMsg.exec();
+ }
+ res.clean();
+}
+
EditTab::~EditTab() {
delete m_ui;
}
@@ -253,7 +279,6 @@ bool EditTab::loadElfFile(Program& program, QFile& file) {
m_ui->curInputSrcLabel->setText("Executable (ELF)");
m_ui->inputSrcPath->setText(file.fileName());
- disableEditor();
return true;
}

MODIFY
src/edittab.h
src/edittab.h
@@ -64,6 +64,8 @@ private slots:
private:
void assemble();
+ void compile();
+
void updateProgramViewer();
bool loadFlatBinaryFile(Program& program, QFile& file, unsigned long entryPoint, unsigned long loadAt);
bool loadAssemblyFile(Program& program, QFile& file);

MODIFY
src/loaddialog.cpp
src/loaddialog.cpp
@@ -71,7 +71,7 @@ void LoadDialog::inputTypeChanged() {
break;
}
case LoadDialog::TypeButtonID::ELF: {
- m_fileType = SourceType::Executable;
+ m_fileType = SourceType::ExternalELF;
updateELFPageState();
break;
}
@@ -93,7 +93,7 @@ void LoadDialog::openFileButtonTriggered() {
filter = "All files (*)";
break;
}
- case SourceType::Executable: {
+ case SourceType::ExternalELF: {
title = "Open executable (ELF) file";
filter = "All files (*)";
break;
@@ -202,7 +202,7 @@ bool LoadDialog::fileTypeValidate(const QFile& file) {
return validateAssemblyFile(file);
case SourceType::FlatBinary:
return validateBinaryFile(file);
- case SourceType::Executable:
+ case SourceType::ExternalELF:
return validateELFFile(file);
}
Q_UNREACHABLE();

MODIFY
src/mainwindow.cpp
src/mainwindow.cpp
@@ -189,7 +189,7 @@ void MainWindow::setupExamplesMenu(QMenu* parent) {
LoadFileParams parms;
parms.filepath = tmpELFFile->fileName();
- parms.type = SourceType::Executable;
+ parms.type = SourceType::ExternalELF;
m_editTab->loadFile(parms);
m_hasSavedFile = false;
tmpELFFile->remove();

MODIFY
src/program.h
src/program.h
namespace Ripes {
-enum class SourceType { Assembly, C, FlatBinary, Executable };
+enum class SourceType {
+ /** Assembly text */
+ Assembly,
+ /** C text */
+ C,
+ /** Flat binary external file */
+ FlatBinary,
+ /** Executable files not compiled from within ripes */
+ ExternalELF,
+ /** Executable files compiled within ripes */
+ InternalELF
+};
#define TEXT_SECTION_NAME ".text"

Discern between internally and externally compiles ELF files

Externally compiles elf files does not have any source code attached
to them (within ripes). Hence, the editor must be disabled.
This is not the case for internally compiled ELF files, wherein we
want to have the editor visible.