diff options
Diffstat (limited to 'src/languages/asmparser.cpp')
-rw-r--r-- | src/languages/asmparser.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/languages/asmparser.cpp b/src/languages/asmparser.cpp new file mode 100644 index 0000000..eb4b7cd --- /dev/null +++ b/src/languages/asmparser.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2005 by David Saxton * + * [email protected] * + * * + * 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 "config.h" +#include "gpsimprocessor.h" + +#include <kdebug.h> +#include <qfile.h> +#include <qregexp.h> + +AsmParser::AsmParser( const QString &url ) + : m_url(url) +{ + m_bContainsRadix = false; + m_type = Absolute; +} + + +AsmParser::~AsmParser() +{ +} + + +bool AsmParser::parse( GpsimDebugger * debugger ) +{ + QFile file(m_url); + if ( !file.open(IO_ReadOnly) ) + return false; + + QTextStream stream( &file ); + + m_type = Absolute; + m_bContainsRadix = false; + m_picID = QString::null; + + QStringList nonAbsoluteOps = QStringList::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 QString line = stream.readLine().stripWhiteSpace(); + if ( m_type != Relocatable ) + { + QString col0 = line.section( QRegExp("[; ]"), 0, 0 ); + col0 = col0.stripWhiteSpace(); + if ( nonAbsoluteOps.contains(col0) ) + m_type = Relocatable; + } + if ( !m_bContainsRadix ) + { + if ( line.contains( QRegExp("^RADIX[\\s]*") ) || line.contains( QRegExp("^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 + QRegExp fullRegExp("[lL][iI][sS][tT][\\s]+[pP][\\s]*=[\\s]*[\\d\\w]+"); + QRegExp 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") + QString fileName = line.mid( 7, fileLineAt-7 ); + QString 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... + QStringList lineParts = QStringList::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 QString lineAndFile = lineParts[1]; + int lineFileSplit = lineAndFile.find("; "); + if ( lineFileSplit == -1 ) + kdDebug() << k_funcinfo << "Could not find file / line split in \""<<lineAndFile<<"\""<<endl; + else + { + QString fileName = lineAndFile.mid( lineFileSplit + 2 ); + QString 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; +} + |