mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-23 20:14: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 "externalviewer.hh"
|
||||
#include "parsecmdline.hh"
|
||||
|
||||
using std::vector;
|
||||
|
||||
ExternalViewer::ExternalViewer( QObject * parent, vector< char > const & data,
|
||||
QString const & extension,
|
||||
QString const & viewerProgram_ )
|
||||
QString const & viewerCmdLine_ )
|
||||
throw( exCantCreateTempFile ):
|
||||
QObject( parent ),
|
||||
tempFile( QDir::temp().filePath( QString( "gd-XXXXXXXX." ) + extension ) ),
|
||||
viewer( this ),
|
||||
viewerProgram( viewerProgram_ )
|
||||
viewerCmdLine( viewerCmdLine_ )
|
||||
{
|
||||
if ( !tempFile.open() || tempFile.write( &data.front(), data.size() ) != data.size() )
|
||||
throw exCantCreateTempFile();
|
||||
|
@ -32,8 +33,17 @@ void ExternalViewer::start() throw( exCantRunViewer )
|
|||
connect( &viewer, SIGNAL( error( QProcess::ProcessError ) ),
|
||||
this, SLOT( deleteLater() ) );
|
||||
|
||||
viewer.start( viewerProgram, QStringList( tempFileName ), QIODevice::NotOpen );
|
||||
QStringList args = parseCommandLine( viewerCmdLine );
|
||||
|
||||
if ( !viewer.waitForStarted() )
|
||||
throw exCantRunViewer( viewerProgram.toStdString() );
|
||||
if ( !args.isEmpty() )
|
||||
{
|
||||
QString program = args.first();
|
||||
args.pop_front();
|
||||
args.push_back( tempFileName );
|
||||
viewer.start( program, args, QIODevice::NotOpen );
|
||||
if ( !viewer.waitForStarted() )
|
||||
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;
|
||||
QProcess viewer;
|
||||
QString viewerProgram;
|
||||
QString viewerCmdLine;
|
||||
QString tempFileName;
|
||||
|
||||
public:
|
||||
|
@ -27,7 +27,7 @@ public:
|
|||
DEF_EX_STR( exCantRunViewer, "Couldn't run external viewer:", Ex )
|
||||
|
||||
ExternalViewer( QObject * parent, std::vector< char > const & data,
|
||||
QString const & extension, QString const & viewerProgram )
|
||||
QString const & extension, QString const & viewerCmdLine )
|
||||
throw( exCantCreateTempFile );
|
||||
|
||||
// Once this is called, the object will be deleted when it's done, even if
|
||||
|
|
|
@ -157,7 +157,8 @@ HEADERS += folding.hh \
|
|||
forvo.hh \
|
||||
country.hh \
|
||||
about.hh \
|
||||
programs.hh
|
||||
programs.hh \
|
||||
parsecmdline.hh
|
||||
FORMS += groups.ui \
|
||||
dictgroupwidget.ui \
|
||||
mainwindow.ui \
|
||||
|
@ -240,7 +241,8 @@ SOURCES += folding.cc \
|
|||
forvo.cc \
|
||||
country.cc \
|
||||
about.cc \
|
||||
programs.cc
|
||||
programs.cc \
|
||||
parsecmdline.cc
|
||||
win32 {
|
||||
SOURCES += mouseover_win32/ThTypes.c
|
||||
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 "utf8.hh"
|
||||
#include "wstring_qt.hh"
|
||||
#include "parsecmdline.hh"
|
||||
|
||||
namespace Programs {
|
||||
|
||||
|
@ -105,7 +106,7 @@ ArticleRequest::ArticleRequest( QString const & word,
|
|||
Config::Program const & prg_ ):
|
||||
prg( prg_ ), process( this )
|
||||
{
|
||||
QStringList args = prg.commandLine.split( ' ', QString::SkipEmptyParts );
|
||||
QStringList args = parseCommandLine( prg.commandLine );
|
||||
|
||||
if ( !args.empty() )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue