From cfe8ca848cce580bf9fde68f1bc1f5b7686dc0a6 Mon Sep 17 00:00:00 2001 From: hama Date: Sun, 14 Feb 2016 08:57:27 +0100 Subject: [PATCH] recommand: command line, tail --- appl/recommand/CommandProcessor.cpp | 70 ++++++ appl/recommand/CommandProcessor.hpp | 2 + appl/recommand/mainwindow.cpp | 39 ++- appl/recommand/mainwindow.hpp | 4 + appl/recommand/mainwindow.ui | 373 +++++++++++++++++++--------- appl/recommand/recommand.hpp | 1 + appl/recommand/recommand.pro | 3 +- base/ReProgramArgs.cpp | 22 ++ base/ReProgramArgs.hpp | 1 + 9 files changed, 396 insertions(+), 119 deletions(-) diff --git a/appl/recommand/CommandProcessor.cpp b/appl/recommand/CommandProcessor.cpp index 9731c71..f702b9f 100644 --- a/appl/recommand/CommandProcessor.cpp +++ b/appl/recommand/CommandProcessor.cpp @@ -54,6 +54,76 @@ void CommandProcessor::out(const QString& message) m_mainWindow->say(LOG_INFO, message); } +/** + * @brief CommandProcessor::tail + * @param args + */ +void CommandProcessor::tail(const QStringList& args) +{ + ReProgramArgs args2("Prints the last N lines of the files", + "tail -n 20 abc.txt xyz.txt"); + args2.addInt("count", "number of lines to print", 'n', "lines", 10); + args2.addBool("quiet", "the filenames will be suppressed", 'q', "quiet", false); + args2.init(args, true); + if (args2.argCount() < 1) + args2.help("no files given"); + else if (args2.argCount() == 1){ + execTail(args2.arg(0), false, args2.getInt("count")); + } else { + for (int ix = 0; ix < args2.argCount(); ix++){ + execTail(args2.arg(ix), ! args2.getBool("quiet"), args2.getInt("count")); + } + } +} + +/** + * Issues the last N lines of a file. + * + * @param file the name of the file + * @param withName true: the filename is issued in front of the content + * @param count the number of lines to issue + */ +void CommandProcessor::execTail(const QString& file, bool withName, int count){ + QByteArray file2 = I18N::s2b(file); + FILE* fp = fopen(file2, "rb"); + if (fp == NULL){ + printf("cannot open %s: %d", file2.constData(), errno); + } else { + if (withName) + printf("%s:\n", file2.constData()); + QByteArray content; + int bufferSize = max(0x10000, count * 100) / 2; + int count2 = 0; + do { + bufferSize *= 2; + content.resize(bufferSize); + size_t pos = fseek(fp, -bufferSize, SEEK_END); + int pos2 = 0; + if ( (pos2 = fread(content.data(), 1, bufferSize, fp)) <= 0){ + break; + } else { + content.resize(pos2); + const char* ptr = content.constData() + pos2 - 1; + const char* start = content.constData(); + if (ptr > start && *ptr == '\n'){ + ptr--; + } + int count2 = 0; + while(ptr > start && count2 < count){ + if (*ptr-- == '\n') + count2--; + if (ptr == content.constData()) + break; + } + if (count2 == count){ + fputs(*ptr == '\n' ? ptr + 1 : ptr, fp); + } + } + } while(count2 != count); + fclose(fp); + } +} + /** * Executes one statement. * diff --git a/appl/recommand/CommandProcessor.hpp b/appl/recommand/CommandProcessor.hpp index 09c626a..5c32dd8 100644 --- a/appl/recommand/CommandProcessor.hpp +++ b/appl/recommand/CommandProcessor.hpp @@ -22,11 +22,13 @@ public: public: QString calcNOfM(int n, int m, const QString& separator = " "); void euroJackpot(const QStringList& args); + void execTail(const QString& file, bool withName, int count); void help(const QString& errorMessage, const QStringList& args); void interpret(const QString& text); void lotto(const QStringList& args); void nOfM(const QStringList& args); void out(const QString& message); + void tail(const QStringList& args); void time(const QStringList& args); void statement(int lineNo, const QString& text); protected: diff --git a/appl/recommand/mainwindow.cpp b/appl/recommand/mainwindow.cpp index e8645e4..ec4b6e2 100644 --- a/appl/recommand/mainwindow.cpp +++ b/appl/recommand/mainwindow.cpp @@ -32,9 +32,11 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : connect(ui->pushButtonSave, SIGNAL(clicked()), this, SLOT(onSave())); connect(ui->pushButtonInterpolate, SIGNAL(clicked()), this, SLOT(onInterpolate())); connect(ui->pushButtonExpand, SIGNAL(clicked()), this, SLOT(onExpand())); + connect(ui->lineEditCommand, SIGNAL(returnPressed()), this, SLOT(onReturnPressed())); + connect(ui->listWidgetHistory, SIGNAL(itemDoubleClicked(QListWidgetItem*)), + this, SLOT(onHistoryDoubleClicked(QListWidgetItem*))); onLoad(); } - /** * Destructor. */ @@ -84,6 +86,15 @@ void MainWindow::onExpand() } } +/** + * Handles a double click in the command history. + * + * @param item the current item + */ +void MainWindow::onHistoryDoubleClicked(QListWidgetItem* item){ + ui->lineEditCommand->setText(item->text()); +} + /** * Set GUI elements from the queue when the GUI timer is triggered. */ @@ -152,6 +163,15 @@ void MainWindow::onInterpolate() } } +/** + * Handles the RETURN button in the command line. + */ +void MainWindow::onReturnPressed(){ + m_processor->interpret(ui->lineEditCommand->text()); + toHistory(ui->lineEditCommand->text()); + ui->lineEditCommand->clear(); +} + /** * Executes the current commands. */ @@ -176,8 +196,10 @@ void MainWindow::onRun() pos2++; ui->plainTextEditResult->clear(); QString script = text.mid(pos1, pos2 - pos1 + 1); - if (script.length() > 10 || script.trimmed().length() > 0) + if (script.length() > 10 || script.trimmed().length() > 0){ + toHistory(script); m_processor->interpret(script); + } } /** @@ -202,6 +224,19 @@ void MainWindow::onSave() ui->plainTextEditPad->toPlainText().toUtf8().constData()); } +/** + * Inserts commands into the command history. + * + * @param commands the commands to insert + */ +void MainWindow::toHistory(const QString& commands) +{ + QStringList list = commands.split('\n'); + for (int ix = 0; ix < list.count(); ix++){ + ui->listWidgetHistory->addItem(list.at(ix)); + } +} + /** * Writes a message. * diff --git a/appl/recommand/mainwindow.hpp b/appl/recommand/mainwindow.hpp index a75d985..60e8884 100644 --- a/appl/recommand/mainwindow.hpp +++ b/appl/recommand/mainwindow.hpp @@ -33,10 +33,14 @@ public slots: void onClearEdit(); void onClearList(); void onExpand(); + void onHistoryDoubleClicked(QListWidgetItem* item); void onInterpolate(); void onLoad(); + void onReturnPressed(); void onRun(); void onSave(); +protected: + void toHistory(const QString& text); public: virtual bool say(ReLoggerLevel level, const QString& message); diff --git a/appl/recommand/mainwindow.ui b/appl/recommand/mainwindow.ui index ffd4d40..11038c7 100644 --- a/appl/recommand/mainwindow.ui +++ b/appl/recommand/mainwindow.ui @@ -10,143 +10,111 @@ 624 + + + 125 + 0 + + MainWindow - + Qt::Vertical - - - - - - - - Write command, try "help;" - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 125 - 0 - - - - Run - - - - - - - - 125 - 0 - - - - Save - - - - - - - - - - - + - 2 + 0 - + + false + + + false + + - Result as list + Command line - + - + + + Type command and <ENTER> + + + + + + + + - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Clear - - - - + + + + 125 + 0 + + + + History: + + - - - - Monospace - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 125 + 0 + + + + Clear + + + - + - Result as edit field + Command pad - + - + - - - - 125 - 0 - - + - From List + Write command, try "help;" - + Qt::Horizontal @@ -159,7 +127,7 @@ - + 125 @@ -167,28 +135,35 @@ - Clear + Run + + + + + + + + 125 + 0 + + + + Save - - - - FreeMono - - - + - + Buffers - + @@ -255,7 +230,7 @@ - + @@ -321,6 +296,172 @@ + + + 0 + + + + Result as list + + + + + + + + + + + 125 + 0 + + + + Suche: + + + + + + + + 125 + 0 + + + + true + + + + + + + + 25 + 16777215 + + + + < + + + + + + + + 25 + 16777215 + + + + > + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 125 + 0 + + + + Clear + + + + + + + + + + Monospace + + + + + + + + + + + Result as edit field + + + + + + + + + 125 + 0 + + + + From List + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 125 + 0 + + + + Clear + + + + + + + + + + FreeMono + + + + + + + diff --git a/appl/recommand/recommand.hpp b/appl/recommand/recommand.hpp index 328cb8a..f82d458 100644 --- a/appl/recommand/recommand.hpp +++ b/appl/recommand/recommand.hpp @@ -11,6 +11,7 @@ #ifndef RECOMMAND_HPP #define RECOMMAND_HPP +#include #include "base/rebase.hpp" #include "gui/regui.hpp" #include "CommandProcessor.hpp" diff --git a/appl/recommand/recommand.pro b/appl/recommand/recommand.pro index 21da3bb..8efbe4f 100644 --- a/appl/recommand/recommand.pro +++ b/appl/recommand/recommand.pro @@ -22,6 +22,7 @@ SOURCES += main.cpp\ ../../base/ReLogger.cpp \ ../../base/ReRandomizer.cpp \ ../../base/ReStringUtils.cpp \ + ../../base/ReProgramArgs.cpp \ ../../gui/ReStateStorage.cpp \ ../../gui/ReGuiApplication.cpp \ ../../gui/ReGuiValidator.cpp \ @@ -32,6 +33,6 @@ SOURCES += main.cpp\ HEADERS += mainwindow.hpp \ CommandProcessor.hpp \ - recommand.hpp + recommand.hpp FORMS += mainwindow.ui diff --git a/base/ReProgramArgs.cpp b/base/ReProgramArgs.cpp index eb79887..fd18d99 100644 --- a/base/ReProgramArgs.cpp +++ b/base/ReProgramArgs.cpp @@ -612,6 +612,28 @@ void ReProgramArgs::help(const char* message, bool issueLastError, } } +/** Initializes the options from the program arguments. + * + * While arguments are preceded by an '-' they will be treated as options. + * The rest of arguments are stored for retrieving with getArg(). + * + * @param argc the count of program arguments (inclusive options) + * @param argv the argument vector + * @param hasProgram true: the first argument is the program name + * + * @throws ReException + */ +void ReProgramArgs::init(const QStringList& args, bool hasProgram) { + QByteArrayList args2; + const char** args3 = new const char*[args.count()]; + for (int ix = 0; ix < args.count(); ix++){ + args2.append(I18N::s2b(args.at(ix))); + args3[ix] = args2.at(ix).constData(); + } + init(args.count(), args3, hasProgram); + delete[] args3; +} + /** Initializes the options from the program arguments. * * While arguments are preceded by an '-' they will be treated as options. diff --git a/base/ReProgramArgs.hpp b/base/ReProgramArgs.hpp index 4363a44..955df4e 100644 --- a/base/ReProgramArgs.hpp +++ b/base/ReProgramArgs.hpp @@ -82,6 +82,7 @@ public: inline void init(int argc, char* argv[]){ return init(argc, (const char**) argv, true); } + void init(const QStringList& args, bool hasProgram); const char* programName() const; void setLastError(const char* message); void setLastError(const QByteArray& message); -- 2.39.5