Commit ac039c8525407361477f041550db6fb0efbc497a

Authored by m-holger
1 parent 0fae76cf

Refactor `QPDFJob`: replace `infilename` with `infile_name()`, centralize input …

…file handling in `Inputs`, and simplify related logic.
libqpdf/QPDFJob.cc
@@ -394,7 +394,7 @@ QPDFJob::createQPDF() @@ -394,7 +394,7 @@ QPDFJob::createQPDF()
394 checkConfiguration(); 394 checkConfiguration();
395 std::unique_ptr<QPDF> pdf_sp; 395 std::unique_ptr<QPDF> pdf_sp;
396 try { 396 try {
397 - processFile(pdf_sp, m->infilename.data(), m->password.data(), true, true); 397 + processFile(pdf_sp, m->infile_nm(), m->password.data(), true, true);
398 } catch (QPDFExc& e) { 398 } catch (QPDFExc& e) {
399 if (e.getErrorCode() == qpdf_e_password) { 399 if (e.getErrorCode() == qpdf_e_password) {
400 // Allow certain operations to work when an incorrect password is supplied. 400 // Allow certain operations to work when an incorrect password is supplied.
@@ -567,10 +567,10 @@ QPDFJob::checkConfiguration() @@ -567,10 +567,10 @@ QPDFJob::checkConfiguration()
567 // standard output. 567 // standard output.
568 m->outfilename = "-"; 568 m->outfilename = "-";
569 } 569 }
570 - if (m->infilename.empty() && !m->empty_input) { 570 + if (m->infile_name().empty() && !m->empty_input) {
571 usage("an input file name is required"); 571 usage("an input file name is required");
572 } 572 }
573 - if (m->replace_input && m->infilename.empty()) { 573 + if (m->replace_input && m->infile_name().empty()) {
574 usage("--replace-input may not be used with --empty"); 574 usage("--replace-input may not be used with --empty");
575 } 575 }
576 if (m->require_outfile && m->outfilename.empty() && !m->replace_input) { 576 if (m->require_outfile && m->outfilename.empty() && !m->replace_input) {
@@ -609,8 +609,7 @@ QPDFJob::checkConfiguration() @@ -609,8 +609,7 @@ QPDFJob::checkConfiguration()
609 if (save_to_stdout) { 609 if (save_to_stdout) {
610 m->log->saveToStandardOutput(true); 610 m->log->saveToStandardOutput(true);
611 } 611 }
612 - if (!m->split_pages && QUtil::same_file(m->infilename.data(), m->outfilename.data())) {  
613 - QTC::TC("qpdf", "QPDFJob same file error"); 612 + if (!m->split_pages && QUtil::same_file(m->infile_nm(), m->outfilename.data())) {
614 usage( 613 usage(
615 "input file and output file are the same; use --replace-input to intentionally " 614 "input file and output file are the same; use --replace-input to intentionally "
616 "overwrite the input file"); 615 "overwrite the input file");
@@ -734,7 +733,7 @@ QPDFJob::doCheck(QPDF&amp; pdf) @@ -734,7 +733,7 @@ QPDFJob::doCheck(QPDF&amp; pdf)
734 // may continue to perform additional checks after finding errors. 733 // may continue to perform additional checks after finding errors.
735 bool okay = true; 734 bool okay = true;
736 auto& cout = *m->log->getInfo(); 735 auto& cout = *m->log->getInfo();
737 - cout << "checking " << m->infilename << "\n"; 736 + cout << "checking " << m->infile_name() << "\n";
738 QPDF::JobSetter::setCheckMode(pdf, true); 737 QPDF::JobSetter::setCheckMode(pdf, true);
739 try { 738 try {
740 int extension_level = pdf.getExtensionLevel(); 739 int extension_level = pdf.getExtensionLevel();
@@ -905,7 +904,7 @@ QPDFJob::doListAttachments(QPDF&amp; pdf) @@ -905,7 +904,7 @@ QPDFJob::doListAttachments(QPDF&amp; pdf)
905 }); 904 });
906 } 905 }
907 } else { 906 } else {
908 - *m->log->getInfo() << m->infilename << " has no embedded files\n"; 907 + *m->log->getInfo() << m->infile_name() << " has no embedded files\n";
909 } 908 }
910 } 909 }
911 910
@@ -1671,7 +1670,6 @@ QPDFJob::doInspection(QPDF&amp; pdf) @@ -1671,7 +1670,6 @@ QPDFJob::doInspection(QPDF&amp; pdf)
1671 doCheck(pdf); 1670 doCheck(pdf);
1672 } 1671 }
1673 if (m->show_npages) { 1672 if (m->show_npages) {
1674 - QTC::TC("qpdf", "QPDFJob npages");  
1675 cout << pdf.getRoot().getKey("/Pages").getKey("/Count").getIntValue() << "\n"; 1673 cout << pdf.getRoot().getKey("/Pages").getKey("/Count").getIntValue() << "\n";
1676 } 1674 }
1677 if (m->show_encryption) { 1675 if (m->show_encryption) {
@@ -1679,9 +1677,9 @@ QPDFJob::doInspection(QPDF&amp; pdf) @@ -1679,9 +1677,9 @@ QPDFJob::doInspection(QPDF&amp; pdf)
1679 } 1677 }
1680 if (m->check_linearization) { 1678 if (m->check_linearization) {
1681 if (!pdf.isLinearized()) { 1679 if (!pdf.isLinearized()) {
1682 - cout << m->infilename << " is not linearized\n"; 1680 + cout << m->infile_name() << " is not linearized\n";
1683 } else if (pdf.checkLinearization()) { 1681 } else if (pdf.checkLinearization()) {
1684 - cout << m->infilename << ": no linearization errors\n"; 1682 + cout << m->infile_name() << ": no linearization errors\n";
1685 } else { 1683 } else {
1686 m->warnings = true; 1684 m->warnings = true;
1687 } 1685 }
@@ -1690,7 +1688,7 @@ QPDFJob::doInspection(QPDF&amp; pdf) @@ -1690,7 +1688,7 @@ QPDFJob::doInspection(QPDF&amp; pdf)
1690 if (pdf.isLinearized()) { 1688 if (pdf.isLinearized()) {
1691 pdf.showLinearizationData(); 1689 pdf.showLinearizationData();
1692 } else { 1690 } else {
1693 - cout << m->infilename << " is not linearized\n"; 1691 + cout << m->infile_name() << " is not linearized\n";
1694 } 1692 }
1695 } 1693 }
1696 if (m->show_xref) { 1694 if (m->show_xref) {
@@ -1727,7 +1725,7 @@ QPDFJob::doProcessOnce( @@ -1727,7 +1725,7 @@ QPDFJob::doProcessOnce(
1727 if (empty) { 1725 if (empty) {
1728 pdf->emptyPDF(); 1726 pdf->emptyPDF();
1729 } else if (main_input && m->json_input) { 1727 } else if (main_input && m->json_input) {
1730 - pdf->createFromJSON(m->infilename); 1728 + pdf->createFromJSON(m->infile_name());
1731 } else { 1729 } else {
1732 fn(pdf.get(), password); 1730 fn(pdf.get(), password);
1733 } 1731 }
@@ -2431,13 +2429,13 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf) @@ -2431,13 +2429,13 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf)
2431 if (m->inputs.selections.empty()) { 2429 if (m->inputs.selections.empty()) {
2432 return; 2430 return;
2433 } 2431 }
2434 - auto& main_input = m->inputs.files[m->infilename]; 2432 + auto& main_input = m->inputs.files[m->infile_name()];
2435 main_input.initialize(m->inputs, &pdf); 2433 main_input.initialize(m->inputs, &pdf);
2436 2434
2437 // Handle "." as a shortcut for the input file. 2435 // Handle "." as a shortcut for the input file.
2438 for (auto& selection: m->inputs.selections) { 2436 for (auto& selection: m->inputs.selections) {
2439 if (selection.filename == ".") { 2437 if (selection.filename == ".") {
2440 - selection.filename = m->infilename; 2438 + selection.filename = m->infile_name();
2441 } else { 2439 } else {
2442 // Force insertion 2440 // Force insertion
2443 (void)m->inputs.files[selection.filename]; 2441 (void)m->inputs.files[selection.filename];
@@ -3012,7 +3010,7 @@ QPDFJob::doSplitPages(QPDF&amp; pdf) @@ -3012,7 +3010,7 @@ QPDFJob::doSplitPages(QPDF&amp; pdf)
3012 page_range += "-" + QUtil::uint_to_string(last, QIntC::to_int(pageno_len)); 3010 page_range += "-" + QUtil::uint_to_string(last, QIntC::to_int(pageno_len));
3013 } 3011 }
3014 std::string outfile = before + page_range + after; 3012 std::string outfile = before + page_range + after;
3015 - if (QUtil::same_file(m->infilename.data(), outfile.data())) { 3013 + if (QUtil::same_file(m->infile_nm(), outfile.data())) {
3016 throw std::runtime_error("split pages would overwrite input file with " + outfile); 3014 throw std::runtime_error("split pages would overwrite input file with " + outfile);
3017 } 3015 }
3018 QPDFWriter w(outpdf, outfile.c_str()); 3016 QPDFWriter w(outpdf, outfile.c_str());
@@ -3031,7 +3029,7 @@ QPDFJob::writeOutfile(QPDF&amp; pdf) @@ -3031,7 +3029,7 @@ QPDFJob::writeOutfile(QPDF&amp; pdf)
3031 if (m->replace_input) { 3029 if (m->replace_input) {
3032 // Append but don't prepend to the path to generate a temporary name. This saves us from 3030 // Append but don't prepend to the path to generate a temporary name. This saves us from
3033 // having to split the path by directory and non-directory. 3031 // having to split the path by directory and non-directory.
3034 - temp_out = m->infilename + ".~qpdf-temp#"; 3032 + temp_out = m->infile_name() + ".~qpdf-temp#";
3035 // m->outfilename will be restored to 0 before temp_out goes out of scope. 3033 // m->outfilename will be restored to 0 before temp_out goes out of scope.
3036 m->outfilename = temp_out; 3034 m->outfilename = temp_out;
3037 } else if (m->outfilename == "-") { 3035 } else if (m->outfilename == "-") {
@@ -3065,13 +3063,13 @@ QPDFJob::writeOutfile(QPDF&amp; pdf) @@ -3065,13 +3063,13 @@ QPDFJob::writeOutfile(QPDF&amp; pdf)
3065 if (m->replace_input) { 3063 if (m->replace_input) {
3066 // We must close the input before we can rename files 3064 // We must close the input before we can rename files
3067 pdf.closeInputSource(); 3065 pdf.closeInputSource();
3068 - std::string backup = m->infilename + ".~qpdf-orig"; 3066 + std::string backup = m->infile_name() + ".~qpdf-orig";
3069 bool warnings = pdf.anyWarnings(); 3067 bool warnings = pdf.anyWarnings();
3070 if (!warnings) { 3068 if (!warnings) {
3071 backup.append(1, '#'); 3069 backup.append(1, '#');
3072 } 3070 }
3073 - QUtil::rename_file(m->infilename.data(), backup.data());  
3074 - QUtil::rename_file(temp_out.data(), m->infilename.data()); 3071 + QUtil::rename_file(m->infile_nm(), backup.data());
  3072 + QUtil::rename_file(temp_out.data(), m->infile_nm());
3075 if (warnings) { 3073 if (warnings) {
3076 *m->log->getError() << m->message_prefix 3074 *m->log->getError() << m->message_prefix
3077 << ": there are warnings; original file kept in " << backup << "\n"; 3075 << ": there are warnings; original file kept in " << backup << "\n";
libqpdf/QPDFJob_config.cc
@@ -15,18 +15,14 @@ QPDFJob::Config::checkConfiguration() @@ -15,18 +15,14 @@ QPDFJob::Config::checkConfiguration()
15 QPDFJob::Config* 15 QPDFJob::Config*
16 QPDFJob::Config::inputFile(std::string const& filename) 16 QPDFJob::Config::inputFile(std::string const& filename)
17 { 17 {
18 - if (o.m->infilename.empty()) {  
19 - o.m->infilename = filename;  
20 - } else {  
21 - usage("input file has already been given");  
22 - } 18 + o.m->inputs.infile_name(filename);
23 return this; 19 return this;
24 } 20 }
25 21
26 QPDFJob::Config* 22 QPDFJob::Config*
27 QPDFJob::Config::emptyInput() 23 QPDFJob::Config::emptyInput()
28 { 24 {
29 - if (o.m->infilename.empty()) { 25 + if (o.m->infile_name().empty()) {
30 // Various places in QPDFJob.cc used to know that the empty string for infile means empty. 26 // Various places in QPDFJob.cc used to know that the empty string for infile means empty.
31 // This approach meant that passing "" as the argument to inputFile in job JSON, or 27 // This approach meant that passing "" as the argument to inputFile in job JSON, or
32 // equivalently using "" as a positional command-line argument would be the same as 28 // equivalently using "" as a positional command-line argument would be the same as
libqpdf/qpdf/QPDFJob_private.hh
@@ -69,6 +69,22 @@ struct QPDFJob::Inputs @@ -69,6 +69,22 @@ struct QPDFJob::Inputs
69 void new_selection( 69 void new_selection(
70 std::string const& filename, std::string const& password, std::string const& range); 70 std::string const& filename, std::string const& password, std::string const& range);
71 71
  72 + std::string const&
  73 + infile_name() const
  74 + {
  75 + return infile_name_;
  76 + }
  77 +
  78 + void
  79 + infile_name(std::string const& name)
  80 + {
  81 + if (!infile_name_.empty()) {
  82 + usage("input file has already been given");
  83 + }
  84 + infile_name_ = name;
  85 + }
  86 +
  87 + std::string infile_name_;
72 std::string encryption_file; 88 std::string encryption_file;
73 std::string encryption_file_password; 89 std::string encryption_file_password;
74 bool keep_files_open{true}; 90 bool keep_files_open{true};
@@ -145,6 +161,10 @@ class QPDFJob::Members @@ -145,6 +161,10 @@ class QPDFJob::Members
145 Members(Members const&) = delete; 161 Members(Members const&) = delete;
146 ~Members() = default; 162 ~Members() = default;
147 163
  164 + inline const char* infile_nm() const;
  165 +
  166 + inline std::string const& infile_name() const;
  167 +
148 private: 168 private:
149 // These default values are duplicated in help and docs. 169 // These default values are duplicated in help and docs.
150 static int constexpr DEFAULT_OI_MIN_WIDTH = 128; 170 static int constexpr DEFAULT_OI_MIN_WIDTH = 128;
@@ -272,7 +292,6 @@ class QPDFJob::Members @@ -272,7 +292,6 @@ class QPDFJob::Members
272 bool replace_input{false}; 292 bool replace_input{false};
273 bool check_is_encrypted{false}; 293 bool check_is_encrypted{false};
274 bool check_requires_password{false}; 294 bool check_requires_password{false};
275 - std::string infilename;  
276 bool empty_input{false}; 295 bool empty_input{false};
277 std::string outfilename; 296 std::string outfilename;
278 bool json_input{false}; 297 bool json_input{false};
@@ -282,4 +301,16 @@ class QPDFJob::Members @@ -282,4 +301,16 @@ class QPDFJob::Members
282 std::vector<PageLabelSpec> page_label_specs; 301 std::vector<PageLabelSpec> page_label_specs;
283 }; 302 };
284 303
285 -#endif // QPDFOBJECT_PRIVATE_HH 304 +inline const char*
  305 +QPDFJob::Members::infile_nm() const
  306 +{
  307 + return inputs.infile_name().data();
  308 +}
  309 +
  310 +inline std::string const&
  311 +QPDFJob::Members::infile_name() const
  312 +{
  313 + return inputs.infile_name();
  314 +}
  315 +
  316 +#endif // QPDFJOB_PRIVATE_HH
qpdf/qpdf.testcov
@@ -208,7 +208,6 @@ QPDF not caching overridden objstm object 0 @@ -208,7 +208,6 @@ QPDF not caching overridden objstm object 0
208 QPDF_optimization indirect outlines 0 208 QPDF_optimization indirect outlines 0
209 QPDF xref space 2 209 QPDF xref space 2
210 QPDFJob pages range omitted in middle 0 210 QPDFJob pages range omitted in middle 0
211 -QPDFJob npages 0  
212 QPDFWriter standard deterministic ID 1 211 QPDFWriter standard deterministic ID 1
213 QPDFWriter linearized deterministic ID 1 212 QPDFWriter linearized deterministic ID 1
214 qpdf-c called qpdf_set_deterministic_ID 0 213 qpdf-c called qpdf_set_deterministic_ID 0
@@ -221,7 +220,6 @@ QPDFParser found fake 1 @@ -221,7 +220,6 @@ QPDFParser found fake 1
221 QPDFParser no val for last key 0 220 QPDFParser no val for last key 0
222 QPDF resolve failure to null 0 221 QPDF resolve failure to null 0
223 QPDFObjectHandle errors in parsecontent 0 222 QPDFObjectHandle errors in parsecontent 0
224 -QPDFJob same file error 0  
225 QPDFJob split-pages %d 0 223 QPDFJob split-pages %d 0
226 QPDFJob split-pages .pdf 0 224 QPDFJob split-pages .pdf 0
227 QPDFJob split-pages other 0 225 QPDFJob split-pages other 0