mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-30 13:24:05 +00:00
Add proper command line parsing (with quotes support) to programs and to the external audio player command line.
This commit is contained in:
parent
92e2317251
commit
d4b687e966
|
@ -3,17 +3,18 @@
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include "externalviewer.hh"
|
#include "externalviewer.hh"
|
||||||
|
#include "parsecmdline.hh"
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
ExternalViewer::ExternalViewer( QObject * parent, vector< char > const & data,
|
ExternalViewer::ExternalViewer( QObject * parent, vector< char > const & data,
|
||||||
QString const & extension,
|
QString const & extension,
|
||||||
QString const & viewerProgram_ )
|
QString const & viewerCmdLine_ )
|
||||||
throw( exCantCreateTempFile ):
|
throw( exCantCreateTempFile ):
|
||||||
QObject( parent ),
|
QObject( parent ),
|
||||||
tempFile( QDir::temp().filePath( QString( "gd-XXXXXXXX." ) + extension ) ),
|
tempFile( QDir::temp().filePath( QString( "gd-XXXXXXXX." ) + extension ) ),
|
||||||
viewer( this ),
|
viewer( this ),
|
||||||
viewerProgram( viewerProgram_ )
|
viewerCmdLine( viewerCmdLine_ )
|
||||||
{
|
{
|
||||||
if ( !tempFile.open() || tempFile.write( &data.front(), data.size() ) != data.size() )
|
if ( !tempFile.open() || tempFile.write( &data.front(), data.size() ) != data.size() )
|
||||||
throw exCantCreateTempFile();
|
throw exCantCreateTempFile();
|
||||||
|
@ -32,8 +33,17 @@ void ExternalViewer::start() throw( exCantRunViewer )
|
||||||
connect( &viewer, SIGNAL( error( QProcess::ProcessError ) ),
|
connect( &viewer, SIGNAL( error( QProcess::ProcessError ) ),
|
||||||
this, SLOT( deleteLater() ) );
|
this, SLOT( deleteLater() ) );
|
||||||
|
|
||||||
viewer.start( viewerProgram, QStringList( tempFileName ), QIODevice::NotOpen );
|
QStringList args = parseCommandLine( viewerCmdLine );
|
||||||
|
|
||||||
|
if ( !args.isEmpty() )
|
||||||
|
{
|
||||||
|
QString program = args.first();
|
||||||
|
args.pop_front();
|
||||||
|
args.push_back( tempFileName );
|
||||||
|
viewer.start( program, args, QIODevice::NotOpen );
|
||||||
if ( !viewer.waitForStarted() )
|
if ( !viewer.waitForStarted() )
|
||||||
throw exCantRunViewer( viewerProgram.toStdString() );
|
throw exCantRunViewer( viewerCmdLine.toUtf8().data() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw exCantRunViewer( tr( "the viewer program name is empty" ).toUtf8().data() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ class ExternalViewer: public QObject
|
||||||
|
|
||||||
QTemporaryFile tempFile;
|
QTemporaryFile tempFile;
|
||||||
QProcess viewer;
|
QProcess viewer;
|
||||||
QString viewerProgram;
|
QString viewerCmdLine;
|
||||||
QString tempFileName;
|
QString tempFileName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -27,7 +27,7 @@ public:
|
||||||
DEF_EX_STR( exCantRunViewer, "Couldn't run external viewer:", Ex )
|
DEF_EX_STR( exCantRunViewer, "Couldn't run external viewer:", Ex )
|
||||||
|
|
||||||
ExternalViewer( QObject * parent, std::vector< char > const & data,
|
ExternalViewer( QObject * parent, std::vector< char > const & data,
|
||||||
QString const & extension, QString const & viewerProgram )
|
QString const & extension, QString const & viewerCmdLine )
|
||||||
throw( exCantCreateTempFile );
|
throw( exCantCreateTempFile );
|
||||||
|
|
||||||
// Once this is called, the object will be deleted when it's done, even if
|
// Once this is called, the object will be deleted when it's done, even if
|
||||||
|
|
|
@ -157,7 +157,8 @@ HEADERS += folding.hh \
|
||||||
forvo.hh \
|
forvo.hh \
|
||||||
country.hh \
|
country.hh \
|
||||||
about.hh \
|
about.hh \
|
||||||
programs.hh
|
programs.hh \
|
||||||
|
parsecmdline.hh
|
||||||
FORMS += groups.ui \
|
FORMS += groups.ui \
|
||||||
dictgroupwidget.ui \
|
dictgroupwidget.ui \
|
||||||
mainwindow.ui \
|
mainwindow.ui \
|
||||||
|
@ -240,7 +241,8 @@ SOURCES += folding.cc \
|
||||||
forvo.cc \
|
forvo.cc \
|
||||||
country.cc \
|
country.cc \
|
||||||
about.cc \
|
about.cc \
|
||||||
programs.cc
|
programs.cc \
|
||||||
|
parsecmdline.cc
|
||||||
win32 {
|
win32 {
|
||||||
SOURCES += mouseover_win32/ThTypes.c
|
SOURCES += mouseover_win32/ThTypes.c
|
||||||
HEADERS += mouseover_win32/ThTypes.h
|
HEADERS += mouseover_win32/ThTypes.h
|
||||||
|
|
53
parsecmdline.cc
Normal file
53
parsecmdline.cc
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include "parsecmdline.hh"
|
||||||
|
|
||||||
|
QStringList parseCommandLine( QString const & commandLine )
|
||||||
|
{
|
||||||
|
// Parse arguments. Handle quotes correctly.
|
||||||
|
QStringList args;
|
||||||
|
bool openQuote = false;
|
||||||
|
bool possibleDoubleQuote = false;
|
||||||
|
bool startNew = true;
|
||||||
|
for( QString::const_iterator c = commandLine.begin(),
|
||||||
|
e = commandLine.end(); c != e; )
|
||||||
|
{
|
||||||
|
if ( *c == '"' && !possibleDoubleQuote )
|
||||||
|
{
|
||||||
|
++c;
|
||||||
|
if ( !openQuote )
|
||||||
|
{
|
||||||
|
openQuote = true;
|
||||||
|
if ( startNew )
|
||||||
|
{
|
||||||
|
args.push_back( QString() );
|
||||||
|
startNew = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
possibleDoubleQuote = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if ( possibleDoubleQuote && *c != '"' )
|
||||||
|
{
|
||||||
|
openQuote = false;
|
||||||
|
possibleDoubleQuote = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if ( *c == ' ' && !openQuote )
|
||||||
|
{
|
||||||
|
++c;
|
||||||
|
startNew = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( startNew )
|
||||||
|
{
|
||||||
|
args.push_back( QString() );
|
||||||
|
startNew = false;
|
||||||
|
}
|
||||||
|
args.last().push_back( *c++ );
|
||||||
|
possibleDoubleQuote = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
11
parsecmdline.hh
Normal file
11
parsecmdline.hh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef PARSECMDLINE_HH
|
||||||
|
#define PARSECMDLINE_HH
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
/// Given a command line (name of the executable with optional arguments),
|
||||||
|
/// separates-out the name and all the arguments into a list. Supports quotes
|
||||||
|
/// and double-quotes.
|
||||||
|
QStringList parseCommandLine( QString const & );
|
||||||
|
|
||||||
|
#endif // PARSECMDLINE_HH
|
|
@ -7,6 +7,7 @@
|
||||||
#include "htmlescape.hh"
|
#include "htmlescape.hh"
|
||||||
#include "utf8.hh"
|
#include "utf8.hh"
|
||||||
#include "wstring_qt.hh"
|
#include "wstring_qt.hh"
|
||||||
|
#include "parsecmdline.hh"
|
||||||
|
|
||||||
namespace Programs {
|
namespace Programs {
|
||||||
|
|
||||||
|
@ -105,7 +106,7 @@ ArticleRequest::ArticleRequest( QString const & word,
|
||||||
Config::Program const & prg_ ):
|
Config::Program const & prg_ ):
|
||||||
prg( prg_ ), process( this )
|
prg( prg_ ), process( this )
|
||||||
{
|
{
|
||||||
QStringList args = prg.commandLine.split( ' ', QString::SkipEmptyParts );
|
QStringList args = parseCommandLine( prg.commandLine );
|
||||||
|
|
||||||
if ( !args.empty() )
|
if ( !args.empty() )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue