Commit 95d127641c60f7230d383feb055cd2bb12935513

Authored by Jay Berkenbilt
1 parent 41c5af8f

QPDFJob: move more top-level trivial handlers into config

generate_auto_job
@@ -41,24 +41,16 @@ not_yet = set([ @@ -41,24 +41,16 @@ not_yet = set([
41 'annotate', 41 'annotate',
42 'assemble', 42 'assemble',
43 'cleartext-metadata', 43 'cleartext-metadata',
44 - 'decode-level',  
45 'extract', 44 'extract',
46 'force-R5', 45 'force-R5',
47 'force-V4', 46 'force-V4',
48 'form', 47 'form',
49 'from', 48 'from',
50 - 'job-json-file',  
51 'modify', 49 'modify',
52 'modify-other', 50 'modify-other',
53 - 'object-streams',  
54 - 'password-file',  
55 - 'password-mode',  
56 'print', 51 'print',
57 - 'remove-unreferenced-resources',  
58 'repeat', 52 'repeat',
59 'rotate', 53 'rotate',
60 - 'show-object',  
61 - 'stream-data',  
62 'to', 54 'to',
63 'use-aes', 55 'use-aes',
64 ]) 56 ])
include/qpdf/auto_job_c_main.hh
@@ -54,6 +54,7 @@ QPDF_DLL Config& copyEncryption(char const* parameter); @@ -54,6 +54,7 @@ QPDF_DLL Config& copyEncryption(char const* parameter);
54 QPDF_DLL Config& encryptionFilePassword(char const* parameter); 54 QPDF_DLL Config& encryptionFilePassword(char const* parameter);
55 QPDF_DLL Config& forceVersion(char const* parameter); 55 QPDF_DLL Config& forceVersion(char const* parameter);
56 QPDF_DLL Config& iiMinBytes(char const* parameter); 56 QPDF_DLL Config& iiMinBytes(char const* parameter);
  57 +QPDF_DLL Config& jobJsonFile(char const* parameter);
57 QPDF_DLL Config& jsonObject(char const* parameter); 58 QPDF_DLL Config& jsonObject(char const* parameter);
58 QPDF_DLL Config& keepFilesOpenThreshold(char const* parameter); 59 QPDF_DLL Config& keepFilesOpenThreshold(char const* parameter);
59 QPDF_DLL Config& linearizePass1(char const* parameter); 60 QPDF_DLL Config& linearizePass1(char const* parameter);
@@ -62,10 +63,17 @@ QPDF_DLL Config& oiMinArea(char const* parameter); @@ -62,10 +63,17 @@ QPDF_DLL Config& oiMinArea(char const* parameter);
62 QPDF_DLL Config& oiMinHeight(char const* parameter); 63 QPDF_DLL Config& oiMinHeight(char const* parameter);
63 QPDF_DLL Config& oiMinWidth(char const* parameter); 64 QPDF_DLL Config& oiMinWidth(char const* parameter);
64 QPDF_DLL Config& password(char const* parameter); 65 QPDF_DLL Config& password(char const* parameter);
  66 +QPDF_DLL Config& passwordFile(char const* parameter);
65 QPDF_DLL Config& removeAttachment(char const* parameter); 67 QPDF_DLL Config& removeAttachment(char const* parameter);
66 QPDF_DLL Config& showAttachment(char const* parameter); 68 QPDF_DLL Config& showAttachment(char const* parameter);
  69 +QPDF_DLL Config& showObject(char const* parameter);
67 QPDF_DLL Config& compressStreams(char const* parameter); 70 QPDF_DLL Config& compressStreams(char const* parameter);
  71 +QPDF_DLL Config& decodeLevel(char const* parameter);
68 QPDF_DLL Config& flattenAnnotations(char const* parameter); 72 QPDF_DLL Config& flattenAnnotations(char const* parameter);
69 QPDF_DLL Config& jsonKey(char const* parameter); 73 QPDF_DLL Config& jsonKey(char const* parameter);
70 QPDF_DLL Config& keepFilesOpen(char const* parameter); 74 QPDF_DLL Config& keepFilesOpen(char const* parameter);
71 QPDF_DLL Config& normalizeContent(char const* parameter); 75 QPDF_DLL Config& normalizeContent(char const* parameter);
  76 +QPDF_DLL Config& objectStreams(char const* parameter);
  77 +QPDF_DLL Config& passwordMode(char const* parameter);
  78 +QPDF_DLL Config& removeUnreferencedResources(char const* parameter);
  79 +QPDF_DLL Config& streamData(char const* parameter);
job.sums
1 # Generated by generate_auto_job 1 # Generated by generate_auto_job
2 -generate_auto_job 66e43cdb4ae166d020be19fcc6f8e9f0445c4de6a5395ff5aff511b89763c4e1 2 +generate_auto_job d41f3092545906dcd9a82f88ff41939bf695a36ecaebfe8559c66bd92b7416fb
3 include/qpdf/auto_job_c_att.hh ecc3f8f711b486b491e811176362a90c022eb225ff12157df3a10ca021be87b1 3 include/qpdf/auto_job_c_att.hh ecc3f8f711b486b491e811176362a90c022eb225ff12157df3a10ca021be87b1
4 include/qpdf/auto_job_c_copy_att.hh caffae3d1faf2cd92a07ba77da638cce31da3e074a047918834195c0f3ed508a 4 include/qpdf/auto_job_c_copy_att.hh caffae3d1faf2cd92a07ba77da638cce31da3e074a047918834195c0f3ed508a
5 -include/qpdf/auto_job_c_main.hh 5fdd9c85aa295a3caec467b9607fe82c874cd3aaeb7806b9d18074f7b96fd085 5 +include/qpdf/auto_job_c_main.hh 1e060e9dd2029d21b29fed03e3a1e62164050b43684bd7434cc9e9707f73150d
6 include/qpdf/auto_job_c_pages.hh 79ee6e52a36fedfd0e6ca60bd926bc25a3e975ab6fa984a7e798a48791e8ba86 6 include/qpdf/auto_job_c_pages.hh 79ee6e52a36fedfd0e6ca60bd926bc25a3e975ab6fa984a7e798a48791e8ba86
7 job.yml 4cd60df0caa74b68cc39352910a8381c3411248bc3edef69f9d16d75e807f451 7 job.yml 4cd60df0caa74b68cc39352910a8381c3411248bc3edef69f9d16d75e807f451
8 -libqpdf/qpdf/auto_job_decl.hh 38f7462e34fea7d46d5e5519ac1742be6e57ea6f66c47b37d5425f3a2b9ca536 8 +libqpdf/qpdf/auto_job_decl.hh f9f2a605fb8b5fed9b74c4cd07c07c3cdee60e2628d082250810c8074d5acd83
9 libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538 9 libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538
10 -libqpdf/qpdf/auto_job_init.hh b49d839078d84398142f8f14bdae8a71f44fbff13cdf7b350b84ef2410aaa6a3 10 +libqpdf/qpdf/auto_job_init.hh b776c87e61d56842f23cb46fb6d4e44f5740e64854844bcc454fd812f7b4f8d5
11 libqpdf/qpdf/auto_job_schema.hh 6e6d72e99dacd02c22d9ac70f4dc78a935f879d2a16c89f07f2bdfa936cc2ae3 11 libqpdf/qpdf/auto_job_schema.hh 6e6d72e99dacd02c22d9ac70f4dc78a935f879d2a16c89f07f2bdfa936cc2ae3
12 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d 12 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d
13 manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1 13 manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1
libqpdf/QPDFJob_argv.cc
@@ -188,33 +188,6 @@ ArgParser::argShowCrypto() @@ -188,33 +188,6 @@ ArgParser::argShowCrypto()
188 } 188 }
189 189
190 void 190 void
191 -ArgParser::argPasswordFile(char* parameter)  
192 -{  
193 - std::list<std::string> lines;  
194 - if (strcmp(parameter, "-") == 0)  
195 - {  
196 - QTC::TC("qpdf", "qpdf password stdin");  
197 - lines = QUtil::read_lines_from_file(std::cin);  
198 - }  
199 - else  
200 - {  
201 - QTC::TC("qpdf", "qpdf password file");  
202 - lines = QUtil::read_lines_from_file(parameter);  
203 - }  
204 - if (lines.size() >= 1)  
205 - {  
206 - o.password = QUtil::make_shared_cstr(lines.front());  
207 -  
208 - if (lines.size() > 1)  
209 - {  
210 - std::cerr << this->ap.getProgname()  
211 - << ": WARNING: all but the first line of"  
212 - << " the password file are ignored" << std::endl;  
213 - }  
214 - }  
215 -}  
216 -  
217 -void  
218 ArgParser::argEncrypt() 191 ArgParser::argEncrypt()
219 { 192 {
220 this->accumulated_args.clear(); 193 this->accumulated_args.clear();
@@ -273,31 +246,6 @@ ArgParser::argEncPositional(char* arg) @@ -273,31 +246,6 @@ ArgParser::argEncPositional(char* arg)
273 } 246 }
274 247
275 void 248 void
276 -ArgParser::argPasswordMode(char* parameter)  
277 -{  
278 - if (strcmp(parameter, "bytes") == 0)  
279 - {  
280 - o.password_mode = QPDFJob::pm_bytes;  
281 - }  
282 - else if (strcmp(parameter, "hex-bytes") == 0)  
283 - {  
284 - o.password_mode = QPDFJob::pm_hex_bytes;  
285 - }  
286 - else if (strcmp(parameter, "unicode") == 0)  
287 - {  
288 - o.password_mode = QPDFJob::pm_unicode;  
289 - }  
290 - else if (strcmp(parameter, "auto") == 0)  
291 - {  
292 - o.password_mode = QPDFJob::pm_auto;  
293 - }  
294 - else  
295 - {  
296 - usage("invalid password-mode option");  
297 - }  
298 -}  
299 -  
300 -void  
301 ArgParser::argEnc256AllowInsecure() 249 ArgParser::argEnc256AllowInsecure()
302 { 250 {
303 o.allow_insecure = true; 251 o.allow_insecure = true;
@@ -454,112 +402,6 @@ ArgParser::argCopyAttachmentsFrom() @@ -454,112 +402,6 @@ ArgParser::argCopyAttachmentsFrom()
454 } 402 }
455 403
456 void 404 void
457 -ArgParser::argStreamData(char* parameter)  
458 -{  
459 - o.stream_data_set = true;  
460 - if (strcmp(parameter, "compress") == 0)  
461 - {  
462 - o.stream_data_mode = qpdf_s_compress;  
463 - }  
464 - else if (strcmp(parameter, "preserve") == 0)  
465 - {  
466 - o.stream_data_mode = qpdf_s_preserve;  
467 - }  
468 - else if (strcmp(parameter, "uncompress") == 0)  
469 - {  
470 - o.stream_data_mode = qpdf_s_uncompress;  
471 - }  
472 - else  
473 - {  
474 - // If this happens, it means streamDataChoices in  
475 - // ArgParser::initOptionTable is wrong.  
476 - usage("invalid stream-data option");  
477 - }  
478 -}  
479 -  
480 -void  
481 -ArgParser::argDecodeLevel(char* parameter)  
482 -{  
483 - o.decode_level_set = true;  
484 - if (strcmp(parameter, "none") == 0)  
485 - {  
486 - o.decode_level = qpdf_dl_none;  
487 - }  
488 - else if (strcmp(parameter, "generalized") == 0)  
489 - {  
490 - o.decode_level = qpdf_dl_generalized;  
491 - }  
492 - else if (strcmp(parameter, "specialized") == 0)  
493 - {  
494 - o.decode_level = qpdf_dl_specialized;  
495 - }  
496 - else if (strcmp(parameter, "all") == 0)  
497 - {  
498 - o.decode_level = qpdf_dl_all;  
499 - }  
500 - else  
501 - {  
502 - // If this happens, it means decodeLevelChoices in  
503 - // ArgParser::initOptionTable is wrong.  
504 - usage("invalid option");  
505 - }  
506 -}  
507 -  
508 -void  
509 -ArgParser::argObjectStreams(char* parameter)  
510 -{  
511 - o.object_stream_set = true;  
512 - if (strcmp(parameter, "disable") == 0)  
513 - {  
514 - o.object_stream_mode = qpdf_o_disable;  
515 - }  
516 - else if (strcmp(parameter, "preserve") == 0)  
517 - {  
518 - o.object_stream_mode = qpdf_o_preserve;  
519 - }  
520 - else if (strcmp(parameter, "generate") == 0)  
521 - {  
522 - o.object_stream_mode = qpdf_o_generate;  
523 - }  
524 - else  
525 - {  
526 - // If this happens, it means objectStreamsChoices in  
527 - // ArgParser::initOptionTable is wrong.  
528 - usage("invalid object stream mode");  
529 - }  
530 -}  
531 -  
532 -void  
533 -ArgParser::argRemoveUnreferencedResources(char* parameter)  
534 -{  
535 - if (strcmp(parameter, "auto") == 0)  
536 - {  
537 - o.remove_unreferenced_page_resources = QPDFJob::re_auto;  
538 - }  
539 - else if (strcmp(parameter, "yes") == 0)  
540 - {  
541 - o.remove_unreferenced_page_resources = QPDFJob::re_yes;  
542 - }  
543 - else if (strcmp(parameter, "no") == 0)  
544 - {  
545 - o.remove_unreferenced_page_resources = QPDFJob::re_no;  
546 - }  
547 - else  
548 - {  
549 - // If this happens, it means remove_unref_choices in  
550 - // ArgParser::initOptionTable is wrong.  
551 - usage("invalid value for --remove-unreferenced-page-resources");  
552 - }  
553 -}  
554 -  
555 -void  
556 -ArgParser::argShowObject(char* parameter)  
557 -{  
558 - QPDFJob::parse_object_id(parameter, o.show_trailer, o.show_obj, o.show_gen);  
559 - o.require_outfile = false;  
560 -}  
561 -  
562 -void  
563 ArgParser::argEnc40Print(char* parameter) 405 ArgParser::argEnc40Print(char* parameter)
564 { 406 {
565 o.r2_print = (strcmp(parameter, "y") == 0); 407 o.r2_print = (strcmp(parameter, "y") == 0);
@@ -817,25 +659,6 @@ ArgParser::argEndCopyAttachment() @@ -817,25 +659,6 @@ ArgParser::argEndCopyAttachment()
817 } 659 }
818 660
819 void 661 void
820 -ArgParser::argJobJsonFile(char* parameter)  
821 -{  
822 - PointerHolder<char> file_buf;  
823 - size_t size;  
824 - QUtil::read_file_into_memory(parameter, file_buf, size);  
825 - try  
826 - {  
827 - o.initializeFromJson(std::string(file_buf.getPointer(), size));  
828 - }  
829 - catch (std::exception& e)  
830 - {  
831 - throw std::runtime_error(  
832 - "error with job-json file " + std::string(parameter) + " " +  
833 - e.what() + "\nRun " + this->ap.getProgname() +  
834 - "--job-json-help for information on the file format.");  
835 - }  
836 -}  
837 -  
838 -void  
839 ArgParser::argJobJsonHelp() 662 ArgParser::argJobJsonHelp()
840 { 663 {
841 std::cout << JOB_SCHEMA_DATA << std::endl; 664 std::cout << JOB_SCHEMA_DATA << std::endl;
libqpdf/QPDFJob_config.cc
1 #include <qpdf/QPDFJob.hh> 1 #include <qpdf/QPDFJob.hh>
2 #include <qpdf/QUtil.hh> 2 #include <qpdf/QUtil.hh>
  3 +#include <qpdf/QTC.hh>
3 #include <cstring> 4 #include <cstring>
4 5
  6 +static void usage(std::string const& msg)
  7 +{
  8 + throw QPDFJob::ConfigError(msg);
  9 +}
  10 +
5 QPDFJob::Config& 11 QPDFJob::Config&
6 QPDFJob::Config::allowWeakCrypto() 12 QPDFJob::Config::allowWeakCrypto()
7 { 13 {
@@ -497,6 +503,191 @@ QPDFJob::Config::withImages() @@ -497,6 +503,191 @@ QPDFJob::Config::withImages()
497 return *this; 503 return *this;
498 } 504 }
499 505
  506 +QPDFJob::Config&
  507 +QPDFJob::Config::passwordFile(char const* parameter)
  508 +{
  509 + std::list<std::string> lines;
  510 + if (strcmp(parameter, "-") == 0)
  511 + {
  512 + QTC::TC("qpdf", "QPDFJob_config password stdin");
  513 + lines = QUtil::read_lines_from_file(std::cin);
  514 + }
  515 + else
  516 + {
  517 + QTC::TC("qpdf", "QPDFJob_config password file");
  518 + lines = QUtil::read_lines_from_file(parameter);
  519 + }
  520 + if (lines.size() >= 1)
  521 + {
  522 + o.password = QUtil::make_shared_cstr(lines.front());
  523 +
  524 + if (lines.size() > 1)
  525 + {
  526 + std::cerr << this->o.m->message_prefix
  527 + << ": WARNING: all but the first line of"
  528 + << " the password file are ignored" << std::endl;
  529 + }
  530 + }
  531 + return *this;
  532 +}
  533 +
  534 +QPDFJob::Config&
  535 +QPDFJob::Config::passwordMode(char const* parameter)
  536 +{
  537 + if (strcmp(parameter, "bytes") == 0)
  538 + {
  539 + o.password_mode = QPDFJob::pm_bytes;
  540 + }
  541 + else if (strcmp(parameter, "hex-bytes") == 0)
  542 + {
  543 + o.password_mode = QPDFJob::pm_hex_bytes;
  544 + }
  545 + else if (strcmp(parameter, "unicode") == 0)
  546 + {
  547 + o.password_mode = QPDFJob::pm_unicode;
  548 + }
  549 + else if (strcmp(parameter, "auto") == 0)
  550 + {
  551 + o.password_mode = QPDFJob::pm_auto;
  552 + }
  553 + else
  554 + {
  555 + usage("invalid password-mode option");
  556 + }
  557 + return *this;
  558 +}
  559 +
  560 +QPDFJob::Config&
  561 +QPDFJob::Config::streamData(char const* parameter)
  562 +{
  563 + o.stream_data_set = true;
  564 + if (strcmp(parameter, "compress") == 0)
  565 + {
  566 + o.stream_data_mode = qpdf_s_compress;
  567 + }
  568 + else if (strcmp(parameter, "preserve") == 0)
  569 + {
  570 + o.stream_data_mode = qpdf_s_preserve;
  571 + }
  572 + else if (strcmp(parameter, "uncompress") == 0)
  573 + {
  574 + o.stream_data_mode = qpdf_s_uncompress;
  575 + }
  576 + else
  577 + {
  578 + // If this happens, it means streamDataChoices in
  579 + // ArgParser::initOptionTable is wrong.
  580 + usage("invalid stream-data option");
  581 + }
  582 + return *this;
  583 +}
  584 +
  585 +QPDFJob::Config&
  586 +QPDFJob::Config::decodeLevel(char const* parameter)
  587 +{
  588 + o.decode_level_set = true;
  589 + if (strcmp(parameter, "none") == 0)
  590 + {
  591 + o.decode_level = qpdf_dl_none;
  592 + }
  593 + else if (strcmp(parameter, "generalized") == 0)
  594 + {
  595 + o.decode_level = qpdf_dl_generalized;
  596 + }
  597 + else if (strcmp(parameter, "specialized") == 0)
  598 + {
  599 + o.decode_level = qpdf_dl_specialized;
  600 + }
  601 + else if (strcmp(parameter, "all") == 0)
  602 + {
  603 + o.decode_level = qpdf_dl_all;
  604 + }
  605 + else
  606 + {
  607 + // If this happens, it means decodeLevelChoices in
  608 + // ArgParser::initOptionTable is wrong.
  609 + usage("invalid option");
  610 + }
  611 + return *this;
  612 +}
  613 +
  614 +QPDFJob::Config&
  615 +QPDFJob::Config::objectStreams(char const* parameter)
  616 +{
  617 + o.object_stream_set = true;
  618 + if (strcmp(parameter, "disable") == 0)
  619 + {
  620 + o.object_stream_mode = qpdf_o_disable;
  621 + }
  622 + else if (strcmp(parameter, "preserve") == 0)
  623 + {
  624 + o.object_stream_mode = qpdf_o_preserve;
  625 + }
  626 + else if (strcmp(parameter, "generate") == 0)
  627 + {
  628 + o.object_stream_mode = qpdf_o_generate;
  629 + }
  630 + else
  631 + {
  632 + // If this happens, it means objectStreamsChoices in
  633 + // ArgParser::initOptionTable is wrong.
  634 + usage("invalid object stream mode");
  635 + }
  636 + return *this;
  637 +}
  638 +
  639 +QPDFJob::Config&
  640 +QPDFJob::Config::removeUnreferencedResources(char const* parameter)
  641 +{
  642 + if (strcmp(parameter, "auto") == 0)
  643 + {
  644 + o.remove_unreferenced_page_resources = QPDFJob::re_auto;
  645 + }
  646 + else if (strcmp(parameter, "yes") == 0)
  647 + {
  648 + o.remove_unreferenced_page_resources = QPDFJob::re_yes;
  649 + }
  650 + else if (strcmp(parameter, "no") == 0)
  651 + {
  652 + o.remove_unreferenced_page_resources = QPDFJob::re_no;
  653 + }
  654 + else
  655 + {
  656 + // If this happens, it means remove_unref_choices in
  657 + // ArgParser::initOptionTable is wrong.
  658 + usage("invalid value for --remove-unreferenced-page-resources");
  659 + }
  660 + return *this;
  661 +}
  662 +
  663 +QPDFJob::Config&
  664 +QPDFJob::Config::showObject(char const* parameter)
  665 +{
  666 + QPDFJob::parse_object_id(parameter, o.show_trailer, o.show_obj, o.show_gen);
  667 + o.require_outfile = false;
  668 + return *this;
  669 +}
  670 +
  671 +QPDFJob::Config&
  672 +QPDFJob::Config::jobJsonFile(char const* parameter)
  673 +{
  674 + PointerHolder<char> file_buf;
  675 + size_t size;
  676 + QUtil::read_file_into_memory(parameter, file_buf, size);
  677 + try
  678 + {
  679 + o.initializeFromJson(std::string(file_buf.getPointer(), size));
  680 + }
  681 + catch (std::exception& e)
  682 + {
  683 + throw std::runtime_error(
  684 + "error with job-json file " + std::string(parameter) + " " +
  685 + e.what() + "\nRun " + this->o.m->message_prefix +
  686 + "--job-json-help for information on the file format.");
  687 + }
  688 + return *this;
  689 +}
  690 +
500 std::shared_ptr<QPDFJob::CopyAttConfig> 691 std::shared_ptr<QPDFJob::CopyAttConfig>
501 QPDFJob::Config::copyAttachmentsFrom() 692 QPDFJob::Config::copyAttachmentsFrom()
502 { 693 {
@@ -534,7 +725,7 @@ QPDFJob::CopyAttConfig::end() @@ -534,7 +725,7 @@ QPDFJob::CopyAttConfig::end()
534 { 725 {
535 if (this->caf.path.empty()) 726 if (this->caf.path.empty())
536 { 727 {
537 - throw QPDFJob::ConfigError("copy attachments: no path specified"); 728 + usage("copy attachments: no path specified");
538 } 729 }
539 this->config.o.attachments_to_copy.push_back(this->caf); 730 this->config.o.attachments_to_copy.push_back(this->caf);
540 return this->config; 731 return this->config;
@@ -577,8 +768,7 @@ QPDFJob::AttConfig::creationdate(char const* parameter) @@ -577,8 +768,7 @@ QPDFJob::AttConfig::creationdate(char const* parameter)
577 { 768 {
578 if (! QUtil::pdf_time_to_qpdf_time(parameter)) 769 if (! QUtil::pdf_time_to_qpdf_time(parameter))
579 { 770 {
580 - throw QPDFJob::ConfigError(  
581 - std::string(parameter) + " is not a valid PDF timestamp"); 771 + usage(std::string(parameter) + " is not a valid PDF timestamp");
582 } 772 }
583 this->att.creationdate = parameter; 773 this->att.creationdate = parameter;
584 return *this; 774 return *this;
@@ -589,8 +779,7 @@ QPDFJob::AttConfig::moddate(char const* parameter) @@ -589,8 +779,7 @@ QPDFJob::AttConfig::moddate(char const* parameter)
589 { 779 {
590 if (! QUtil::pdf_time_to_qpdf_time(parameter)) 780 if (! QUtil::pdf_time_to_qpdf_time(parameter))
591 { 781 {
592 - throw QPDFJob::ConfigError(  
593 - std::string(parameter) + " is not a valid PDF timestamp"); 782 + usage(std::string(parameter) + " is not a valid PDF timestamp");
594 } 783 }
595 this->att.moddate = parameter; 784 this->att.moddate = parameter;
596 return *this; 785 return *this;
@@ -601,8 +790,7 @@ QPDFJob::AttConfig::mimetype(char const* parameter) @@ -601,8 +790,7 @@ QPDFJob::AttConfig::mimetype(char const* parameter)
601 { 790 {
602 if (strchr(parameter, '/') == nullptr) 791 if (strchr(parameter, '/') == nullptr)
603 { 792 {
604 - throw QPDFJob::ConfigError(  
605 - "mime type should be specified as type/subtype"); 793 + usage("mime type should be specified as type/subtype");
606 } 794 }
607 this->att.mimetype = parameter; 795 this->att.mimetype = parameter;
608 return *this; 796 return *this;
@@ -629,13 +817,12 @@ QPDFJob::AttConfig::end() @@ -629,13 +817,12 @@ QPDFJob::AttConfig::end()
629 QUtil::get_current_qpdf_time()); 817 QUtil::get_current_qpdf_time());
630 if (this->att.path.empty()) 818 if (this->att.path.empty())
631 { 819 {
632 - throw QPDFJob::ConfigError("add attachment: no path specified"); 820 + usage("add attachment: no path specified");
633 } 821 }
634 std::string last_element = QUtil::path_basename(this->att.path); 822 std::string last_element = QUtil::path_basename(this->att.path);
635 if (last_element.empty()) 823 if (last_element.empty())
636 { 824 {
637 - throw QPDFJob::ConfigError(  
638 - "path for --add-attachment may not be empty"); 825 + usage("path for --add-attachment may not be empty");
639 } 826 }
640 if (this->att.filename.empty()) 827 if (this->att.filename.empty())
641 { 828 {
@@ -674,7 +861,7 @@ QPDFJob::PagesConfig::end() @@ -674,7 +861,7 @@ QPDFJob::PagesConfig::end()
674 { 861 {
675 if (this->config.o.page_specs.empty()) 862 if (this->config.o.page_specs.empty())
676 { 863 {
677 - throw QPDFJob::ConfigError("--pages: no page specifications given"); 864 + usage("--pages: no page specifications given");
678 } 865 }
679 return this->config; 866 return this->config;
680 } 867 }
libqpdf/qpdf/auto_job_decl.hh
@@ -24,15 +24,7 @@ void argEncrypt(); @@ -24,15 +24,7 @@ void argEncrypt();
24 void argOverlay(); 24 void argOverlay();
25 void argPages(); 25 void argPages();
26 void argUnderlay(); 26 void argUnderlay();
27 -void argJobJsonFile(char *);  
28 -void argPasswordFile(char *);  
29 void argRotate(char *); 27 void argRotate(char *);
30 -void argShowObject(char *);  
31 -void argDecodeLevel(char *);  
32 -void argObjectStreams(char *);  
33 -void argPasswordMode(char *);  
34 -void argRemoveUnreferencedResources(char *);  
35 -void argStreamData(char *);  
36 void argPagesPositional(char*); 28 void argPagesPositional(char*);
37 void argPagesPassword(char *); 29 void argPagesPassword(char *);
38 void argEndPages(); 30 void argEndPages();
libqpdf/qpdf/auto_job_init.hh
@@ -86,7 +86,7 @@ this-&gt;ap.addRequiredParameter(&quot;copy-encryption&quot;, [this](char *x){c_main-&gt;copyEnc @@ -86,7 +86,7 @@ this-&gt;ap.addRequiredParameter(&quot;copy-encryption&quot;, [this](char *x){c_main-&gt;copyEnc
86 this->ap.addRequiredParameter("encryption-file-password", [this](char *x){c_main->encryptionFilePassword(x);}, "password"); 86 this->ap.addRequiredParameter("encryption-file-password", [this](char *x){c_main->encryptionFilePassword(x);}, "password");
87 this->ap.addRequiredParameter("force-version", [this](char *x){c_main->forceVersion(x);}, "version"); 87 this->ap.addRequiredParameter("force-version", [this](char *x){c_main->forceVersion(x);}, "version");
88 this->ap.addRequiredParameter("ii-min-bytes", [this](char *x){c_main->iiMinBytes(x);}, "minimum"); 88 this->ap.addRequiredParameter("ii-min-bytes", [this](char *x){c_main->iiMinBytes(x);}, "minimum");
89 -this->ap.addRequiredParameter("job-json-file", p(&ArgParser::argJobJsonFile), "file"); 89 +this->ap.addRequiredParameter("job-json-file", [this](char *x){c_main->jobJsonFile(x);}, "file");
90 this->ap.addRequiredParameter("json-object", [this](char *x){c_main->jsonObject(x);}, "trailer"); 90 this->ap.addRequiredParameter("json-object", [this](char *x){c_main->jsonObject(x);}, "trailer");
91 this->ap.addRequiredParameter("keep-files-open-threshold", [this](char *x){c_main->keepFilesOpenThreshold(x);}, "count"); 91 this->ap.addRequiredParameter("keep-files-open-threshold", [this](char *x){c_main->keepFilesOpenThreshold(x);}, "count");
92 this->ap.addRequiredParameter("linearize-pass1", [this](char *x){c_main->linearizePass1(x);}, "filename"); 92 this->ap.addRequiredParameter("linearize-pass1", [this](char *x){c_main->linearizePass1(x);}, "filename");
@@ -95,21 +95,21 @@ this-&gt;ap.addRequiredParameter(&quot;oi-min-area&quot;, [this](char *x){c_main-&gt;oiMinArea(x @@ -95,21 +95,21 @@ this-&gt;ap.addRequiredParameter(&quot;oi-min-area&quot;, [this](char *x){c_main-&gt;oiMinArea(x
95 this->ap.addRequiredParameter("oi-min-height", [this](char *x){c_main->oiMinHeight(x);}, "minimum"); 95 this->ap.addRequiredParameter("oi-min-height", [this](char *x){c_main->oiMinHeight(x);}, "minimum");
96 this->ap.addRequiredParameter("oi-min-width", [this](char *x){c_main->oiMinWidth(x);}, "minimum"); 96 this->ap.addRequiredParameter("oi-min-width", [this](char *x){c_main->oiMinWidth(x);}, "minimum");
97 this->ap.addRequiredParameter("password", [this](char *x){c_main->password(x);}, "password"); 97 this->ap.addRequiredParameter("password", [this](char *x){c_main->password(x);}, "password");
98 -this->ap.addRequiredParameter("password-file", p(&ArgParser::argPasswordFile), "password"); 98 +this->ap.addRequiredParameter("password-file", [this](char *x){c_main->passwordFile(x);}, "password");
99 this->ap.addRequiredParameter("remove-attachment", [this](char *x){c_main->removeAttachment(x);}, "attachment"); 99 this->ap.addRequiredParameter("remove-attachment", [this](char *x){c_main->removeAttachment(x);}, "attachment");
100 this->ap.addRequiredParameter("rotate", p(&ArgParser::argRotate), "[+|-]angle"); 100 this->ap.addRequiredParameter("rotate", p(&ArgParser::argRotate), "[+|-]angle");
101 this->ap.addRequiredParameter("show-attachment", [this](char *x){c_main->showAttachment(x);}, "attachment"); 101 this->ap.addRequiredParameter("show-attachment", [this](char *x){c_main->showAttachment(x);}, "attachment");
102 -this->ap.addRequiredParameter("show-object", p(&ArgParser::argShowObject), "trailer"); 102 +this->ap.addRequiredParameter("show-object", [this](char *x){c_main->showObject(x);}, "trailer");
103 this->ap.addChoices("compress-streams", [this](char *x){c_main->compressStreams(x);}, true, yn_choices); 103 this->ap.addChoices("compress-streams", [this](char *x){c_main->compressStreams(x);}, true, yn_choices);
104 -this->ap.addChoices("decode-level", p(&ArgParser::argDecodeLevel), true, decode_level_choices); 104 +this->ap.addChoices("decode-level", [this](char *x){c_main->decodeLevel(x);}, true, decode_level_choices);
105 this->ap.addChoices("flatten-annotations", [this](char *x){c_main->flattenAnnotations(x);}, true, flatten_choices); 105 this->ap.addChoices("flatten-annotations", [this](char *x){c_main->flattenAnnotations(x);}, true, flatten_choices);
106 this->ap.addChoices("json-key", [this](char *x){c_main->jsonKey(x);}, true, json_key_choices); 106 this->ap.addChoices("json-key", [this](char *x){c_main->jsonKey(x);}, true, json_key_choices);
107 this->ap.addChoices("keep-files-open", [this](char *x){c_main->keepFilesOpen(x);}, true, yn_choices); 107 this->ap.addChoices("keep-files-open", [this](char *x){c_main->keepFilesOpen(x);}, true, yn_choices);
108 this->ap.addChoices("normalize-content", [this](char *x){c_main->normalizeContent(x);}, true, yn_choices); 108 this->ap.addChoices("normalize-content", [this](char *x){c_main->normalizeContent(x);}, true, yn_choices);
109 -this->ap.addChoices("object-streams", p(&ArgParser::argObjectStreams), true, object_streams_choices);  
110 -this->ap.addChoices("password-mode", p(&ArgParser::argPasswordMode), true, password_mode_choices);  
111 -this->ap.addChoices("remove-unreferenced-resources", p(&ArgParser::argRemoveUnreferencedResources), true, remove_unref_choices);  
112 -this->ap.addChoices("stream-data", p(&ArgParser::argStreamData), true, stream_data_choices); 109 +this->ap.addChoices("object-streams", [this](char *x){c_main->objectStreams(x);}, true, object_streams_choices);
  110 +this->ap.addChoices("password-mode", [this](char *x){c_main->passwordMode(x);}, true, password_mode_choices);
  111 +this->ap.addChoices("remove-unreferenced-resources", [this](char *x){c_main->removeUnreferencedResources(x);}, true, remove_unref_choices);
  112 +this->ap.addChoices("stream-data", [this](char *x){c_main->streamData(x);}, true, stream_data_choices);
113 this->ap.registerOptionTable("pages", b(&ArgParser::argEndPages)); 113 this->ap.registerOptionTable("pages", b(&ArgParser::argEndPages));
114 this->ap.addPositional(p(&ArgParser::argPagesPositional)); 114 this->ap.addPositional(p(&ArgParser::argPagesPositional));
115 this->ap.addRequiredParameter("password", p(&ArgParser::argPagesPassword), "password"); 115 this->ap.addRequiredParameter("password", p(&ArgParser::argPagesPassword), "password");
qpdf/qpdf.testcov
@@ -567,8 +567,6 @@ NNTree erased last item in tree 0 @@ -567,8 +567,6 @@ NNTree erased last item in tree 0
567 NNTree remove limits from root 0 567 NNTree remove limits from root 0
568 QPDFPageObjectHelper unresolved names 0 568 QPDFPageObjectHelper unresolved names 0
569 QPDFPageObjectHelper resolving unresolved 0 569 QPDFPageObjectHelper resolving unresolved 0
570 -qpdf password stdin 0  
571 -qpdf password file 0  
572 QPDFFileSpecObjectHelper empty compat_name 0 570 QPDFFileSpecObjectHelper empty compat_name 0
573 QPDFFileSpecObjectHelper non-empty compat_name 0 571 QPDFFileSpecObjectHelper non-empty compat_name 0
574 QPDFPageObjectHelper flatten inherit rotate 0 572 QPDFPageObjectHelper flatten inherit rotate 0
@@ -630,3 +628,5 @@ qpdf check encrypted not encrypted 0 @@ -630,3 +628,5 @@ qpdf check encrypted not encrypted 0
630 qpdf check password password incorrect 0 628 qpdf check password password incorrect 0
631 qpdf check password password correct 0 629 qpdf check password password correct 0
632 qpdf check password not encrypted 0 630 qpdf check password not encrypted 0
  631 +QPDFJob_config password file 0
  632 +QPDFJob_config password stdin 0