File indexing completed on 2024-06-16 11:34:34

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"