|
|
|
/***************************************************************************
|
|
|
|
* 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. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "asmparser.h"
|
|
|
|
#include "gpsimprocessor.h"
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
|
|
|
|
AsmParser::AsmParser( const TQString &url )
|
|
|
|
: m_url(url)
|
|
|
|
{
|
|
|
|
m_bContainsRadix = false;
|
|
|
|
m_type = Absolute;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AsmParser::~AsmParser()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AsmParser::parse( GpsimDebugger * debugger )
|
|
|
|
{
|
|
|
|
TQFile file(m_url);
|
|
|
|
if ( !file.open(IO_ReadOnly) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQTextStream stream( &file );
|
|
|
|
|
|
|
|
m_type = Absolute;
|
|
|
|
m_bContainsRadix = false;
|
|
|
|
m_picID = TQString();
|
|
|
|
|
|
|
|
TQStringList nonAbsoluteOps = TQStringList::split( ",",
|
|
|
|
"code,.def,.dim,.direct,endw,extern,.file,global,idata,.ident,.line,.type,udata,udata_acs,udata_ovr,udata_shr" );
|
|
|
|
|
|
|
|
unsigned inputAtLine = 0;
|
|
|
|
while ( !stream.atEnd() )
|
|
|
|
{
|
|
|
|
const TQString line = stream.readLine().stripWhiteSpace();
|
|
|
|
if ( m_type != Relocatable )
|
|
|
|
{
|
|
|
|
TQString col0 = line.section( TQRegExp("[; ]"), 0, 0 );
|
|
|
|
col0 = col0.stripWhiteSpace();
|
|
|
|
if ( nonAbsoluteOps.contains(col0) )
|
|
|
|
m_type = Relocatable;
|
|
|
|
}
|
|
|
|
if ( !m_bContainsRadix )
|
|
|
|
{
|
|
|
|
if ( line.contains( TQRegExp("^RADIX[\\s]*") ) || line.contains( TQRegExp("^radix[\\s]*") ) )
|
|
|
|
m_bContainsRadix = true;
|
|
|
|
}
|
|
|
|
if ( m_picID.isEmpty() )
|
|
|
|
{
|
|
|
|
// We look for "list p = ", and "list p = picid ", and subtract the positions / lengths away from each other to get the picid text position
|
|
|
|
TQRegExp fullRegExp("[lL][iI][sS][tT][\\s]+[pP][\\s]*=[\\s]*[\\d\\w]+");
|
|
|
|
TQRegExp halfRegExp("[lL][iI][sS][tT][\\s]+[pP][\\s]*=[\\s]*");
|
|
|
|
|
|
|
|
int startPos = fullRegExp.search(line);
|
|
|
|
if ( (startPos != -1) && (startPos == halfRegExp.search(line)) )
|
|
|
|
{
|
|
|
|
m_picID = line.mid( startPos + halfRegExp.matchedLength(), fullRegExp.matchedLength() - halfRegExp.matchedLength() );
|
|
|
|
m_picID = m_picID.upper();
|
|
|
|
if ( !m_picID.startsWith("P") )
|
|
|
|
m_picID.prepend("P");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifndef NO_GPSIM
|
|
|
|
if ( debugger && line.startsWith(";#CSRC\t") )
|
|
|
|
{
|
|
|
|
// Assembly file produced (by sdcc) from C, line is in format:
|
|
|
|
// ;#CSRC\t[file-name] [file-line]
|
|
|
|
// The filename can contain spaces.
|
|
|
|
int fileLineAt = line.findRev(" ");
|
|
|
|
|
|
|
|
if ( fileLineAt == -1 )
|
|
|
|
kdWarning() << k_funcinfo << "Syntax error in line \"" << line << "\" while looking for file-line" << endl;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 7 = length_of(";#CSRC\t")
|
|
|
|
TQString fileName = line.mid( 7, fileLineAt-7 );
|
|
|
|
TQString fileLineString = line.mid( fileLineAt+1, line.length() - fileLineAt - 1 );
|
|
|
|
|
|
|
|
if ( fileName.startsWith("\"") )
|
|
|
|
{
|
|
|
|
// Newer versions of SDCC insert " around the filename
|
|
|
|
fileName.remove( 0, 1 ); // First "
|
|
|
|
fileName.remove( fileName.length()-1, 1 ); // Last "
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
int fileLine = fileLineString.toInt(&ok) - 1;
|
|
|
|
if ( ok && fileLine >= 0 )
|
|
|
|
debugger->associateLine( fileName, fileLine, m_url, inputAtLine );
|
|
|
|
else
|
|
|
|
kdDebug() << k_funcinfo << "Not a valid line number: \"" << fileLineString << "\"" << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( debugger && (line.startsWith(".line\t") || line.startsWith(";#MSRC") ) )
|
|
|
|
{
|
|
|
|
// Assembly file produced by either sdcc or microbe, line is in format:
|
|
|
|
// \t[".line"/"#MSRC"]\t[file-line]; [file-name]\t[c/microbe source code for that line]
|
|
|
|
// We're screwed if the file name contains tabs, but hopefully not many do...
|
|
|
|
TQStringList lineParts = TQStringList::split( '\t', line );
|
|
|
|
if ( lineParts.size() < 2 )
|
|
|
|
kdWarning() << k_funcinfo << "Line is in wrong format for extracing source line and file: \""<<line<<"\""<<endl;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const TQString lineAndFile = lineParts[1];
|
|
|
|
int lineFileSplit = lineAndFile.find("; ");
|
|
|
|
if ( lineFileSplit == -1 )
|
|
|
|
kdDebug() << k_funcinfo << "Could not find file / line split in \""<<lineAndFile<<"\""<<endl;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQString fileName = lineAndFile.mid( lineFileSplit + 2 );
|
|
|
|
TQString fileLineString = lineAndFile.left( lineFileSplit );
|
|
|
|
|
|
|
|
if ( fileName.startsWith("\"") )
|
|
|
|
{
|
|
|
|
// Newer versions of SDCC insert " around the filename
|
|
|
|
fileName.remove( 0, 1 ); // First "
|
|
|
|
fileName.remove( fileName.length()-1, 1 ); // Last "
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
int fileLine = fileLineString.toInt(&ok) - 1;
|
|
|
|
if ( ok && fileLine >= 0 )
|
|
|
|
debugger->associateLine( fileName, fileLine, m_url, inputAtLine );
|
|
|
|
else
|
|
|
|
kdDebug() << k_funcinfo << "Not a valid line number: \"" << fileLineString << "\"" << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // !NO_GPSIM
|
|
|
|
inputAtLine++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|