Logo Search packages:      
Sourcecode: ktechlab version File versions  Download package

processchain.cpp

/***************************************************************************
 *   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 )
00086 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;
      }
}


00143 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"

Generated by  Doxygen 1.6.0   Back to index