File indexing completed on 2022-10-04 15:12:33

0001 /* This file is part of KDevelop
0002    Copyright 2017 Anton Anikin <anton@anikin.xyz>
0003 
0004    This program is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (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 GNU
0012    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; see the file COPYING. If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "utils.h"
0021 
0022 #include <interfaces/icore.h>
0023 #include <interfaces/iuicontroller.h>
0024 
0025 #include <KLocalizedString>
0026 #include <KMessageBox>
0027 #include <KParts/MainWindow>
0028 
0029 #include <QAbstractTableModel>
0030 #include <QMap>
0031 #include <QProcess>
0032 #include <QPushButton>
0033 #include <QStandardPaths>
0034 
0035 namespace Valgrind
0036 {
0037 
0038 QString eventFullName(const QString& eventShortName)
0039 {
0040     static QMap<QString, QString> fullNames;
0041     static bool initDone = false;
0042     if (!initDone) {
0043         initDone = true;
0044 
0045         // full names are from KCachegrind
0046 
0047         fullNames["Ir"  ] = i18n("Instruction Fetch");
0048         fullNames["Dr"  ] = i18n("Data Read Access");
0049         fullNames["Dw"  ] = i18n("Data Write Access");
0050         fullNames["I1mr"] = i18n("L1 Instr. Fetch Miss");
0051         fullNames["D1mr"] = i18n("L1 Data Read Miss");
0052         fullNames["D1mw"] = i18n("L1 Data Write Miss");
0053         fullNames["ILmr"] = i18n("LL Instr. Fetch Miss");
0054         fullNames["DLmr"] = i18n("LL Data Read Miss");
0055         fullNames["DLmw"] = i18n("LL Data Write Miss");
0056 
0057         fullNames["Bc"  ] = i18n("Conditional Branch");
0058         fullNames["Bcm" ] = i18n("Mispredicted Cond. Branch");
0059         fullNames["Bi"  ] = i18n("Indirect Branch");
0060         fullNames["Bim" ] = i18n("Mispredicted Ind. Branch");
0061     }
0062 
0063     return fullNames.value(eventShortName, eventShortName);
0064 }
0065 
0066 QString displayValue(int value)
0067 {
0068     QString result = QString::number(value);
0069     int length = result.length();
0070 
0071     for (int i = 0; i < (length / 3); ++i) {
0072         int pos = result.length() - (4 * i + 3);
0073         if (!pos) {
0074             break;
0075         }
0076         result.insert(pos, ' ');
0077     }
0078 
0079     return result;
0080 }
0081 
0082 QString displayValue(double value)
0083 {
0084     return QString::number(value, 'f', 2);
0085 }
0086 
0087 void emitDataChanged(QAbstractTableModel* model)
0088 {
0089     Q_ASSERT(model);
0090     emit model->dataChanged(model->index(0,0),
0091                             model->index(model->rowCount() - 1, model->columnCount() - 1),
0092                             { Qt::DisplayRole });
0093 }
0094 
0095 void setupVisualizerProcess(
0096     QProcess* visualizerProcess,
0097     QPushButton* startButton,
0098     std::function<void()> startFunction,
0099     bool startImmediately)
0100 {
0101     Q_ASSERT(visualizerProcess);
0102     Q_ASSERT(startButton);
0103 
0104     QObject::connect(startButton, &QPushButton::clicked,
0105                      startButton, [startFunction]() {
0106                          startFunction();
0107                     });
0108 
0109     QObject::connect(visualizerProcess, &QProcess::started, startButton, [startButton]() {
0110         startButton->setEnabled(false);
0111     });
0112 
0113     QObject::connect(visualizerProcess, &QProcess::errorOccurred, startButton, [visualizerProcess, startButton]() {
0114         QString errorMessage;
0115         if (visualizerProcess->error() == QProcess::FailedToStart) {
0116             errorMessage += i18n("Failed to start visualizer from \"%1\".", visualizerProcess->program());
0117             errorMessage += QStringLiteral("\n\n");
0118             errorMessage += i18n("Check your settings and install the visualizer if necessary.");
0119         } else {
0120             errorMessage += i18n("Error during visualizer execution:");
0121             errorMessage += QStringLiteral("\n\n");
0122             errorMessage += visualizerProcess->errorString();
0123         }
0124         KMessageBox::error(activeMainWindow(), errorMessage, i18n("Valgrind Error"));
0125 
0126         startButton->setEnabled(true);
0127     });
0128 
0129     QObject::connect(visualizerProcess, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
0130                      startButton, [startButton]() {
0131                          startButton->setEnabled(true);
0132                     });
0133 
0134     if (startImmediately) {
0135         startFunction();
0136     }
0137 }
0138 
0139 QWidget* activeMainWindow()
0140 {
0141     return KDevelop::ICore::self()->uiController()->activeMainWindow();
0142 }
0143 
0144 QString findExecutable(const QString &executableName)
0145 {
0146     QString executablePath = QStandardPaths::findExecutable(executableName);
0147     return executablePath.isEmpty() ? executableName : executablePath;
0148 }
0149 
0150 }