processchain.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by David Saxton                                    *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "asmparser.h"
00012 #include "docmanager.h"
00013 #include "gplib.h"
00014 #include "src/core/ktlconfig.h"
00015 #include "language.h"
00016 #include "languagemanager.h"
00017 #include "logview.h"
00018 #include "outputmethoddlg.h"
00019 #include "processchain.h"
00020 #include "projectmanager.h"
00021 #include "textdocument.h"
00022 
00023 #include "flowcode.h"
00024 #include "gpasm.h"
00025 #include "gpdasm.h"
00026 #include "gplink.h"
00027 #include "microbe.h"
00028 #include "picprogrammer.h"
00029 #include "sdcc.h"
00030 
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <ktempfile.h>
00034 #include <qfile.h>
00035 #include <qtimer.h>
00036 
00037 
00038 //BEGIN class ProcessChain
00039 ProcessChain::ProcessChain( ProcessOptions options, KTechlab * ktechlab, const char *name )
00040         : QObject( (QObject*)ktechlab, name)
00041 {
00042         m_pKTechlab = ktechlab;
00043         m_pFlowCode = 0;
00044         m_pGpasm = 0;
00045         m_pGpdasm = 0;
00046         m_pGplib = 0;
00047         m_pGplink = 0;
00048         m_pMicrobe = 0;
00049         m_pPicProgrammer = 0;
00050         m_pSDCC = 0;
00051         m_processOptions = options;
00052 
00053         QString target;
00054         if ( ProcessOptions::ProcessPath::to( options.processPath() ) == ProcessOptions::ProcessPath::Pic )
00055                 target = options.m_picID;
00056         else
00057                 target = options.targetFile();
00058         
00059         LanguageManager::self()->logView()->addOutput( i18n("Building: %1").arg( target ), LogView::ot_important );
00060         QTimer::singleShot( 0, this, SLOT(compile()) );
00061 }
00062 
00063 ProcessChain::~ProcessChain()
00064 {
00065         delete m_pFlowCode;
00066         delete m_pGpasm;
00067         delete m_pGpdasm;
00068         delete m_pGplib;
00069         delete m_pGplink;
00070         delete m_pMicrobe;
00071         delete m_pPicProgrammer;
00072         delete m_pSDCC;
00073 }
00074 
00075 // void ProcessChain::compile( ProcessOptions * options )
00076 void ProcessChain::compile()
00077 {
00078         // If the micro id in the options is empty, then attempt to get it from any
00079         // open project (it might not be necessarily...but won't hurt if it isn't).
00080         if ( m_processOptions.m_picID.isEmpty() )
00081         {
00082                 if ( ProjectInfo * projectInfo = ProjectManager::self()->currentProject() )
00083                 {
00084                         ProjectItem * projectItem = projectInfo->findItem( m_processOptions.inputFiles().first() );
00085                         if (projectItem)
00086                                 m_processOptions.m_picID = projectItem->microID();
00087                 }
00088         }
00089         
00090         switch ( m_processOptions.processPath() )
00091         {
00092 #define DIRECT_PROCESS( path, processor ) case ProcessOptions::ProcessPath::path: { processor()->processInput(m_processOptions); break; }
00093 #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; }
00094 
00095                 INDIRECT_PROCESS(       AssemblyAbsolute_PIC,                   gpasm,          ".hex" )
00096                 DIRECT_PROCESS(         AssemblyAbsolute_Program,               gpasm )
00097                 INDIRECT_PROCESS(       AssemblyRelocatable_Library,    gpasm,          ".o" )
00098                 DIRECT_PROCESS(         AssemblyRelocatable_Object,             gpasm )
00099                 INDIRECT_PROCESS(       AssemblyRelocatable_PIC,                gpasm,          ".o" )
00100                 INDIRECT_PROCESS(       AssemblyRelocatable_Program,    gpasm,          ".o" )
00101                 DIRECT_PROCESS(         C_AssemblyRelocatable,                  sdcc )
00102                 INDIRECT_PROCESS(       C_Library,                                              sdcc,           ".asm" )
00103                 INDIRECT_PROCESS(       C_Object,                                               sdcc,           ".asm" )
00104                 INDIRECT_PROCESS(       C_PIC,                                                  sdcc,           ".asm" )
00105                 INDIRECT_PROCESS(       C_Program,                                              sdcc,           ".asm" )
00106                 INDIRECT_PROCESS(       FlowCode_AssemblyAbsolute,              flowCode,       ".microbe" )
00107                 DIRECT_PROCESS(         FlowCode_Microbe,                               flowCode )
00108                 INDIRECT_PROCESS(       FlowCode_PIC,                                   flowCode,       ".microbe" )
00109                 INDIRECT_PROCESS(       FlowCode_Program,                               flowCode,       ".microbe" )
00110                 DIRECT_PROCESS(         Microbe_AssemblyAbsolute,               microbe )
00111                 INDIRECT_PROCESS(       Microbe_PIC,                                    microbe,        ".asm" )
00112                 INDIRECT_PROCESS(       Microbe_Program,                                microbe,        ".asm" )
00113                 DIRECT_PROCESS(         Object_Disassembly,                             gpdasm )
00114                 DIRECT_PROCESS(         Object_Library,                                 gplib )
00115                 INDIRECT_PROCESS(       Object_PIC,                                             gplink,         ".lib" )
00116                 DIRECT_PROCESS(         Object_Program,                                 gplink )
00117                 DIRECT_PROCESS(         PIC_AssemblyAbsolute,                   picProgrammer )
00118                 DIRECT_PROCESS(         Program_Disassembly,                    gpdasm )
00119                 DIRECT_PROCESS(         Program_PIC,                                    picProgrammer )
00120 #undef DIRECT_PROCESS
00121 #undef INDIRECT_PROCESS
00122                         
00123                 case ProcessOptions::ProcessPath::Invalid:
00124                         kdWarning() << k_funcinfo << "Process path is invalid" << endl;
00125                         
00126                 case ProcessOptions::ProcessPath::None:
00127                         kdWarning() << k_funcinfo << "Nothing to do" << endl;
00128                         break;
00129         }
00130 }
00131 
00132 
00133 void ProcessChain::slotFinishedCompile(Language *language)
00134 {
00135         ProcessOptions options = language->processOptions();
00136         
00137         if ( options.b_addToProject && ProjectManager::self()->currentProject() )
00138                 ProjectManager::self()->currentProject()->addFile( KURL(options.targetFile()) );
00139         
00140         ProcessOptions::ProcessPath::MediaType typeTo = ProcessOptions::ProcessPath::to( m_processOptions.processPath() );
00141         
00142         TextDocument * editor = 0;
00143         if ( KTLConfig::reuseSameViewForOutput() )
00144         {
00145                 editor = options.textOutputTarget();
00146                 if ( editor && (!editor->url().isEmpty() || editor->isModified()) )
00147                         editor = 0;
00148         }
00149         
00150         switch (typeTo)
00151         {
00152                 case ProcessOptions::ProcessPath::AssemblyAbsolute:
00153                 case ProcessOptions::ProcessPath::AssemblyRelocatable:
00154                 case ProcessOptions::ProcessPath::C:
00155                 case ProcessOptions::ProcessPath::Disassembly:
00156                 case ProcessOptions::ProcessPath::Library:
00157                 case ProcessOptions::ProcessPath::Microbe:
00158                 case ProcessOptions::ProcessPath::Object:
00159                 case ProcessOptions::ProcessPath::Program:
00160                 {
00161                         switch ( options.method() )
00162                         {
00163                                 case ProcessOptions::Method::LoadAsNew:
00164                                 {
00165                                         if ( !editor )
00166                                                 editor = DocManager::self()->createTextDocument();
00167                                         
00168                                         if ( !editor )
00169                                                 break;
00170                                 
00171                                         QString text;
00172                                         QFile f( options.targetFile() );
00173                                         if ( !f.open( IO_ReadOnly ) )
00174                                         {
00175                                                 editor->deleteLater();
00176                                                 editor = 0;
00177                                                 break;
00178                                         }
00179                                 
00180                                         QTextStream stream(&f);
00181                                 
00182                                         while ( !stream.atEnd() )
00183                                                 text += stream.readLine()+'\n';
00184                                 
00185                                         f.close();
00186         
00187                                         editor->setText( text, true );
00188                                         break;
00189                                 }
00190                         
00191                                 case ProcessOptions::Method::Load:
00192                                 {
00193                                         editor = dynamic_cast<TextDocument*>( DocManager::self()->openURL(options.targetFile()) );
00194                                         break;
00195                                 }
00196                         
00197                                 case ProcessOptions::Method::Forget:
00198                                         break;
00199                         }
00200                 }
00201                         
00202                 case ProcessOptions::ProcessPath::FlowCode:
00203                 case ProcessOptions::ProcessPath::Pic:
00204                 case ProcessOptions::ProcessPath::Unknown:
00205                         break;
00206         }
00207         
00208         
00209         if (editor)
00210         {
00211                 switch (typeTo)
00212                 {
00213                         case ProcessOptions::ProcessPath::AssemblyAbsolute:
00214                         case ProcessOptions::ProcessPath::AssemblyRelocatable:
00215                         {
00216                                 if ( KTLConfig::autoFormatMBOutput() )
00217                                         editor->formatAssembly();
00218                                 editor->slotInitLanguage( TextDocument::ct_asm );
00219                                 break;
00220                         }
00221                 
00222                         case ProcessOptions::ProcessPath::C:
00223                                 editor->slotInitLanguage( TextDocument::ct_c );
00224                                 break;
00225                         
00226                         case ProcessOptions::ProcessPath::Disassembly:
00227                                 break;
00228                         
00229                         case ProcessOptions::ProcessPath::Library:
00230                         case ProcessOptions::ProcessPath::Object:
00231                         case ProcessOptions::ProcessPath::Program:
00232                                 editor->slotInitLanguage( TextDocument::ct_hex );
00233                                 break;
00234                         
00235                         case ProcessOptions::ProcessPath::Microbe:
00236                                 editor->slotInitLanguage( TextDocument::ct_microbe );
00237                                 break;
00238                         
00239                         case ProcessOptions::ProcessPath::FlowCode:
00240                         case ProcessOptions::ProcessPath::Pic:
00241                         case ProcessOptions::ProcessPath::Unknown:
00242                                 break;
00243                 }
00244                 
00245                 DocManager::self()->giveDocumentFocus( editor );
00246         }
00247         
00248         options.setTextOutputtedTo( editor );
00249 
00250         emit successful(options);
00251         emit successful();
00252 }
00253 
00254 #define LanguageFunction(a,b,c) \
00255 a * ProcessChain::b( ) \
00256 { \
00257         if ( !c ) \
00258         { \
00259                 c = new a( this, m_pKTechlab ); \
00260                 connect( c, SIGNAL(processSucceeded(Language* )), this, SLOT(slotFinishedCompile(Language* )) ); \
00261                 connect( c, SIGNAL(processFailed(Language* )), this, SIGNAL(failed()) ); \
00262         } \
00263         return c; \
00264 }
00265 
00266 LanguageFunction( FlowCode, flowCode, m_pFlowCode )
00267 LanguageFunction( Gpasm, gpasm, m_pGpasm )
00268 LanguageFunction( Gpdasm, gpdasm, m_pGpdasm )
00269 LanguageFunction( Gplib, gplib, m_pGplib )
00270 LanguageFunction( Gplink, gplink, m_pGplink )
00271 LanguageFunction( Microbe, microbe, m_pMicrobe )
00272 LanguageFunction( PicProgrammer, picProgrammer, m_pPicProgrammer )
00273 LanguageFunction( SDCC, sdcc, m_pSDCC )
00274 //END class ProcessChain
00275 
00276 
00277 
00278 //BEGIN class ProcessListChain
00279 ProcessListChain::ProcessListChain( ProcessOptionsList pol, KTechlab * parent, const char * name )
00280         : QObject( (QObject*)parent, name )
00281 {
00282         m_processOptionsList = pol;
00283         m_pKTechlab = parent;
00284         
00285         // Start us off...
00286         slotProcessChainSuccessful();
00287 }
00288 
00289 
00290 void ProcessListChain::slotProcessChainSuccessful()
00291 {
00292         if ( m_processOptionsList.isEmpty() )
00293         {
00294                 emit successful();
00295                 return;
00296         }
00297         
00298         ProcessOptionsList::iterator it = m_processOptionsList.begin();
00299         ProcessOptions po = *it;
00300         m_processOptionsList.remove(it);
00301         
00302         ProcessChain * pc = LanguageManager::self()->compile(po);
00303         
00304         connect( pc, SIGNAL(successful()), this, SLOT(slotProcessChainSuccessful()) );
00305         connect( pc, SIGNAL(failed()), this, SLOT(slotProcessChainFailed()) );
00306 }
00307 
00308 
00309 void ProcessListChain::slotProcessChainFailed()
00310 {
00311         emit failed();
00312 }
00313 //END class ProcessListChain
00314 
00315 
00316 #include "processchain.moc"

Generated on Tue May 8 17:05:32 2007 for KTechLab by  doxygen 1.5.1