/*************************************************************************** * Copyright (C) 2003-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 "asmformatter.h" #include "core/ktlconfig.h" #include "picinfo12bit.h" #include "picinfo14bit.h" #include "picinfo16bit.h" static TQString extractComment( const TQString & line ) { int pos = line.find( ';' ); if ( pos == -1 ) return ""; return line.right( line.length() - pos ); } //BEGIN class AsmFormatter AsmFormatter::AsmFormatter() { } AsmFormatter::~AsmFormatter() { } TQString AsmFormatter::tidyAsm( TQStringList lines ) { // Update our indentation values from config m_indentAsmName = KTLConfig::indentAsmName(); m_indentAsmData = KTLConfig::indentAsmData(); m_indentEqu = KTLConfig::indentEqu(); m_indentEquValue = KTLConfig::indentEquValue(); m_indentComment = m_indentEquComment = KTLConfig::indentComment(); TQStringList::iterator end = lines.end(); for ( TQStringList::iterator slit = lines.begin(); slit != end; ++slit ) { switch ( lineType(*slit) ) { case Other: break; case Equ: *slit = tidyEqu( *slit ); break; case Instruction: *slit = tidyInstruction( *slit ); break; } } TQString code; for ( TQStringList::iterator slit = lines.begin(); slit != end; ++slit ) code.append( *slit + '\n' ); return code; } void AsmFormatter::pad( TQString & text, int length ) { int padLength = length - text.length(); if ( padLength <= 0 ) return; TQString pad; pad.fill( ' ', padLength ); text += pad; } TQString AsmFormatter::tidyInstruction( const TQString & oldLine ) { InstructionParts parts( oldLine ); TQString line; if ( !parts.label().isEmpty() ) line = parts.label() + ' '; pad( line, m_indentAsmName ); if ( !parts.operand().isEmpty() ) line += parts.operand() + ' '; pad( line, m_indentAsmData ); if ( !parts.operandData().isEmpty() ) line += parts.operandData(); pad( line, m_indentComment ); if ( parts.comment().isEmpty() ) { // Remove any whitespace at the end if we're not padding out a comment while ( !line.isEmpty() && line[ line.length() - 1 ].isSpace() ) line.remove( line.length() -1, 1 ); } else line += parts.comment(); return line; } TQString AsmFormatter::tidyEqu( const TQString & oldLine ) { TQString comment = extractComment( oldLine ); TQString code = oldLine; code.remove( comment ); code = code.simplifyWhiteSpace(); TQStringList parts = TQStringList::split( ' ', code ); TQString pad0, pad1, pad2; pad0.fill( ' ', m_indentEqu - (*parts.at(0)).length() ); pad1.fill( ' ', m_indentEquValue - m_indentEqu - (*parts.at(1)).length() ); pad2.fill( ' ', m_indentEquComment - m_indentEquValue - m_indentEqu - (*parts.at(2)).length() ); code = *parts.at(0) + pad0; code += *parts.at(1) + pad1; code += *parts.at(2); if ( !comment.isEmpty() ) { code += pad2; code += comment; } return code; } AsmFormatter::LineType AsmFormatter::lineType( TQString line ) { line = line.simplifyWhiteSpace(); line.remove( extractComment( line ) ); TQStringList parts = TQStringList::split( ' ', line ); TQStringList::iterator end = parts.end(); for ( TQStringList::iterator it = parts.begin(); it != end; ++it ) { if ( (*it).lower() == "equ" ) return Equ; } InstructionParts instructionParts( line ); if ( !instructionParts.operand().isEmpty() ) return Instruction; return Other; } //END class AsmFormatter //BEGIN class InstructionParts InstructionParts::InstructionParts( TQString line ) { m_comment = extractComment( line ); line.remove( m_comment ); line = line.simplifyWhiteSpace(); TQStringList parts = TQStringList::split( ' ', line ); bool foundOperand = false; TQStringList::iterator end = parts.end(); for ( TQStringList::iterator it = parts.begin(); it != end; ++it ) { if ( foundOperand ) { // Already found the operand, so anything else must be the operand // data. if ( m_operandData.isEmpty() ) m_operandData = *it; else m_operandData += ' ' + *it; continue; } if ( PicAsm12bit::self()->operandList().contains( (*it).upper() ) || PicAsm14bit::self()->operandList().contains( (*it).upper() ) || PicAsm16bit::self()->operandList().contains( (*it).upper() ) ) { m_operand = *it; foundOperand = true; } else { // Must be a label m_label = *it; } } } //END class InstructionParts