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/language.cpp

559 lines
12 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 "ktechlab.h"
#include "language.h"
#include "logview.h"
#include "outputmethoddlg.h"
#include "processchain.h"
#include "projectmanager.h"
#include "languagemanager.h"
#include "src/core/ktlconfig.h"
#include <kdebug.h>
#include <kio/netaccess.h>
#include <kmessagebox.h>
#include <kprocess.h>
#include <tqregexp.h>
#include <tqtimer.h>
//BEGIN class Language
Language::Language( ProcessChain *processChain, KTechlab *parent, const TQString &name )
: TQObject(parent,name)
{
p_ktechlab = parent;
p_processChain = processChain;
}
Language::~Language()
{
}
void Language::outputMessage( const TQString &message )
{
LanguageManager::self()->slotMessage( message, extractMessageInfo(message) );
}
void Language::outputWarning( const TQString &message )
{
LanguageManager::self()->slotWarning( message, extractMessageInfo(message) );
}
void Language::outputError( const TQString &message )
{
LanguageManager::self()->slotError( message, extractMessageInfo(message) );
m_errorCount++;
}
void Language::finish( bool successful )
{
if (successful)
{
outputMessage(m_successfulMessage + "\n");
p_ktechlab->slotChangeStatusbar(m_successfulMessage);
ProcessOptions::ProcessPath::Path newPath = outputPath( m_processOptions.processPath() );
if ( newPath == ProcessOptions::ProcessPath::None )
emit processSucceeded(this);
else if (p_processChain)
{
m_processOptions.setInputFiles( m_processOptions.intermediaryOutput() );
m_processOptions.setIntermediaryOutput( m_processOptions.targetFile() );
m_processOptions.setProcessPath(newPath);
// p_processChain->compile(m_processOptions);
p_processChain->setProcessOptions(m_processOptions);
p_processChain->compile();
}
}
else
{
outputError(m_failedMessage + "\n");
p_ktechlab->slotChangeStatusbar(m_failedMessage);
emit processFailed(this);
return;
}
}
void Language::reset()
{
m_errorCount = 0;
}
MessageInfo Language::extractMessageInfo( const TQString &text )
{
if ( !text.startsWith("/") )
return MessageInfo();
const int index = text.find( ":", 0, false );
if ( index == -1 )
return MessageInfo();
const TQString fileName = text.left(index);
// Extra line number
const TQString message = text.right(text.length()-index);
const int linePos = message.find( TQRegExp(":[\\d]+") );
int line = -1;
if ( linePos != -1 )
{
const int linePosEnd = message.find( ':', linePos+1 );
if ( linePosEnd != -1 )
{
const TQString number = message.mid( linePos+1, linePosEnd-linePos-1 ).stripWhiteSpace();
bool ok;
line = number.toInt(&ok)-1;
if (!ok) line = -1;
}
}
return MessageInfo( fileName, line );
}
//END class Language
//BEGIN class ProcessOptionsSpecial
ProcessOptionsSpecial::ProcessOptionsSpecial()
{
m_bOutputMapFile = true;
b_forceList = true;
b_addToProject = ProjectManager::self()->currentProject();
p_flowCodeDocument = 0l;
switch ( KTLConfig::hexFormat() )
{
case KTLConfig::EnumHexFormat::inhx8m:
m_hexFormat = "inhx8m";
break;
case KTLConfig::EnumHexFormat::inhx8s:
m_hexFormat = "inhx8s";
break;
case KTLConfig::EnumHexFormat::inhx16:
m_hexFormat = "inhx16";
break;
case KTLConfig::EnumHexFormat::inhx32:
default:
m_hexFormat = "inhx32";
break;
}
}
//END class ProcessOptionsSpecial
//BEGIN class ProcessOptions
ProcessOptions::ProcessOptions()
{
m_pHelper = new ProcessOptionsHelper;
b_targetFileSet = false;
m_pTextOutputTarget = 0l;
}
ProcessOptions::ProcessOptions( OutputMethodInfo info )
{
m_pHelper = new ProcessOptionsHelper;
b_addToProject = info.addToProject();
m_picID = info.picID();
b_targetFileSet = false;
TQString target;
if ( !KIO::NetAccess::download( info.outputFile(), target, 0l ) )
{
// If the file could not be downloaded, for example does not
// exist on disk, NetAccess will tell us what error to use
KMessageBox::error( 0l, KIO::NetAccess::lastErrorString() );
return;
}
setTargetFile(target);
switch ( info.method() )
{
case OutputMethodInfo::Method::Direct:
m_method = Method::LoadAsNew;
break;
case OutputMethodInfo::Method::SaveAndForget:
m_method = Method::Forget;
break;
case OutputMethodInfo::Method::SaveAndLoad:
m_method = Method::Load;
break;
}
}
void ProcessOptions::setTextOutputTarget( TextDocument * target, TQObject * receiver, const char * slot )
{
m_pTextOutputTarget = target;
TQObject::connect( m_pHelper, TQT_SIGNAL(textOutputtedTo( TextDocument* )), receiver, slot );
}
void ProcessOptions::setTextOutputtedTo( TextDocument * outputtedTo )
{
m_pTextOutputTarget = outputtedTo;
emit m_pHelper->textOutputtedTo( m_pTextOutputTarget );
}
void ProcessOptions::setTargetFile( const TQString &file )
{
if (b_targetFileSet)
{
kdWarning() << "Trying to reset target file!"<<endl;
return;
}
m_targetFile = file;
m_intermediaryFile = file;
b_targetFileSet = true;
}
ProcessOptions::ProcessPath::MediaType ProcessOptions::guessMediaType( const TQString & url )
{
TQString extension = url.right( url.length() - url.findRev('.') - 1 );
extension = extension.lower();
if ( extension == "asm" )
{
// We'll have to look at the file contents to determine its type...
AsmParser p( url );
p.parse();
switch ( p.type() )
{
case AsmParser::Relocatable:
return ProcessPath::AssemblyRelocatable;
case AsmParser::Absolute:
return ProcessPath::AssemblyAbsolute;
}
}
if ( extension == "c" )
return ProcessPath::C;
if ( extension == "flowcode" )
return ProcessPath::FlowCode;
if ( extension == "a" || extension == "lib" )
return ProcessPath::Library;
if ( extension == "microbe" || extension == "basic" )
return ProcessPath::Microbe;
if ( extension == "o" )
return ProcessPath::Object;
if ( extension == "hex" )
return ProcessPath::Program;
return ProcessPath::Unknown;
}
ProcessOptions::ProcessPath::Path ProcessOptions::ProcessPath::path( MediaType from, MediaType to )
{
switch (from)
{
case AssemblyAbsolute:
switch (to)
{
case AssemblyAbsolute:
return None;
case Pic:
return AssemblyAbsolute_PIC;
case Program:
return AssemblyAbsolute_Program;
case AssemblyRelocatable:
case C:
case Disassembly:
case FlowCode:
case Library:
case Microbe:
case Object:
case Unknown:
return Invalid;
}
case AssemblyRelocatable:
switch (to)
{
case Library:
return AssemblyRelocatable_Library;
case Object:
return AssemblyRelocatable_Object;
case Pic:
return AssemblyRelocatable_PIC;
case Program:
return AssemblyRelocatable_Program;
case AssemblyAbsolute:
case AssemblyRelocatable:
case C:
case Disassembly:
case FlowCode:
case Microbe:
case Unknown:
return Invalid;
}
case C:
switch (to)
{
case AssemblyRelocatable:
return C_AssemblyRelocatable;
case Library:
return C_Library;
case Object:
return C_Object;
case Pic:
return C_PIC;
case Program:
return C_Program;
case AssemblyAbsolute:
case C:
case Disassembly:
case FlowCode:
case Microbe:
case Unknown:
return Invalid;
}
case Disassembly:
return Invalid;
case FlowCode:
switch (to)
{
case AssemblyAbsolute:
return FlowCode_AssemblyAbsolute;
case Microbe:
return FlowCode_Microbe;
case Pic:
return FlowCode_PIC;
case Program:
return FlowCode_Program;
case AssemblyRelocatable:
case C:
case Disassembly:
case FlowCode:
case Library:
case Object:
case Unknown:
return Invalid;
}
case Library:
return Invalid;
case Microbe:
switch (to)
{
case AssemblyAbsolute:
return Microbe_AssemblyAbsolute;
case Pic:
return Microbe_PIC;
case Program:
return Microbe_Program;
case AssemblyRelocatable:
case C:
case Disassembly:
case FlowCode:
case Library:
case Microbe:
case Object:
case Unknown:
return Invalid;
}
case Object:
switch (to)
{
case Disassembly:
return Object_Disassembly;
case Library:
return Object_Library;
case Pic:
return Object_PIC;
case Program:
return Object_Program;
case AssemblyAbsolute:
case AssemblyRelocatable:
case C:
case FlowCode:
case Microbe:
case Object:
case Unknown:
return Invalid;
}
case Pic:
return Invalid;
case Program:
switch (to)
{
case Disassembly:
return Program_Disassembly;
case Pic:
return Program_PIC;
case AssemblyAbsolute:
case AssemblyRelocatable:
case C:
case FlowCode:
case Library:
case Microbe:
case Object:
case Program:
case Unknown:
return Invalid;
}
case Unknown:
return Invalid;
}
return Invalid;
}
ProcessOptions::ProcessPath::MediaType ProcessOptions::ProcessPath::from( Path path )
{
switch (path)
{
case ProcessPath::AssemblyAbsolute_PIC:
case ProcessPath::AssemblyAbsolute_Program:
return AssemblyAbsolute;
case ProcessPath::AssemblyRelocatable_Library:
case ProcessPath::AssemblyRelocatable_Object:
case ProcessPath::AssemblyRelocatable_PIC:
case ProcessPath::AssemblyRelocatable_Program:
return AssemblyRelocatable;
case ProcessPath::C_AssemblyRelocatable:
case ProcessPath::C_Library:
case ProcessPath::C_Object:
case ProcessPath::C_PIC:
case ProcessPath::C_Program:
return C;
case ProcessPath::FlowCode_AssemblyAbsolute:
case ProcessPath::FlowCode_Microbe:
case ProcessPath::FlowCode_PIC:
case ProcessPath::FlowCode_Program:
return FlowCode;
case ProcessPath::Microbe_AssemblyAbsolute:
case ProcessPath::Microbe_PIC:
case ProcessPath::Microbe_Program:
return Microbe;
case ProcessPath::Object_Disassembly:
case ProcessPath::Object_Library:
case ProcessPath::Object_PIC:
case ProcessPath::Object_Program:
return Object;
case ProcessPath::PIC_AssemblyAbsolute:
return Pic;
case ProcessPath::Program_Disassembly:
case ProcessPath::Program_PIC:
return Program;
case ProcessPath::Invalid:
case ProcessPath::None:
return Unknown;
}
return Unknown;
}
ProcessOptions::ProcessPath::MediaType ProcessOptions::ProcessPath::to( Path path )
{
switch (path)
{
case ProcessPath::FlowCode_AssemblyAbsolute:
case ProcessPath::Microbe_AssemblyAbsolute:
case ProcessPath::PIC_AssemblyAbsolute:
return AssemblyAbsolute;
case ProcessPath::C_AssemblyRelocatable:
return AssemblyRelocatable;
case ProcessPath::Object_Disassembly:
case ProcessPath::Program_Disassembly:
return Disassembly;
case ProcessPath::AssemblyRelocatable_Library:
case ProcessPath::C_Library:
case ProcessPath::Object_Library:
return Library;
case ProcessPath::FlowCode_Microbe:
return Microbe;
case ProcessPath::AssemblyRelocatable_Object:
case ProcessPath::C_Object:
return Object;
case ProcessPath::AssemblyAbsolute_PIC:
case ProcessPath::AssemblyRelocatable_PIC:
case ProcessPath::C_PIC:
case ProcessPath::FlowCode_PIC:
case ProcessPath::Microbe_PIC:
case ProcessPath::Object_PIC:
case ProcessPath::Program_PIC:
return Pic;
case ProcessPath::AssemblyAbsolute_Program:
case ProcessPath::AssemblyRelocatable_Program:
case ProcessPath::C_Program:
case ProcessPath::FlowCode_Program:
case ProcessPath::Microbe_Program:
case ProcessPath::Object_Program:
return Program;
case ProcessPath::Invalid:
case ProcessPath::None:
return Unknown;
}
return Unknown;
}
//END class ProcessOptions
#include "language.moc"