File indexing completed on 2025-02-16 08:27:16
0001 /*************************************************************************** 0002 * Copyright (C) 2003-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 "asmformatter.h" 0012 #include "picinfo12bit.h" 0013 #include "picinfo14bit.h" 0014 #include "picinfo16bit.h" 0015 0016 #include <ktlconfig.h> 0017 0018 static QString extractComment(const QString &line) 0019 { 0020 int pos = line.indexOf(';'); 0021 0022 if (pos == -1) 0023 return ""; 0024 0025 return line.right(line.length() - pos); 0026 } 0027 0028 // BEGIN class AsmFormatter 0029 AsmFormatter::AsmFormatter() 0030 { 0031 } 0032 0033 AsmFormatter::~AsmFormatter() 0034 { 0035 } 0036 0037 QString AsmFormatter::tidyAsm(QStringList lines) 0038 { 0039 // Update our indentation values from config 0040 m_indentAsmName = KTLConfig::indentAsmName(); 0041 m_indentAsmData = KTLConfig::indentAsmData(); 0042 m_indentEqu = KTLConfig::indentEqu(); 0043 m_indentEquValue = KTLConfig::indentEquValue(); 0044 m_indentComment = m_indentEquComment = KTLConfig::indentComment(); 0045 0046 QStringList::iterator end = lines.end(); 0047 for (QStringList::iterator slit = lines.begin(); slit != end; ++slit) { 0048 switch (lineType(*slit)) { 0049 case Other: 0050 break; 0051 0052 case Equ: 0053 *slit = tidyEqu(*slit); 0054 break; 0055 0056 case Instruction: 0057 *slit = tidyInstruction(*slit); 0058 break; 0059 } 0060 } 0061 0062 QString code; 0063 0064 for (QStringList::iterator slit = lines.begin(); slit != end; ++slit) 0065 code.append(*slit + '\n'); 0066 0067 return code; 0068 } 0069 0070 void AsmFormatter::pad(QString &text, int length) 0071 { 0072 int padLength = length - text.length(); 0073 if (padLength <= 0) 0074 return; 0075 0076 QString pad; 0077 pad.fill(' ', padLength); 0078 text += pad; 0079 } 0080 0081 QString AsmFormatter::tidyInstruction(const QString &oldLine) 0082 { 0083 InstructionParts parts(oldLine); 0084 QString line; 0085 0086 if (!parts.label().isEmpty()) 0087 line = parts.label() + ' '; 0088 pad(line, m_indentAsmName); 0089 0090 if (!parts.operand().isEmpty()) 0091 line += parts.operand() + ' '; 0092 pad(line, m_indentAsmData); 0093 0094 if (!parts.operandData().isEmpty()) 0095 line += parts.operandData(); 0096 pad(line, m_indentComment); 0097 0098 if (parts.comment().isEmpty()) { 0099 // Remove any whitespace at the end if we're not padding out a comment 0100 while (!line.isEmpty() && line[line.length() - 1].isSpace()) 0101 line.remove(line.length() - 1, 1); 0102 } else 0103 line += parts.comment(); 0104 0105 return line; 0106 } 0107 0108 QString AsmFormatter::tidyEqu(const QString &oldLine) 0109 { 0110 QString comment = extractComment(oldLine); 0111 QString code = oldLine; 0112 code.remove(comment); 0113 code = code.simplified(); 0114 0115 QStringList parts = code.split(' ', Qt::SkipEmptyParts); // QStringList::split( ' ', code ); // 2018.12.01 0116 0117 QString pad0, pad1, pad2; 0118 pad0.fill(' ', m_indentEqu - (parts.at(0)).length()); 0119 pad1.fill(' ', m_indentEquValue - m_indentEqu - (parts.at(1)).length()); 0120 pad2.fill(' ', m_indentEquComment - m_indentEquValue - m_indentEqu - (parts.at(2)).length()); 0121 0122 code = parts.at(0) + pad0; 0123 code += parts.at(1) + pad1; 0124 code += parts.at(2); 0125 if (!comment.isEmpty()) { 0126 code += pad2; 0127 code += comment; 0128 } 0129 0130 return code; 0131 } 0132 0133 AsmFormatter::LineType AsmFormatter::lineType(QString line) 0134 { 0135 line = line.simplified(); 0136 0137 line.remove(extractComment(line)); 0138 0139 QStringList parts = line.split(' ', Qt::SkipEmptyParts); // QStringList::split( ' ', line ); // 2018.12.01 0140 QStringList::iterator end = parts.end(); 0141 for (QStringList::iterator it = parts.begin(); it != end; ++it) { 0142 if ((*it).toLower() == "equ") 0143 return Equ; 0144 } 0145 0146 InstructionParts instructionParts(line); 0147 if (!instructionParts.operand().isEmpty()) 0148 return Instruction; 0149 0150 return Other; 0151 } 0152 // END class AsmFormatter 0153 0154 // BEGIN class InstructionParts 0155 InstructionParts::InstructionParts(QString line) 0156 { 0157 m_comment = extractComment(line); 0158 line.remove(m_comment); 0159 0160 line = line.simplified(); 0161 QStringList parts = line.split(' ', Qt::SkipEmptyParts); // QStringList::split( ' ', line ); // 2018.12.01 0162 0163 bool foundOperand = false; 0164 QStringList::iterator end = parts.end(); 0165 for (QStringList::iterator it = parts.begin(); it != end; ++it) { 0166 if (foundOperand) { 0167 // Already found the operand, so anything else must be the operand 0168 // data. 0169 0170 if (m_operandData.isEmpty()) 0171 m_operandData = *it; 0172 else 0173 m_operandData += ' ' + *it; 0174 0175 continue; 0176 } 0177 0178 if (PicAsm12bit::self()->operandList().contains((*it).toUpper()) || PicAsm14bit::self()->operandList().contains((*it).toUpper()) || PicAsm16bit::self()->operandList().contains((*it).toUpper())) { 0179 m_operand = *it; 0180 foundOperand = true; 0181 } else { 0182 // Must be a label 0183 m_label = *it; 0184 } 0185 } 0186 } 0187 // END class InstructionParts