File indexing completed on 2024-05-12 05:26:19
0001 /* 0002 * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org> 0003 * 0004 * This program is free software; you can redistribute it and/or modify 0005 * it under the terms of the GNU General Public License as published by 0006 * the Free Software Foundation; either version 2 of the License, or 0007 * (at your option) any later version. 0008 * 0009 * This program is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 * GNU General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU General Public License 0015 * along with this program; if not, write to the 0016 * Free Software Foundation, Inc., 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 0018 */ 0019 0020 #include "state.h" 0021 0022 #include <QCoreApplication> 0023 #include <QDebug> 0024 #include <QEventLoop> 0025 #include <QTextStream> 0026 0027 #include "common/log.h" 0028 0029 static bool s_hasEventLoop = false; 0030 0031 class State::Private 0032 { 0033 public: 0034 Private() : outStream(stdout) 0035 { 0036 } 0037 0038 QEventLoop *eventLoop() 0039 { 0040 if (!event) { 0041 event = new QEventLoop; 0042 } 0043 0044 return event; 0045 } 0046 0047 int debugLevel = 0; 0048 QEventLoop *event = 0; 0049 bool timing = false; 0050 QTextStream outStream; 0051 QList<QStringList> table; 0052 }; 0053 0054 State::State() : d(new Private) 0055 { 0056 } 0057 0058 void State::print(const QString &message, unsigned int indentationLevel) const 0059 { 0060 for (unsigned int i = 0; i < indentationLevel; ++i) { 0061 d->outStream << "\t"; 0062 } 0063 0064 d->outStream << message; 0065 } 0066 0067 void State::printLine(const QString &message, unsigned int indentationLevel) const 0068 { 0069 print(message, indentationLevel); 0070 d->outStream << "\n"; 0071 d->outStream.flush(); 0072 } 0073 0074 void State::printError(const QString &errorMessage, const QString &errorCode) const 0075 { 0076 printLine("ERROR" + (errorCode.isEmpty() ? "" : " " + errorCode) + ": " + errorMessage); 0077 } 0078 0079 void State::stageTableLine(const QStringList &line) const 0080 { 0081 d->table << line; 0082 } 0083 0084 void State::printTable(const QList<QStringList> &table) const 0085 { 0086 //First let's find out the maximum size for each column depending on the content 0087 QVector<int> columnSizes; 0088 columnSizes.fill(0, 10); 0089 for (const auto &row : table) { 0090 for (int columnIndex = 0; columnIndex < row.size(); columnIndex++) { 0091 if (columnSizes.size() <= columnIndex) { 0092 columnSizes.append(0); 0093 } 0094 columnSizes[columnIndex] = qMax(columnSizes[columnIndex], row[columnIndex].size()); 0095 } 0096 } 0097 //And now print the table 0098 for (const auto &row : table) { 0099 for (int columnIndex = 0; columnIndex < row.size(); columnIndex++) { 0100 if (columnIndex > 0) { 0101 d->outStream << " | "; 0102 } 0103 d->outStream << row[columnIndex].leftJustified(columnSizes[columnIndex], ' ', true); 0104 } 0105 d->outStream << "\n"; 0106 } 0107 d->outStream.flush(); 0108 } 0109 0110 void State::flushTable() const 0111 { 0112 printTable(d->table); 0113 d->table.clear(); 0114 } 0115 0116 void State::setDebugLevel(unsigned int level) 0117 { 0118 if (level < 7) { 0119 d->debugLevel = level; 0120 } 0121 } 0122 0123 unsigned int State::debugLevel() const 0124 { 0125 return d->debugLevel; 0126 } 0127 0128 int State::commandStarted() const 0129 { 0130 SinkTrace() << "Command started"; 0131 if (!s_hasEventLoop) { 0132 return QCoreApplication::exec(); 0133 } else if (!d->eventLoop()->isRunning()) { 0134 return d->eventLoop()->exec(); 0135 } 0136 0137 return 0; 0138 } 0139 0140 void State::commandFinished(int returnCode) const 0141 { 0142 SinkTrace() << "Command finished. Exit code: " << returnCode; 0143 if (!s_hasEventLoop) { 0144 QCoreApplication::exit(returnCode); 0145 } else { 0146 d->eventLoop()->exit(returnCode); 0147 } 0148 } 0149 0150 void State::setHasEventLoop(bool evented) 0151 { 0152 s_hasEventLoop = evented; 0153 } 0154 0155 bool State::hasEventLoop() 0156 { 0157 return s_hasEventLoop; 0158 } 0159 0160 void State::setCommandTiming(bool time) 0161 { 0162 d->timing = time; 0163 } 0164 0165 bool State::commandTiming() const 0166 { 0167 return d->timing; 0168 } 0169 0170 void State::setLoggingLevel(const QString &level) const 0171 { 0172 Sink::Log::setDebugOutputLevel(Sink::Log::debugLevelFromName(level.toLatin1())); 0173 } 0174 0175 QString State::loggingLevel() const 0176 { 0177 // do not turn this into a single line return: that core dumps due to allocation of 0178 // the byte array in Sink::Log 0179 QByteArray rv = Sink::Log::debugLevelName(Sink::Log::debugOutputLevel()); 0180 return rv.toLower(); 0181 }