File indexing completed on 2024-06-16 11:34:34

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "asmparser.h"
0012 #include "config.h"
0013 #include "gpsimprocessor.h"
0014 
0015 #include <QFile>
0016 #include <QRegExp>
0017 #include <QStringList>
0018 
0019 #include <ktechlab_debug.h>
0020 
0021 AsmParser::AsmParser(const QString &url)
0022     : m_url(url)
0023 {
0024     m_bContainsRadix = false;
0025     m_type = Absolute;
0026 }
0027 
0028 AsmParser::~AsmParser()
0029 {
0030 }
0031 
0032 bool AsmParser::parse(GpsimDebugger *debugger)
0033 {
0034     QFile file(m_url);
0035     if (!file.open(QIODevice::ReadOnly))
0036         return false;
0037 
0038     QTextStream stream(&file);
0039 
0040     m_type = Absolute;
0041     m_bContainsRadix = false;
0042     m_picID = QString();
0043 
0044     // QStringList nonAbsoluteOps = QStringList::split( ",",
0045     //      "code,.def,.dim,.direct,endw,extern,.file,global,idata,.ident,.line,.type,udata,udata_acs,udata_ovr,udata_shr" );
0046     QStringList nonAbsoluteOps = QString("code,.def,.dim,.direct,endw,extern,.file,global,idata,.ident,.line,.type,udata,udata_acs,udata_ovr,udata_shr").split(",");
0047 
0048     unsigned inputAtLine = 0;
0049     while (!stream.atEnd()) {
0050         const QString line = stream.readLine().trimmed();
0051         if (m_type != Relocatable) {
0052             QString col0 = line.section(QRegExp("[; ]"), 0, 0);
0053             col0 = col0.trimmed();
0054             if (nonAbsoluteOps.contains(col0))
0055                 m_type = Relocatable;
0056         }
0057 
0058         if (!m_bContainsRadix) {
0059             if (line.contains(QRegExp("^RADIX[\\s]*")) || line.contains(QRegExp("^radix[\\s]*")))
0060                 m_bContainsRadix = true;
0061         }
0062 
0063         if (m_picID.isEmpty()) {
0064             // We look for "list p = ", and "list p = picid ", and subtract the positions / lengths away from each other to get the picid text position
0065             QRegExp fullRegExp("[lL][iI][sS][tT][\\s]+[pP][\\s]*=[\\s]*[\\d\\w]+");
0066             QRegExp halfRegExp("[lL][iI][sS][tT][\\s]+[pP][\\s]*=[\\s]*");
0067 
0068             int startPos = fullRegExp.indexIn(line);
0069             if ((startPos != -1) && (startPos == halfRegExp.indexIn(line))) {
0070                 m_picID = line.mid(startPos + halfRegExp.matchedLength(), fullRegExp.matchedLength() - halfRegExp.matchedLength());
0071                 m_picID = m_picID.toUpper();
0072                 if (!m_picID.startsWith("P"))
0073                     m_picID.prepend("P");
0074             }
0075         }
0076 #ifndef NO_GPSIM
0077         if (debugger && line.startsWith(";#CSRC\t")) {
0078             // Assembly file produced (by sdcc) from C, line is in format:
0079             // ;#CSRC\t[file-name] [file-line]
0080             // The filename can contain spaces.
0081             int fileLineAt = line.lastIndexOf(" ");
0082 
0083             if (fileLineAt == -1)
0084                 qCWarning(KTL_LOG) << "Syntax error in line \"" << line << "\" while looking for file-line";
0085             else {
0086                 // 7 = length_of(";#CSRC\t")
0087                 QString fileName = line.mid(7, fileLineAt - 7);
0088                 QString fileLineString = line.mid(fileLineAt + 1, line.length() - fileLineAt - 1);
0089 
0090                 if (fileName.startsWith("\"")) {
0091                     // Newer versions of SDCC insert " around the filename
0092                     fileName.remove(0, 1);                     // First "
0093                     fileName.remove(fileName.length() - 1, 1); // Last "
0094                 }
0095 
0096                 bool ok;
0097                 int fileLine = fileLineString.toInt(&ok) - 1;
0098                 if (ok && fileLine >= 0)
0099                     debugger->associateLine(fileName, fileLine, m_url, inputAtLine);
0100                 else
0101                     qCDebug(KTL_LOG) << "Not a valid line number: \"" << fileLineString << "\"";
0102             }
0103         }
0104 
0105         if (debugger && (line.startsWith(".line\t") || line.startsWith(";#MSRC"))) {
0106             // Assembly file produced by either sdcc or microbe, line is in format:
0107             // \t[".line"/"#MSRC"]\t[file-line]; [file-name]\t[c/microbe source code for that line]
0108             // We're screwed if the file name contains tabs, but hopefully not many do...
0109             // QStringList lineParts = QStringList::split( '\t', line ); // 2018.12.01
0110             QStringList lineParts = line.split('\t', Qt::SkipEmptyParts);
0111             if (lineParts.size() < 2)
0112                 qCWarning(KTL_LOG) << "Line is in wrong format for extracting source line and file: \"" << line << "\"";
0113             else {
0114                 const QString lineAndFile = lineParts[1];
0115                 int lineFileSplit = lineAndFile.indexOf("; ");
0116                 if (lineFileSplit == -1)
0117                     qCDebug(KTL_LOG) << "Could not find file / line split in \"" << lineAndFile << "\"";
0118                 else {
0119                     QString fileName = lineAndFile.mid(lineFileSplit + 2);
0120                     QString fileLineString = lineAndFile.left(lineFileSplit);
0121 
0122                     if (fileName.startsWith("\"")) {
0123                         // Newer versions of SDCC insert " around the filename
0124                         fileName.remove(0, 1);                     // First "
0125                         fileName.remove(fileName.length() - 1, 1); // Last "
0126                     }
0127 
0128                     bool ok;
0129                     int fileLine = fileLineString.toInt(&ok) - 1;
0130                     if (ok && fileLine >= 0)
0131                         debugger->associateLine(fileName, fileLine, m_url, inputAtLine);
0132                     else
0133                         qCDebug(KTL_LOG) << "Not a valid line number: \"" << fileLineString << "\"";
0134                 }
0135             }
0136         }
0137 #else
0138         Q_UNUSED(debugger);
0139 #endif // !NO_GPSIM
0140         inputAtLine++;
0141     }
0142 
0143     return true;
0144 }