asmparser.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by David Saxton                                    *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "asmparser.h"
00012 #include "config.h"
00013 #include "gpsimprocessor.h"
00014 
00015 #include <kdebug.h>
00016 #include <qfile.h>
00017 #include <qregexp.h>
00018 
00019 AsmParser::AsmParser( const QString &url )
00020         : m_url(url)
00021 {
00022         m_bContainsRadix = false;
00023         m_type = Absolute;
00024 }
00025 
00026 AsmParser::~AsmParser()
00027 {
00028 }
00029 
00030 bool AsmParser::parse( GpsimDebugger * debugger )
00031 {
00032         QFile file(m_url);
00033         if ( !file.open(IO_ReadOnly) )
00034                 return false;
00035         
00036         QTextStream stream( &file );
00037         
00038         m_type = Absolute;
00039         m_bContainsRadix = false;
00040         m_picID = QString::null;
00041         
00042         QStringList nonAbsoluteOps = QStringList::split( ",",
00043                         "code,.def,.dim,.direct,endw,extern,.file,global,idata,.ident,.line,.type,udata,udata_acs,udata_ovr,udata_shr" );
00044         
00045         unsigned inputAtLine = 0;
00046         while ( !stream.atEnd() ) {
00047                 const QString line = stream.readLine().stripWhiteSpace();
00048                 if ( m_type != Relocatable )
00049                 {
00050                         QString col0 = line.section( QRegExp("[; ]"), 0, 0 );
00051                         col0 = col0.stripWhiteSpace();
00052                         if ( nonAbsoluteOps.contains(col0) )
00053                                 m_type = Relocatable;
00054                 }
00055 
00056                 if ( !m_bContainsRadix ) {
00057                         if ( line.contains( QRegExp("^RADIX[\\s]*") ) || line.contains( QRegExp("^radix[\\s]*") ) )
00058                                 m_bContainsRadix = true;
00059                 }
00060                 if ( m_picID.isEmpty() )
00061                 {
00062                         // We look for "list p = ", and "list p = picid ", and subtract the positions / lengths away from each other to get the picid text position
00063                         QRegExp fullRegExp("[lL][iI][sS][tT][\\s]+[pP][\\s]*=[\\s]*[\\d\\w]+");
00064                         QRegExp halfRegExp("[lL][iI][sS][tT][\\s]+[pP][\\s]*=[\\s]*");
00065                         
00066                         int startPos = fullRegExp.search(line);
00067                         if ( (startPos != -1) && (startPos == halfRegExp.search(line)) )
00068                         {
00069                                 m_picID = line.mid( startPos + halfRegExp.matchedLength(), fullRegExp.matchedLength() - halfRegExp.matchedLength() );
00070                                 m_picID = m_picID.upper();
00071                                 if ( !m_picID.startsWith("P") )
00072                                         m_picID.prepend("P");
00073                         }
00074                 }
00075 #ifndef NO_GPSIM
00076                 if ( debugger && line.startsWith(";#CSRC\t") ) {
00077                         // Assembly file produced (by sdcc) from C, line is in format:
00078                         // ;#CSRC\t[file-name] [file-line]
00079                         // The filename can contain spaces.
00080                         int fileLineAt = line.findRev(" ");
00081                         
00082                         if ( fileLineAt == -1 )
00083                                 kdWarning() << k_funcinfo << "Syntax error in line \"" << line << "\" while looking for file-line" << endl;
00084                         else
00085                         {
00086                                 // 7 = length_of(";#CSRC\t")
00087                                 QString fileName = line.mid( 7, fileLineAt-7 );
00088                                 QString fileLineString = line.mid( fileLineAt+1, line.length() - fileLineAt - 1 );
00089                                         
00090                                 if ( fileName.startsWith("\"") )
00091                                 {
00092                                         // Newer versions of SDCC insert " around the filename
00093                                         fileName.remove( 0, 1 ); // First "
00094                                         fileName.remove( fileName.length()-1, 1 ); // Last "
00095                                 }
00096                                 
00097                                 bool ok;
00098                                 int fileLine = fileLineString.toInt(&ok) - 1;
00099                                 if ( ok && fileLine >= 0 )
00100                                         debugger->associateLine( fileName, fileLine, m_url, inputAtLine );
00101                                 else
00102                                         kdDebug() << k_funcinfo << "Not a valid line number: \"" << fileLineString << "\"" << endl;
00103                         }
00104                 }
00105                 if ( debugger && (line.startsWith(".line\t") || line.startsWith(";#MSRC") ) )
00106                 {
00107                         // Assembly file produced by either sdcc or microbe, line is in format:
00108                         // \t[".line"/"#MSRC"]\t[file-line]; [file-name]\t[c/microbe source code for that line]
00109                         // We're screwed if the file name contains tabs, but hopefully not many do...
00110                         QStringList lineParts = QStringList::split( '\t', line );
00111                         if ( lineParts.size() < 2 )
00112                                 kdWarning() << k_funcinfo << "Line is in wrong format for extracing source line and file: \""<<line<<"\""<<endl;
00113                         else {
00114                                 const QString lineAndFile = lineParts[1];
00115                                 int lineFileSplit = lineAndFile.find("; ");
00116                                 if ( lineFileSplit == -1 )
00117                                         kdDebug() << k_funcinfo << "Could not find file / line split in \""<<lineAndFile<<"\""<<endl;
00118                                 else {
00119                                         QString fileName = lineAndFile.mid( lineFileSplit + 2 );
00120                                         QString fileLineString = lineAndFile.left( lineFileSplit );
00121                                         
00122                                         if ( fileName.startsWith("\"") ) {
00123                                                 // Newer versions of SDCC insert " around the filename
00124                                                 fileName.remove( 0, 1 ); // First "
00125                                                 fileName.remove( fileName.length()-1, 1 ); // Last "
00126                                         }
00127                                 
00128                                         bool ok;
00129                                         int fileLine = fileLineString.toInt(&ok) - 1;
00130                                         if ( ok && fileLine >= 0 )
00131                                                 debugger->associateLine( fileName, fileLine, m_url, inputAtLine );
00132                                         else kdDebug() << k_funcinfo << "Not a valid line number: \"" << fileLineString << "\"" << endl;
00133                                 }
00134                         }
00135                 }
00136 #endif // !NO_GPSIM
00137                 inputAtLine++;
00138         }
00139         return true;
00140 }
00141 

Generated on Tue May 8 17:05:27 2007 for KTechLab by  doxygen 1.5.1