mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-23 03:18:59 +00:00
Slightly improve bash completion arg parsing
This commit is contained in:
parent
6b90f3db4d
commit
52a0b767c8
67
qpdf/qpdf.cc
67
qpdf/qpdf.cc
@ -1414,32 +1414,87 @@ void
|
|||||||
ArgParser::handleBashArguments()
|
ArgParser::handleBashArguments()
|
||||||
{
|
{
|
||||||
// Do a minimal job of parsing bash_line into arguments. This
|
// Do a minimal job of parsing bash_line into arguments. This
|
||||||
// doesn't do everything the shell does, but it should be good
|
// doesn't do everything the shell does (e.g. $(...), variable
|
||||||
// enough for purposes of handling completion. We can't use
|
// expansion, arithmetic, globs, etc.), but it should be good
|
||||||
// new_argv because this has to interoperate with @file arguments.
|
// enough for purposes of handling completion. As we build up the
|
||||||
|
// new argv, we can't use this->new_argv because this code has to
|
||||||
|
// interoperate with @file arguments, so memory for both ways of
|
||||||
|
// fabricating argv has to be protected.
|
||||||
|
|
||||||
enum { st_top, st_quote } state = st_top;
|
bool last_was_backslash = false;
|
||||||
|
enum { st_top, st_squote, st_dquote } state = st_top;
|
||||||
std::string arg;
|
std::string arg;
|
||||||
for (std::string::iterator iter = bash_line.begin();
|
for (std::string::iterator iter = bash_line.begin();
|
||||||
iter != bash_line.end(); ++iter)
|
iter != bash_line.end(); ++iter)
|
||||||
{
|
{
|
||||||
char ch = (*iter);
|
char ch = (*iter);
|
||||||
if ((state == st_top) && QUtil::is_space(ch) && (! arg.empty()))
|
if (last_was_backslash)
|
||||||
|
{
|
||||||
|
arg.append(1, ch);
|
||||||
|
last_was_backslash = false;
|
||||||
|
}
|
||||||
|
else if (ch == '\\')
|
||||||
|
{
|
||||||
|
last_was_backslash = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool append = false;
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case st_top:
|
||||||
|
if (QUtil::is_space(ch))
|
||||||
|
{
|
||||||
|
if (! arg.empty())
|
||||||
{
|
{
|
||||||
bash_argv.push_back(
|
bash_argv.push_back(
|
||||||
PointerHolder<char>(
|
PointerHolder<char>(
|
||||||
true, QUtil::copy_string(arg.c_str())));
|
true, QUtil::copy_string(arg.c_str())));
|
||||||
arg.clear();
|
arg.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (ch == '"')
|
||||||
|
{
|
||||||
|
state = st_dquote;
|
||||||
|
}
|
||||||
|
else if (ch == '\'')
|
||||||
|
{
|
||||||
|
state = st_squote;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
append = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_squote:
|
||||||
|
if (ch == '\'')
|
||||||
|
{
|
||||||
|
state = st_top;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
append = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_dquote:
|
||||||
if (ch == '"')
|
if (ch == '"')
|
||||||
{
|
{
|
||||||
state = (state == st_top ? st_quote : st_top);
|
state = st_top;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
append = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (append)
|
||||||
|
{
|
||||||
arg.append(1, ch);
|
arg.append(1, ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (bash_argv.empty())
|
if (bash_argv.empty())
|
||||||
{
|
{
|
||||||
// This can't happen if properly invoked by bash, but ensure
|
// This can't happen if properly invoked by bash, but ensure
|
||||||
|
@ -117,6 +117,12 @@ my @completion_tests = (
|
|||||||
['qpdf --decode-lzzz', 15, 'decode-l'],
|
['qpdf --decode-lzzz', 15, 'decode-l'],
|
||||||
['qpdf --decode-level=', undef, 'decode-level'],
|
['qpdf --decode-level=', undef, 'decode-level'],
|
||||||
['qpdf --check -', undef, 'later-arg'],
|
['qpdf --check -', undef, 'later-arg'],
|
||||||
|
['qpdf infile outfile oops --ch', undef, 'usage-empty'],
|
||||||
|
['qpdf --encrypt \'user " password\' ', undef, 'quoting'],
|
||||||
|
['qpdf --encrypt \'user password\' ', undef, 'quoting'],
|
||||||
|
['qpdf --encrypt "user password" ', undef, 'quoting'],
|
||||||
|
['qpdf --encrypt "user pass\'word" ', undef, 'quoting'],
|
||||||
|
['qpdf --encrypt user\ password ', undef, 'quoting'],
|
||||||
);
|
);
|
||||||
$n_tests += scalar(@completion_tests);
|
$n_tests += scalar(@completion_tests);
|
||||||
foreach my $c (@completion_tests)
|
foreach my $c (@completion_tests)
|
||||||
|
1
qpdf/qtest/qpdf/completion-quoting.out
Normal file
1
qpdf/qtest/qpdf/completion-quoting.out
Normal file
@ -0,0 +1 @@
|
|||||||
|
owner-password
|
1
qpdf/qtest/qpdf/completion-usage-empty.out
Normal file
1
qpdf/qtest/qpdf/completion-usage-empty.out
Normal file
@ -0,0 +1 @@
|
|||||||
|
!--check
|
Loading…
Reference in New Issue
Block a user