summaryrefslogtreecommitdiffstats
path: root/src/languages/asmparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/languages/asmparser.cpp')
-rw-r--r--src/languages/asmparser.cpp150
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 *
+ * *
+ * 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;
+}
+