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 "externallanguage.h" 0012 #include "languagemanager.h" 0013 #include "logview.h" 0014 0015 #include <KProcess> 0016 #include <KShell> 0017 0018 #include <QRegExp> 0019 #include <QTimer> 0020 0021 #include <ktechlab_debug.h> 0022 0023 ExternalLanguage::ExternalLanguage(ProcessChain *processChain, const QString &name) 0024 : Language(processChain, name) 0025 { 0026 m_languageProcess = nullptr; 0027 } 0028 0029 ExternalLanguage::~ExternalLanguage() 0030 { 0031 deleteLanguageProcess(); 0032 } 0033 0034 void ExternalLanguage::deleteLanguageProcess() 0035 { 0036 if (!m_languageProcess) 0037 return; 0038 0039 // I'm not too sure if this combination of killing the process is the best way.... 0040 // m_languageProcess->tryTerminate(); 0041 // QTimer::singleShot( 5000, m_languageProcess, SLOT( kill() ) ); 0042 // delete m_languageProcess; 0043 m_languageProcess->kill(); 0044 m_languageProcess->deleteLater(); 0045 0046 m_languageProcess = nullptr; 0047 } 0048 0049 void ExternalLanguage::processStdout() 0050 { 0051 QString allOut = m_languageProcess->readAllStandardOutput(); 0052 QStringList lines = allOut.split('\n', Qt::SkipEmptyParts); // QStringList::split( '\n', allOut, false ); // 2018.12.01 0053 QStringList::iterator end = lines.end(); 0054 0055 for (QStringList::iterator it = lines.begin(); it != end; ++it) { 0056 if (isError(*it)) { 0057 outputError(*it); 0058 outputtedError(*it); 0059 } else if (isWarning(*it)) { 0060 outputWarning(*it); 0061 outputtedWarning(*it); 0062 } else { 0063 outputMessage(*it); 0064 outputtedMessage(*it); 0065 } 0066 } 0067 } 0068 0069 void ExternalLanguage::processStderr() 0070 { 0071 QString allStdErr = m_languageProcess->readAllStandardError(); 0072 QStringList lines = allStdErr.split('\n', Qt::SkipEmptyParts); // QStringList::split( '\n', allStdErr, false ); 0073 QStringList::iterator end = lines.end(); 0074 0075 for (QStringList::iterator it = lines.begin(); it != end; ++it) { 0076 if (isStderrOutputFatal(*it)) { 0077 outputError(*it); 0078 outputtedError(*it); 0079 } else { 0080 outputWarning(*it); 0081 outputtedWarning(*it); 0082 } 0083 } 0084 } 0085 0086 void ExternalLanguage::processExited(int, QProcess::ExitStatus) 0087 { 0088 if (!m_languageProcess) { 0089 qCDebug(KTL_LOG) << " m_languageProcess == nullptr, returning"; 0090 return; 0091 } 0092 bool allOk = processExited((m_languageProcess->exitStatus() == QProcess::NormalExit) && (m_errorCount == 0)); 0093 finish(allOk); 0094 deleteLanguageProcess(); 0095 } 0096 0097 void ExternalLanguage::processInitFailed() 0098 { 0099 finish(false); 0100 deleteLanguageProcess(); 0101 } 0102 0103 bool ExternalLanguage::start() 0104 { 0105 displayProcessCommand(); 0106 0107 m_languageProcess->setOutputChannelMode(KProcess::SeparateChannels); 0108 0109 m_languageProcess->start(); 0110 return m_languageProcess->waitForStarted(); 0111 } 0112 0113 void ExternalLanguage::resetLanguageProcess() 0114 { 0115 reset(); 0116 deleteLanguageProcess(); 0117 m_errorCount = 0; 0118 0119 m_languageProcess = new KProcess(this); 0120 0121 connect(m_languageProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(processStdout())); 0122 0123 connect(m_languageProcess, SIGNAL(readyReadStandardError()), this, SLOT(processStderr())); 0124 0125 connect(m_languageProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processExited(int, QProcess::ExitStatus))); 0126 } 0127 0128 void ExternalLanguage::displayProcessCommand() 0129 { 0130 QStringList quotedArguments; 0131 QList<QString> arguments = m_languageProcess->program(); 0132 // QList<QString> arguments; 0133 // for (QList<QByteArray>::const_iterator itArgs = m_languageProcess->args().begin(); 0134 // itArgs != m_languageProcess->args().end(); 0135 // ++itArgs) { 0136 // arguments.append(QString(*itArgs)); 0137 // } 0138 0139 if (arguments.size() == 1) 0140 quotedArguments << arguments[0]; 0141 0142 else { 0143 QList<QString>::const_iterator end = arguments.end(); 0144 0145 for (QList<QString>::const_iterator it = arguments.begin(); it != end; ++it) { 0146 if ((*it).isEmpty() || (*it).contains(QRegExp("[\\s]"))) 0147 quotedArguments << KShell::quoteArg(*it); 0148 else 0149 quotedArguments << *it; 0150 } 0151 } 0152 0153 // outputMessage( "<i>" + quotedArguments.join(" ") + "</i>" ); 0154 outputMessage(quotedArguments.join(" ")); 0155 // LanguageManager::self()->logView()->addOutput( quotedArguments.join(" "), LogView::ot_info ); 0156 } 0157 0158 #include "moc_externallanguage.cpp"