2022-01-05 22:20:20 +00:00
|
|
|
#include <qpdf/QPDFJob.hh>
|
|
|
|
|
2022-01-11 20:52:58 +00:00
|
|
|
// See "HOW TO ADD A COMMAND-LINE ARGUMENT" in README-maintainer.
|
|
|
|
|
2023-05-20 11:22:32 +00:00
|
|
|
#include <cstring>
|
2022-01-05 22:20:20 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
#include <qpdf/QPDFArgParser.hh>
|
|
|
|
#include <qpdf/QPDFCryptoProvider.hh>
|
2022-06-18 14:33:27 +00:00
|
|
|
#include <qpdf/QPDFLogger.hh>
|
2022-01-05 22:20:20 +00:00
|
|
|
#include <qpdf/QTC.hh>
|
|
|
|
#include <qpdf/QUtil.hh>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
class ArgParser
|
|
|
|
{
|
|
|
|
public:
|
2022-01-29 13:54:08 +00:00
|
|
|
ArgParser(QPDFArgParser& ap, std::shared_ptr<QPDFJob::Config> c_main);
|
2022-01-05 22:20:20 +00:00
|
|
|
void parseOptions();
|
|
|
|
|
|
|
|
private:
|
2022-01-06 16:35:14 +00:00
|
|
|
#include <qpdf/auto_job_decl.hh>
|
2022-01-05 22:20:20 +00:00
|
|
|
|
|
|
|
void usage(std::string const& message);
|
2022-01-06 19:26:41 +00:00
|
|
|
void initOptionTables();
|
2022-01-05 22:20:20 +00:00
|
|
|
|
|
|
|
QPDFArgParser ap;
|
2022-01-25 16:07:53 +00:00
|
|
|
std::shared_ptr<QPDFJob::Config> c_main;
|
|
|
|
std::shared_ptr<QPDFJob::CopyAttConfig> c_copy_att;
|
2022-01-25 21:37:17 +00:00
|
|
|
std::shared_ptr<QPDFJob::AttConfig> c_att;
|
2022-01-26 00:01:10 +00:00
|
|
|
std::shared_ptr<QPDFJob::PagesConfig> c_pages;
|
2022-01-26 14:38:34 +00:00
|
|
|
std::shared_ptr<QPDFJob::UOConfig> c_uo;
|
2022-01-26 18:17:57 +00:00
|
|
|
std::shared_ptr<QPDFJob::EncConfig> c_enc;
|
2022-02-01 18:37:31 +00:00
|
|
|
std::vector<std::string> accumulated_args;
|
2023-06-01 13:12:39 +00:00
|
|
|
std::shared_ptr<char> pages_password{nullptr};
|
2023-12-22 23:14:11 +00:00
|
|
|
std::string user_password;
|
|
|
|
std::string owner_password;
|
|
|
|
bool used_enc_password_args{false};
|
2023-06-01 13:12:39 +00:00
|
|
|
bool gave_input{false};
|
|
|
|
bool gave_output{false};
|
2022-01-05 22:20:20 +00:00
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
2022-01-29 13:54:08 +00:00
|
|
|
ArgParser::ArgParser(QPDFArgParser& ap, std::shared_ptr<QPDFJob::Config> c_main) :
|
2022-01-05 22:20:20 +00:00
|
|
|
ap(ap),
|
2023-06-01 13:12:39 +00:00
|
|
|
c_main(c_main)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-06 19:26:41 +00:00
|
|
|
initOptionTables();
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
2022-01-11 16:49:33 +00:00
|
|
|
#include <qpdf/auto_job_help.hh>
|
|
|
|
|
2022-01-05 22:20:20 +00:00
|
|
|
void
|
2022-01-06 19:26:41 +00:00
|
|
|
ArgParser::initOptionTables()
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-06 16:46:40 +00:00
|
|
|
#include <qpdf/auto_job_init.hh>
|
2022-01-29 14:01:20 +00:00
|
|
|
this->ap.addFinalCheck([this]() { c_main->checkConfiguration(); });
|
2022-01-11 16:49:33 +00:00
|
|
|
// add_help is defined in auto_job_help.hh
|
|
|
|
add_help(this->ap);
|
2022-02-15 20:34:35 +00:00
|
|
|
// Special case: ignore -- at the top level. This undocumented behavior is for backward
|
|
|
|
// compatibility; it was unintentionally the case prior to 10.6, and some users were relying on
|
|
|
|
// it.
|
|
|
|
this->ap.selectMainOptionTable();
|
|
|
|
this->ap.addBare("--", []() {});
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-02-01 18:37:31 +00:00
|
|
|
ArgParser::argPositional(std::string const& arg)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-26 18:56:13 +00:00
|
|
|
if (!this->gave_input) {
|
|
|
|
c_main->inputFile(arg);
|
|
|
|
this->gave_input = true;
|
|
|
|
} else if (!this->gave_output) {
|
|
|
|
c_main->outputFile(arg);
|
|
|
|
this->gave_output = true;
|
2022-01-05 22:20:20 +00:00
|
|
|
} else {
|
2022-02-01 18:37:31 +00:00
|
|
|
usage("unknown argument " + arg);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-26 18:39:22 +00:00
|
|
|
void
|
|
|
|
ArgParser::argEmpty()
|
|
|
|
{
|
2022-01-26 18:56:13 +00:00
|
|
|
c_main->emptyInput();
|
|
|
|
this->gave_input = true;
|
2022-01-26 18:39:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argReplaceInput()
|
|
|
|
{
|
2022-01-26 18:56:13 +00:00
|
|
|
c_main->replaceInput();
|
|
|
|
this->gave_output = true;
|
2022-01-26 18:39:22 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 22:20:20 +00:00
|
|
|
void
|
|
|
|
ArgParser::argVersion()
|
|
|
|
{
|
|
|
|
auto whoami = this->ap.getProgname();
|
2022-06-18 14:33:27 +00:00
|
|
|
*QPDFLogger::defaultLogger()->getInfo()
|
|
|
|
<< whoami << " version " << QPDF::QPDFVersion() << "\n"
|
|
|
|
<< "Run " << whoami << " --copyright to see copyright and license information.\n";
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argCopyright()
|
|
|
|
{
|
2022-02-04 21:31:31 +00:00
|
|
|
// clang-format off
|
2022-01-05 22:20:20 +00:00
|
|
|
// Make sure the output looks right on an 80-column display.
|
|
|
|
// 1 2 3 4 5 6 7 8
|
|
|
|
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
2022-06-18 14:33:27 +00:00
|
|
|
*QPDFLogger::defaultLogger()->getInfo()
|
2022-01-05 22:20:20 +00:00
|
|
|
<< this->ap.getProgname()
|
2022-06-18 14:33:27 +00:00
|
|
|
<< " version " << QPDF::QPDFVersion() << "\n"
|
|
|
|
<< "\n"
|
2024-01-01 15:55:55 +00:00
|
|
|
<< "Copyright (c) 2005-2024 Jay Berkenbilt\n"
|
2022-06-18 14:33:27 +00:00
|
|
|
<< "QPDF is licensed under the Apache License, Version 2.0 (the \"License\");\n"
|
|
|
|
<< "you may not use this file except in compliance with the License.\n"
|
|
|
|
<< "You may obtain a copy of the License at\n"
|
|
|
|
<< "\n"
|
|
|
|
<< " http://www.apache.org/licenses/LICENSE-2.0\n"
|
|
|
|
<< "\n"
|
|
|
|
<< "Unless required by applicable law or agreed to in writing, software\n"
|
|
|
|
<< "distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
|
|
<< "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
|
|
|
|
<< "See the License for the specific language governing permissions and\n"
|
|
|
|
<< "limitations under the License.\n"
|
|
|
|
<< "\n"
|
|
|
|
<< "Versions of qpdf prior to version 7 were released under the terms\n"
|
|
|
|
<< "of version 2.0 of the Artistic License. At your option, you may\n"
|
|
|
|
<< "continue to consider qpdf to be licensed under those terms. Please\n"
|
|
|
|
<< "see the manual for additional information.\n";
|
2022-02-04 21:31:31 +00:00
|
|
|
// clang-format on
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-07-31 12:03:18 +00:00
|
|
|
ArgParser::argJsonHelp(std::string const& parameter)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-07-31 12:03:18 +00:00
|
|
|
int version = JSON::LATEST;
|
|
|
|
if (!(parameter.empty() || (parameter == "latest"))) {
|
|
|
|
version = QUtil::string_to_int(parameter.c_str());
|
|
|
|
}
|
|
|
|
if ((version < 1) || (version > JSON::LATEST)) {
|
|
|
|
usage(std::string("unsupported json version ") + parameter);
|
|
|
|
}
|
|
|
|
*QPDFLogger::defaultLogger()->getInfo() << QPDFJob::json_out_schema(version) << "\n";
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argShowCrypto()
|
|
|
|
{
|
|
|
|
auto crypto = QPDFCryptoProvider::getRegisteredImpls();
|
|
|
|
std::string default_crypto = QPDFCryptoProvider::getDefaultProvider();
|
2022-06-18 14:33:27 +00:00
|
|
|
*QPDFLogger::defaultLogger()->getInfo() << default_crypto << "\n";
|
2022-01-05 22:20:20 +00:00
|
|
|
for (auto const& iter: crypto) {
|
|
|
|
if (iter != default_crypto) {
|
2022-06-18 14:33:27 +00:00
|
|
|
*QPDFLogger::defaultLogger()->getInfo() << iter << "\n";
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argEncrypt()
|
|
|
|
{
|
2023-12-23 01:09:31 +00:00
|
|
|
this->c_enc = c_main->encrypt(0, "", "");
|
2022-01-05 22:20:20 +00:00
|
|
|
this->accumulated_args.clear();
|
2022-01-06 16:35:14 +00:00
|
|
|
this->ap.selectOptionTable(O_ENCRYPTION);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-02-01 18:37:31 +00:00
|
|
|
ArgParser::argEncPositional(std::string const& arg)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2023-12-22 23:14:11 +00:00
|
|
|
if (used_enc_password_args) {
|
|
|
|
usage("positional and dashed encryption arguments may not be mixed");
|
|
|
|
}
|
|
|
|
|
2022-01-05 22:20:20 +00:00
|
|
|
this->accumulated_args.push_back(arg);
|
2023-12-22 23:14:11 +00:00
|
|
|
if (this->accumulated_args.size() < 3) {
|
2022-01-05 22:20:20 +00:00
|
|
|
return;
|
|
|
|
}
|
2023-12-22 23:14:11 +00:00
|
|
|
user_password = this->accumulated_args.at(0);
|
|
|
|
owner_password = this->accumulated_args.at(1);
|
|
|
|
auto len_str = this->accumulated_args.at(2);
|
|
|
|
this->accumulated_args.clear();
|
|
|
|
argEncBits(len_str);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
2023-12-22 21:27:56 +00:00
|
|
|
void
|
|
|
|
ArgParser::argEncUserPassword(std::string const& arg)
|
|
|
|
{
|
2023-12-22 23:14:11 +00:00
|
|
|
if (!accumulated_args.empty()) {
|
|
|
|
usage("positional and dashed encryption arguments may not be mixed");
|
|
|
|
}
|
|
|
|
this->used_enc_password_args = true;
|
|
|
|
this->user_password = arg;
|
2023-12-22 21:27:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argEncOwnerPassword(std::string const& arg)
|
|
|
|
{
|
2023-12-22 23:14:11 +00:00
|
|
|
if (!accumulated_args.empty()) {
|
|
|
|
usage("positional and dashed encryption arguments may not be mixed");
|
|
|
|
}
|
|
|
|
this->used_enc_password_args = true;
|
|
|
|
this->owner_password = arg;
|
2023-12-22 21:27:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argEncBits(std::string const& arg)
|
|
|
|
{
|
2023-12-22 23:14:11 +00:00
|
|
|
if (!accumulated_args.empty()) {
|
|
|
|
usage("positional and dashed encryption arguments may not be mixed");
|
|
|
|
}
|
|
|
|
int keylen = 0;
|
|
|
|
if (arg == "40") {
|
|
|
|
keylen = 40;
|
|
|
|
this->ap.selectOptionTable(O_40_BIT_ENCRYPTION);
|
|
|
|
} else if (arg == "128") {
|
|
|
|
keylen = 128;
|
|
|
|
this->ap.selectOptionTable(O_128_BIT_ENCRYPTION);
|
|
|
|
} else if (arg == "256") {
|
|
|
|
keylen = 256;
|
|
|
|
this->ap.selectOptionTable(O_256_BIT_ENCRYPTION);
|
|
|
|
} else {
|
|
|
|
usage("encryption key length must be 40, 128, or 256");
|
|
|
|
}
|
|
|
|
this->c_enc = c_main->encrypt(keylen, user_password, owner_password);
|
2023-12-22 21:27:56 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 22:20:20 +00:00
|
|
|
void
|
|
|
|
ArgParser::argPages()
|
|
|
|
{
|
|
|
|
this->accumulated_args.clear();
|
2022-01-26 00:01:10 +00:00
|
|
|
this->c_pages = c_main->pages();
|
2022-01-05 22:20:20 +00:00
|
|
|
this->ap.selectOptionTable(O_PAGES);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-02-01 18:37:31 +00:00
|
|
|
ArgParser::argPagesPassword(std::string const& parameter)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-02-01 18:37:31 +00:00
|
|
|
if (this->pages_password) {
|
2022-02-01 12:49:00 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob duplicated pages password");
|
2022-01-05 22:20:20 +00:00
|
|
|
usage("--password already specified for this file");
|
|
|
|
}
|
|
|
|
if (this->accumulated_args.size() != 1) {
|
2022-02-01 12:49:00 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob misplaced pages password");
|
2022-01-05 22:20:20 +00:00
|
|
|
usage("in --pages, --password must immediately follow a file name");
|
|
|
|
}
|
2022-02-01 18:37:31 +00:00
|
|
|
this->pages_password = QUtil::make_shared_cstr(parameter);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-02-01 18:37:31 +00:00
|
|
|
ArgParser::argPagesPositional(std::string const& arg)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-02-01 18:37:31 +00:00
|
|
|
if (arg.empty()) {
|
2022-01-05 22:20:20 +00:00
|
|
|
if (this->accumulated_args.empty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this->accumulated_args.push_back(arg);
|
|
|
|
}
|
|
|
|
|
2022-02-01 18:37:31 +00:00
|
|
|
std::string file = this->accumulated_args.at(0);
|
|
|
|
char const* range_p = nullptr;
|
2022-01-05 22:20:20 +00:00
|
|
|
|
|
|
|
size_t n_args = this->accumulated_args.size();
|
|
|
|
if (n_args >= 2) {
|
2022-02-01 18:37:31 +00:00
|
|
|
// will be copied before accumulated_args is cleared
|
|
|
|
range_p = this->accumulated_args.at(1).c_str();
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// See if the user omitted the range entirely, in which case we assume "1-z".
|
2022-02-01 18:37:31 +00:00
|
|
|
std::string next_file;
|
|
|
|
if (range_p == nullptr) {
|
|
|
|
if (arg.empty()) {
|
2022-01-05 22:20:20 +00:00
|
|
|
// The filename or password was the last argument
|
2022-02-01 12:49:00 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob pages range omitted at end", this->pages_password ? 0 : 1);
|
2022-01-05 22:20:20 +00:00
|
|
|
} else {
|
|
|
|
// We need to accumulate some more arguments
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
try {
|
2022-02-01 18:37:31 +00:00
|
|
|
QUtil::parse_numrange(range_p, 0);
|
2022-01-05 22:20:20 +00:00
|
|
|
} catch (std::runtime_error& e1) {
|
|
|
|
// The range is invalid. Let's see if it's a file.
|
2022-02-01 18:37:31 +00:00
|
|
|
if (strcmp(range_p, ".") == 0) {
|
2022-01-05 22:20:20 +00:00
|
|
|
// "." means the input file.
|
2022-02-01 12:49:00 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob pages range omitted with .");
|
2022-02-01 18:37:31 +00:00
|
|
|
} else if (QUtil::file_can_be_opened(range_p)) {
|
2022-02-01 12:49:00 +00:00
|
|
|
QTC::TC("qpdf", "QPDFJob pages range omitted in middle");
|
2022-01-05 22:20:20 +00:00
|
|
|
// Yup, it's a file.
|
|
|
|
} else {
|
|
|
|
// Give the range error
|
|
|
|
usage(e1.what());
|
|
|
|
}
|
2022-02-01 18:37:31 +00:00
|
|
|
next_file = range_p;
|
|
|
|
range_p = nullptr;
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
}
|
2022-02-01 18:37:31 +00:00
|
|
|
std::string range(range_p ? range_p : "1-z");
|
|
|
|
this->c_pages->pageSpec(file, range, this->pages_password.get());
|
2022-01-05 22:20:20 +00:00
|
|
|
this->accumulated_args.clear();
|
|
|
|
this->pages_password = nullptr;
|
2022-02-01 18:37:31 +00:00
|
|
|
if (!next_file.empty()) {
|
2022-01-05 22:20:20 +00:00
|
|
|
this->accumulated_args.push_back(next_file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argEndPages()
|
|
|
|
{
|
2022-02-01 18:37:31 +00:00
|
|
|
argPagesPositional("");
|
2022-01-26 22:02:30 +00:00
|
|
|
c_pages->endPages();
|
2022-01-26 00:01:10 +00:00
|
|
|
c_pages = nullptr;
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argUnderlay()
|
|
|
|
{
|
2022-01-26 14:38:34 +00:00
|
|
|
this->c_uo = c_main->underlay();
|
|
|
|
this->ap.selectOptionTable(O_UNDERLAY_OVERLAY);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argOverlay()
|
|
|
|
{
|
2022-01-26 14:38:34 +00:00
|
|
|
this->c_uo = c_main->overlay();
|
|
|
|
this->ap.selectOptionTable(O_UNDERLAY_OVERLAY);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argAddAttachment()
|
|
|
|
{
|
2022-01-25 21:37:17 +00:00
|
|
|
this->c_att = c_main->addAttachment();
|
2022-01-05 22:20:20 +00:00
|
|
|
this->ap.selectOptionTable(O_ATTACHMENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-06 18:23:15 +00:00
|
|
|
ArgParser::argCopyAttachmentsFrom()
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-25 16:07:53 +00:00
|
|
|
this->c_copy_att = c_main->copyAttachmentsFrom();
|
2022-01-05 22:20:20 +00:00
|
|
|
this->ap.selectOptionTable(O_COPY_ATTACHMENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-06 18:23:15 +00:00
|
|
|
ArgParser::argEndEncryption()
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-26 22:02:30 +00:00
|
|
|
c_enc->endEncrypt();
|
2022-01-26 18:17:57 +00:00
|
|
|
c_enc = nullptr;
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
2022-01-06 19:26:41 +00:00
|
|
|
void
|
|
|
|
ArgParser::argEnd40BitEncryption()
|
|
|
|
{
|
|
|
|
argEndEncryption();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argEnd128BitEncryption()
|
|
|
|
{
|
|
|
|
argEndEncryption();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argEnd256BitEncryption()
|
|
|
|
{
|
|
|
|
argEndEncryption();
|
|
|
|
}
|
|
|
|
|
2022-01-05 22:20:20 +00:00
|
|
|
void
|
2022-02-01 18:37:31 +00:00
|
|
|
ArgParser::argUOPositional(std::string const& arg)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-31 18:07:19 +00:00
|
|
|
c_uo->file(arg);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-06 18:23:15 +00:00
|
|
|
ArgParser::argEndUnderlayOverlay()
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-26 22:02:30 +00:00
|
|
|
c_uo->endUnderlayOverlay();
|
2022-01-26 14:38:34 +00:00
|
|
|
c_uo = nullptr;
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-02-01 18:37:31 +00:00
|
|
|
ArgParser::argAttPositional(std::string const& arg)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-31 18:07:19 +00:00
|
|
|
c_att->file(arg);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-06 18:23:15 +00:00
|
|
|
ArgParser::argEndAttachment()
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-26 22:02:30 +00:00
|
|
|
c_att->endAddAttachment();
|
2022-01-25 21:37:17 +00:00
|
|
|
c_att = nullptr;
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-02-01 18:37:31 +00:00
|
|
|
ArgParser::argCopyAttPositional(std::string const& arg)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-31 18:07:19 +00:00
|
|
|
c_copy_att->file(arg);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-06 18:23:15 +00:00
|
|
|
ArgParser::argEndCopyAttachment()
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
2022-01-26 22:02:30 +00:00
|
|
|
c_copy_att->endCopyAttachmentsFrom();
|
2022-01-25 16:07:53 +00:00
|
|
|
c_copy_att = nullptr;
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
2024-01-05 17:16:13 +00:00
|
|
|
void
|
|
|
|
ArgParser::argSetPageLabels()
|
|
|
|
{
|
|
|
|
this->ap.selectOptionTable(O_SET_PAGE_LABELS);
|
|
|
|
accumulated_args.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argPageLabelsPositional(std::string const& arg)
|
|
|
|
{
|
|
|
|
accumulated_args.push_back(arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::argEndSetPageLabels()
|
|
|
|
{
|
|
|
|
c_main->setPageLabels(accumulated_args);
|
|
|
|
accumulated_args.clear();
|
|
|
|
}
|
|
|
|
|
2022-01-22 21:29:13 +00:00
|
|
|
void
|
|
|
|
ArgParser::argJobJsonHelp()
|
|
|
|
{
|
2022-06-18 14:33:27 +00:00
|
|
|
*QPDFLogger::defaultLogger()->getInfo()
|
2022-07-31 12:03:18 +00:00
|
|
|
<< QPDFJob::job_json_schema(QPDFJob::LATEST_JOB_JSON) << "\n";
|
2022-01-22 21:29:13 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 22:20:20 +00:00
|
|
|
void
|
|
|
|
ArgParser::usage(std::string const& message)
|
|
|
|
{
|
2022-01-06 14:51:34 +00:00
|
|
|
this->ap.usage(message);
|
2022-01-05 22:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ArgParser::parseOptions()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
this->ap.parseArgs();
|
2022-01-28 12:46:04 +00:00
|
|
|
} catch (std::runtime_error& e) {
|
2022-01-05 22:20:20 +00:00
|
|
|
usage(e.what());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-02-01 18:49:11 +00:00
|
|
|
QPDFJob::initializeFromArgv(char const* const argv[], char const* progname_env)
|
2022-01-05 22:20:20 +00:00
|
|
|
{
|
|
|
|
if (progname_env == nullptr) {
|
|
|
|
progname_env = "QPDF_EXECUTABLE";
|
|
|
|
}
|
2022-02-01 18:49:11 +00:00
|
|
|
int argc = 0;
|
|
|
|
for (auto k = argv; *k; ++k) {
|
|
|
|
++argc;
|
|
|
|
}
|
2022-01-22 23:57:01 +00:00
|
|
|
QPDFArgParser qap(argc, argv, progname_env);
|
|
|
|
setMessagePrefix(qap.getProgname());
|
2022-01-29 13:54:08 +00:00
|
|
|
ArgParser ap(qap, config());
|
2022-01-05 22:20:20 +00:00
|
|
|
ap.parseOptions();
|
|
|
|
}
|