diff --git a/generate_auto_job b/generate_auto_job index 7a2b97b0..4adac176 100755 --- a/generate_auto_job +++ b/generate_auto_job @@ -71,7 +71,6 @@ not_yet = set([ 'password', 'password-file', 'password-mode', - 'prefix', 'print', 'remove-unreferenced-resources', 'repeat', @@ -326,26 +325,26 @@ class Main: self.update_hashes() # DON'T ADD CODE TO generate AFTER update_hashes - def handle_trivial(self, i, identifier, config, kind, v): + def handle_trivial(self, i, identifier, cfg, kind, v): # QXXXQ could potentially generate declarations for config # methods separately by config object if kind == 'bare': self.init.append(f'this->ap.addBare("{i}", ' - f'[this](){{{config}.{identifier}();}});') + f'[this](){{{cfg}->{identifier}();}});') elif kind == 'optional_parameter': self.init.append(f'this->ap.addOptionalParameter("{i}", ' - f'[this](char *x){{{config}.{identifier}(x);}});') + f'[this](char *x){{{cfg}->{identifier}(x);}});') elif kind == 'required_parameter': self.init.append(f'this->ap.addRequiredParameter("{i}", ' - f'[this](char *x){{{config}.{identifier}(x);}}' + f'[this](char *x){{{cfg}->{identifier}(x);}}' f', "{v}");') elif kind == 'required_choices': self.init.append(f'this->ap.addChoices("{i}", ' - f'[this](char *x){{{config}.{identifier}(x);}}' + f'[this](char *x){{{cfg}->{identifier}(x);}}' f', true, {v}_choices);') elif kind == 'optional_choices': self.init.append(f'this->ap.addChoices("{i}", ' - f'[this](char *x){{{config}.{identifier}(x);}}' + f'[this](char *x){{{cfg}->{identifier}(x);}}' f', false, {v}_choices);') def handle_flag(self, i, identifier, kind, v): diff --git a/include/qpdf/QPDFJob.hh b/include/qpdf/QPDFJob.hh index c76d85cc..a4be63e9 100644 --- a/include/qpdf/QPDFJob.hh +++ b/include/qpdf/QPDFJob.hh @@ -100,11 +100,44 @@ class QPDFJob // CONFIGURATION // (implemented in QPDFJob_config.cc) + private: + struct CopyAttachmentFrom + { + std::string path; + std::string password; + std::string prefix; + }; + + public: + class Config; + class CopyAttConfig + { + friend class QPDFJob; + friend class Config; + public: + QPDF_DLL CopyAttConfig& filename(char const* parameter); + // QXXXQ auto + QPDF_DLL CopyAttConfig& prefix(char const* parameter); + QPDF_DLL CopyAttConfig& password(char const* parameter); + QPDF_DLL Config& end(); + // /QXXXQ + + private: + CopyAttConfig(Config&); + CopyAttConfig(CopyAttConfig const&) = delete; + + Config& config; + CopyAttachmentFrom caf; + }; + // Configuration is performed by calling methods XXX QXXXQ document class Config { friend class QPDFJob; public: + QPDF_DLL + std::shared_ptr copyAttachmentsFrom(); + // QXXXQ could potentially generate these declarations QPDF_DLL Config& allowWeakCrypto(); QPDF_DLL Config& check(); @@ -171,9 +204,11 @@ class QPDFJob QPDF_DLL Config& verbose(); QPDF_DLL Config& warningExit0(); QPDF_DLL Config& withImages(); + // /QXXXQ private: Config() = delete; + Config(Config const&) = delete; Config(QPDFJob& job) : o(job) { @@ -183,7 +218,7 @@ class QPDFJob friend class Config; QPDF_DLL - Config config(); + std::shared_ptr config(); // QXXXQ set options -- implemented in QPDFJob_options.cc @@ -295,13 +330,6 @@ class QPDFJob bool replace; }; - struct CopyAttachmentFrom - { - std::string path; - std::string password; - std::string prefix; - }; - enum remove_unref_e { re_auto, re_yes, re_no }; std::shared_ptr password; diff --git a/job.sums b/job.sums index 5fa7c399..eddd8750 100644 --- a/job.sums +++ b/job.sums @@ -1,9 +1,9 @@ # Generated by generate_auto_job -generate_auto_job ab9b8cdb8ccf47417d265eebcf562c51bf4d5bff6abaf0920931b972f6c7b80b -job.yml 2752b11028530f127b06e9731834dc3ae4c3b13d0161608e3b258cd2a79767d7 -libqpdf/qpdf/auto_job_decl.hh db95ca0864e7495532095cd193be1ff0c15797b9ccaf252024c1154bae57b365 +generate_auto_job 8e2c467c47a66caef46497d96be461e7373e22124abe1bde3ef353bd99452609 +job.yml 55d272cca0657e1f96ca92f5253edb6c6e24e6ea19e37690446d2111adc13f91 +libqpdf/qpdf/auto_job_decl.hh ff9bbeec974f6a7e6ed2ba205e3d7f81fbe4f6224860a9ba37c30b817b951a90 libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538 -libqpdf/qpdf/auto_job_init.hh 864bb0a01df93bff129e7bc1723611d4e73f20ef7b0e33bd52261811eee43e2f +libqpdf/qpdf/auto_job_init.hh 45e3d28708c7506a681477a7865fa39dcd10e93819875a8d5664d6629f6e5245 libqpdf/qpdf/auto_job_schema.hh c91a4e182e088797b70dda94af03ca32d360f3564890132da2a8bdc3c4432423 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1 diff --git a/job.yml b/job.yml index 71a9a820..388360ea 100644 --- a/job.yml +++ b/job.yml @@ -60,7 +60,7 @@ options: - show-crypto - job-json-help - table: main - config: jc + config: c_main positional: true bare: - add-attachment @@ -215,6 +215,7 @@ options: mimetype: mime/type description: description - table: copy attachment + config: c_copy_att prefix: CopyAtt positional: true required_parameter: diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 487201f8..ca479812 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -453,10 +453,10 @@ QPDFJob::doIfVerbose( } } -QPDFJob::Config +std::shared_ptr QPDFJob::config() { - return Config(*this); + return std::shared_ptr(new Config(*this)); } void diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index 1adb34ee..9a78018e 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -26,7 +26,8 @@ namespace class ArgParser { public: - ArgParser(QPDFArgParser& ap, QPDFJob::Config& jc, QPDFJob& o); + ArgParser(QPDFArgParser& ap, + std::shared_ptr c_main, QPDFJob& o); void parseOptions(); private: @@ -42,16 +43,18 @@ namespace QPDFArgParser ap; QPDFJob& o; - QPDFJob::Config& jc; + std::shared_ptr c_main; + std::shared_ptr c_copy_att; std::vector accumulated_args; // points to member in ap char* pages_password; }; } -ArgParser::ArgParser(QPDFArgParser& ap, QPDFJob::Config& jc, QPDFJob& o) : +ArgParser::ArgParser(QPDFArgParser& ap, + std::shared_ptr c_main, QPDFJob& o) : ap(ap), o(o), - jc(jc), + c_main(c_main), pages_password(nullptr) { initOptionTables(); @@ -451,7 +454,7 @@ ArgParser::argAddAttachment() void ArgParser::argCopyAttachmentsFrom() { - o.attachments_to_copy.push_back(QPDFJob::CopyAttachmentFrom()); + this->c_copy_att = c_main->copyAttachmentsFrom(); this->ap.selectOptionTable(O_COPY_ATTACHMENT); } @@ -888,28 +891,21 @@ ArgParser::argEndAttachment() void ArgParser::argCopyAttPositional(char* arg) { - o.attachments_to_copy.back().path = arg; -} - -void -ArgParser::argCopyAttPrefix(char* parameter) -{ - o.attachments_to_copy.back().prefix = parameter; + c_copy_att->filename(arg); } void ArgParser::argCopyAttPassword(char* parameter) { - o.attachments_to_copy.back().password = parameter; + // QXXXQ @TRIVIAL + c_copy_att->password(parameter); } void ArgParser::argEndCopyAttachment() { - if (o.attachments_to_copy.back().path.empty()) - { - usage("copy attachments: no path specified"); - } + c_copy_att->end(); + c_copy_att = nullptr; } void @@ -1072,8 +1068,7 @@ QPDFJob::initializeFromArgv(int argc, char* argv[], char const* progname_env) } QPDFArgParser qap(argc, argv, progname_env); setMessagePrefix(qap.getProgname()); - auto jc = config(); - ArgParser ap(qap, jc, *this); + ArgParser ap(qap, config(), *this); ap.parseOptions(); } diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index ac038aa9..923d9302 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -489,3 +489,46 @@ QPDFJob::Config::withImages() o.show_page_images = true; return *this; } + +std::shared_ptr +QPDFJob::Config::copyAttachmentsFrom() +{ + return std::shared_ptr(new CopyAttConfig(*this)); +} + +QPDFJob::CopyAttConfig::CopyAttConfig(Config& c) : + config(c) +{ +} + +QPDFJob::CopyAttConfig& +QPDFJob::CopyAttConfig::filename(char const* parameter) +{ + this->caf.path = parameter; + return *this; +} + +QPDFJob::CopyAttConfig& +QPDFJob::CopyAttConfig::prefix(char const* parameter) +{ + this->caf.prefix = parameter; + return *this; +} + +QPDFJob::CopyAttConfig& +QPDFJob::CopyAttConfig::password(char const* parameter) +{ + this->caf.password = parameter; + return *this; +} + +QPDFJob::Config& +QPDFJob::CopyAttConfig::end() +{ + if (this->caf.path.empty()) + { + throw std::runtime_error("copy attachments: no path specified"); + } + this->config.o.attachments_to_copy.push_back(this->caf); + return this->config; +} diff --git a/libqpdf/qpdf/auto_job_decl.hh b/libqpdf/qpdf/auto_job_decl.hh index b63251b9..8718c3e4 100644 --- a/libqpdf/qpdf/auto_job_decl.hh +++ b/libqpdf/qpdf/auto_job_decl.hh @@ -75,6 +75,5 @@ void argAttMimetype(char *); void argAttDescription(char *); void argEndAttachment(); void argCopyAttPositional(char*); -void argCopyAttPrefix(char *); void argCopyAttPassword(char *); void argEndCopyAttachment(); diff --git a/libqpdf/qpdf/auto_job_init.hh b/libqpdf/qpdf/auto_job_init.hh index d1630014..cba6347d 100644 --- a/libqpdf/qpdf/auto_job_init.hh +++ b/libqpdf/qpdf/auto_job_init.hh @@ -30,82 +30,82 @@ this->ap.addBare("job-json-help", b(&ArgParser::argJobJsonHelp)); this->ap.selectMainOptionTable(); this->ap.addPositional(p(&ArgParser::argPositional)); this->ap.addBare("add-attachment", b(&ArgParser::argAddAttachment)); -this->ap.addBare("allow-weak-crypto", [this](){jc.allowWeakCrypto();}); -this->ap.addBare("check", [this](){jc.check();}); -this->ap.addBare("check-linearization", [this](){jc.checkLinearization();}); -this->ap.addBare("coalesce-contents", [this](){jc.coalesceContents();}); +this->ap.addBare("allow-weak-crypto", [this](){c_main->allowWeakCrypto();}); +this->ap.addBare("check", [this](){c_main->check();}); +this->ap.addBare("check-linearization", [this](){c_main->checkLinearization();}); +this->ap.addBare("coalesce-contents", [this](){c_main->coalesceContents();}); this->ap.addBare("copy-attachments-from", b(&ArgParser::argCopyAttachmentsFrom)); -this->ap.addBare("decrypt", [this](){jc.decrypt();}); -this->ap.addBare("deterministic-id", [this](){jc.deterministicId();}); -this->ap.addBare("empty", [this](){jc.empty();}); +this->ap.addBare("decrypt", [this](){c_main->decrypt();}); +this->ap.addBare("deterministic-id", [this](){c_main->deterministicId();}); +this->ap.addBare("empty", [this](){c_main->empty();}); this->ap.addBare("encrypt", b(&ArgParser::argEncrypt)); -this->ap.addBare("externalize-inline-images", [this](){jc.externalizeInlineImages();}); -this->ap.addBare("filtered-stream-data", [this](){jc.filteredStreamData();}); -this->ap.addBare("flatten-rotation", [this](){jc.flattenRotation();}); -this->ap.addBare("generate-appearances", [this](){jc.generateAppearances();}); -this->ap.addBare("ignore-xref-streams", [this](){jc.ignoreXrefStreams();}); -this->ap.addBare("is-encrypted", [this](){jc.isEncrypted();}); -this->ap.addBare("json", [this](){jc.json();}); -this->ap.addBare("keep-inline-images", [this](){jc.keepInlineImages();}); -this->ap.addBare("linearize", [this](){jc.linearize();}); -this->ap.addBare("list-attachments", [this](){jc.listAttachments();}); -this->ap.addBare("newline-before-endstream", [this](){jc.newlineBeforeEndstream();}); -this->ap.addBare("no-original-object-ids", [this](){jc.noOriginalObjectIds();}); -this->ap.addBare("no-warn", [this](){jc.noWarn();}); -this->ap.addBare("optimize-images", [this](){jc.optimizeImages();}); +this->ap.addBare("externalize-inline-images", [this](){c_main->externalizeInlineImages();}); +this->ap.addBare("filtered-stream-data", [this](){c_main->filteredStreamData();}); +this->ap.addBare("flatten-rotation", [this](){c_main->flattenRotation();}); +this->ap.addBare("generate-appearances", [this](){c_main->generateAppearances();}); +this->ap.addBare("ignore-xref-streams", [this](){c_main->ignoreXrefStreams();}); +this->ap.addBare("is-encrypted", [this](){c_main->isEncrypted();}); +this->ap.addBare("json", [this](){c_main->json();}); +this->ap.addBare("keep-inline-images", [this](){c_main->keepInlineImages();}); +this->ap.addBare("linearize", [this](){c_main->linearize();}); +this->ap.addBare("list-attachments", [this](){c_main->listAttachments();}); +this->ap.addBare("newline-before-endstream", [this](){c_main->newlineBeforeEndstream();}); +this->ap.addBare("no-original-object-ids", [this](){c_main->noOriginalObjectIds();}); +this->ap.addBare("no-warn", [this](){c_main->noWarn();}); +this->ap.addBare("optimize-images", [this](){c_main->optimizeImages();}); this->ap.addBare("overlay", b(&ArgParser::argOverlay)); this->ap.addBare("pages", b(&ArgParser::argPages)); -this->ap.addBare("password-is-hex-key", [this](){jc.passwordIsHexKey();}); -this->ap.addBare("preserve-unreferenced", [this](){jc.preserveUnreferenced();}); -this->ap.addBare("preserve-unreferenced-resources", [this](){jc.preserveUnreferencedResources();}); -this->ap.addBare("progress", [this](){jc.progress();}); -this->ap.addBare("qdf", [this](){jc.qdf();}); -this->ap.addBare("raw-stream-data", [this](){jc.rawStreamData();}); -this->ap.addBare("recompress-flate", [this](){jc.recompressFlate();}); -this->ap.addBare("remove-page-labels", [this](){jc.removePageLabels();}); -this->ap.addBare("replace-input", [this](){jc.replaceInput();}); -this->ap.addBare("requires-password", [this](){jc.requiresPassword();}); -this->ap.addBare("show-encryption", [this](){jc.showEncryption();}); -this->ap.addBare("show-encryption-key", [this](){jc.showEncryptionKey();}); -this->ap.addBare("show-linearization", [this](){jc.showLinearization();}); -this->ap.addBare("show-npages", [this](){jc.showNpages();}); -this->ap.addBare("show-pages", [this](){jc.showPages();}); -this->ap.addBare("show-xref", [this](){jc.showXref();}); -this->ap.addBare("static-aes-iv", [this](){jc.staticAesIv();}); -this->ap.addBare("static-id", [this](){jc.staticId();}); -this->ap.addBare("suppress-password-recovery", [this](){jc.suppressPasswordRecovery();}); -this->ap.addBare("suppress-recovery", [this](){jc.suppressRecovery();}); +this->ap.addBare("password-is-hex-key", [this](){c_main->passwordIsHexKey();}); +this->ap.addBare("preserve-unreferenced", [this](){c_main->preserveUnreferenced();}); +this->ap.addBare("preserve-unreferenced-resources", [this](){c_main->preserveUnreferencedResources();}); +this->ap.addBare("progress", [this](){c_main->progress();}); +this->ap.addBare("qdf", [this](){c_main->qdf();}); +this->ap.addBare("raw-stream-data", [this](){c_main->rawStreamData();}); +this->ap.addBare("recompress-flate", [this](){c_main->recompressFlate();}); +this->ap.addBare("remove-page-labels", [this](){c_main->removePageLabels();}); +this->ap.addBare("replace-input", [this](){c_main->replaceInput();}); +this->ap.addBare("requires-password", [this](){c_main->requiresPassword();}); +this->ap.addBare("show-encryption", [this](){c_main->showEncryption();}); +this->ap.addBare("show-encryption-key", [this](){c_main->showEncryptionKey();}); +this->ap.addBare("show-linearization", [this](){c_main->showLinearization();}); +this->ap.addBare("show-npages", [this](){c_main->showNpages();}); +this->ap.addBare("show-pages", [this](){c_main->showPages();}); +this->ap.addBare("show-xref", [this](){c_main->showXref();}); +this->ap.addBare("static-aes-iv", [this](){c_main->staticAesIv();}); +this->ap.addBare("static-id", [this](){c_main->staticId();}); +this->ap.addBare("suppress-password-recovery", [this](){c_main->suppressPasswordRecovery();}); +this->ap.addBare("suppress-recovery", [this](){c_main->suppressRecovery();}); this->ap.addBare("underlay", b(&ArgParser::argUnderlay)); -this->ap.addBare("verbose", [this](){jc.verbose();}); -this->ap.addBare("warning-exit-0", [this](){jc.warningExit0();}); -this->ap.addBare("with-images", [this](){jc.withImages();}); -this->ap.addOptionalParameter("collate", [this](char *x){jc.collate(x);}); -this->ap.addOptionalParameter("split-pages", [this](char *x){jc.splitPages(x);}); -this->ap.addRequiredParameter("compression-level", [this](char *x){jc.compressionLevel(x);}, "level"); -this->ap.addRequiredParameter("copy-encryption", [this](char *x){jc.copyEncryption(x);}, "file"); -this->ap.addRequiredParameter("encryption-file-password", [this](char *x){jc.encryptionFilePassword(x);}, "password"); -this->ap.addRequiredParameter("force-version", [this](char *x){jc.forceVersion(x);}, "version"); -this->ap.addRequiredParameter("ii-min-bytes", [this](char *x){jc.iiMinBytes(x);}, "minimum"); +this->ap.addBare("verbose", [this](){c_main->verbose();}); +this->ap.addBare("warning-exit-0", [this](){c_main->warningExit0();}); +this->ap.addBare("with-images", [this](){c_main->withImages();}); +this->ap.addOptionalParameter("collate", [this](char *x){c_main->collate(x);}); +this->ap.addOptionalParameter("split-pages", [this](char *x){c_main->splitPages(x);}); +this->ap.addRequiredParameter("compression-level", [this](char *x){c_main->compressionLevel(x);}, "level"); +this->ap.addRequiredParameter("copy-encryption", [this](char *x){c_main->copyEncryption(x);}, "file"); +this->ap.addRequiredParameter("encryption-file-password", [this](char *x){c_main->encryptionFilePassword(x);}, "password"); +this->ap.addRequiredParameter("force-version", [this](char *x){c_main->forceVersion(x);}, "version"); +this->ap.addRequiredParameter("ii-min-bytes", [this](char *x){c_main->iiMinBytes(x);}, "minimum"); this->ap.addRequiredParameter("job-json-file", p(&ArgParser::argJobJsonFile), "file"); -this->ap.addRequiredParameter("json-object", [this](char *x){jc.jsonObject(x);}, "trailer"); -this->ap.addRequiredParameter("keep-files-open-threshold", [this](char *x){jc.keepFilesOpenThreshold(x);}, "count"); -this->ap.addRequiredParameter("linearize-pass1", [this](char *x){jc.linearizePass1(x);}, "filename"); -this->ap.addRequiredParameter("min-version", [this](char *x){jc.minVersion(x);}, "version"); -this->ap.addRequiredParameter("oi-min-area", [this](char *x){jc.oiMinArea(x);}, "minimum"); -this->ap.addRequiredParameter("oi-min-height", [this](char *x){jc.oiMinHeight(x);}, "minimum"); -this->ap.addRequiredParameter("oi-min-width", [this](char *x){jc.oiMinWidth(x);}, "minimum"); +this->ap.addRequiredParameter("json-object", [this](char *x){c_main->jsonObject(x);}, "trailer"); +this->ap.addRequiredParameter("keep-files-open-threshold", [this](char *x){c_main->keepFilesOpenThreshold(x);}, "count"); +this->ap.addRequiredParameter("linearize-pass1", [this](char *x){c_main->linearizePass1(x);}, "filename"); +this->ap.addRequiredParameter("min-version", [this](char *x){c_main->minVersion(x);}, "version"); +this->ap.addRequiredParameter("oi-min-area", [this](char *x){c_main->oiMinArea(x);}, "minimum"); +this->ap.addRequiredParameter("oi-min-height", [this](char *x){c_main->oiMinHeight(x);}, "minimum"); +this->ap.addRequiredParameter("oi-min-width", [this](char *x){c_main->oiMinWidth(x);}, "minimum"); this->ap.addRequiredParameter("password", p(&ArgParser::argPassword), "password"); this->ap.addRequiredParameter("password-file", p(&ArgParser::argPasswordFile), "password"); -this->ap.addRequiredParameter("remove-attachment", [this](char *x){jc.removeAttachment(x);}, "attachment"); +this->ap.addRequiredParameter("remove-attachment", [this](char *x){c_main->removeAttachment(x);}, "attachment"); this->ap.addRequiredParameter("rotate", p(&ArgParser::argRotate), "[+|-]angle"); -this->ap.addRequiredParameter("show-attachment", [this](char *x){jc.showAttachment(x);}, "attachment"); +this->ap.addRequiredParameter("show-attachment", [this](char *x){c_main->showAttachment(x);}, "attachment"); this->ap.addRequiredParameter("show-object", p(&ArgParser::argShowObject), "trailer"); -this->ap.addChoices("compress-streams", [this](char *x){jc.compressStreams(x);}, true, yn_choices); +this->ap.addChoices("compress-streams", [this](char *x){c_main->compressStreams(x);}, true, yn_choices); this->ap.addChoices("decode-level", p(&ArgParser::argDecodeLevel), true, decode_level_choices); -this->ap.addChoices("flatten-annotations", [this](char *x){jc.flattenAnnotations(x);}, true, flatten_choices); -this->ap.addChoices("json-key", [this](char *x){jc.jsonKey(x);}, true, json_key_choices); -this->ap.addChoices("keep-files-open", [this](char *x){jc.keepFilesOpen(x);}, true, yn_choices); -this->ap.addChoices("normalize-content", [this](char *x){jc.normalizeContent(x);}, true, yn_choices); +this->ap.addChoices("flatten-annotations", [this](char *x){c_main->flattenAnnotations(x);}, true, flatten_choices); +this->ap.addChoices("json-key", [this](char *x){c_main->jsonKey(x);}, true, json_key_choices); +this->ap.addChoices("keep-files-open", [this](char *x){c_main->keepFilesOpen(x);}, true, yn_choices); +this->ap.addChoices("normalize-content", [this](char *x){c_main->normalizeContent(x);}, 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); @@ -152,7 +152,7 @@ this->ap.addRequiredParameter("mimetype", p(&ArgParser::argAttMimetype), "mime/t this->ap.addRequiredParameter("description", p(&ArgParser::argAttDescription), "description"); this->ap.registerOptionTable("copy attachment", b(&ArgParser::argEndCopyAttachment)); this->ap.addPositional(p(&ArgParser::argCopyAttPositional)); -this->ap.addRequiredParameter("prefix", p(&ArgParser::argCopyAttPrefix), "prefix"); +this->ap.addRequiredParameter("prefix", [this](char *x){c_copy_att->prefix(x);}, "prefix"); this->ap.addRequiredParameter("password", p(&ArgParser::argCopyAttPassword), "password"); this->ap.selectOptionTable("256-bit encryption"); this->ap.copyFromOtherTable("cleartext-metadata", "128-bit encryption");