/***************************************************************************** * AppleSAWS - The Apple Software Analysis WorkShop * * Copyright (C) 2015-2021 Mark D. Long * * * * 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 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ #include "applesoftformatter.h" #include "util.h" #include #include #include #define HEXPREFIX "0x" ApplesoftFormatter::ApplesoftFormatter(QObject *parent) : QObject(parent) { m_file = Q_NULLPTR; } void ApplesoftFormatter::setFile(ApplesoftFile *file) { m_file = file; emit newFile(file); } void ApplesoftFormatter::formatDocument(QTextDocument *doc) { if (!doc) return; doc->clear(); QTextCursor cursor(doc); cursor.beginEditBlock(); bool synhl = (m_format_options.testFlag(SyntaxHighlighting)); foreach (ApplesoftLine line, m_file->getLines()) { QString linestring = QString("%1 ").arg(line.linenum,5,10,QChar(' ')); if (synhl) { cursor.insertText(linestring, ApplesoftToken::textFormat(ApplesoftToken::LineNumberTokenVal)); } else { cursor.insertText(linestring,ApplesoftToken::defaultTextFormat()); } QVectorIteratortokenIt(line.tokens); bool isBranchTarget = false; while (tokenIt.hasNext()) { ApplesoftToken token = tokenIt.next(); if (token.isOptFmtToken()) { switch (token.getTokenId()) { case ApplesoftToken::OptFmtFlagFlowTargetNextTokenValue: { if (m_format_options.testFlag(ShowIntsAsHex)) isBranchTarget = true; break; } case ApplesoftToken::OptFmtIndentLineBreakTokenValue: { if (m_format_options.testFlag(ReindentCode)) cursor.insertBlock(); break; } case ApplesoftToken::OptFmtIndentSpaceTokenValue: { if (m_format_options.testFlag(ReindentCode)) cursor.insertText(" ",ApplesoftToken::defaultTextFormat()); break; } case ApplesoftToken::OptFmtIndentTabTokenValue: { if (m_format_options.testFlag(ReindentCode)) cursor.insertText(" ",ApplesoftToken::defaultTextFormat()); break; } case ApplesoftToken::OptFmtLeadingSpaceTokenValue: { cursor.insertText(" ",ApplesoftToken::defaultTextFormat()); break; } case ApplesoftToken::OptFmtReturnLineBreakTokenValue: { if (m_format_options.testFlag(BreakAfterReturn)) cursor.insertBlock(); break; } default: { break; } } } // isOptFmt else { QString tokenstr = token.getRawPrintableString(); QTextCharFormat fmt = ApplesoftToken::defaultTextFormat(); if (synhl) fmt = token.textFormat(); if (token.getTokenId() == ApplesoftToken::IntegerTokenVal) { if (m_format_options.testFlag(ShowIntsAsHex) && !isBranchTarget) { quint32 ui32val = token.getUnsignedIntegerValue(); qint32 i32val = token.getIntegerValue(); if ((i32val < 128 && i32val >= -128) || ui32val < 256) { quint8 ui8 = ui32val; tokenstr = HEXPREFIX+uint8ToHex(ui8); } else if ((i32val < 32768 && i32val >= -32768) || ui32val < 65536) { quint16 ui16 = ui32val; tokenstr = HEXPREFIX+uint16ToHex(ui16); } else { tokenstr = HEXPREFIX+uint32ToHex(ui32val); } } // isShowIntsAsHex isBranchTarget = false; } // if (m_format_options.testFlag(ShowCtrlChars)) // { // tokenstr.replace(QChar(0x7f),QChar(0x2401)); // for (int idx = 1; idx <= 0x1f; idx++) { // if (idx == '\n') continue; // tokenstr.replace(QChar(idx),QChar(idx+0x2400)); // } // } // if ShowCtrlChars QTextCharFormat invFormat = ApplesoftToken::defaultInverseTextFormat(); if (m_format_options.testFlag(SyntaxHighlighting)) invFormat = ApplesoftToken::textFormat( ApplesoftToken::ControlCharTokenVal); foreach (QChar ch, tokenstr) { if (ch == QChar(0x7f)) { cursor.insertText(QChar(0x00d7),invFormat); } else if (ch < QChar(' ')) { if (m_format_options.testFlag(ShowCtrlChars)) { QChar newch = ch.unicode()+0x40; cursor.insertText(newch,invFormat); } } else cursor.insertText(ch,fmt); } } } // while tokenIt.hasNext() cursor.insertBlock(); } // foreach line cursor.endEditBlock(); }