triage: Fix warnings and Windows issues; some enhancements (#1591)

Changes:
- Fixed compiler warnings
- Add "*.*" to file open menu so files without suffix can be opened
- Make it work under Windows
- Make wget() and unpackArchive() methods so they can access the UI
- wget() and unpackArchive() use the new method runProcess() now that also does some error handling
- Errors are shown in the status bar for easier debugging / usage
- Add readme.txt
- Let travis build the triage tool
This commit is contained in:
Sebastian 2019-01-12 09:16:43 +01:00 committed by GitHub
parent d54017a0c4
commit 1042208c2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 22 deletions

View File

@ -168,6 +168,12 @@ script:
- echo $CXXFLAGS - echo $CXXFLAGS
- make -s -j2 - make -s -j2
- cd ../ - cd ../
# Build triage
- cd ./tools/triage
- git clean -dfx .
- qmake
- make -s -j2
- cd ../../
notifications: notifications:
irc: irc:

View File

@ -17,7 +17,11 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow) ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
std::srand(std::time(0)); std::srand(static_cast<unsigned int>(std::time(Q_NULLPTR)));
QDir workFolder(WORK_FOLDER);
if (!workFolder.exists()) {
workFolder.mkdir(WORK_FOLDER);
}
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -27,7 +31,8 @@ MainWindow::~MainWindow()
void MainWindow::loadFile() void MainWindow::loadFile()
{ {
const QString fileName = QFileDialog::getOpenFileName(this, tr("daca results file"), WORK_FOLDER, tr("Text files (*.txt)")); ui->statusBar->clearMessage();
const QString fileName = QFileDialog::getOpenFileName(this, tr("daca results file"), WORK_FOLDER, tr("Text files (*.txt);;All (*.*)"));
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
ui->results->clear(); ui->results->clear();
@ -75,34 +80,64 @@ void MainWindow::loadFile()
} }
} }
static bool wget(const QString url) bool MainWindow::runProcess(const QString &programName, const QStringList &arguments)
{ {
QProcess process; QProcess process;
process.setWorkingDirectory(WORK_FOLDER); process.setWorkingDirectory(WORK_FOLDER);
process.start("wget", QStringList() << url); process.start(programName, arguments);
return process.waitForFinished(-1); bool success = process.waitForFinished(-1);
if (!success) {
QString errorstr(programName);
errorstr.append(": ");
errorstr.append(process.errorString());
ui->statusBar->showMessage(errorstr);
} else {
int exitCode = process.exitCode();
if (exitCode != 0) {
success = false;
const QByteArray stderrOutput = process.readAllStandardError();
QString errorstr(programName);
errorstr.append(QString(": exited with %1: ").arg(exitCode));
errorstr.append(stderrOutput);
ui->statusBar->showMessage(errorstr);
}
}
return success;
} }
static bool unpackArchive(const QString archiveName) bool MainWindow::wget(const QString url)
{
return runProcess("wget", QStringList() << url);
}
bool MainWindow::unpackArchive(const QString archiveName)
{ {
// Unpack archive // Unpack archive
QStringList args; QStringList args;
#ifdef Q_OS_WIN
/* On Windows --force-local is necessary because tar wants to connect to a remote system
* when a colon is found in the archiveName. So "C:/Users/blah/triage/package" would not work
* without it. */
args << "--force-local";
#endif
if (archiveName.endsWith(".tar.gz")) if (archiveName.endsWith(".tar.gz"))
args << "xzvf"; args << "-xzvf";
else if (archiveName.endsWith(".tar.bz2")) else if (archiveName.endsWith(".tar.bz2"))
args << "xjvf"; args << "-xjvf";
else if (archiveName.endsWith(".tar.xz")) else if (archiveName.endsWith(".tar.xz"))
args << "xJvf"; args << "-xJvf";
else {
// Try to automatically find an (un)compressor for this archive
args << "-xavf";
}
args << archiveName; args << archiveName;
QProcess process; return runProcess("tar", args);
process.setWorkingDirectory(WORK_FOLDER);
process.start("tar", args);
return process.waitForFinished(-1);
} }
void MainWindow::showResult(QListWidgetItem *item) void MainWindow::showResult(QListWidgetItem *item)
{ {
ui->statusBar->clearMessage();
if (!item->text().startsWith("ftp://")) if (!item->text().startsWith("ftp://"))
return; return;
const QStringList lines = item->text().split("\n"); const QStringList lines = item->text().split("\n");
@ -115,7 +150,7 @@ void MainWindow::showResult(QListWidgetItem *item)
const QString archiveName = url.mid(url.lastIndexOf("/") + 1); const QString archiveName = url.mid(url.lastIndexOf("/") + 1);
const int pos1 = msg.indexOf(":"); const int pos1 = msg.indexOf(":");
const int pos2 = msg.indexOf(":", pos1+1); const int pos2 = msg.indexOf(":", pos1+1);
const QString fileName = msg.left(msg.indexOf(":")); const QString fileName = WORK_FOLDER + '/' + msg.left(msg.indexOf(":"));
const int lineNumber = msg.mid(pos1+1,pos2-pos1-1).toInt(); const int lineNumber = msg.mid(pos1+1,pos2-pos1-1).toInt();
if (!QFileInfo(fileName).exists()) { if (!QFileInfo(fileName).exists()) {
@ -135,12 +170,18 @@ void MainWindow::showResult(QListWidgetItem *item)
// Open file // Open file
ui->code->setFocus(); ui->code->setFocus();
QFile f(WORK_FOLDER + '/' + fileName); QFile f(fileName);
f.open(QIODevice::ReadOnly | QIODevice::Text); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream textStream(&f); const QString errorMsg =
const QString fileData = textStream.readAll(); QString("Opening file %1 failed: %2").arg(f.fileName()).arg(f.errorString());
ui->code->setError(fileData, lineNumber, QStringList()); ui->statusBar->showMessage(errorMsg);
} else {
QTextStream textStream(&f);
const QString fileData = textStream.readAll();
ui->code->setError(fileData, lineNumber, QStringList());
ui->edit1->setText(url); ui->edit1->setText(url);
ui->edit2->setText(WORK_FOLDER + '/' + fileName); ui->edit2->setText(fileName);
f.close();
}
} }

View File

@ -12,7 +12,7 @@ class MainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
public: public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(QWidget *parent = Q_NULLPTR);
MainWindow(const MainWindow &) = delete; MainWindow(const MainWindow &) = delete;
~MainWindow(); ~MainWindow();
MainWindow &operator=(const MainWindow &) = delete; MainWindow &operator=(const MainWindow &) = delete;
@ -23,6 +23,10 @@ public slots:
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
bool runProcess(const QString &programName, const QStringList & arguments);
bool wget(const QString url);
bool unpackArchive(const QString archiveName);
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

18
tools/triage/readme.txt Normal file
View File

@ -0,0 +1,18 @@
triage tool
This tool lets you comfortably look at Cppcheck analysis results for daca packages. It automatically
downloads the package, extracts it and jumps to the corresponding source code for a Cppcheck
message.
triage uses "wget" and "tar"
On Linux the tool can be directly run since the programs should be installed.
On Windows something like Cygwin is necessary and the directory containing the executables must be
in the PATH environment variable (for example "C:\cygwin\bin").
Usage:
After triage has been started you have to load a daca results file via the "Load" button.
The file must contain the package URL line beginning with "ftp://" and the Cppcheck messages.
When the results file has been parsed successfully you can see a list of Cppcheck messages directly
beneath the "Load" button. Double-click any entry to let the tool show the source code and jump to
and mark the corresponding line. If the package is not found it is downloaded and extracted
automatically. So after the first double-click it is normal that it takes some time until the
source code is shown.