From b18d067d51a3e2c6aad97e4620970512318580a4 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Sat, 1 Feb 2014 19:19:06 +0100 Subject: [PATCH] Refactored command-line parser into a separate class. Consequently, eliminated a lot of redundant code in "main" and "win_main". --- src/cli.cpp | 149 +++++++++++++++++++++++++ src/cli.h | 63 +++++++++++ src/main.cpp | 81 +++++--------- src/version.h | 2 +- src/win_main.cpp | 85 ++++++-------- x264_launcher_MSVC2013.vcxproj | 2 + x264_launcher_MSVC2013.vcxproj.filters | 8 +- 7 files changed, 285 insertions(+), 105 deletions(-) create mode 100644 src/cli.cpp create mode 100644 src/cli.h diff --git a/src/cli.cpp b/src/cli.cpp new file mode 100644 index 0000000..889e19f --- /dev/null +++ b/src/cli.cpp @@ -0,0 +1,149 @@ +/////////////////////////////////////////////////////////////////////////////// +// Simple x264 Launcher +// Copyright (C) 2004-2014 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cli.h" +#include "global.h" + +/////////////////////////////////////////////////////////////////////////////// +// Pre-defined commands +/////////////////////////////////////////////////////////////////////////////// + +static struct +{ + const char *longName; + const int optionCount; + const int identifier; +} +s_parameters[] = +{ + { "add", 1, CLI_PARAM_ADD_FILE }, + { "add-file", 1, CLI_PARAM_ADD_FILE }, + { "add-job", 3, CLI_PARAM_ADD_JOB }, + { "force-start", 0, CLI_PARAM_FORCE_START }, + { "no-force-start", 0, CLI_PARAM_NO_FORCE_START }, + { "force-enqueue", 0, CLI_PARAM_FORCE_ENQUEUE }, + { "no-force-enqueue", 0, CLI_PARAM_NO_FORCE_ENQUEUE }, + { "skip-avisynth-check", 0, CLI_PARAM_SKIP_AVS_CHECK }, + { "skip-vapoursynth-check", 0, CLI_PARAM_SKIP_VPS_CHECK }, + { "force-cpu-no-64bit", 0, CLI_PARAM_FORCE_CPU_NO_X64 }, + { "no-deadlock-detection", 0, CLI_PARAM_NO_DEADLOCK }, + { "console", 0, CLI_PARAM_DEBUG_CONSOLE }, + { "no-console", 0, CLI_PARAM_NO_DEBUG_CONSOLE }, + { "no-style", 0, CLI_PARAM_NO_GUI_STYLE }, + { NULL, 0, 0 } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CLI Parser +/////////////////////////////////////////////////////////////////////////////// + +CLIParser::CLIParser(const QStringList &args) +: + m_args(args) +{ + m_iter = m_args.constBegin(); + + //Skip the application name, which is expected at args[0] + if(m_iter != m_args.constEnd()) m_iter++; +} + +CLIParser::~CLIParser(void) +{ + /*Nothing to do*/ +} + +bool CLIParser::nextOption(int &identifier, QStringList *options) +{ + identifier = -1; + if(options) options->clear(); + int numOpts = 0; + + if(m_iter != m_args.constEnd()) + { + const QString current = *(m_iter++); + for(size_t i = 0; s_parameters[i].longName != NULL; i++) + { + if(X264_STRCMP(current, QString("--%1").arg(QString::fromLatin1(s_parameters[i].longName)))) + { + numOpts = s_parameters[i].optionCount; + identifier = s_parameters[i].identifier; + break; + } + } + if(identifier < 0) + { + qWarning("Invalid command-line option \"%s\" was encountered!", current.toUtf8().constData()); + m_iter = m_args.constEnd(); + } + } + + while((identifier >= 0) && (numOpts > 0)) + { + if(m_iter != m_args.constEnd()) + { + if(options) + { + *options << *m_iter; + } + m_iter++; numOpts--; + } + else + { + qWarning("Too few arguments for command \"--%s\" specified!", identifier2string(identifier)); + break; + } + } + + return ((identifier >= 0) && (numOpts <= 0)); +} + +bool CLIParser::checkFlag(const int &identifier, const QStringList &args) +{ + CLIParser parser(args); + int currentId; + + while(parser.nextOption(currentId, NULL)) + { + if(currentId == identifier) + { + return true; + } + } + + return false; +} + +const char *CLIParser::identifier2string(const int &identifier) +{ + const char *longName = NULL; + + for(size_t i = 0; s_parameters[i].longName != NULL; i++) + { + if(s_parameters[i].identifier == identifier) + { + longName = s_parameters[i].longName; + } + } + + return longName; +} diff --git a/src/cli.h b/src/cli.h new file mode 100644 index 0000000..ff6011f --- /dev/null +++ b/src/cli.h @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////////// +// Simple x264 Launcher +// Copyright (C) 2004-2014 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +/////////////////////////////////////////////////////////////////////////////// +// CLI parameter identifiers +/////////////////////////////////////////////////////////////////////////////// + +static const int CLI_PARAM_ADD_FILE = 0; +static const int CLI_PARAM_ADD_JOB = 1; +static const int CLI_PARAM_FORCE_START = 2; +static const int CLI_PARAM_NO_FORCE_START = 3; +static const int CLI_PARAM_FORCE_ENQUEUE = 4; +static const int CLI_PARAM_NO_FORCE_ENQUEUE = 5; +static const int CLI_PARAM_SKIP_AVS_CHECK = 6; +static const int CLI_PARAM_SKIP_VPS_CHECK = 7; +static const int CLI_PARAM_SKIP_X264_CHECK = 8; +static const int CLI_PARAM_FORCE_CPU_NO_X64 = 9; +static const int CLI_PARAM_NO_DEADLOCK = 10; +static const int CLI_PARAM_DEBUG_CONSOLE = 11; +static const int CLI_PARAM_NO_DEBUG_CONSOLE = 12; +static const int CLI_PARAM_NO_GUI_STYLE = 13; + +/////////////////////////////////////////////////////////////////////////////// +// CLI Parser +/////////////////////////////////////////////////////////////////////////////// + +class CLIParser +{ +public: + CLIParser(const QStringList &args); + ~CLIParser(void); + + bool nextOption(int &identifier, QStringList *options = NULL); + + static bool checkFlag(const int &identifier, const QStringList &args); + static const char *identifier2string(const int &identifier); + +protected: + const QStringList &m_args; + QStringList::ConstIterator m_iter; +}; diff --git a/src/main.cpp b/src/main.cpp index bdf9b9e..f2da7ec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,7 @@ #include "global.h" #include "win_main.h" +#include "cli.h" #include "ipc.h" #include "taskbar7.h" @@ -35,7 +36,7 @@ #include //Forward declaration -void handleMultipleInstances(QStringList args, IPC *ipc); +void handleMultipleInstances(const QStringList &args, IPC *ipc); /////////////////////////////////////////////////////////////////////////////// // Main function @@ -134,67 +135,43 @@ static int x264_main(int argc, char* argv[]) // Multi-instance handler /////////////////////////////////////////////////////////////////////////////// -void handleMultipleInstances(QStringList args, IPC *ipc) +void handleMultipleInstances(const QStringList &args, IPC *ipc) { bool commandSent = false; unsigned int flags = 0; - //Skip the program file name - args.takeFirst(); + //Initialize command-line parser + CLIParser parser(args); + int identifier; + QStringList options; //Process all command-line arguments - while(!args.isEmpty()) + while(parser.nextOption(identifier, &options)) { - const QString current = args.takeFirst(); - if(X264_STRCMP(current, "--add") || X264_STRCMP(current, "--add-file")) + switch(identifier) { + case CLI_PARAM_ADD_FILE: + ipc->sendAsync(IPC_OPCODE_ADD_FILE, options, flags); commandSent = true; - if(!args.isEmpty()) - { - if(!ipc->sendAsync(IPC_OPCODE_ADD_FILE, QStringList() << args.takeFirst())) - { - break; - } - } - else - { - qWarning("Argument for '--add-file' is missing!"); - } - } - else if(X264_STRCMP(current, "--add-job")) - { - commandSent = true; - if(args.size() >= 3) - { - const QStringList list = args.mid(0, 3); - args.erase(args.begin(), args.begin() + 3); - if(!ipc->sendAsync(IPC_OPCODE_ADD_JOB, list, flags)) - { - break; - } - } - else - { - qWarning("Argument(s) for '--add-job' are missing!"); - args.clear(); - } - } - else if(X264_STRCMP(current, "--force-start") || X264_STRCMP(current, "--no-force-start")) - { - const bool bEnabled = X264_STRCMP(current, "--force-start"); - flags = bEnabled ? (flags | IPC_FLAG_FORCE_START) : (flags & (~IPC_FLAG_FORCE_START)); - if(bEnabled) flags = flags & (~IPC_FLAG_FORCE_ENQUEUE); - } - else if(X264_STRCMP(current, "--force-enqueue") || X264_STRCMP(current, "--no-force-enqueue")) - { - const bool bEnabled = X264_STRCMP(current, "--force-enqueue"); - flags = bEnabled ? (flags | IPC_FLAG_FORCE_ENQUEUE) : (flags & (~IPC_FLAG_FORCE_ENQUEUE)); - if(bEnabled) flags = flags & (~IPC_FLAG_FORCE_START); - } - else if(!current.startsWith("--")) - { - qWarning("Unknown argument: %s", current.toUtf8().constData()); break; + case CLI_PARAM_ADD_JOB: + ipc->sendAsync(IPC_OPCODE_ADD_JOB, options, flags); + commandSent = true; + break; + case CLI_PARAM_FORCE_START: + flags = ((flags | IPC_FLAG_FORCE_START) & (~IPC_FLAG_FORCE_ENQUEUE)); + break; + case CLI_PARAM_NO_FORCE_START: + flags = (flags & (~IPC_FLAG_FORCE_START)); + break; + case CLI_PARAM_FORCE_ENQUEUE: + flags = ((flags | IPC_FLAG_FORCE_ENQUEUE) & (~IPC_FLAG_FORCE_START)); + break; + case CLI_PARAM_NO_FORCE_ENQUEUE: + flags = (flags & (~IPC_FLAG_FORCE_ENQUEUE)); + break; + default: + qWarning("Unknown command-line option!"); } } diff --git a/src/version.h b/src/version.h index 78fc625..b9b822c 100644 --- a/src/version.h +++ b/src/version.h @@ -26,7 +26,7 @@ #define VER_X264_MAJOR 2 #define VER_X264_MINOR 3 #define VER_X264_PATCH 0 -#define VER_X264_BUILD 740 +#define VER_X264_BUILD 743 #define VER_X264_MINIMUM_REV 2380 #define VER_X264_CURRENT_API 142 diff --git a/src/win_main.cpp b/src/win_main.cpp index 6380a8c..438ea87 100644 --- a/src/win_main.cpp +++ b/src/win_main.cpp @@ -23,6 +23,7 @@ #include "uic_win_main.h" #include "global.h" +#include "cli.h" #include "ipc.h" #include "model_status.h" #include "model_jobList.h" @@ -755,6 +756,7 @@ void MainWindow::init(void) return; } + const QStringList arguments = x264_arguments(); static const char *binFiles = "x86/x264_8bit_x86.exe:x64/x264_8bit_x64.exe:x86/x264_10bit_x86.exe:x64/x264_10bit_x64.exe:x86/avs2yuv_x86.exe:x64/avs2yuv_x64.exe"; QStringList binaries = QString::fromLatin1(binFiles).split(":", QString::SkipEmptyParts); @@ -833,21 +835,21 @@ void MainWindow::init(void) } //Skip version check (not recommended!) - if(qApp->arguments().contains("--skip-x264-version-check", Qt::CaseInsensitive)) + if(CLIParser::checkFlag(CLI_PARAM_SKIP_X264_CHECK, arguments)) { qWarning("x264 version check disabled, you have been warned!\n"); m_skipVersionTest = true; } //Don't abort encoding process on timeout (not recommended!) - if(qApp->arguments().contains("--no-deadlock-detection", Qt::CaseInsensitive)) + if(CLIParser::checkFlag(CLI_PARAM_NO_DEADLOCK, arguments)) { qWarning("Deadlock detection disabled, you have been warned!\n"); m_abortOnTimeout = false; } //Check for Avisynth support - if(!qApp->arguments().contains("--skip-avisynth-check", Qt::CaseInsensitive)) + if(!CLIParser::checkFlag(CLI_PARAM_SKIP_AVS_CHECK, arguments)) { qDebug("[Check for Avisynth support]"); volatile double avisynthVersion = 0.0; @@ -874,7 +876,7 @@ void MainWindow::init(void) } //Check for VapourSynth support - if(!qApp->arguments().contains("--skip-vapoursynth-check", Qt::CaseInsensitive)) + if(!CLIParser::checkFlag(CLI_PARAM_SKIP_VPS_CHECK, arguments)) { qDebug("[Check for VapourSynth support]"); volatile double avisynthVersion = 0.0; @@ -1498,58 +1500,39 @@ bool MainWindow::parseCommandLineArgs(void) { bool bCommandAccepted = false; unsigned int flags = 0; - - QStringList files; - QStringList args = x264_arguments(); - - args.takeFirst(); //Pop argv[0] - while(!args.isEmpty()) + //Initialize command-line parser + CLIParser parser(x264_arguments()); + int identifier; + QStringList options; + + //Process all command-line arguments + while(parser.nextOption(identifier, &options)) { - QString current = args.takeFirst(); - if(X264_STRCMP(current, "--add") || X264_STRCMP(current, "--add-file")) + switch(identifier) { + case CLI_PARAM_ADD_FILE: + handleCommand(IPC_OPCODE_ADD_FILE, options, flags); bCommandAccepted = true; - if(!args.isEmpty()) - { - handleCommand(IPC_OPCODE_ADD_FILE, QStringList() << args.takeFirst()); - } - else - { - qWarning("Argument for '--add-file' is missing!"); - } - } - else if(X264_STRCMP(current, "--add-job")) - { - bCommandAccepted = true; - if(args.size() >= 3) - { - const QStringList list = args.mid(0, 3); - args.erase(args.begin(), args.begin() + 3); - handleCommand(IPC_OPCODE_ADD_JOB, list, flags); - } - else - { - qWarning("Argument(s) for '--add-job' are missing!"); - args.clear(); - } - } - else if(X264_STRCMP(current, "--force-start") || X264_STRCMP(current, "--no-force-start")) - { - const bool bEnabled = X264_STRCMP(current, "--force-start"); - flags = bEnabled ? (flags | IPC_FLAG_FORCE_START) : (flags & (~IPC_FLAG_FORCE_START)); - if(bEnabled) flags = flags & (~IPC_FLAG_FORCE_ENQUEUE); - } - else if(X264_STRCMP(current, "--force-enqueue") || X264_STRCMP(current, "--no-force-enqueue")) - { - const bool bEnabled = X264_STRCMP(current, "--force-enqueue"); - flags = bEnabled ? (flags | IPC_FLAG_FORCE_ENQUEUE) : (flags & (~IPC_FLAG_FORCE_ENQUEUE)); - if(bEnabled) flags = flags & (~IPC_FLAG_FORCE_START); - } - else if(!current.startsWith("--")) - { - qWarning("Unknown argument: %s", current.toUtf8().constData()); break; + case CLI_PARAM_ADD_JOB: + handleCommand(IPC_OPCODE_ADD_JOB, options, flags); + bCommandAccepted = true; + break; + case CLI_PARAM_FORCE_START: + flags = ((flags | IPC_FLAG_FORCE_START) & (~IPC_FLAG_FORCE_ENQUEUE)); + break; + case CLI_PARAM_NO_FORCE_START: + flags = (flags & (~IPC_FLAG_FORCE_START)); + break; + case CLI_PARAM_FORCE_ENQUEUE: + flags = ((flags | IPC_FLAG_FORCE_ENQUEUE) & (~IPC_FLAG_FORCE_START)); + break; + case CLI_PARAM_NO_FORCE_ENQUEUE: + flags = (flags & (~IPC_FLAG_FORCE_ENQUEUE)); + break; + default: + qWarning("Unknown command-line option!"); } } diff --git a/x264_launcher_MSVC2013.vcxproj b/x264_launcher_MSVC2013.vcxproj index 5464f52..8c00474 100644 --- a/x264_launcher_MSVC2013.vcxproj +++ b/x264_launcher_MSVC2013.vcxproj @@ -294,6 +294,7 @@ copy /Y "$(QTDIR)\plugins\imageformats\qgif4.dll" "$(TargetDir)\imageformats" + "$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\moc\moc_%(Filename).cpp" "%(FullPath)" @@ -364,6 +365,7 @@ copy /Y "$(QTDIR)\plugins\imageformats\qgif4.dll" "$(TargetDir)\imageformats" + diff --git a/x264_launcher_MSVC2013.vcxproj.filters b/x264_launcher_MSVC2013.vcxproj.filters index 14abe90..1891069 100644 --- a/x264_launcher_MSVC2013.vcxproj.filters +++ b/x264_launcher_MSVC2013.vcxproj.filters @@ -75,7 +75,7 @@ Header Files - + Header Files @@ -191,6 +191,9 @@ Generated Files + + Source Files + @@ -250,6 +253,9 @@ Header Files + + Header Files +