summaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/QPDFArgParser.cc84
-rw-r--r--libqpdf/QPDFJob_argv.cc3
-rw-r--r--libqpdf/qpdf/auto_job_decl.hh1
-rw-r--r--libqpdf/qpdf/auto_job_init.hh47
4 files changed, 74 insertions, 61 deletions
diff --git a/libqpdf/QPDFArgParser.cc b/libqpdf/QPDFArgParser.cc
index a24b00eb..f32b8759 100644
--- a/libqpdf/QPDFArgParser.cc
+++ b/libqpdf/QPDFArgParser.cc
@@ -35,6 +35,9 @@ QPDFArgParser::QPDFArgParser(int argc, char* argv[], char const* progname_env) :
m(new Members(argc, argv, progname_env))
{
selectHelpOptionTable();
+ char const* help_choices[] = {"all", 0};
+ addChoices(
+ "help", bindParam(&QPDFArgParser::argHelp, this), false, help_choices);
addBare("completion-bash",
std::bind(std::mem_fn(&QPDFArgParser::argCompletionBash), this));
addBare("completion-zsh",
@@ -139,13 +142,14 @@ QPDFArgParser::addOptionalParameter(
}
void
-QPDFArgParser::addRequiredChoices(
+QPDFArgParser::addChoices(
std::string const& arg,
param_arg_handler_t handler,
+ bool required,
char const** choices)
{
OptionEntry& oe = registerArg(arg);
- oe.parameter_needed = true;
+ oe.parameter_needed = required;
oe.param_arg_handler = handler;
for (char const** i = choices; *i; ++i)
{
@@ -254,6 +258,12 @@ QPDFArgParser::argCompletionZsh()
}
void
+QPDFArgParser::argHelp(char*)
+{
+ // QXXXQ
+}
+
+void
QPDFArgParser::handleArgFileArguments()
{
// Support reading arguments from files. Create a new argv. Ensure
@@ -624,10 +634,9 @@ QPDFArgParser::parseArgs()
}
OptionEntry& oe = oep->second;
- if ((oe.parameter_needed && (0 == parameter)) ||
- ((! oe.choices.empty() &&
- ((0 == parameter) ||
- (0 == oe.choices.count(parameter))))))
+ if ((oe.parameter_needed && (nullptr == parameter)) ||
+ ((! oe.choices.empty() && (nullptr != parameter) &&
+ (0 == oe.choices.count(parameter)))))
{
std::string message =
"--" + arg_s + " must be given as --" + arg_s + "=";
@@ -708,12 +717,13 @@ QPDFArgParser::doFinalChecks()
}
void
-QPDFArgParser::addChoicesToCompletions(std::string const& option,
+QPDFArgParser::addChoicesToCompletions(option_table_t& option_table,
+ std::string const& option,
std::string const& extra_prefix)
{
- if (this->m->option_table->count(option) != 0)
+ if (option_table.count(option) != 0)
{
- OptionEntry& oe = (*this->m->option_table)[option];
+ OptionEntry& oe = option_table[option];
for (std::set<std::string>::iterator iter = oe.choices.begin();
iter != oe.choices.end(); ++iter)
{
@@ -724,18 +734,16 @@ QPDFArgParser::addChoicesToCompletions(std::string const& option,
}
void
-QPDFArgParser::addOptionsToCompletions()
+QPDFArgParser::addOptionsToCompletions(option_table_t& option_table)
{
- for (std::map<std::string, OptionEntry>::iterator iter =
- this->m->option_table->begin();
- iter != this->m->option_table->end(); ++iter)
+ for (auto& iter: option_table)
{
- std::string const& arg = (*iter).first;
+ std::string const& arg = iter.first;
if (arg == "--")
{
continue;
}
- OptionEntry& oe = (*iter).second;
+ OptionEntry& oe = iter.second;
std::string base = "--" + arg;
if (oe.param_arg_handler)
{
@@ -743,7 +751,7 @@ QPDFArgParser::addOptionsToCompletions()
{
// zsh doesn't treat = as a word separator, so add all
// the options so we don't get a space after the =.
- addChoicesToCompletions(arg, base + "=");
+ addChoicesToCompletions(option_table, arg, base + "=");
}
this->m->completions.insert(base + "=");
}
@@ -755,6 +763,22 @@ QPDFArgParser::addOptionsToCompletions()
}
void
+QPDFArgParser::insertCompletions(option_table_t& option_table,
+ std::string const& choice_option,
+ std::string const& extra_prefix)
+{
+ if (! choice_option.empty())
+ {
+ addChoicesToCompletions(option_table, choice_option, extra_prefix);
+ }
+ else if ((! this->m->bash_cur.empty()) &&
+ (this->m->bash_cur.at(0) == '-'))
+ {
+ addOptionsToCompletions(option_table);
+ }
+}
+
+void
QPDFArgParser::handleCompletion()
{
std::string extra_prefix;
@@ -795,29 +819,17 @@ QPDFArgParser::handleCompletion()
}
}
}
- if (! choice_option.empty())
+ if (this->m->zsh_completion && (! choice_option.empty()))
{
- if (this->m->zsh_completion)
- {
- // zsh wants --option=choice rather than just choice
- extra_prefix = "--" + choice_option + "=";
- }
- addChoicesToCompletions(choice_option, extra_prefix);
+ // zsh wants --option=choice rather than just choice
+ extra_prefix = "--" + choice_option + "=";
}
- else if ((! this->m->bash_cur.empty()) &&
- (this->m->bash_cur.at(0) == '-'))
+ insertCompletions(*this->m->option_table, choice_option, extra_prefix);
+ if (this->m->argc == 1)
{
- addOptionsToCompletions();
- if (this->m->argc == 1)
- {
- // Help options are valid only by themselves.
- for (std::map<std::string, OptionEntry>::iterator iter =
- this->m->help_option_table.begin();
- iter != this->m->help_option_table.end(); ++iter)
- {
- this->m->completions.insert("--" + (*iter).first);
- }
- }
+ // Help options are valid only by themselves.
+ insertCompletions(
+ this->m->help_option_table, choice_option, extra_prefix);
}
}
std::string prefix = extra_prefix + this->m->bash_cur;
diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc
index 0cf12cd4..9b678257 100644
--- a/libqpdf/QPDFJob_argv.cc
+++ b/libqpdf/QPDFJob_argv.cc
@@ -127,9 +127,11 @@ ArgParser::argCopyright()
<< std::endl;
}
+#if 0
void
ArgParser::argHelp()
{
+ // QXXXQ
std::cout
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
<< "Usage: qpdf [options] {infile | --empty} [page_selection_options] outfile\n"
@@ -630,6 +632,7 @@ ArgParser::argHelp()
<< "qpdf to completely ignore warnings. qpdf does not use exit status 1,\n"
<< "since that is used by the shell if it can't execute qpdf.\n";
}
+#endif
void
ArgParser::argJsonHelp()
diff --git a/libqpdf/qpdf/auto_job_decl.hh b/libqpdf/qpdf/auto_job_decl.hh
index 076a8f68..1f2b4263 100644
--- a/libqpdf/qpdf/auto_job_decl.hh
+++ b/libqpdf/qpdf/auto_job_decl.hh
@@ -12,7 +12,6 @@ static constexpr char const* O_UNDERLAY_OVERLAY = "underlay/overlay";
static constexpr char const* O_ATTACHMENT = "attachment";
static constexpr char const* O_COPY_ATTACHMENT = "copy attachment";
-void argHelp();
void argVersion();
void argCopyright();
void argJsonHelp();
diff --git a/libqpdf/qpdf/auto_job_init.hh b/libqpdf/qpdf/auto_job_init.hh
index 8566312f..3d7cdd7b 100644
--- a/libqpdf/qpdf/auto_job_init.hh
+++ b/libqpdf/qpdf/auto_job_init.hh
@@ -22,7 +22,6 @@ char const* print128_choices[] = {"full", "low", "none", 0};
char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
this->ap.selectHelpOptionTable();
-this->ap.addBare("help", b(&ArgParser::argHelp));
this->ap.addBare("version", b(&ArgParser::argVersion));
this->ap.addBare("copyright", b(&ArgParser::argCopyright));
this->ap.addBare("json-help", b(&ArgParser::argJsonHelp));
@@ -99,38 +98,38 @@ this->ap.addRequiredParameter("remove-attachment", p(&ArgParser::argRemoveAttach
this->ap.addRequiredParameter("rotate", p(&ArgParser::argRotate), "[+|-]angle");
this->ap.addRequiredParameter("show-attachment", p(&ArgParser::argShowAttachment), "attachment");
this->ap.addRequiredParameter("show-object", p(&ArgParser::argShowObject), "trailer");
-this->ap.addRequiredChoices("compress-streams", p(&ArgParser::argCompressStreams), yn_choices);
-this->ap.addRequiredChoices("decode-level", p(&ArgParser::argDecodeLevel), decode_level_choices);
-this->ap.addRequiredChoices("flatten-annotations", p(&ArgParser::argFlattenAnnotations), flatten_choices);
-this->ap.addRequiredChoices("json-key", p(&ArgParser::argJsonKey), json_key_choices);
-this->ap.addRequiredChoices("keep-files-open", p(&ArgParser::argKeepFilesOpen), yn_choices);
-this->ap.addRequiredChoices("normalize-content", p(&ArgParser::argNormalizeContent), yn_choices);
-this->ap.addRequiredChoices("object-streams", p(&ArgParser::argObjectStreams), object_streams_choices);
-this->ap.addRequiredChoices("password-mode", p(&ArgParser::argPasswordMode), password_mode_choices);
-this->ap.addRequiredChoices("remove-unreferenced-resources", p(&ArgParser::argRemoveUnreferencedResources), remove_unref_choices);
-this->ap.addRequiredChoices("stream-data", p(&ArgParser::argStreamData), stream_data_choices);
+this->ap.addChoices("compress-streams", p(&ArgParser::argCompressStreams), true, yn_choices);
+this->ap.addChoices("decode-level", p(&ArgParser::argDecodeLevel), true, decode_level_choices);
+this->ap.addChoices("flatten-annotations", p(&ArgParser::argFlattenAnnotations), true, flatten_choices);
+this->ap.addChoices("json-key", p(&ArgParser::argJsonKey), true, json_key_choices);
+this->ap.addChoices("keep-files-open", p(&ArgParser::argKeepFilesOpen), true, yn_choices);
+this->ap.addChoices("normalize-content", p(&ArgParser::argNormalizeContent), true, yn_choices);
+this->ap.addChoices("object-streams", p(&ArgParser::argObjectStreams), true, object_streams_choices);
+this->ap.addChoices("password-mode", p(&ArgParser::argPasswordMode), true, password_mode_choices);
+this->ap.addChoices("remove-unreferenced-resources", p(&ArgParser::argRemoveUnreferencedResources), true, remove_unref_choices);
+this->ap.addChoices("stream-data", p(&ArgParser::argStreamData), true, stream_data_choices);
this->ap.registerOptionTable("pages", b(&ArgParser::argEndPages));
this->ap.addPositional(p(&ArgParser::argPagesPositional));
this->ap.addRequiredParameter("password", p(&ArgParser::argPagesPassword), "password");
this->ap.registerOptionTable("encryption", b(&ArgParser::argEndEncryption));
this->ap.addPositional(p(&ArgParser::argEncPositional));
this->ap.registerOptionTable("40-bit encryption", b(&ArgParser::argEnd40BitEncryption));
-this->ap.addRequiredChoices("extract", p(&ArgParser::argEnc40Extract), yn_choices);
-this->ap.addRequiredChoices("annotate", p(&ArgParser::argEnc40Annotate), yn_choices);
-this->ap.addRequiredChoices("print", p(&ArgParser::argEnc40Print), yn_choices);
-this->ap.addRequiredChoices("modify", p(&ArgParser::argEnc40Modify), yn_choices);
+this->ap.addChoices("extract", p(&ArgParser::argEnc40Extract), true, yn_choices);
+this->ap.addChoices("annotate", p(&ArgParser::argEnc40Annotate), true, yn_choices);
+this->ap.addChoices("print", p(&ArgParser::argEnc40Print), true, yn_choices);
+this->ap.addChoices("modify", p(&ArgParser::argEnc40Modify), true, yn_choices);
this->ap.registerOptionTable("128-bit encryption", b(&ArgParser::argEnd128BitEncryption));
this->ap.addBare("cleartext-metadata", b(&ArgParser::argEnc128CleartextMetadata));
this->ap.addBare("force-V4", b(&ArgParser::argEnc128ForceV4));
-this->ap.addRequiredChoices("accessibility", p(&ArgParser::argEnc128Accessibility), yn_choices);
-this->ap.addRequiredChoices("extract", p(&ArgParser::argEnc128Extract), yn_choices);
-this->ap.addRequiredChoices("print", p(&ArgParser::argEnc128Print), print128_choices);
-this->ap.addRequiredChoices("assemble", p(&ArgParser::argEnc128Assemble), yn_choices);
-this->ap.addRequiredChoices("annotate", p(&ArgParser::argEnc128Annotate), yn_choices);
-this->ap.addRequiredChoices("form", p(&ArgParser::argEnc128Form), yn_choices);
-this->ap.addRequiredChoices("modify-other", p(&ArgParser::argEnc128ModifyOther), yn_choices);
-this->ap.addRequiredChoices("modify", p(&ArgParser::argEnc128Modify), modify128_choices);
-this->ap.addRequiredChoices("use-aes", p(&ArgParser::argEnc128UseAes), yn_choices);
+this->ap.addChoices("accessibility", p(&ArgParser::argEnc128Accessibility), true, yn_choices);
+this->ap.addChoices("extract", p(&ArgParser::argEnc128Extract), true, yn_choices);
+this->ap.addChoices("print", p(&ArgParser::argEnc128Print), true, print128_choices);
+this->ap.addChoices("assemble", p(&ArgParser::argEnc128Assemble), true, yn_choices);
+this->ap.addChoices("annotate", p(&ArgParser::argEnc128Annotate), true, yn_choices);
+this->ap.addChoices("form", p(&ArgParser::argEnc128Form), true, yn_choices);
+this->ap.addChoices("modify-other", p(&ArgParser::argEnc128ModifyOther), true, yn_choices);
+this->ap.addChoices("modify", p(&ArgParser::argEnc128Modify), true, modify128_choices);
+this->ap.addChoices("use-aes", p(&ArgParser::argEnc128UseAes), true, yn_choices);
this->ap.registerOptionTable("256-bit encryption", b(&ArgParser::argEnd256BitEncryption));
this->ap.addBare("force-R5", b(&ArgParser::argEnc256ForceR5));
this->ap.addBare("allow-insecure", b(&ArgParser::argEnc256AllowInsecure));