diff --git a/generate_auto_job b/generate_auto_job index 2d9689df..333eb68f 100755 --- a/generate_auto_job +++ b/generate_auto_job @@ -32,30 +32,6 @@ def write_file(filename): os.rename(tmpfile, filename) -# QXXXQ -# These are trivial but not in main and so need a different config -# object. Some are in more than one table. -not_yet = set([ - 'accessibility', - 'allow-insecure', - 'annotate', - 'assemble', - 'cleartext-metadata', - 'extract', - 'force-R5', - 'force-V4', - 'form', - 'from', - 'modify', - 'modify-other', - 'print', - 'repeat', - 'rotate', - 'to', - 'use-aes', -]) - - class Main: SOURCES = [ whoami, @@ -447,8 +423,7 @@ class Main: for i, [kind, v] in flags.items(): self.options_without_help.add(f'--{i}') add_jdata(i, table_prefix or table) - # QXXXQ not_yet - if i in not_yet or config is None or i in o.get('manual', []): + if config is None or i in o.get('manual', []): identifier = self.to_identifier(i, arg_prefix, False) self.handle_flag(i, identifier, kind, v) else: diff --git a/include/qpdf/QPDFJob.hh b/include/qpdf/QPDFJob.hh index 6445665a..9f4a1e70 100644 --- a/include/qpdf/QPDFJob.hh +++ b/include/qpdf/QPDFJob.hh @@ -201,6 +201,22 @@ class QPDFJob Config& config; }; + class UOConfig + { + friend class QPDFJob; + friend class Config; + public: + QPDF_DLL UOConfig& path(char const* parameter); + +# include + + private: + UOConfig(Config&); + UOConfig(PagesConfig const&) = delete; + + Config& config; + }; + // Configuration is performed by calling methods XXX QXXXQ document class Config { @@ -210,6 +226,8 @@ class QPDFJob std::shared_ptr copyAttachmentsFrom(); std::shared_ptr addAttachment(); std::shared_ptr pages(); + std::shared_ptr overlay(); + std::shared_ptr underlay(); # include @@ -422,16 +440,12 @@ class QPDFJob bool check_requires_password; std::shared_ptr infilename; std::shared_ptr outfilename; - - // Helper functions - void parseRotationParameter(std::string const&); - std::vector parseNumrange(char const* range, int max, - bool throw_error = false); - - // QXXXQ END-PUBLIC private: + // Helper functions + void parseRotationParameter(std::string const&); + std::vector parseNumrange(char const* range, int max); // Basic file processing std::shared_ptr processFile( diff --git a/include/qpdf/auto_job_c_main.hh b/include/qpdf/auto_job_c_main.hh index 09b1ed83..eb0f18be 100644 --- a/include/qpdf/auto_job_c_main.hh +++ b/include/qpdf/auto_job_c_main.hh @@ -65,6 +65,7 @@ QPDF_DLL Config& oiMinWidth(char const* parameter); QPDF_DLL Config& password(char const* parameter); QPDF_DLL Config& passwordFile(char const* parameter); QPDF_DLL Config& removeAttachment(char const* parameter); +QPDF_DLL Config& rotate(char const* parameter); QPDF_DLL Config& showAttachment(char const* parameter); QPDF_DLL Config& showObject(char const* parameter); QPDF_DLL Config& compressStreams(char const* parameter); diff --git a/include/qpdf/auto_job_c_uo.hh b/include/qpdf/auto_job_c_uo.hh new file mode 100644 index 00000000..39b54511 --- /dev/null +++ b/include/qpdf/auto_job_c_uo.hh @@ -0,0 +1,10 @@ +// +// This file is automatically generated by generate_auto_job. +// Edits will be automatically overwritten if the build is +// run in maintainer mode. +// +QPDF_DLL Config& end(); +QPDF_DLL UOConfig& to(char const* parameter); +QPDF_DLL UOConfig& from(char const* parameter); +QPDF_DLL UOConfig& repeat(char const* parameter); +QPDF_DLL UOConfig& password(char const* parameter); diff --git a/job.sums b/job.sums index 8ccba12d..3a4953a1 100644 --- a/job.sums +++ b/job.sums @@ -1,13 +1,14 @@ # Generated by generate_auto_job -generate_auto_job d41f3092545906dcd9a82f88ff41939bf695a36ecaebfe8559c66bd92b7416fb +generate_auto_job 7a539a822d332e33e08495a82a3fb86ceed2da2bb92ca492dd7ed888d226ab6a include/qpdf/auto_job_c_att.hh ecc3f8f711b486b491e811176362a90c022eb225ff12157df3a10ca021be87b1 include/qpdf/auto_job_c_copy_att.hh caffae3d1faf2cd92a07ba77da638cce31da3e074a047918834195c0f3ed508a -include/qpdf/auto_job_c_main.hh 1e060e9dd2029d21b29fed03e3a1e62164050b43684bd7434cc9e9707f73150d +include/qpdf/auto_job_c_main.hh 7f7c0a4d8e640a2d24908af348f7b658ca81d3d8aa5346cf4327f6c1d4021119 include/qpdf/auto_job_c_pages.hh 79ee6e52a36fedfd0e6ca60bd926bc25a3e975ab6fa984a7e798a48791e8ba86 -job.yml 4cd60df0caa74b68cc39352910a8381c3411248bc3edef69f9d16d75e807f451 -libqpdf/qpdf/auto_job_decl.hh f9f2a605fb8b5fed9b74c4cd07c07c3cdee60e2628d082250810c8074d5acd83 +include/qpdf/auto_job_c_uo.hh 80404376f19fe57d67421ad0c5fb1755811758c73870df96f081f032b196deff +job.yml 1f508cb7108c55885fbe98537676573bbfddf7b476b2023fd10a975d47afc037 +libqpdf/qpdf/auto_job_decl.hh dc9232ed6961d709abacbbf71eb7d19c5e6951894aec6f480afcd3b6ba463206 libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538 -libqpdf/qpdf/auto_job_init.hh b776c87e61d56842f23cb46fb6d4e44f5740e64854844bcc454fd812f7b4f8d5 +libqpdf/qpdf/auto_job_init.hh 25a93a4ded91e1faa2d6a9d2bb85d811b5b49ae54c9fbdccad65b94538365418 libqpdf/qpdf/auto_job_schema.hh 6e6d72e99dacd02c22d9ac70f4dc78a935f879d2a16c89f07f2bdfa936cc2ae3 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1 diff --git a/job.yml b/job.yml index 1b379e3d..6547a820 100644 --- a/job.yml +++ b/job.yml @@ -205,6 +205,7 @@ options: - force-R5 - allow-insecure - table: underlay/overlay + config: c_uo prefix: UO positional: true required_parameter: diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 85df861b..025b7224 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -507,7 +507,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter) bool range_valid = false; try { - parseNumrange(range.c_str(), 0, true); + QUtil::parse_numrange(range.c_str(), 0); range_valid = true; } catch (std::runtime_error const&) @@ -532,7 +532,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter) } std::vector -QPDFJob::parseNumrange(char const* range, int max, bool throw_error) +QPDFJob::parseNumrange(char const* range, int max) { try { @@ -540,14 +540,7 @@ QPDFJob::parseNumrange(char const* range, int max, bool throw_error) } catch (std::runtime_error& e) { - if (throw_error) - { - throw(e); - } - else - { - throw ConfigError(e.what()); - } + throw ConfigError(e.what()); } return std::vector(); } diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index 7cd8e22e..d2b38211 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -36,7 +36,6 @@ namespace void usage(std::string const& message); void initOptionTables(); void doFinalChecks(); - void parseUnderOverlayOptions(QPDFJob::UnderOverlay*); QPDFArgParser ap; QPDFJob& o; @@ -44,6 +43,7 @@ namespace std::shared_ptr c_copy_att; std::shared_ptr c_att; std::shared_ptr c_pages; + std::shared_ptr c_uo; std::vector accumulated_args; // points to member in ap char* pages_password; }; @@ -321,7 +321,7 @@ ArgParser::argPagesPositional(char* arg) { try { - o.parseNumrange(range, 0, true); + QUtil::parse_numrange(range, 0); } catch (std::runtime_error& e1) { @@ -369,19 +369,15 @@ ArgParser::argEndPages() void ArgParser::argUnderlay() { - parseUnderOverlayOptions(&o.underlay); + this->c_uo = c_main->underlay(); + this->ap.selectOptionTable(O_UNDERLAY_OVERLAY); } void ArgParser::argOverlay() { - parseUnderOverlayOptions(&o.overlay); -} - -void -ArgParser::argRotate(char* parameter) -{ - o.parseRotationParameter(parameter); + this->c_uo = c_main->overlay(); + this->ap.selectOptionTable(O_UNDERLAY_OVERLAY); } void @@ -576,57 +572,14 @@ ArgParser::argEnd256BitEncryption() void ArgParser::argUOPositional(char* arg) { - if (! o.under_overlay->filename.empty()) - { - usage(o.under_overlay->which + " file already specified"); - } - else - { - o.under_overlay->filename = arg; - } -} - -void -ArgParser::argUOTo(char* parameter) -{ - o.parseNumrange(parameter, 0); - o.under_overlay->to_nr = parameter; -} - -void -ArgParser::argUOFrom(char* parameter) -{ - if (strlen(parameter)) - { - o.parseNumrange(parameter, 0); - } - o.under_overlay->from_nr = parameter; -} - -void -ArgParser::argUORepeat(char* parameter) -{ - if (strlen(parameter)) - { - o.parseNumrange(parameter, 0); - } - o.under_overlay->repeat_nr = parameter; -} - -void -ArgParser::argUOPassword(char* parameter) -{ - o.under_overlay->password = QUtil::make_shared_cstr(parameter); + c_uo->path(arg); } void ArgParser::argEndUnderlayOverlay() { - if (o.under_overlay->filename.empty()) - { - usage(o.under_overlay->which + " file not specified"); - } - o.under_overlay = 0; + c_uo->end(); + c_uo = nullptr; } void @@ -667,13 +620,6 @@ ArgParser::usage(std::string const& message) this->ap.usage(message); } -void -ArgParser::parseUnderOverlayOptions(QPDFJob::UnderOverlay* uo) -{ - o.under_overlay = uo; - this->ap.selectOptionTable(O_UNDERLAY_OVERLAY); -} - void ArgParser::parseOptions() { diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index 2110f005..c313c219 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -688,6 +688,13 @@ QPDFJob::Config::jobJsonFile(char const* parameter) return *this; } +QPDFJob::Config& +QPDFJob::Config::rotate(char const* parameter) +{ + o.parseRotationParameter(parameter); + return *this; +} + std::shared_ptr QPDFJob::Config::copyAttachmentsFrom() { @@ -875,3 +882,84 @@ QPDFJob::PagesConfig::pageSpec(std::string const& filename, QPDFJob::PageSpec(filename, password, range)); return *this; } + +std::shared_ptr +QPDFJob::Config::overlay() +{ + o.under_overlay = &o.overlay; + return std::shared_ptr(new UOConfig(*this)); +} + +std::shared_ptr +QPDFJob::Config::underlay() +{ + o.under_overlay = &o.underlay; + return std::shared_ptr(new UOConfig(*this)); +} + +QPDFJob::UOConfig::UOConfig(Config& c) : + config(c) +{ +} + +QPDFJob::Config& +QPDFJob::UOConfig::end() +{ + if (config.o.under_overlay->filename.empty()) + { + usage(config.o.under_overlay->which + " file not specified"); + } + config.o.under_overlay = 0; + return this->config; +} + +QPDFJob::UOConfig& +QPDFJob::UOConfig::path(char const* parameter) +{ + if (! config.o.under_overlay->filename.empty()) + { + usage(config.o.under_overlay->which + " file already specified"); + } + else + { + config.o.under_overlay->filename = parameter; + } + return *this; +} + +QPDFJob::UOConfig& +QPDFJob::UOConfig::to(char const* parameter) +{ + config.o.parseNumrange(parameter, 0); + config.o.under_overlay->to_nr = parameter; + return *this; +} + +QPDFJob::UOConfig& +QPDFJob::UOConfig::from(char const* parameter) +{ + if (strlen(parameter)) + { + config.o.parseNumrange(parameter, 0); + } + config.o.under_overlay->from_nr = parameter; + return *this; +} + +QPDFJob::UOConfig& +QPDFJob::UOConfig::repeat(char const* parameter) +{ + if (strlen(parameter)) + { + config.o.parseNumrange(parameter, 0); + } + config.o.under_overlay->repeat_nr = parameter; + return *this; +} + +QPDFJob::UOConfig& +QPDFJob::UOConfig::password(char const* parameter) +{ + config.o.under_overlay->password = QUtil::make_shared_cstr(parameter); + return *this; +} diff --git a/libqpdf/qpdf/auto_job_decl.hh b/libqpdf/qpdf/auto_job_decl.hh index d65df1d9..1dc3fef5 100644 --- a/libqpdf/qpdf/auto_job_decl.hh +++ b/libqpdf/qpdf/auto_job_decl.hh @@ -24,7 +24,6 @@ void argEncrypt(); void argOverlay(); void argPages(); void argUnderlay(); -void argRotate(char *); void argPagesPositional(char*); void argPagesPassword(char *); void argEndPages(); @@ -51,10 +50,6 @@ void argEnc256ForceR5(); void argEnc256AllowInsecure(); void argEnd256BitEncryption(); void argUOPositional(char*); -void argUOTo(char *); -void argUOFrom(char *); -void argUORepeat(char *); -void argUOPassword(char *); void argEndUnderlayOverlay(); void argAttPositional(char*); void argEndAttachment(); diff --git a/libqpdf/qpdf/auto_job_init.hh b/libqpdf/qpdf/auto_job_init.hh index bdf9cb0e..7c34e8b1 100644 --- a/libqpdf/qpdf/auto_job_init.hh +++ b/libqpdf/qpdf/auto_job_init.hh @@ -97,7 +97,7 @@ this->ap.addRequiredParameter("oi-min-width", [this](char *x){c_main->oiMinWidth this->ap.addRequiredParameter("password", [this](char *x){c_main->password(x);}, "password"); this->ap.addRequiredParameter("password-file", [this](char *x){c_main->passwordFile(x);}, "password"); this->ap.addRequiredParameter("remove-attachment", [this](char *x){c_main->removeAttachment(x);}, "attachment"); -this->ap.addRequiredParameter("rotate", p(&ArgParser::argRotate), "[+|-]angle"); +this->ap.addRequiredParameter("rotate", [this](char *x){c_main->rotate(x);}, "[+|-]angle"); this->ap.addRequiredParameter("show-attachment", [this](char *x){c_main->showAttachment(x);}, "attachment"); this->ap.addRequiredParameter("show-object", [this](char *x){c_main->showObject(x);}, "trailer"); this->ap.addChoices("compress-streams", [this](char *x){c_main->compressStreams(x);}, true, yn_choices); @@ -137,10 +137,10 @@ this->ap.addBare("force-R5", b(&ArgParser::argEnc256ForceR5)); this->ap.addBare("allow-insecure", b(&ArgParser::argEnc256AllowInsecure)); this->ap.registerOptionTable("underlay/overlay", b(&ArgParser::argEndUnderlayOverlay)); this->ap.addPositional(p(&ArgParser::argUOPositional)); -this->ap.addRequiredParameter("to", p(&ArgParser::argUOTo), "page-range"); -this->ap.addRequiredParameter("from", p(&ArgParser::argUOFrom), "page-range"); -this->ap.addRequiredParameter("repeat", p(&ArgParser::argUORepeat), "page-range"); -this->ap.addRequiredParameter("password", p(&ArgParser::argUOPassword), "password"); +this->ap.addRequiredParameter("to", [this](char *x){c_uo->to(x);}, "page-range"); +this->ap.addRequiredParameter("from", [this](char *x){c_uo->from(x);}, "page-range"); +this->ap.addRequiredParameter("repeat", [this](char *x){c_uo->repeat(x);}, "page-range"); +this->ap.addRequiredParameter("password", [this](char *x){c_uo->password(x);}, "password"); this->ap.registerOptionTable("attachment", b(&ArgParser::argEndAttachment)); this->ap.addPositional(p(&ArgParser::argAttPositional)); this->ap.addBare("replace", [this](){c_att->replace();});