Refactored command-line parser into a separate class. Consequently, eliminated a lot of redundant code in "main" and "win_main".

This commit is contained in:
LoRd_MuldeR 2014-02-01 19:19:06 +01:00
parent c899d1aa3f
commit b18d067d51
7 changed files with 285 additions and 105 deletions

149
src/cli.cpp Normal file
View File

@ -0,0 +1,149 @@
///////////////////////////////////////////////////////////////////////////////
// Simple x264 Launcher
// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
//
// 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;
}

63
src/cli.h Normal file
View File

@ -0,0 +1,63 @@
///////////////////////////////////////////////////////////////////////////////
// Simple x264 Launcher
// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
//
// 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 <QStringList>
///////////////////////////////////////////////////////////////////////////////
// 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;
};

View File

@ -21,6 +21,7 @@
#include "global.h" #include "global.h"
#include "win_main.h" #include "win_main.h"
#include "cli.h"
#include "ipc.h" #include "ipc.h"
#include "taskbar7.h" #include "taskbar7.h"
@ -35,7 +36,7 @@
#include <Windows.h> #include <Windows.h>
//Forward declaration //Forward declaration
void handleMultipleInstances(QStringList args, IPC *ipc); void handleMultipleInstances(const QStringList &args, IPC *ipc);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Main function // Main function
@ -134,67 +135,43 @@ static int x264_main(int argc, char* argv[])
// Multi-instance handler // Multi-instance handler
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void handleMultipleInstances(QStringList args, IPC *ipc) void handleMultipleInstances(const QStringList &args, IPC *ipc)
{ {
bool commandSent = false; bool commandSent = false;
unsigned int flags = 0; unsigned int flags = 0;
//Skip the program file name //Initialize command-line parser
args.takeFirst(); CLIParser parser(args);
int identifier;
QStringList options;
//Process all command-line arguments //Process all command-line arguments
while(!args.isEmpty()) while(parser.nextOption(identifier, &options))
{ {
const QString current = args.takeFirst(); switch(identifier)
if(X264_STRCMP(current, "--add") || X264_STRCMP(current, "--add-file"))
{ {
case CLI_PARAM_ADD_FILE:
ipc->sendAsync(IPC_OPCODE_ADD_FILE, options, flags);
commandSent = true; 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; 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!");
} }
} }

View File

@ -26,7 +26,7 @@
#define VER_X264_MAJOR 2 #define VER_X264_MAJOR 2
#define VER_X264_MINOR 3 #define VER_X264_MINOR 3
#define VER_X264_PATCH 0 #define VER_X264_PATCH 0
#define VER_X264_BUILD 740 #define VER_X264_BUILD 743
#define VER_X264_MINIMUM_REV 2380 #define VER_X264_MINIMUM_REV 2380
#define VER_X264_CURRENT_API 142 #define VER_X264_CURRENT_API 142

View File

@ -23,6 +23,7 @@
#include "uic_win_main.h" #include "uic_win_main.h"
#include "global.h" #include "global.h"
#include "cli.h"
#include "ipc.h" #include "ipc.h"
#include "model_status.h" #include "model_status.h"
#include "model_jobList.h" #include "model_jobList.h"
@ -755,6 +756,7 @@ void MainWindow::init(void)
return; 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"; 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); QStringList binaries = QString::fromLatin1(binFiles).split(":", QString::SkipEmptyParts);
@ -833,21 +835,21 @@ void MainWindow::init(void)
} }
//Skip version check (not recommended!) //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"); qWarning("x264 version check disabled, you have been warned!\n");
m_skipVersionTest = true; m_skipVersionTest = true;
} }
//Don't abort encoding process on timeout (not recommended!) //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"); qWarning("Deadlock detection disabled, you have been warned!\n");
m_abortOnTimeout = false; m_abortOnTimeout = false;
} }
//Check for Avisynth support //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]"); qDebug("[Check for Avisynth support]");
volatile double avisynthVersion = 0.0; volatile double avisynthVersion = 0.0;
@ -874,7 +876,7 @@ void MainWindow::init(void)
} }
//Check for VapourSynth support //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]"); qDebug("[Check for VapourSynth support]");
volatile double avisynthVersion = 0.0; volatile double avisynthVersion = 0.0;
@ -1498,58 +1500,39 @@ bool MainWindow::parseCommandLineArgs(void)
{ {
bool bCommandAccepted = false; bool bCommandAccepted = false;
unsigned int flags = 0; 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(); switch(identifier)
if(X264_STRCMP(current, "--add") || X264_STRCMP(current, "--add-file"))
{ {
case CLI_PARAM_ADD_FILE:
handleCommand(IPC_OPCODE_ADD_FILE, options, flags);
bCommandAccepted = true; 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; 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!");
} }
} }

View File

@ -294,6 +294,7 @@ copy /Y "$(QTDIR)\plugins\imageformats\qgif4.dll" "$(TargetDir)\imageformats"
<ClInclude Include="src\3rd_party\avisynth_c.h" /> <ClInclude Include="src\3rd_party\avisynth_c.h" />
<ClInclude Include="src\3rd_party\blake2.h" /> <ClInclude Include="src\3rd_party\blake2.h" />
<ClInclude Include="src\checksum.h" /> <ClInclude Include="src\checksum.h" />
<ClInclude Include="src\cli.h" />
<ClInclude Include="src\global.h" /> <ClInclude Include="src\global.h" />
<CustomBuild Include="src\model_jobList.h"> <CustomBuild Include="src\model_jobList.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\moc\moc_%(Filename).cpp" "%(FullPath)"</Command> <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\moc\moc_%(Filename).cpp" "%(FullPath)"</Command>
@ -364,6 +365,7 @@ copy /Y "$(QTDIR)\plugins\imageformats\qgif4.dll" "$(TargetDir)\imageformats"
<ClCompile Include="src\3rd_party\blake2.c" /> <ClCompile Include="src\3rd_party\blake2.c" />
<ClCompile Include="src\3rd_party\qtmain_win.cpp" /> <ClCompile Include="src\3rd_party\qtmain_win.cpp" />
<ClCompile Include="src\checksum.cpp" /> <ClCompile Include="src\checksum.cpp" />
<ClCompile Include="src\cli.cpp" />
<ClCompile Include="src\ipc.cpp" /> <ClCompile Include="src\ipc.cpp" />
<ClCompile Include="src\job_object.cpp" /> <ClCompile Include="src\job_object.cpp" />
<ClCompile Include="src\model_jobList.cpp" /> <ClCompile Include="src\model_jobList.cpp" />

View File

@ -75,7 +75,7 @@
<ClInclude Include="src\checksum.h"> <ClInclude Include="src\checksum.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\ipc.h"> <ClInclude Include="src\cli.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
@ -191,6 +191,9 @@
<ClCompile Include="tmp\moc\moc_ipc.cpp"> <ClCompile Include="tmp\moc\moc_ipc.cpp">
<Filter>Generated Files</Filter> <Filter>Generated Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\cli.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="src\win_main.h"> <CustomBuild Include="src\win_main.h">
@ -250,6 +253,9 @@
<CustomBuild Include="src\thread_updater.h"> <CustomBuild Include="src\thread_updater.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</CustomBuild> </CustomBuild>
<CustomBuild Include="src\ipc.h">
<Filter>Header Files</Filter>
</CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="x264_launcher.rc"> <ResourceCompile Include="x264_launcher.rc">