You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ktechlab/src/languages/processchain.cpp

327 lines
9.4 KiB

/***************************************************************************
* 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 <tdelocale.h>
#include <tdetempfile.h>
#include <tqfile.h>
#include <tqtimer.h>
//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<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, 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"