00001
00002
00003
00004
00005
00006
00007
00008
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
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
00076 void ProcessChain::compile()
00077 {
00078
00079
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
00275
00276
00277
00278
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
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
00314
00315
00316 #include "processchain.moc"