diff options
Diffstat (limited to 'src/languages/processchain.cpp')
-rw-r--r-- | src/languages/processchain.cpp | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/src/languages/processchain.cpp b/src/languages/processchain.cpp new file mode 100644 index 0000000..e17c6ae --- /dev/null +++ b/src/languages/processchain.cpp @@ -0,0 +1,326 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * david@bluehaze.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include "asmparser.h" +#include "docmanager.h" +#include "gplib.h" +#include "src/core/ktlconfig.h" +#include "language.h" +#include "languagemanager.h" +#include "logview.h" +#include "outputmethoddlg.h" +#include "processchain.h" +#include "projectmanager.h" +#include "textdocument.h" + +#include "flowcode.h" +#include "gpasm.h" +#include "gpdasm.h" +#include "gplink.h" +#include "microbe.h" +#include "picprogrammer.h" +#include "sdcc.h" + +#include <kdebug.h> +#include <klocale.h> +#include <ktempfile.h> +#include <qfile.h> +#include <qtimer.h> + + +//BEGIN class ProcessChain +ProcessChain::ProcessChain( ProcessOptions options, KTechlab * ktechlab, const char *name ) + : QObject( (QObject*)ktechlab, name) +{ + m_pKTechlab = ktechlab; + m_pFlowCode = 0l; + m_pGpasm = 0l; + m_pGpdasm = 0l; + m_pGplib = 0l; + m_pGplink = 0l; + m_pMicrobe = 0l; + m_pPicProgrammer = 0l; + m_pSDCC = 0l; + m_processOptions = options; + + QString target; + if ( ProcessOptions::ProcessPath::to( options.processPath() ) == ProcessOptions::ProcessPath::Pic ) + target = options.m_picID; + else + target = options.targetFile(); + + LanguageManager::self()->logView()->addOutput( i18n("Building: %1").arg( target ), LogView::ot_important ); + QTimer::singleShot( 0, this, SLOT(compile()) ); +} + + +ProcessChain::~ProcessChain() +{ + delete m_pFlowCode; + m_pFlowCode = 0l; + delete m_pGpasm; + m_pGpasm = 0l; + delete m_pGpdasm; + m_pGpdasm = 0l; + delete m_pGplib; + m_pGplib = 0l; + delete m_pGplink; + m_pGplink = 0l; + delete m_pMicrobe; + m_pMicrobe = 0l; + delete m_pPicProgrammer; + m_pPicProgrammer = 0l; + delete m_pSDCC; + m_pSDCC = 0l; +} + + +// void ProcessChain::compile( ProcessOptions * options ) +void ProcessChain::compile() +{ + // If the micro id in the options is empty, then attempt to get it from any + // open project (it might not be necessarily...but won't hurt if it isn't). + if ( m_processOptions.m_picID.isEmpty() ) + { + if ( ProjectInfo * projectInfo = ProjectManager::self()->currentProject() ) + { + ProjectItem * projectItem = projectInfo->findItem( m_processOptions.inputFiles().first() ); + if (projectItem) + m_processOptions.m_picID = projectItem->microID(); + } + } + + switch ( m_processOptions.processPath() ) + { +#define DIRECT_PROCESS( path, processor ) case ProcessOptions::ProcessPath::path: { processor()->processInput(m_processOptions); break; } +#define INDIRECT_PROCESS( path, processor, extension ) case ProcessOptions::ProcessPath::path: { KTempFile f( QString::null, extension ); f.close(); m_processOptions.setIntermediaryOutput( f.name() ); processor()->processInput(m_processOptions); break; } + + INDIRECT_PROCESS( AssemblyAbsolute_PIC, gpasm, ".hex" ) + DIRECT_PROCESS( AssemblyAbsolute_Program, gpasm ) + INDIRECT_PROCESS( AssemblyRelocatable_Library, gpasm, ".o" ) + DIRECT_PROCESS( AssemblyRelocatable_Object, gpasm ) + INDIRECT_PROCESS( AssemblyRelocatable_PIC, gpasm, ".o" ) + INDIRECT_PROCESS( AssemblyRelocatable_Program, gpasm, ".o" ) + DIRECT_PROCESS( C_AssemblyRelocatable, sdcc ) + INDIRECT_PROCESS( C_Library, sdcc, ".asm" ) + INDIRECT_PROCESS( C_Object, sdcc, ".asm" ) + INDIRECT_PROCESS( C_PIC, sdcc, ".asm" ) + INDIRECT_PROCESS( C_Program, sdcc, ".asm" ) + INDIRECT_PROCESS( FlowCode_AssemblyAbsolute, flowCode, ".microbe" ) + DIRECT_PROCESS( FlowCode_Microbe, flowCode ) + INDIRECT_PROCESS( FlowCode_PIC, flowCode, ".microbe" ) + INDIRECT_PROCESS( FlowCode_Program, flowCode, ".microbe" ) + DIRECT_PROCESS( Microbe_AssemblyAbsolute, microbe ) + INDIRECT_PROCESS( Microbe_PIC, microbe, ".asm" ) + INDIRECT_PROCESS( Microbe_Program, microbe, ".asm" ) + DIRECT_PROCESS( Object_Disassembly, gpdasm ) + DIRECT_PROCESS( Object_Library, gplib ) + INDIRECT_PROCESS( Object_PIC, gplink, ".lib" ) + DIRECT_PROCESS( Object_Program, gplink ) + DIRECT_PROCESS( PIC_AssemblyAbsolute, picProgrammer ) + DIRECT_PROCESS( Program_Disassembly, gpdasm ) + DIRECT_PROCESS( Program_PIC, picProgrammer ) +#undef DIRECT_PROCESS +#undef INDIRECT_PROCESS + + case ProcessOptions::ProcessPath::Invalid: + kdWarning() << k_funcinfo << "Process path is invalid" << endl; + + case ProcessOptions::ProcessPath::None: + kdWarning() << k_funcinfo << "Nothing to do" << endl; + break; + } +} + + +void ProcessChain::slotFinishedCompile(Language *language) +{ + ProcessOptions options = language->processOptions(); + + if ( options.b_addToProject && ProjectManager::self()->currentProject() ) + ProjectManager::self()->currentProject()->addFile( KURL(options.targetFile()) ); + + ProcessOptions::ProcessPath::MediaType typeTo = ProcessOptions::ProcessPath::to( m_processOptions.processPath() ); + + TextDocument * editor = 0l; + if ( KTLConfig::reuseSameViewForOutput() ) + { + editor = options.textOutputTarget(); + if ( editor && (!editor->url().isEmpty() || editor->isModified()) ) + editor = 0l; + } + + switch (typeTo) + { + case ProcessOptions::ProcessPath::AssemblyAbsolute: + case ProcessOptions::ProcessPath::AssemblyRelocatable: + case ProcessOptions::ProcessPath::C: + case ProcessOptions::ProcessPath::Disassembly: + case ProcessOptions::ProcessPath::Library: + case ProcessOptions::ProcessPath::Microbe: + case ProcessOptions::ProcessPath::Object: + case ProcessOptions::ProcessPath::Program: + { + switch ( options.method() ) + { + case ProcessOptions::Method::LoadAsNew: + { + if ( !editor ) + editor = DocManager::self()->createTextDocument(); + + if ( !editor ) + break; + + QString text; + QFile f( options.targetFile() ); + if ( !f.open( IO_ReadOnly ) ) + { + editor->deleteLater(); + editor = 0l; + break; + } + + QTextStream stream(&f); + + while ( !stream.atEnd() ) + text += stream.readLine()+'\n'; + + f.close(); + + editor->setText( text, true ); + break; + } + + case ProcessOptions::Method::Load: + { + editor = dynamic_cast<TextDocument*>( DocManager::self()->openURL(options.targetFile()) ); + break; + } + + case ProcessOptions::Method::Forget: + break; + } + } + + case ProcessOptions::ProcessPath::FlowCode: + case ProcessOptions::ProcessPath::Pic: + case ProcessOptions::ProcessPath::Unknown: + break; + } + + + if (editor) + { + switch (typeTo) + { + case ProcessOptions::ProcessPath::AssemblyAbsolute: + case ProcessOptions::ProcessPath::AssemblyRelocatable: + { + if ( KTLConfig::autoFormatMBOutput() ) + editor->formatAssembly(); + editor->slotInitLanguage( TextDocument::ct_asm ); + break; + } + + case ProcessOptions::ProcessPath::C: + editor->slotInitLanguage( TextDocument::ct_c ); + break; + + case ProcessOptions::ProcessPath::Disassembly: + break; + + case ProcessOptions::ProcessPath::Library: + case ProcessOptions::ProcessPath::Object: + case ProcessOptions::ProcessPath::Program: + editor->slotInitLanguage( TextDocument::ct_hex ); + break; + + case ProcessOptions::ProcessPath::Microbe: + editor->slotInitLanguage( TextDocument::ct_microbe ); + break; + + case ProcessOptions::ProcessPath::FlowCode: + case ProcessOptions::ProcessPath::Pic: + case ProcessOptions::ProcessPath::Unknown: + break; + } + + DocManager::self()->giveDocumentFocus( editor ); + } + + options.setTextOutputtedTo( editor ); + + emit successful(options); + emit successful(); +} + +#define LanguageFunction(a,b,c) \ +a * ProcessChain::b( ) \ +{ \ + if ( !c ) \ + { \ + c = new a( this, m_pKTechlab ); \ + connect( c, SIGNAL(processSucceeded(Language* )), this, SLOT(slotFinishedCompile(Language* )) ); \ + connect( c, SIGNAL(processFailed(Language* )), this, SIGNAL(failed()) ); \ + } \ + return c; \ +} + +LanguageFunction( FlowCode, flowCode, m_pFlowCode ) +LanguageFunction( Gpasm, gpasm, m_pGpasm ) +LanguageFunction( Gpdasm, gpdasm, m_pGpdasm ) +LanguageFunction( Gplib, gplib, m_pGplib ) +LanguageFunction( Gplink, gplink, m_pGplink ) +LanguageFunction( Microbe, microbe, m_pMicrobe ) +LanguageFunction( PicProgrammer, picProgrammer, m_pPicProgrammer ) +LanguageFunction( SDCC, sdcc, m_pSDCC ) +//END class ProcessChain + + + +//BEGIN class ProcessListChain +ProcessListChain::ProcessListChain( ProcessOptionsList pol, KTechlab * parent, const char * name ) + : QObject( (QObject*)parent, name ) +{ + m_processOptionsList = pol; + m_pKTechlab = parent; + + // Start us off... + slotProcessChainSuccessful(); +} + + +void ProcessListChain::slotProcessChainSuccessful() +{ + if ( m_processOptionsList.isEmpty() ) + { + emit successful(); + return; + } + + ProcessOptionsList::iterator it = m_processOptionsList.begin(); + ProcessOptions po = *it; + m_processOptionsList.remove(it); + + ProcessChain * pc = LanguageManager::self()->compile(po); + + connect( pc, SIGNAL(successful()), this, SLOT(slotProcessChainSuccessful()) ); + connect( pc, SIGNAL(failed()), this, SLOT(slotProcessChainFailed()) ); +} + + +void ProcessListChain::slotProcessChainFailed() +{ + emit failed(); +} +//END class ProcessListChain + + +#include "processchain.moc" |