From e0725dfadc824c1b586cf1e79261f94b98a9b8c4 Mon Sep 17 00:00:00 2001 From: poikilos <7557867+poikilos@users.noreply.github.com> Date: Fri, 13 Mar 2020 03:28:54 -0400 Subject: [PATCH] Accept standard input such as via the pipe character! --- changelog.md | 10 ++++++++++ main.cpp | 5 +++++ mainwindow.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++------ mainwindow.h | 4 ++++ readme.md | 54 +++++++++++++++++++++++--------------------------- 5 files changed, 92 insertions(+), 35 deletions(-) diff --git a/changelog.md b/changelog.md index 6195c5c..55b0e07 100644 --- a/changelog.md +++ b/changelog.md @@ -3,12 +3,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [git] - 2020-03-13 +### Added +- Accept standard input such as by piping from another program! + +### Changed +- Instead of dialog boxes regarding missing input, show lines in the + + ## [git] - 2020-03-13 ### Added - Run the script as a user not named "root" to install to use the prefix ~/.local (if the `PREFIX` environment variable is not specified) + ## [1.2.0] - 2020-03-12 ### Added - Handle Minetest Lua Warnings. diff --git a/main.cpp b/main.cpp index d39dcd0..0ecdae2 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,14 @@ #include "mainwindow.h" #include #include +#include int main(int argc, char *argv[]) { + std::cin.sync_with_stdio(false); /**< Stop in_avail from always being 0 + (See #include #include - +#include int iErrors = 0; int iWarnings = 0; int iTODOs = 0; @@ -336,6 +336,7 @@ bool MainWindow::isFatalSourceError(QString sErrStreamLine) MainWindow::~MainWindow() { + delete this->inTimer; delete ui; } void MainWindow::init(QString errorsListFileName) @@ -402,15 +403,28 @@ void MainWindow::init(QString errorsListFileName) } } } else { - QString my_path = QCoreApplication::applicationFilePath(); - QMessageBox::information(this, "Output Inspector - Help", my_path + ": Output Inspector cannot read the output file due to permissions or other read error (tried \"./" + errorsListFileName + "\")."); + if (std::cin.rdbuf()->in_avail() < 1) { + QString my_path = QCoreApplication::applicationFilePath(); + QString title = "Output Inspector - Help"; + QString msg = my_path + ": Output Inspector cannot read the output file due to permissions or other read error (tried \"./" + errorsListFileName + "\")."; + QMessageBox::information(this, title, msg); + // this->addLine(title + ":" + msg, true); + } } } // end if could open file named errorsListFileName else { - QString my_path = QCoreApplication::applicationFilePath(); - QMessageBox::information(this, "Output Inspector - Help", my_path + ": Output Inspector cannot find the output file to process (tried \"./" + errorsListFileName + "\")."); + if (std::cin.rdbuf()->in_avail() < 1) { + QString my_path = QCoreApplication::applicationFilePath(); + QString title = "Output Inspector - Help"; + QString msg = my_path + ": Output Inspector cannot find the output file to process (tried \"./" + errorsListFileName + "\")."; + QMessageBox::information(this, title, msg); + // this->addLine(title + ":" + msg, true); + } } - + this->inTimer = new QTimer(this); + this->inTimer->setInterval(500); // milliseconds + connect(this->inTimer, SIGNAL(timeout()), this, SLOT(readInput())); + this->inTimer->start(); } // end init /** @@ -1234,4 +1248,32 @@ void MainWindow::on_mainListWidget_itemDoubleClicked(QListWidgetItem* item) qInfo().noquote() << "ERROR: '" + sErr + "'"; } } +} + +void MainWindow::readInput() +{ + int limit = 50; + int count = 0; + std::string line = " "; + while (count < limit && !line.empty()) { + std::streamsize size = std::cin.rdbuf()->in_avail(); + if (size < 1) { + // qInfo().noquote() << "OutputInspector: There is no input: got " << size; + // Prevent waiting forever for a line. + break; + } + std::getline(std::cin, line); + if (!std::cin.eof()) { + // qInfo().noquote() << "OutputInspector: input is '" << line.c_str() << "'."; + // this->addLine(QString("OutputInspector: input is: ") + QString::fromStdString(line), true); + this->addLine(QString::fromStdString(line), true); + } + else { + // qInfo().noquote() << "OutputInspector: input has ended."; + // this->addLine("# OutputInspector: input has ended.", true); + break; + } + count++; + } + } // end MainWindow::on_mainListWidget_itemDoubleClicked diff --git a/mainwindow.h b/mainwindow.h index c4699e7..90cfbdb 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -3,6 +3,7 @@ #include #include +#include // #include @@ -77,6 +78,7 @@ class MainWindow : public QMainWindow private slots: void on_mainListWidget_itemDoubleClicked(QListWidgetItem *item); + void readInput(); private: Ui::MainWindow *ui; @@ -104,6 +106,8 @@ private slots: QString m_ActualJumpColumn; void pushWarnings(); /**< Push warnings to the GUI. */ + + QTimer* inTimer; /**< Read standard input lines regularly **/ }; #endif // MAINWINDOW_H diff --git a/readme.md b/readme.md index aaf6325..1067aeb 100644 --- a/readme.md +++ b/readme.md @@ -5,6 +5,7 @@ After using your compiler/linting tool, you can now double-click an error or warning to jump (using Kate or Geany line,col jump feature) to the file and line of code having the issue (see Usage below). + ## Features * Jumps to source line if you double-click error * Color codes lines in your output (red: error; orange: warning; yellow: issue in installed library used [if in site-packages]; black: formatting marks; gray: unrecognized information) @@ -13,38 +14,33 @@ of code having the issue (see Usage below). * inline comment mark is determined from file extension: py, pyw, sh, c, h, cpp, hpp, js, java, php, bat, command * Installs passthrough-outputinspector for use in IDEs (see Usage) -## Formats -So far, compilers/linters with the following output format is readable as input -for outputinspector (see Usage for specific cases): -``` -foo.js: line 1, col 10, reason -``` -or -``` -foo.py:20:29: reason -``` -or -``` -foo.cs(1,10): reason -``` -or\ -**nosetests** (no column, with parenthesis or not, terminated with comma or -newline) ## Usage -* For automatic usage on Linux, create a build command in Geany: - * "Build," "Set Build Commands" - * Set Execute (or an empty box under "Independent commands") to:\ - `passthrough-outputinspector python3 "%f"`\ - (if you set the Execute command, the gear button will run - passthrough-outputinspector and then the button will turn into a stop button - and be able to stop both passthrough-outputinspector and outputinspector) - * You can send up to 7 additional params as passthrough-outputinspector - checks for that many. Example:\ +Before first use, make sure kate or geany package is installed (run +install script again if wasn't when install script ran--it recreates +the config based on detecting kate's location if you enter y for yes). + +### Piping +You can pipe output from another program to get near-realtime (depending +on your OS's implementation of piping) results without using files. + +To get error output, run: `... 2>&1 >/dev/null | outputinspector`; +otherwise, simply run: `... | outputinspector` +(where "..." is your program). + +### GUI-based use +For automatic usage on Linux, create a build command in Geany: +* "Build," "Set Build Commands" +* Set Execute (or an empty box under "Independent commands") to:\ + `passthrough-outputinspector python3 "%f"`\ + (if you set the Execute command, the gear button will run + passthrough-outputinspector and then the button will turn into a stop button + and be able to stop both passthrough-outputinspector and outputinspector) + * You can send up to 7 additional params as passthrough-outputinspector + checks for that many. Example:\ `passthrough-outputinspector python3 "%f" --ExitOnNoErrors=no` -* make sure kate or geany package is installed (run install script again if -wasn't when install script ran--it recreates the config based on detecting -kate's location if you enter y for yes) + +### Specific Uses * For py file linting: you can use pycodestyle (tested with pycodestyle-3 command--package may be named python3-pycodestyle in your Linux distro): ```