File indexing completed on 2025-04-20 05:11:07
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 }