/*************************************************************************** * 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 #include #include #include #include //BEGIN class ProcessChain ProcessChain::ProcessChain( ProcessOptions options, KTechlab * ktechlab, const char *name ) : TQObject( (TQObject*)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; TQString 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 ); TQTimer::singleShot( 0, this, TQT_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( TQString(), 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; TQString text; TQFile f( options.targetFile() ); if ( !f.open( IO_ReadOnly ) ) { editor->deleteLater(); editor = 0l; break; } TQTextStream stream(&f); while ( !stream.atEnd() ) text += stream.readLine()+'\n'; f.close(); editor->setText( text, true ); break; } case ProcessOptions::Method::Load: { editor = dynamic_cast( 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, TQT_SIGNAL(processSucceeded(Language* )), this, TQT_SLOT(slotFinishedCompile(Language* )) ); \ connect( c, TQT_SIGNAL(processFailed(Language* )), this, TQT_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 ) : TQObject( (TQObject*)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, TQT_SIGNAL(successful()), this, TQT_SLOT(slotProcessChainSuccessful()) ); connect( pc, TQT_SIGNAL(failed()), this, TQT_SLOT(slotProcessChainFailed()) ); } void ProcessListChain::slotProcessChainFailed() { emit failed(); } //END class ProcessListChain #include "processchain.moc"