From b02d37bc0ae0b7af6077637f855be8579c768c22 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Tue, 1 Feb 2022 13:37:31 -0500 Subject: Make QPDFArgParser accept const argv This makes it much more convention to use the initializeFromArgv functions since you can use string literals. --- generate_auto_job | 65 +++++---- include/qpdf/QPDFJob.hh | 14 +- include/qpdf/QUtil.hh | 9 +- include/qpdf/auto_job_c_att.hh | 12 +- include/qpdf/auto_job_c_copy_att.hh | 4 +- include/qpdf/auto_job_c_enc.hh | 18 +-- include/qpdf/auto_job_c_main.hh | 64 ++++----- include/qpdf/auto_job_c_uo.hh | 8 +- include/qpdf/qpdfjob-c.h | 4 +- job.sums | 18 +-- libqpdf/QPDFArgParser.cc | 88 ++++++------ libqpdf/QPDFJob_argv.cc | 65 +++++---- libqpdf/QPDFJob_config.cc | 263 ++++++++++++++++++------------------ libqpdf/QUtil.cc | 28 +++- libqpdf/qpdf/QPDFArgParser.hh | 38 ++---- libqpdf/qpdf/auto_job_decl.hh | 14 +- libqpdf/qpdf/auto_job_init.hh | 132 +++++++++--------- libqpdf/qpdf/auto_job_json_init.hh | 130 +++++++++--------- libqpdf/qpdfjob-c.cc | 7 +- libtests/arg_parser.cc | 24 ++-- libtests/main_from_wmain.cc | 29 +++- libtests/qtest/qutil/wmain.out | 3 + qpdf/qpdfjob-ctest.c | 20 +-- 23 files changed, 556 insertions(+), 501 deletions(-) diff --git a/generate_auto_job b/generate_auto_job index e56c0e60..df848ba3 100755 --- a/generate_auto_job +++ b/generate_auto_job @@ -111,13 +111,14 @@ from contextlib import contextmanager # Every command-line option in the main option table has a # corresponding method in Config whose name is the option converted to # camel case. For bare options and options with optional parameters, a -# version exists that takes no arguments. For others, a version exists -# that takes a char const*. For example, the --qdf flag implies a -# qdf() method in Config, and the --object-streams flag implies an -# objectStreams(char const*) method in Config. For flags in option -# tables, the method is declared inside a config class specific to the -# option table. The mapping between option tables and config classes -# is explicit in job.yml. Positional arguments are handled +# version exists that takes no arguments. For other than bare options, +# a version exist, possibly in addition, that takes a std::string +# const&. For example, the --qdf flag implies a qdf() method in +# Config, and the --object-streams flag implies an +# objectStreams(std::string const&) method in Config. For flags in +# option tables, the method is declared inside a config class specific +# to the option table. The mapping between option tables and config +# classes is explicit in job.yml. Positional arguments are handled # individually and manually -- see QPDFJob.hh in the CONFIGURATION # section for details. See examples/qpdf-job.cc for an example. # @@ -460,29 +461,33 @@ class Main: self.init.append(f'this->ap.addBare("{i}", ' f'[this](){{{cfg}->{identifier}();}});') elif kind == 'required_parameter': - self.init.append(f'this->ap.addRequiredParameter("{i}", ' - f'[this](char *x){{{cfg}->{identifier}(x);}}' - f', "{v}");') + self.init.append( + f'this->ap.addRequiredParameter("{i}", ' + f'[this](std::string const& x){{{cfg}->{identifier}(x);}}' + f', "{v}");') elif kind == 'optional_parameter': decl_arg_optional = True - self.init.append(f'this->ap.addOptionalParameter("{i}", ' - f'[this](char *x){{{cfg}->{identifier}(x);}});') + self.init.append( + f'this->ap.addOptionalParameter("{i}", ' + f'[this](std::string const& x){{{cfg}->{identifier}(x);}});') elif kind == 'required_choices': - self.init.append(f'this->ap.addChoices("{i}", ' - f'[this](char *x){{{cfg}->{identifier}(x);}}' - f', true, {v}_choices);') + self.init.append( + f'this->ap.addChoices("{i}", ' + f'[this](std::string const& x){{{cfg}->{identifier}(x);}}' + f', true, {v}_choices);') elif kind == 'optional_choices': decl_arg_optional = True - self.init.append(f'this->ap.addChoices("{i}", ' - f'[this](char *x){{{cfg}->{identifier}(x);}}' - f', false, {v}_choices);') + self.init.append( + f'this->ap.addChoices("{i}", ' + f'[this](std::string const& x){{{cfg}->{identifier}(x);}}' + f', false, {v}_choices);') # Generate declarations for config methods separately by # config object. config_prefix = prefix + 'Config' arg = '' if decl_arg: - arg = 'char const* parameter' + arg = 'std::string const& parameter' fn = f'{config_prefix}* {identifier}({arg})' if fn not in self.declared_configs: self.declared_configs.add(fn) @@ -510,21 +515,21 @@ class Main: self.init.append(f'this->ap.addBare("{i}", ' f'b(&ArgParser::{identifier}));') elif kind == 'required_parameter': - self.decls.append(f'void {identifier}(char *);') + self.decls.append(f'void {identifier}(std::string const&);') self.init.append(f'this->ap.addRequiredParameter("{i}", ' f'p(&ArgParser::{identifier})' f', "{v}");') elif kind == 'optional_parameter': - self.decls.append(f'void {identifier}(char *);') + self.decls.append(f'void {identifier}(std::string const&);') self.init.append(f'this->ap.addOptionalParameter("{i}", ' f'p(&ArgParser::{identifier}));') elif kind == 'required_choices': - self.decls.append(f'void {identifier}(char *);') + self.decls.append(f'void {identifier}(std::string const&);') self.init.append(f'this->ap.addChoices("{i}", ' f'p(&ArgParser::{identifier})' f', true, {v}_choices);') elif kind == 'optional_choices': - self.decls.append(f'void {identifier}(char *);') + self.decls.append(f'void {identifier}(std::string const&);') self.init.append(f'this->ap.addChoices("{i}", ' f'p(&ArgParser::{identifier})' f', false, {v}_choices);') @@ -555,7 +560,8 @@ class Main: self.init.append('auto b = [this](void (ArgParser::*f)()) {') self.init.append(' return QPDFArgParser::bindBare(f, this);') self.init.append('};') - self.init.append('auto p = [this](void (ArgParser::*f)(char *)) {') + self.init.append( + 'auto p = [this](void (ArgParser::*f)(std::string const&)) {') self.init.append(' return QPDFArgParser::bindParam(f, this);') self.init.append('};') self.init.append('') @@ -615,7 +621,8 @@ class Main: self.init.append(f'this->ap.registerOptionTable("{table}",' f' b(&ArgParser::{identifier}));') if o.get('positional', False): - self.decls.append(f'void {arg_prefix}Positional(char*);') + self.decls.append( + f'void {arg_prefix}Positional(std::string const&);') self.init.append('this->ap.addPositional(' f'p(&ArgParser::{arg_prefix}Positional));') @@ -667,16 +674,18 @@ class Main: # so the handler has to deal with it. The empty string is # also allowed for non-optional. self.json_init.append( - f'addParameter([this](char const* p)' + f'addParameter([this](std::string const& p)' f' {{ {config}->{flag_key}(p); }});') elif kind == 'required_choices': self.json_init.append( f'addChoices({v}_choices, true,' - f' [this](char const* p) {{ {config}->{flag_key}(p); }});') + f' [this](std::string const& p)' + f' {{ {config}->{flag_key}(p); }});') elif kind == 'optional_choices': self.json_init.append( f'addChoices({v}_choices, false,' - f' [this](char const* p) {{ {config}->{flag_key}(p); }});') + f' [this](std::string const& p)' + f' {{ {config}->{flag_key}(p); }});') def handle_json_manual(self, path): method = re.sub(r'\.([a-zA-Z0-9])', diff --git a/include/qpdf/QPDFJob.hh b/include/qpdf/QPDFJob.hh index e16e5ca1..44ec723c 100644 --- a/include/qpdf/QPDFJob.hh +++ b/include/qpdf/QPDFJob.hh @@ -77,7 +77,7 @@ class QPDFJob // arguments to UTF-8. This method will mutate arguments that are // passed to it. QPDF_DLL - void initializeFromArgv(int argc, char* argv[], + void initializeFromArgv(int argc, char const* const argv[], char const* progname_env = nullptr); // Initialize a QPDFJob from json. Passing partial = true prevents @@ -205,7 +205,7 @@ class QPDFJob QPDF_DLL Config* endAddAttachment(); QPDF_DLL - AttConfig* file(char const* parameter); + AttConfig* file(std::string const& parameter); # include @@ -225,7 +225,7 @@ class QPDFJob QPDF_DLL Config* endCopyAttachmentsFrom(); QPDF_DLL - CopyAttConfig* file(char const* parameter); + CopyAttConfig* file(std::string const& parameter); # include @@ -266,7 +266,7 @@ class QPDFJob QPDF_DLL Config* endUnderlayOverlay(); QPDF_DLL - UOConfig* file(char const* parameter); + UOConfig* file(std::string const& parameter); # include @@ -285,7 +285,7 @@ class QPDFJob QPDF_DLL Config* endEncrypt(); QPDF_DLL - EncConfig* file(char const* parameter); + EncConfig* file(std::string const& parameter); # include @@ -305,11 +305,11 @@ class QPDFJob void checkConfiguration(); QPDF_DLL - Config* inputFile(char const* filename); + Config* inputFile(std::string const& filename); QPDF_DLL Config* emptyInput(); QPDF_DLL - Config* outputFile(char const* filename); + Config* outputFile(std::string const& filename); QPDF_DLL Config* replaceInput(); diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh index d23e3f85..bcd0d407 100644 --- a/include/qpdf/QUtil.hh +++ b/include/qpdf/QUtil.hh @@ -435,8 +435,13 @@ namespace QUtil // invoked, convert all UTF-16 encoded strings to UTF-8, and call // another main. QPDF_DLL - int call_main_from_wmain(int argc, wchar_t* argv[], - std::function realmain); + int call_main_from_wmain( + int argc, wchar_t* argv[], + std::function realmain); + QPDF_DLL + int call_main_from_wmain( + int argc, wchar_t const* const argv[], + std::function realmain); #endif // QPDF_NO_WCHAR_T }; diff --git a/include/qpdf/auto_job_c_att.hh b/include/qpdf/auto_job_c_att.hh index a65d8908..b94774f5 100644 --- a/include/qpdf/auto_job_c_att.hh +++ b/include/qpdf/auto_job_c_att.hh @@ -4,9 +4,9 @@ // run in maintainer mode. // QPDF_DLL AttConfig* replace(); -QPDF_DLL AttConfig* key(char const* parameter); -QPDF_DLL AttConfig* filename(char const* parameter); -QPDF_DLL AttConfig* creationdate(char const* parameter); -QPDF_DLL AttConfig* moddate(char const* parameter); -QPDF_DLL AttConfig* mimetype(char const* parameter); -QPDF_DLL AttConfig* description(char const* parameter); +QPDF_DLL AttConfig* key(std::string const& parameter); +QPDF_DLL AttConfig* filename(std::string const& parameter); +QPDF_DLL AttConfig* creationdate(std::string const& parameter); +QPDF_DLL AttConfig* moddate(std::string const& parameter); +QPDF_DLL AttConfig* mimetype(std::string const& parameter); +QPDF_DLL AttConfig* description(std::string const& parameter); diff --git a/include/qpdf/auto_job_c_copy_att.hh b/include/qpdf/auto_job_c_copy_att.hh index 8049dc6d..e372ab93 100644 --- a/include/qpdf/auto_job_c_copy_att.hh +++ b/include/qpdf/auto_job_c_copy_att.hh @@ -3,5 +3,5 @@ // Edits will be automatically overwritten if the build is // run in maintainer mode. // -QPDF_DLL CopyAttConfig* prefix(char const* parameter); -QPDF_DLL CopyAttConfig* password(char const* parameter); +QPDF_DLL CopyAttConfig* prefix(std::string const& parameter); +QPDF_DLL CopyAttConfig* password(std::string const& parameter); diff --git a/include/qpdf/auto_job_c_enc.hh b/include/qpdf/auto_job_c_enc.hh index c5b10c6b..fc9e3b53 100644 --- a/include/qpdf/auto_job_c_enc.hh +++ b/include/qpdf/auto_job_c_enc.hh @@ -3,16 +3,16 @@ // Edits will be automatically overwritten if the build is // run in maintainer mode. // -QPDF_DLL EncConfig* extract(char const* parameter); -QPDF_DLL EncConfig* annotate(char const* parameter); -QPDF_DLL EncConfig* print(char const* parameter); -QPDF_DLL EncConfig* modify(char const* parameter); +QPDF_DLL EncConfig* extract(std::string const& parameter); +QPDF_DLL EncConfig* annotate(std::string const& parameter); +QPDF_DLL EncConfig* print(std::string const& parameter); +QPDF_DLL EncConfig* modify(std::string const& parameter); QPDF_DLL EncConfig* cleartextMetadata(); QPDF_DLL EncConfig* forceV4(); -QPDF_DLL EncConfig* accessibility(char const* parameter); -QPDF_DLL EncConfig* assemble(char const* parameter); -QPDF_DLL EncConfig* form(char const* parameter); -QPDF_DLL EncConfig* modifyOther(char const* parameter); -QPDF_DLL EncConfig* useAes(char const* parameter); +QPDF_DLL EncConfig* accessibility(std::string const& parameter); +QPDF_DLL EncConfig* assemble(std::string const& parameter); +QPDF_DLL EncConfig* form(std::string const& parameter); +QPDF_DLL EncConfig* modifyOther(std::string const& parameter); +QPDF_DLL EncConfig* useAes(std::string const& parameter); QPDF_DLL EncConfig* forceR5(); QPDF_DLL EncConfig* allowInsecure(); diff --git a/include/qpdf/auto_job_c_main.hh b/include/qpdf/auto_job_c_main.hh index c3b4f63c..87987443 100644 --- a/include/qpdf/auto_job_c_main.hh +++ b/include/qpdf/auto_job_c_main.hh @@ -44,38 +44,38 @@ QPDF_DLL Config* suppressRecovery(); QPDF_DLL Config* verbose(); QPDF_DLL Config* warningExit0(); QPDF_DLL Config* withImages(); -QPDF_DLL Config* compressionLevel(char const* parameter); -QPDF_DLL Config* copyEncryption(char const* parameter); -QPDF_DLL Config* encryptionFilePassword(char const* parameter); -QPDF_DLL Config* forceVersion(char const* parameter); -QPDF_DLL Config* iiMinBytes(char const* parameter); -QPDF_DLL Config* jobJsonFile(char const* parameter); -QPDF_DLL Config* jsonObject(char const* parameter); -QPDF_DLL Config* keepFilesOpenThreshold(char const* parameter); -QPDF_DLL Config* linearizePass1(char const* parameter); -QPDF_DLL Config* minVersion(char const* parameter); -QPDF_DLL Config* oiMinArea(char const* parameter); -QPDF_DLL Config* oiMinHeight(char const* parameter); -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* collate(char const* parameter); +QPDF_DLL Config* compressionLevel(std::string const& parameter); +QPDF_DLL Config* copyEncryption(std::string const& parameter); +QPDF_DLL Config* encryptionFilePassword(std::string const& parameter); +QPDF_DLL Config* forceVersion(std::string const& parameter); +QPDF_DLL Config* iiMinBytes(std::string const& parameter); +QPDF_DLL Config* jobJsonFile(std::string const& parameter); +QPDF_DLL Config* jsonObject(std::string const& parameter); +QPDF_DLL Config* keepFilesOpenThreshold(std::string const& parameter); +QPDF_DLL Config* linearizePass1(std::string const& parameter); +QPDF_DLL Config* minVersion(std::string const& parameter); +QPDF_DLL Config* oiMinArea(std::string const& parameter); +QPDF_DLL Config* oiMinHeight(std::string const& parameter); +QPDF_DLL Config* oiMinWidth(std::string const& parameter); +QPDF_DLL Config* password(std::string const& parameter); +QPDF_DLL Config* passwordFile(std::string const& parameter); +QPDF_DLL Config* removeAttachment(std::string const& parameter); +QPDF_DLL Config* rotate(std::string const& parameter); +QPDF_DLL Config* showAttachment(std::string const& parameter); +QPDF_DLL Config* showObject(std::string const& parameter); +QPDF_DLL Config* collate(std::string const& parameter); QPDF_DLL Config* collate(); -QPDF_DLL Config* splitPages(char const* parameter); +QPDF_DLL Config* splitPages(std::string const& parameter); QPDF_DLL Config* splitPages(); -QPDF_DLL Config* compressStreams(char const* parameter); -QPDF_DLL Config* decodeLevel(char const* parameter); -QPDF_DLL Config* flattenAnnotations(char const* parameter); -QPDF_DLL Config* jsonKey(char const* parameter); -QPDF_DLL Config* keepFilesOpen(char const* parameter); -QPDF_DLL Config* normalizeContent(char const* parameter); -QPDF_DLL Config* objectStreams(char const* parameter); -QPDF_DLL Config* passwordMode(char const* parameter); -QPDF_DLL Config* removeUnreferencedResources(char const* parameter); -QPDF_DLL Config* streamData(char const* parameter); -QPDF_DLL Config* json(char const* parameter); +QPDF_DLL Config* compressStreams(std::string const& parameter); +QPDF_DLL Config* decodeLevel(std::string const& parameter); +QPDF_DLL Config* flattenAnnotations(std::string const& parameter); +QPDF_DLL Config* jsonKey(std::string const& parameter); +QPDF_DLL Config* keepFilesOpen(std::string const& parameter); +QPDF_DLL Config* normalizeContent(std::string const& parameter); +QPDF_DLL Config* objectStreams(std::string const& parameter); +QPDF_DLL Config* passwordMode(std::string const& parameter); +QPDF_DLL Config* removeUnreferencedResources(std::string const& parameter); +QPDF_DLL Config* streamData(std::string const& parameter); +QPDF_DLL Config* json(std::string const& parameter); QPDF_DLL Config* json(); diff --git a/include/qpdf/auto_job_c_uo.hh b/include/qpdf/auto_job_c_uo.hh index a02cd1f8..3c7585c2 100644 --- a/include/qpdf/auto_job_c_uo.hh +++ b/include/qpdf/auto_job_c_uo.hh @@ -3,7 +3,7 @@ // Edits will be automatically overwritten if the build is // run in maintainer mode. // -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); +QPDF_DLL UOConfig* to(std::string const& parameter); +QPDF_DLL UOConfig* from(std::string const& parameter); +QPDF_DLL UOConfig* repeat(std::string const& parameter); +QPDF_DLL UOConfig* password(std::string const& parameter); diff --git a/include/qpdf/qpdfjob-c.h b/include/qpdf/qpdfjob-c.h index 59c42822..59d77660 100644 --- a/include/qpdf/qpdfjob-c.h +++ b/include/qpdf/qpdfjob-c.h @@ -52,7 +52,7 @@ extern "C" { * qpdfjob_run_from_wide_argv instead. */ QPDF_DLL - int qpdfjob_run_from_argv(int argc, char* argv[]); + int qpdfjob_run_from_argv(int argc, char const* const argv[]); #ifndef QPDF_NO_WCHAR_T /* This function is the same as qpdfjob_run_from_argv except argv @@ -60,7 +60,7 @@ extern "C" { * calling from a Windows wmain function. */ QPDF_DLL - int qpdfjob_run_from_wide_argv(int argc, wchar_t* argv[]); + int qpdfjob_run_from_wide_argv(int argc, wchar_t const* const argv[]); #endif /* QPDF_NO_WCHAR_T */ /* This function runs QPDFJob from a job JSON file. See the "QPDF diff --git a/job.sums b/job.sums index d434c642..19593597 100644 --- a/job.sums +++ b/job.sums @@ -1,17 +1,17 @@ # Generated by generate_auto_job -generate_auto_job 5d6ec1e4f0b94d8f73df665061d8a2188cbbe8f25ea42be78ec576547261d5ac -include/qpdf/auto_job_c_att.hh 7ad43bb374c1370ef32ebdcdcb7b73a61d281f7f4e3f12755585872ab30fb60e -include/qpdf/auto_job_c_copy_att.hh 32275d03cdc69b703dd7e02ba0bbe15756e714e9ad185484773a6178dc09e1ee -include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf52f64c1d6be99265 -include/qpdf/auto_job_c_main.hh 69d5ea26098bcb6ec5b5e37ba0bca9e7d16a784d2618e0c05d635046848d5123 +generate_auto_job e7c7b33330d398552de77b369abbda5299f1a6aa66034bbeef47be61e2363091 +include/qpdf/auto_job_c_att.hh 1f5d589ccf6684b09a203da261c31fc90a866e6eefe906b673e2d6d5a08ef753 +include/qpdf/auto_job_c_copy_att.hh 65bdce5382a60f1815214297cf005072f17556ec4a15317b600f9ecc9cb89ea4 +include/qpdf/auto_job_c_enc.hh 37ca99a124a34bb613f154c6c8934761bd7e7cc5a2719798ccec7edf05b4aeb9 +include/qpdf/auto_job_c_main.hh 1130a203a513659fbfdd3ab8e435779e402d4f519a11f572ab421b8e937f1d7a include/qpdf/auto_job_c_pages.hh 931840b329a36ca0e41401190e04537b47f2867671a6643bfd8da74014202671 -include/qpdf/auto_job_c_uo.hh 0585b7de459fa479d9e51a45fa92de0ff6dee748efc9ec1cedd0dde6cee1ad50 +include/qpdf/auto_job_c_uo.hh 4a1148f815a5d0833d2c519dac940be34825294c8c26f77da65e48fdc75f178e job.yml 9544c6e046b25d3274731fbcd07ba25b300fd67055021ac4364ad8a91f77c6b6 -libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6 +libqpdf/qpdf/auto_job_decl.hh c15c5c4f25f32a8086d579fc40d64326467a74a08209b8fbccf9f996ca2970ab libqpdf/qpdf/auto_job_help.hh 43184f01816b5210bbc981de8de48446546fb94f4fd6e63cfc7f2fbac3578e6b -libqpdf/qpdf/auto_job_init.hh fd13b9f730e6275a39a15d193bd9af19cf37f4495699ec1886c2b208d7811ab1 +libqpdf/qpdf/auto_job_init.hh 4d6c4641347e9ee9ea8d057a37d008c9f0f73484c6a04eb879b7a2f8889828bd libqpdf/qpdf/auto_job_json_decl.hh c5e3fd38a3b0c569eb0c6b4c60953a09cd6bc7d3361a357a81f64fe36af2b0cf -libqpdf/qpdf/auto_job_json_init.hh 3f86ce40931ca8f417d050fcd49104d73c1fa4e977ad19d54b372831a8ea17ed +libqpdf/qpdf/auto_job_json_init.hh b070350d304d137ba594c1ba40b373137e8459735f04b8ca0f8a2ffd1908c69e libqpdf/qpdf/auto_job_schema.hh 18a3780671d95224cb9a27dcac627c421cae509d59f33a63e6bda0ab53cce923 manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3 manual/cli.rst 3746df6c4f115387cca0d921f25619a6b8407fc10b0e4c9dcf40b0b1656c6f8a diff --git a/libqpdf/QPDFArgParser.cc b/libqpdf/QPDFArgParser.cc index 194f5b16..9c735e65 100644 --- a/libqpdf/QPDFArgParser.cc +++ b/libqpdf/QPDFArgParser.cc @@ -8,11 +8,10 @@ #include QPDFArgParser::Members::Members( - int argc, char* argv[], char const* progname_env) : + int argc, char const* const argv[], char const* progname_env) : argc(argc), argv(argv), - whoami(QUtil::getWhoami(argv[0])), progname_env(progname_env), cur_arg(0), bash_completion(false), @@ -20,14 +19,18 @@ QPDFArgParser::Members::Members( option_table(nullptr), final_check_handler(nullptr) { + auto tmp = QUtil::make_shared_cstr(argv[0]); + char* p = QUtil::getWhoami(tmp.get()); // Remove prefix added by libtool for consistency during testing. - if (strncmp(whoami, "lt-", 3) == 0) + if (strncmp(p, "lt-", 3) == 0) { - whoami += 3; + p += 3; } + whoami = p; } -QPDFArgParser::QPDFArgParser(int argc, char* argv[], char const* progname_env) : +QPDFArgParser::QPDFArgParser(int argc, char const* const argv[], + char const* progname_env) : m(new Members(argc, argv, progname_env)) { selectHelpOptionTable(); @@ -250,17 +253,17 @@ QPDFArgParser::argCompletionZsh() } void -QPDFArgParser::argHelp(char* p) +QPDFArgParser::argHelp(std::string const& p) { std::cout << getHelp(p); exit(0); } void -QPDFArgParser::invalidHelpArg(char* p) +QPDFArgParser::invalidHelpArg(std::string const& p) { usage(std::string("unknown help option") + - (p ? (std::string(" ") + p) : "")); + (p.empty() ? "" : (" " + p))); } void @@ -272,7 +275,7 @@ QPDFArgParser::handleArgFileArguments() this->m->new_argv.push_back(QUtil::make_shared_cstr(this->m->argv[0])); for (int i = 1; i < this->m->argc; ++i) { - char* argfile = 0; + char const* argfile = 0; if ((strlen(this->m->argv[i]) > 1) && (this->m->argv[i][0] == '@')) { argfile = 1 + this->m->argv[i]; @@ -295,16 +298,16 @@ QPDFArgParser::handleArgFileArguments() QUtil::make_shared_cstr(this->m->argv[i])); } } - this->m->argv_ph = std::shared_ptr( - new char*[1 + this->m->new_argv.size()], - std::default_delete()); - this->m->argv = this->m->argv_ph.get(); + this->m->argv_ph = std::shared_ptr( + new char const*[1 + this->m->new_argv.size()], + std::default_delete()); for (size_t i = 0; i < this->m->new_argv.size(); ++i) { - this->m->argv[i] = this->m->new_argv.at(i).get(); + this->m->argv_ph.get()[i] = this->m->new_argv.at(i).get(); } this->m->argc = QIntC::to_int(this->m->new_argv.size()); - this->m->argv[this->m->argc] = 0; + this->m->argv_ph.get()[this->m->argc] = nullptr; + this->m->argv = this->m->argv_ph.get(); } void @@ -400,16 +403,16 @@ QPDFArgParser::handleBashArguments() } // Explicitly discard any non-space-terminated word. The "current // word" is handled specially. - this->m->bash_argv_ph = std::shared_ptr( - new char*[1 + this->m->bash_argv.size()], - std::default_delete()); - this->m->argv = this->m->bash_argv_ph.get(); + this->m->bash_argv_ph = std::shared_ptr( + new char const*[1 + this->m->bash_argv.size()], + std::default_delete()); for (size_t i = 0; i < this->m->bash_argv.size(); ++i) { - this->m->argv[i] = this->m->bash_argv.at(i).get(); + this->m->bash_argv_ph.get()[i] = this->m->bash_argv.at(i).get(); } this->m->argc = QIntC::to_int(this->m->bash_argv.size()); - this->m->argv[this->m->argc] = 0; + this->m->bash_argv_ph.get()[this->m->argc] = nullptr; + this->m->argv = this->m->bash_argv_ph.get(); } void @@ -424,10 +427,10 @@ QPDFArgParser::usage(std::string const& message) } void -QPDFArgParser::readArgsFromFile(char const* filename) +QPDFArgParser::readArgsFromFile(std::string const& filename) { std::list lines; - if (strcmp(filename, "-") == 0) + if (filename == "-") { QTC::TC("libtests", "QPDFArgParser read args from stdin"); lines = QUtil::read_lines_from_file(std::cin); @@ -435,7 +438,7 @@ QPDFArgParser::readArgsFromFile(char const* filename) else { QTC::TC("libtests", "QPDFArgParser read args from file"); - lines = QUtil::read_lines_from_file(filename); + lines = QUtil::read_lines_from_file(filename.c_str()); } for (auto const& line: lines) { @@ -547,8 +550,9 @@ QPDFArgParser::parseArgs() bool help_option = false; bool end_option = false; auto oep = this->m->option_table->end(); - char* arg = this->m->argv[this->m->cur_arg]; - char* parameter = nullptr; + char const* arg = this->m->argv[this->m->cur_arg]; + std::string parameter; + bool have_parameter = false; std::string o_arg(arg); std::string arg_s(arg); if ((strcmp(arg, "--") == 0) && @@ -577,20 +581,25 @@ QPDFArgParser::parseArgs() { QTC::TC("libtests", "QPDFArgParser single dash"); } - if (strlen(arg) > 0) + + // Prevent --=something from being treated as an empty arg + // by searching for = from after the first character. We + // do this since the empty string in the option table is + // for positional arguments. Besides, it doesn't make + // sense to have an empty option. + arg_s = arg; + size_t equal_pos = std::string::npos; + if (arg_s.length() > 0) { - // Prevent --=something from being treated as an empty - // arg since the empty string in the option table is - // for positional arguments. - parameter = const_cast(strchr(1 + arg, '=')); + equal_pos = arg_s.find('=', 1); } - if (parameter) + if (equal_pos != std::string::npos) { - *parameter++ = 0; + have_parameter = true; + parameter = arg_s.substr(equal_pos + 1); + arg_s = arg_s.substr(0, equal_pos); } - arg_s = arg; - if ((! this->m->bash_completion) && (this->m->argc == 2) && (this->m->cur_arg == 1) && this->m->help_option_table.count(arg_s)) @@ -629,8 +638,8 @@ QPDFArgParser::parseArgs() } OptionEntry& oe = oep->second; - if ((oe.parameter_needed && (nullptr == parameter)) || - ((! oe.choices.empty() && (nullptr != parameter) && + if ((oe.parameter_needed && (! have_parameter)) || + ((! oe.choices.empty() && have_parameter && (0 == oe.choices.count(parameter))))) { std::string message = @@ -977,16 +986,15 @@ QPDFArgParser::getTopicHelp(std::string const& name, } std::string -QPDFArgParser::getHelp(char const* topic_or_option) +QPDFArgParser::getHelp(std::string const& arg) { std::ostringstream msg; - if ((topic_or_option == nullptr) || (strlen(topic_or_option) == 0)) + if (arg.empty()) { getTopHelp(msg); } else { - std::string arg(topic_or_option); if (arg == "all") { getAllHelp(msg); diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index 203e4b27..e2870309 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -39,8 +39,8 @@ namespace std::shared_ptr c_pages; std::shared_ptr c_uo; std::shared_ptr c_enc; - std::vector accumulated_args; // points to member in ap - char* pages_password; + std::vector accumulated_args; + std::shared_ptr pages_password; bool gave_input; bool gave_output; }; @@ -70,7 +70,7 @@ ArgParser::initOptionTables() } void -ArgParser::argPositional(char* arg) +ArgParser::argPositional(std::string const& arg) { if (! this->gave_input) { @@ -84,7 +84,7 @@ ArgParser::argPositional(char* arg) } else { - usage(std::string("unknown argument ") + arg); + usage("unknown argument " + arg); } } @@ -188,7 +188,7 @@ ArgParser::argEncrypt() } void -ArgParser::argEncPositional(char* arg) +ArgParser::argEncPositional(std::string const& arg) { this->accumulated_args.push_back(arg); size_t n_args = this->accumulated_args.size(); @@ -244,9 +244,9 @@ ArgParser::argPages() } void -ArgParser::argPagesPassword(char* parameter) +ArgParser::argPagesPassword(std::string const& parameter) { - if (this->pages_password != nullptr) + if (this->pages_password) { QTC::TC("qpdf", "QPDFJob duplicated pages password"); usage("--password already specified for this file"); @@ -256,13 +256,13 @@ ArgParser::argPagesPassword(char* parameter) QTC::TC("qpdf", "QPDFJob misplaced pages password"); usage("in --pages, --password must immediately follow a file name"); } - this->pages_password = parameter; + this->pages_password = QUtil::make_shared_cstr(parameter); } void -ArgParser::argPagesPositional(char* arg) +ArgParser::argPagesPositional(std::string const& arg) { - if (arg == nullptr) + if (arg.empty()) { if (this->accumulated_args.empty()) { @@ -274,25 +274,26 @@ ArgParser::argPagesPositional(char* arg) this->accumulated_args.push_back(arg); } - char const* file = this->accumulated_args.at(0); - char const* range = nullptr; + std::string file = this->accumulated_args.at(0); + char const* range_p = nullptr; size_t n_args = this->accumulated_args.size(); if (n_args >= 2) { - range = this->accumulated_args.at(1); + // will be copied before accumulated_args is cleared + range_p = this->accumulated_args.at(1).c_str(); } // See if the user omitted the range entirely, in which case we // assume "1-z". - char* next_file = nullptr; - if (range == nullptr) + std::string next_file; + if (range_p == nullptr) { - if (arg == nullptr) + if (arg.empty()) { // The filename or password was the last argument QTC::TC("qpdf", "QPDFJob pages range omitted at end", - this->pages_password == nullptr ? 0 : 1); + this->pages_password ? 0 : 1); } else { @@ -304,17 +305,17 @@ ArgParser::argPagesPositional(char* arg) { try { - QUtil::parse_numrange(range, 0); + QUtil::parse_numrange(range_p, 0); } catch (std::runtime_error& e1) { // The range is invalid. Let's see if it's a file. - if (strcmp(range, ".") == 0) + if (strcmp(range_p, ".") == 0) { // "." means the input file. QTC::TC("qpdf", "QPDFJob pages range omitted with ."); } - else if (QUtil::file_can_be_opened(range)) + else if (QUtil::file_can_be_opened(range_p)) { QTC::TC("qpdf", "QPDFJob pages range omitted in middle"); // Yup, it's a file. @@ -324,18 +325,15 @@ ArgParser::argPagesPositional(char* arg) // Give the range error usage(e1.what()); } - next_file = const_cast(range); - range = nullptr; + next_file = range_p; + range_p = nullptr; } } - if (range == nullptr) - { - range = "1-z"; - } - this->c_pages->pageSpec(file, range, this->pages_password); + std::string range(range_p ? range_p : "1-z"); + this->c_pages->pageSpec(file, range, this->pages_password.get()); this->accumulated_args.clear(); this->pages_password = nullptr; - if (next_file != nullptr) + if (! next_file.empty()) { this->accumulated_args.push_back(next_file); } @@ -344,7 +342,7 @@ ArgParser::argPagesPositional(char* arg) void ArgParser::argEndPages() { - argPagesPositional(nullptr); + argPagesPositional(""); c_pages->endPages(); c_pages = nullptr; } @@ -403,7 +401,7 @@ ArgParser::argEnd256BitEncryption() } void -ArgParser::argUOPositional(char* arg) +ArgParser::argUOPositional(std::string const& arg) { c_uo->file(arg); } @@ -416,7 +414,7 @@ ArgParser::argEndUnderlayOverlay() } void -ArgParser::argAttPositional(char* arg) +ArgParser::argAttPositional(std::string const& arg) { c_att->file(arg); } @@ -429,7 +427,7 @@ ArgParser::argEndAttachment() } void -ArgParser::argCopyAttPositional(char* arg) +ArgParser::argCopyAttPositional(std::string const& arg) { c_copy_att->file(arg); } @@ -467,7 +465,8 @@ ArgParser::parseOptions() } void -QPDFJob::initializeFromArgv(int argc, char* argv[], char const* progname_env) +QPDFJob::initializeFromArgv(int argc, char const* const argv[], + char const* progname_env) { if (progname_env == nullptr) { diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index 68eaf5c8..da119b39 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -1,7 +1,6 @@ #include #include #include -#include void QPDFJob::Config::checkConfiguration() @@ -10,7 +9,7 @@ QPDFJob::Config::checkConfiguration() } QPDFJob::Config* -QPDFJob::Config::inputFile(char const* filename) +QPDFJob::Config::inputFile(std::string const& filename) { if (o.m->infilename == 0) { @@ -46,7 +45,7 @@ QPDFJob::Config::emptyInput() } QPDFJob::Config* -QPDFJob::Config::outputFile(char const* filename) +QPDFJob::Config::outputFile(std::string const& filename) { if ((o.m->outfilename == 0) && (! o.m->replace_input)) { @@ -107,35 +106,34 @@ QPDFJob::Config::coalesceContents() QPDFJob::Config* QPDFJob::Config::collate() { - return collate(nullptr); + return collate(""); } QPDFJob::Config* -QPDFJob::Config::collate(char const* parameter) +QPDFJob::Config::collate(std::string const& parameter) { - auto n = (((parameter == 0) || (strlen(parameter) == 0)) ? 1 : - QUtil::string_to_uint(parameter)); + auto n = (parameter.empty() ? 1 : QUtil::string_to_uint(parameter.c_str())); o.m->collate = QIntC::to_size(n); return this; } QPDFJob::Config* -QPDFJob::Config::compressStreams(char const* parameter) +QPDFJob::Config::compressStreams(std::string const& parameter) { o.m->compress_streams_set = true; - o.m->compress_streams = (strcmp(parameter, "y") == 0); + o.m->compress_streams = (parameter == "y"); return this; } QPDFJob::Config* -QPDFJob::Config::compressionLevel(char const* parameter) +QPDFJob::Config::compressionLevel(std::string const& parameter) { - o.m->compression_level = QUtil::string_to_int(parameter); + o.m->compression_level = QUtil::string_to_int(parameter.c_str()); return this; } QPDFJob::Config* -QPDFJob::Config::copyEncryption(char const* parameter) +QPDFJob::Config::copyEncryption(std::string const& parameter) { o.m->encryption_file = parameter; o.m->copy_encryption = true; @@ -161,7 +159,7 @@ QPDFJob::Config::deterministicId() } QPDFJob::Config* -QPDFJob::Config::encryptionFilePassword(char const* parameter) +QPDFJob::Config::encryptionFilePassword(std::string const& parameter) { o.m->encryption_file_password = QUtil::make_shared_cstr(parameter); return this; @@ -182,17 +180,21 @@ QPDFJob::Config::filteredStreamData() } QPDFJob::Config* -QPDFJob::Config::flattenAnnotations(char const* parameter) +QPDFJob::Config::flattenAnnotations(std::string const& parameter) { o.m->flatten_annotations = true; - if (strcmp(parameter, "screen") == 0) + if (parameter == "screen") { o.m->flatten_annotations_forbidden |= an_no_view; } - else if (strcmp(parameter, "print") == 0) + else if (parameter == "print") { o.m->flatten_annotations_required |= an_print; } + else if (parameter != "all") + { + usage("invalid flatten-annotations option"); + } return this; } @@ -204,7 +206,7 @@ QPDFJob::Config::flattenRotation() } QPDFJob::Config* -QPDFJob::Config::forceVersion(char const* parameter) +QPDFJob::Config::forceVersion(std::string const& parameter) { o.m->force_version = parameter; return this; @@ -225,9 +227,9 @@ QPDFJob::Config::ignoreXrefStreams() } QPDFJob::Config* -QPDFJob::Config::iiMinBytes(char const* parameter) +QPDFJob::Config::iiMinBytes(std::string const& parameter) { - o.m->ii_min_bytes = QUtil::string_to_uint(parameter); + o.m->ii_min_bytes = QUtil::string_to_uint(parameter.c_str()); return this; } @@ -242,27 +244,25 @@ QPDFJob::Config::isEncrypted() QPDFJob::Config* QPDFJob::Config::json() { - return json(nullptr); + return json(""); } QPDFJob::Config* -QPDFJob::Config::json(char const* parameter) +QPDFJob::Config::json(std::string const& parameter) { - if (parameter && strlen(parameter)) + if (parameter.empty()) { - if (strcmp(parameter, "latest") == 0) - { - o.m->json_version = 1; - } - else - { - o.m->json_version = QUtil::string_to_int(parameter); - } + // The default value is 1 for backward compatibility. + o.m->json_version = 1; } - else + else if (parameter == "latest") { o.m->json_version = 1; } + else + { + o.m->json_version = QUtil::string_to_int(parameter.c_str()); + } if (o.m->json_version != 1) { usage(std::string("unsupported json version ") + parameter); @@ -272,31 +272,31 @@ QPDFJob::Config::json(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::jsonKey(char const* parameter) +QPDFJob::Config::jsonKey(std::string const& parameter) { o.m->json_keys.insert(parameter); return this; } QPDFJob::Config* -QPDFJob::Config::jsonObject(char const* parameter) +QPDFJob::Config::jsonObject(std::string const& parameter) { o.m->json_objects.insert(parameter); return this; } QPDFJob::Config* -QPDFJob::Config::keepFilesOpen(char const* parameter) +QPDFJob::Config::keepFilesOpen(std::string const& parameter) { o.m->keep_files_open_set = true; - o.m->keep_files_open = (strcmp(parameter, "y") == 0); + o.m->keep_files_open = (parameter == "y"); return this; } QPDFJob::Config* -QPDFJob::Config::keepFilesOpenThreshold(char const* parameter) +QPDFJob::Config::keepFilesOpenThreshold(std::string const& parameter) { - o.m->keep_files_open_threshold = QUtil::string_to_uint(parameter); + o.m->keep_files_open_threshold = QUtil::string_to_uint(parameter.c_str()); return this; } @@ -315,7 +315,7 @@ QPDFJob::Config::linearize() } QPDFJob::Config* -QPDFJob::Config::linearizePass1(char const* parameter) +QPDFJob::Config::linearizePass1(std::string const& parameter) { o.m->linearize_pass1 = parameter; return this; @@ -330,7 +330,7 @@ QPDFJob::Config::listAttachments() } QPDFJob::Config* -QPDFJob::Config::minVersion(char const* parameter) +QPDFJob::Config::minVersion(std::string const& parameter) { o.m->min_version = parameter; return this; @@ -358,31 +358,31 @@ QPDFJob::Config::noWarn() } QPDFJob::Config* -QPDFJob::Config::normalizeContent(char const* parameter) +QPDFJob::Config::normalizeContent(std::string const& parameter) { o.m->normalize_set = true; - o.m->normalize = (strcmp(parameter, "y") == 0); + o.m->normalize = (parameter == "y"); return this; } QPDFJob::Config* -QPDFJob::Config::oiMinArea(char const* parameter) +QPDFJob::Config::oiMinArea(std::string const& parameter) { - o.m->oi_min_area = QUtil::string_to_uint(parameter); + o.m->oi_min_area = QUtil::string_to_uint(parameter.c_str()); return this; } QPDFJob::Config* -QPDFJob::Config::oiMinHeight(char const* parameter) +QPDFJob::Config::oiMinHeight(std::string const& parameter) { - o.m->oi_min_height = QUtil::string_to_uint(parameter); + o.m->oi_min_height = QUtil::string_to_uint(parameter.c_str()); return this; } QPDFJob::Config* -QPDFJob::Config::oiMinWidth(char const* parameter) +QPDFJob::Config::oiMinWidth(std::string const& parameter) { - o.m->oi_min_width = QUtil::string_to_uint(parameter); + o.m->oi_min_width = QUtil::string_to_uint(parameter.c_str()); return this; } @@ -394,7 +394,7 @@ QPDFJob::Config::optimizeImages() } QPDFJob::Config* -QPDFJob::Config::password(char const* parameter) +QPDFJob::Config::password(std::string const& parameter) { o.m->password = QUtil::make_shared_cstr(parameter); return this; @@ -451,7 +451,7 @@ QPDFJob::Config::recompressFlate() } QPDFJob::Config* -QPDFJob::Config::removeAttachment(char const* parameter) +QPDFJob::Config::removeAttachment(std::string const& parameter) { o.m->attachments_to_remove.push_back(parameter); return this; @@ -473,7 +473,7 @@ QPDFJob::Config::requiresPassword() } QPDFJob::Config* -QPDFJob::Config::showAttachment(char const* parameter) +QPDFJob::Config::showAttachment(std::string const& parameter) { o.m->attachment_to_show = parameter; o.m->require_outfile = false; @@ -530,14 +530,13 @@ QPDFJob::Config::showXref() QPDFJob::Config* QPDFJob::Config::splitPages() { - return splitPages(nullptr); + return splitPages(""); } QPDFJob::Config* -QPDFJob::Config::splitPages(char const* parameter) +QPDFJob::Config::splitPages(std::string const& parameter) { - int n = (((parameter == 0) || (strlen(parameter) == 0)) ? 1 : - QUtil::string_to_int(parameter)); + int n = (parameter.empty() ? 1 : QUtil::string_to_int(parameter.c_str())); o.m->split_pages = n; return this; } @@ -592,10 +591,10 @@ QPDFJob::Config::withImages() } QPDFJob::Config* -QPDFJob::Config::passwordFile(char const* parameter) +QPDFJob::Config::passwordFile(std::string const& parameter) { std::list lines; - if (strcmp(parameter, "-") == 0) + if (parameter == "-") { QTC::TC("qpdf", "QPDFJob_config password stdin"); lines = QUtil::read_lines_from_file(std::cin); @@ -603,7 +602,7 @@ QPDFJob::Config::passwordFile(char const* parameter) else { QTC::TC("qpdf", "QPDFJob_config password file"); - lines = QUtil::read_lines_from_file(parameter); + lines = QUtil::read_lines_from_file(parameter.c_str()); } if (lines.size() >= 1) { @@ -620,21 +619,21 @@ QPDFJob::Config::passwordFile(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::passwordMode(char const* parameter) +QPDFJob::Config::passwordMode(std::string const& parameter) { - if (strcmp(parameter, "bytes") == 0) + if (parameter == "bytes") { o.m->password_mode = QPDFJob::pm_bytes; } - else if (strcmp(parameter, "hex-bytes") == 0) + else if (parameter == "hex-bytes") { o.m->password_mode = QPDFJob::pm_hex_bytes; } - else if (strcmp(parameter, "unicode") == 0) + else if (parameter == "unicode") { o.m->password_mode = QPDFJob::pm_unicode; } - else if (strcmp(parameter, "auto") == 0) + else if (parameter == "auto") { o.m->password_mode = QPDFJob::pm_auto; } @@ -646,18 +645,18 @@ QPDFJob::Config::passwordMode(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::streamData(char const* parameter) +QPDFJob::Config::streamData(std::string const& parameter) { o.m->stream_data_set = true; - if (strcmp(parameter, "compress") == 0) + if (parameter == "compress") { o.m->stream_data_mode = qpdf_s_compress; } - else if (strcmp(parameter, "preserve") == 0) + else if (parameter == "preserve") { o.m->stream_data_mode = qpdf_s_preserve; } - else if (strcmp(parameter, "uncompress") == 0) + else if (parameter == "uncompress") { o.m->stream_data_mode = qpdf_s_uncompress; } @@ -669,22 +668,22 @@ QPDFJob::Config::streamData(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::decodeLevel(char const* parameter) +QPDFJob::Config::decodeLevel(std::string const& parameter) { o.m->decode_level_set = true; - if (strcmp(parameter, "none") == 0) + if (parameter == "none") { o.m->decode_level = qpdf_dl_none; } - else if (strcmp(parameter, "generalized") == 0) + else if (parameter == "generalized") { o.m->decode_level = qpdf_dl_generalized; } - else if (strcmp(parameter, "specialized") == 0) + else if (parameter == "specialized") { o.m->decode_level = qpdf_dl_specialized; } - else if (strcmp(parameter, "all") == 0) + else if (parameter == "all") { o.m->decode_level = qpdf_dl_all; } @@ -696,18 +695,18 @@ QPDFJob::Config::decodeLevel(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::objectStreams(char const* parameter) +QPDFJob::Config::objectStreams(std::string const& parameter) { o.m->object_stream_set = true; - if (strcmp(parameter, "disable") == 0) + if (parameter == "disable") { o.m->object_stream_mode = qpdf_o_disable; } - else if (strcmp(parameter, "preserve") == 0) + else if (parameter == "preserve") { o.m->object_stream_mode = qpdf_o_preserve; } - else if (strcmp(parameter, "generate") == 0) + else if (parameter == "generate") { o.m->object_stream_mode = qpdf_o_generate; } @@ -719,17 +718,17 @@ QPDFJob::Config::objectStreams(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::removeUnreferencedResources(char const* parameter) +QPDFJob::Config::removeUnreferencedResources(std::string const& parameter) { - if (strcmp(parameter, "auto") == 0) + if (parameter == "auto") { o.m->remove_unreferenced_page_resources = QPDFJob::re_auto; } - else if (strcmp(parameter, "yes") == 0) + else if (parameter == "yes") { o.m->remove_unreferenced_page_resources = QPDFJob::re_yes; } - else if (strcmp(parameter, "no") == 0) + else if (parameter == "no") { o.m->remove_unreferenced_page_resources = QPDFJob::re_no; } @@ -741,7 +740,7 @@ QPDFJob::Config::removeUnreferencedResources(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::showObject(char const* parameter) +QPDFJob::Config::showObject(std::string const& parameter) { QPDFJob::parse_object_id( parameter, o.m->show_trailer, o.m->show_obj, o.m->show_gen); @@ -750,11 +749,11 @@ QPDFJob::Config::showObject(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::jobJsonFile(char const* parameter) +QPDFJob::Config::jobJsonFile(std::string const& parameter) { PointerHolder file_buf; size_t size; - QUtil::read_file_into_memory(parameter, file_buf, size); + QUtil::read_file_into_memory(parameter.c_str(), file_buf, size); try { o.initializeFromJson(std::string(file_buf.getPointer(), size), true); @@ -770,7 +769,7 @@ QPDFJob::Config::jobJsonFile(char const* parameter) } QPDFJob::Config* -QPDFJob::Config::rotate(char const* parameter) +QPDFJob::Config::rotate(std::string const& parameter) { o.parseRotationParameter(parameter); return this; @@ -788,21 +787,21 @@ QPDFJob::CopyAttConfig::CopyAttConfig(Config* c) : } QPDFJob::CopyAttConfig* -QPDFJob::CopyAttConfig::file(char const* parameter) +QPDFJob::CopyAttConfig::file(std::string const& parameter) { this->caf.path = parameter; return this; } QPDFJob::CopyAttConfig* -QPDFJob::CopyAttConfig::prefix(char const* parameter) +QPDFJob::CopyAttConfig::prefix(std::string const& parameter) { this->caf.prefix = parameter; return this; } QPDFJob::CopyAttConfig* -QPDFJob::CopyAttConfig::password(char const* parameter) +QPDFJob::CopyAttConfig::password(std::string const& parameter) { this->caf.password = parameter; return this; @@ -831,28 +830,28 @@ QPDFJob::Config::addAttachment() } QPDFJob::AttConfig* -QPDFJob::AttConfig::file(char const* parameter) +QPDFJob::AttConfig::file(std::string const& parameter) { this->att.path = parameter; return this; } QPDFJob::AttConfig* -QPDFJob::AttConfig::key(char const* parameter) +QPDFJob::AttConfig::key(std::string const& parameter) { this->att.key = parameter; return this; } QPDFJob::AttConfig* -QPDFJob::AttConfig::filename(char const* parameter) +QPDFJob::AttConfig::filename(std::string const& parameter) { this->att.filename = parameter; return this; } QPDFJob::AttConfig* -QPDFJob::AttConfig::creationdate(char const* parameter) +QPDFJob::AttConfig::creationdate(std::string const& parameter) { if (! QUtil::pdf_time_to_qpdf_time(parameter)) { @@ -863,7 +862,7 @@ QPDFJob::AttConfig::creationdate(char const* parameter) } QPDFJob::AttConfig* -QPDFJob::AttConfig::moddate(char const* parameter) +QPDFJob::AttConfig::moddate(std::string const& parameter) { if (! QUtil::pdf_time_to_qpdf_time(parameter)) { @@ -874,9 +873,9 @@ QPDFJob::AttConfig::moddate(char const* parameter) } QPDFJob::AttConfig* -QPDFJob::AttConfig::mimetype(char const* parameter) +QPDFJob::AttConfig::mimetype(std::string const& parameter) { - if (strchr(parameter, '/') == nullptr) + if (parameter.find('/') == std::string::npos) { usage("mime type should be specified as type/subtype"); } @@ -885,7 +884,7 @@ QPDFJob::AttConfig::mimetype(char const* parameter) } QPDFJob::AttConfig* -QPDFJob::AttConfig::description(char const* parameter) +QPDFJob::AttConfig::description(std::string const& parameter) { this->att.description = parameter; return this; @@ -999,7 +998,7 @@ QPDFJob::UOConfig::endUnderlayOverlay() } QPDFJob::UOConfig* -QPDFJob::UOConfig::file(char const* parameter) +QPDFJob::UOConfig::file(std::string const& parameter) { if (! config->o.m->under_overlay->filename.empty()) { @@ -1013,37 +1012,37 @@ QPDFJob::UOConfig::file(char const* parameter) } QPDFJob::UOConfig* -QPDFJob::UOConfig::to(char const* parameter) +QPDFJob::UOConfig::to(std::string const& parameter) { - config->o.parseNumrange(parameter, 0); + config->o.parseNumrange(parameter.c_str(), 0); config->o.m->under_overlay->to_nr = parameter; return this; } QPDFJob::UOConfig* -QPDFJob::UOConfig::from(char const* parameter) +QPDFJob::UOConfig::from(std::string const& parameter) { - if (strlen(parameter)) + if (! parameter.empty()) { - config->o.parseNumrange(parameter, 0); + config->o.parseNumrange(parameter.c_str(), 0); } config->o.m->under_overlay->from_nr = parameter; return this; } QPDFJob::UOConfig* -QPDFJob::UOConfig::repeat(char const* parameter) +QPDFJob::UOConfig::repeat(std::string const& parameter) { - if (strlen(parameter)) + if (! parameter.empty()) { - config->o.parseNumrange(parameter, 0); + config->o.parseNumrange(parameter.c_str(), 0); } config->o.m->under_overlay->repeat_nr = parameter; return this; } QPDFJob::UOConfig* -QPDFJob::UOConfig::password(char const* parameter) +QPDFJob::UOConfig::password(std::string const& parameter) { config->o.m->under_overlay->password = QUtil::make_shared_cstr(parameter); return this; @@ -1086,42 +1085,42 @@ QPDFJob::EncConfig::allowInsecure() } QPDFJob::EncConfig* -QPDFJob::EncConfig::accessibility(char const* parameter) +QPDFJob::EncConfig::accessibility(std::string const& parameter) { - config->o.m->r3_accessibility = (strcmp(parameter, "y") == 0); + config->o.m->r3_accessibility = (parameter == "y"); return this; } QPDFJob::EncConfig* -QPDFJob::EncConfig::extract(char const* parameter) +QPDFJob::EncConfig::extract(std::string const& parameter) { if (config->o.m->keylen == 40) { - config->o.m->r2_extract = (strcmp(parameter, "y") == 0); + config->o.m->r2_extract = (parameter == "y"); } else { - config->o.m->r3_extract = (strcmp(parameter, "y") == 0); + config->o.m->r3_extract = (parameter == "y"); } return this; } QPDFJob::EncConfig* -QPDFJob::EncConfig::print(char const* parameter) +QPDFJob::EncConfig::print(std::string const& parameter) { if (config->o.m->keylen == 40) { - config->o.m->r2_print = (strcmp(parameter, "y") == 0); + config->o.m->r2_print = (parameter == "y"); } - else if (strcmp(parameter, "full") == 0) + else if (parameter == "full") { config->o.m->r3_print = qpdf_r3p_full; } - else if (strcmp(parameter, "low") == 0) + else if (parameter == "low") { config->o.m->r3_print = qpdf_r3p_low; } - else if (strcmp(parameter, "none") == 0) + else if (parameter == "none") { config->o.m->r3_print = qpdf_r3p_none; } @@ -1133,41 +1132,41 @@ QPDFJob::EncConfig::print(char const* parameter) } QPDFJob::EncConfig* -QPDFJob::EncConfig::modify(char const* parameter) +QPDFJob::EncConfig::modify(std::string const& parameter) { if (config->o.m->keylen == 40) { - config->o.m->r2_modify = (strcmp(parameter, "y") == 0); + config->o.m->r2_modify = (parameter == "y"); } - else if (strcmp(parameter, "all") == 0) + else if (parameter == "all") { config->o.m->r3_assemble = true; config->o.m->r3_annotate_and_form = true; config->o.m->r3_form_filling = true; config->o.m->r3_modify_other = true; } - else if (strcmp(parameter, "annotate") == 0) + else if (parameter == "annotate") { config->o.m->r3_assemble = true; config->o.m->r3_annotate_and_form = true; config->o.m->r3_form_filling = true; config->o.m->r3_modify_other = false; } - else if (strcmp(parameter, "form") == 0) + else if (parameter == "form") { config->o.m->r3_assemble = true; config->o.m->r3_annotate_and_form = false; config->o.m->r3_form_filling = true; config->o.m->r3_modify_other = false; } - else if (strcmp(parameter, "assembly") == 0) + else if (parameter == "assembly") { config->o.m->r3_assemble = true; config->o.m->r3_annotate_and_form = false; config->o.m->r3_form_filling = false; config->o.m->r3_modify_other = false; } - else if (strcmp(parameter, "none") == 0) + else if (parameter == "none") { config->o.m->r3_assemble = false; config->o.m->r3_annotate_and_form = false; @@ -1189,44 +1188,44 @@ QPDFJob::EncConfig::cleartextMetadata() } QPDFJob::EncConfig* -QPDFJob::EncConfig::assemble(char const* parameter) +QPDFJob::EncConfig::assemble(std::string const& parameter) { - config->o.m->r3_assemble = (strcmp(parameter, "y") == 0); + config->o.m->r3_assemble = (parameter == "y"); return this; } QPDFJob::EncConfig* -QPDFJob::EncConfig::annotate(char const* parameter) +QPDFJob::EncConfig::annotate(std::string const& parameter) { if (config->o.m->keylen == 40) { - config->o.m->r2_annotate = (strcmp(parameter, "y") == 0); + config->o.m->r2_annotate = (parameter == "y"); } else { - config->o.m->r3_annotate_and_form = (strcmp(parameter, "y") == 0); + config->o.m->r3_annotate_and_form = (parameter == "y"); } return this; } QPDFJob::EncConfig* -QPDFJob::EncConfig::form(char const* parameter) +QPDFJob::EncConfig::form(std::string const& parameter) { - config->o.m->r3_form_filling = (strcmp(parameter, "y") == 0); + config->o.m->r3_form_filling = (parameter == "y"); return this; } QPDFJob::EncConfig* -QPDFJob::EncConfig::modifyOther(char const* parameter) +QPDFJob::EncConfig::modifyOther(std::string const& parameter) { - config->o.m->r3_modify_other = (strcmp(parameter, "y") == 0); + config->o.m->r3_modify_other = (parameter == "y"); return this; } QPDFJob::EncConfig* -QPDFJob::EncConfig::useAes(char const* parameter) +QPDFJob::EncConfig::useAes(std::string const& parameter) { - config->o.m->use_aes = (strcmp(parameter, "y") == 0); + config->o.m->use_aes = (parameter == "y"); return this; } diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index cfd1bb1e..e8170823 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -2615,9 +2615,9 @@ QUtil::possible_repaired_encodings(std::string supplied) } #ifndef QPDF_NO_WCHAR_T -int -QUtil::call_main_from_wmain(int argc, wchar_t* argv[], - std::function realmain) +static int +call_main_from_wmain(bool, int argc, wchar_t const* const argv[], + std::function realmain) { // argv contains UTF-16-encoded strings with a 16-bit wchar_t. // Convert this to UTF-8-encoded strings for compatibility with @@ -2640,7 +2640,8 @@ QUtil::call_main_from_wmain(int argc, wchar_t* argv[], utf8_argv.push_back(QUtil::make_shared_cstr(utf8)); } auto utf8_argv_sp = - std::shared_ptr(new char*[1+utf8_argv.size()], std::default_delete()); + std::shared_ptr( + new char*[1+utf8_argv.size()], std::default_delete()); char** new_argv = utf8_argv_sp.get(); for (size_t i = 0; i < utf8_argv.size(); ++i) { @@ -2650,4 +2651,23 @@ QUtil::call_main_from_wmain(int argc, wchar_t* argv[], new_argv[argc] = 0; return realmain(argc, new_argv); } + +int +QUtil::call_main_from_wmain(int argc, wchar_t* argv[], + std::function realmain) +{ + return ::call_main_from_wmain(true, argc, argv, realmain); +} + +int +QUtil::call_main_from_wmain( + int argc, wchar_t const* const argv[], + std::function realmain) +{ + return ::call_main_from_wmain( + true, argc, argv, [realmain](int new_argc, char* new_argv[]) { + return realmain(new_argc, new_argv); + }); +} + #endif // QPDF_NO_WCHAR_T diff --git a/libqpdf/qpdf/QPDFArgParser.hh b/libqpdf/qpdf/QPDFArgParser.hh index d2515894..cdc850f7 100644 --- a/libqpdf/qpdf/QPDFArgParser.hh +++ b/libqpdf/qpdf/QPDFArgParser.hh @@ -21,16 +21,6 @@ // done mostly by automatically-generated code (one-off code for // qpdf), though the handlers themselves are hand-coded. See // generate_auto_job at the top of the source tree for details. - -// Note about memory: there is code that expects argv to be a char*[], -// meaning that arguments are writable. Several operations, including -// reading arguments from a file or parsing a line for bash -// completion, involve fabricating an argv array. To ensure that the -// memory is valid and is cleaned up properly, we keep various vectors -// of smart character pointers that argv points into. In order for -// those pointers to remain valid, the QPDFArgParser instance must -// remain in scope for the life of any code that may reference -// anything from argv. class QPDFArgParser { public: @@ -38,7 +28,7 @@ class QPDFArgParser // name of the executable for setting up completion. This may be // needed if the program is invoked by a wrapper. QPDF_DLL - QPDFArgParser(int argc, char* argv[], char const* progname_env); + QPDFArgParser(int argc, char const* const argv[], char const* progname_env); // Calls exit(0) if a help option is given or if in completion // mode. If there are argument parsing errors, QPDFUsage is @@ -60,7 +50,7 @@ class QPDFArgParser // a series of options that end with `--`. typedef std::function bare_arg_handler_t; - typedef std::function param_arg_handler_t; + typedef std::function param_arg_handler_t; QPDF_DLL void selectMainOptionTable(); @@ -163,7 +153,7 @@ class QPDFArgParser // unknown value returns a string directing the user to run the // top-level --help option. QPDF_DLL - std::string getHelp(char const* topic_or_option); + std::string getHelp(std::string const& topic_or_option); // Convenience methods for adding member functions of a class as // handlers. @@ -173,7 +163,7 @@ class QPDFArgParser return std::bind(std::mem_fn(f), o); } template - static param_arg_handler_t bindParam(void (T::*f)(char *), T* o) + static param_arg_handler_t bindParam(void (T::*f)(std::string const&), T* o) { return std::bind(std::mem_fn(f), o, std::placeholders::_1); } @@ -238,13 +228,13 @@ class QPDFArgParser void argCompletionBash(); void argCompletionZsh(); - void argHelp(char*); - void invalidHelpArg(char*); + void argHelp(std::string const&); + void invalidHelpArg(std::string const&); void checkCompletion(); void handleArgFileArguments(); void handleBashArguments(); - void readArgsFromFile(char const* filename); + void readArgsFromFile(std::string const& filename); void doFinalChecks(); void addOptionsToCompletions(option_table_t&); void addChoicesToCompletions( @@ -267,12 +257,12 @@ class QPDFArgParser ~Members() = default; private: - Members(int argc, char* argv[], char const* progname_env); + Members(int argc, char const* const argv[], char const* progname_env); Members(Members const&) = delete; int argc; - char** argv; - char const* whoami; + char const* const* argv; + std::string whoami; std::string progname_env; int cur_arg; bool bash_completion; @@ -287,10 +277,10 @@ class QPDFArgParser option_table_t* option_table; std::string option_table_name; bare_arg_handler_t final_check_handler; - std::vector> new_argv; - std::vector> bash_argv; - std::shared_ptr argv_ph; - std::shared_ptr bash_argv_ph; + std::vector> new_argv; + std::vector> bash_argv; + std::shared_ptr argv_ph; + std::shared_ptr bash_argv_ph; std::map help_topics; std::map option_help; std::string help_footer; diff --git a/libqpdf/qpdf/auto_job_decl.hh b/libqpdf/qpdf/auto_job_decl.hh index 86b5b293..2671d130 100644 --- a/libqpdf/qpdf/auto_job_decl.hh +++ b/libqpdf/qpdf/auto_job_decl.hh @@ -17,7 +17,7 @@ void argCopyright(); void argJsonHelp(); void argShowCrypto(); void argJobJsonHelp(); -void argPositional(char*); +void argPositional(std::string const&); void argAddAttachment(); void argCopyAttachmentsFrom(); void argEmpty(); @@ -26,17 +26,17 @@ void argOverlay(); void argPages(); void argReplaceInput(); void argUnderlay(); -void argPagesPositional(char*); -void argPagesPassword(char *); +void argPagesPositional(std::string const&); +void argPagesPassword(std::string const&); void argEndPages(); -void argEncPositional(char*); +void argEncPositional(std::string const&); void argEndEncryption(); void argEnd40BitEncryption(); void argEnd128BitEncryption(); void argEnd256BitEncryption(); -void argUOPositional(char*); +void argUOPositional(std::string const&); void argEndUnderlayOverlay(); -void argAttPositional(char*); +void argAttPositional(std::string const&); void argEndAttachment(); -void argCopyAttPositional(char*); +void argCopyAttPositional(std::string const&); void argEndCopyAttachment(); diff --git a/libqpdf/qpdf/auto_job_init.hh b/libqpdf/qpdf/auto_job_init.hh index 17ab0848..54506493 100644 --- a/libqpdf/qpdf/auto_job_init.hh +++ b/libqpdf/qpdf/auto_job_init.hh @@ -6,7 +6,7 @@ auto b = [this](void (ArgParser::*f)()) { return QPDFArgParser::bindBare(f, this); }; -auto p = [this](void (ArgParser::*f)(char *)) { +auto p = [this](void (ArgParser::*f)(std::string const&)) { return QPDFArgParser::bindParam(f, this); }; @@ -79,88 +79,88 @@ this->ap.addBare("underlay", b(&ArgParser::argUnderlay)); 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.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", [this](char *x){c_main->jobJsonFile(x);}, "file"); -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", [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", [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.addOptionalParameter("collate", [this](char *x){c_main->collate(x);}); -this->ap.addOptionalParameter("split-pages", [this](char *x){c_main->splitPages(x);}); -this->ap.addChoices("compress-streams", [this](char *x){c_main->compressStreams(x);}, true, yn_choices); -this->ap.addChoices("decode-level", [this](char *x){c_main->decodeLevel(x);}, true, decode_level_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", [this](char *x){c_main->objectStreams(x);}, true, object_streams_choices); -this->ap.addChoices("password-mode", [this](char *x){c_main->passwordMode(x);}, true, password_mode_choices); -this->ap.addChoices("remove-unreferenced-resources", [this](char *x){c_main->removeUnreferencedResources(x);}, true, remove_unref_choices); -this->ap.addChoices("stream-data", [this](char *x){c_main->streamData(x);}, true, stream_data_choices); -this->ap.addChoices("json", [this](char *x){c_main->json(x);}, false, json_version_choices); +this->ap.addRequiredParameter("compression-level", [this](std::string const& x){c_main->compressionLevel(x);}, "level"); +this->ap.addRequiredParameter("copy-encryption", [this](std::string const& x){c_main->copyEncryption(x);}, "file"); +this->ap.addRequiredParameter("encryption-file-password", [this](std::string const& x){c_main->encryptionFilePassword(x);}, "password"); +this->ap.addRequiredParameter("force-version", [this](std::string const& x){c_main->forceVersion(x);}, "version"); +this->ap.addRequiredParameter("ii-min-bytes", [this](std::string const& x){c_main->iiMinBytes(x);}, "minimum"); +this->ap.addRequiredParameter("job-json-file", [this](std::string const& x){c_main->jobJsonFile(x);}, "file"); +this->ap.addRequiredParameter("json-object", [this](std::string const& x){c_main->jsonObject(x);}, "trailer"); +this->ap.addRequiredParameter("keep-files-open-threshold", [this](std::string const& x){c_main->keepFilesOpenThreshold(x);}, "count"); +this->ap.addRequiredParameter("linearize-pass1", [this](std::string const& x){c_main->linearizePass1(x);}, "filename"); +this->ap.addRequiredParameter("min-version", [this](std::string const& x){c_main->minVersion(x);}, "version"); +this->ap.addRequiredParameter("oi-min-area", [this](std::string const& x){c_main->oiMinArea(x);}, "minimum"); +this->ap.addRequiredParameter("oi-min-height", [this](std::string const& x){c_main->oiMinHeight(x);}, "minimum"); +this->ap.addRequiredParameter("oi-min-width", [this](std::string const& x){c_main->oiMinWidth(x);}, "minimum"); +this->ap.addRequiredParameter("password", [this](std::string const& x){c_main->password(x);}, "password"); +this->ap.addRequiredParameter("password-file", [this](std::string const& x){c_main->passwordFile(x);}, "password"); +this->ap.addRequiredParameter("remove-attachment", [this](std::string const& x){c_main->removeAttachment(x);}, "attachment"); +this->ap.addRequiredParameter("rotate", [this](std::string const& x){c_main->rotate(x);}, "[+|-]angle"); +this->ap.addRequiredParameter("show-attachment", [this](std::string const& x){c_main->showAttachment(x);}, "attachment"); +this->ap.addRequiredParameter("show-object", [this](std::string const& x){c_main->showObject(x);}, "trailer"); +this->ap.addOptionalParameter("collate", [this](std::string const& x){c_main->collate(x);}); +this->ap.addOptionalParameter("split-pages", [this](std::string const& x){c_main->splitPages(x);}); +this->ap.addChoices("compress-streams", [this](std::string const& x){c_main->compressStreams(x);}, true, yn_choices); +this->ap.addChoices("decode-level", [this](std::string const& x){c_main->decodeLevel(x);}, true, decode_level_choices); +this->ap.addChoices("flatten-annotations", [this](std::string const& x){c_main->flattenAnnotations(x);}, true, flatten_choices); +this->ap.addChoices("json-key", [this](std::string const& x){c_main->jsonKey(x);}, true, json_key_choices); +this->ap.addChoices("keep-files-open", [this](std::string const& x){c_main->keepFilesOpen(x);}, true, yn_choices); +this->ap.addChoices("normalize-content", [this](std::string const& x){c_main->normalizeContent(x);}, true, yn_choices); +this->ap.addChoices("object-streams", [this](std::string const& x){c_main->objectStreams(x);}, true, object_streams_choices); +this->ap.addChoices("password-mode", [this](std::string const& x){c_main->passwordMode(x);}, true, password_mode_choices); +this->ap.addChoices("remove-unreferenced-resources", [this](std::string const& x){c_main->removeUnreferencedResources(x);}, true, remove_unref_choices); +this->ap.addChoices("stream-data", [this](std::string const& x){c_main->streamData(x);}, true, stream_data_choices); +this->ap.addChoices("json", [this](std::string const& x){c_main->json(x);}, false, json_version_choices); this->ap.registerOptionTable("pages", b(&ArgParser::argEndPages)); this->ap.addPositional(p(&ArgParser::argPagesPositional)); this->ap.addRequiredParameter("password", p(&ArgParser::argPagesPassword), "password"); this->ap.registerOptionTable("encryption", b(&ArgParser::argEndEncryption)); this->ap.addPositional(p(&ArgParser::argEncPositional)); this->ap.registerOptionTable("40-bit encryption", b(&ArgParser::argEnd40BitEncryption)); -this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices); -this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices); -this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, yn_choices); -this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, yn_choices); +this->ap.addChoices("extract", [this](std::string const& x){c_enc->extract(x);}, true, yn_choices); +this->ap.addChoices("annotate", [this](std::string const& x){c_enc->annotate(x);}, true, yn_choices); +this->ap.addChoices("print", [this](std::string const& x){c_enc->print(x);}, true, yn_choices); +this->ap.addChoices("modify", [this](std::string const& x){c_enc->modify(x);}, true, yn_choices); this->ap.registerOptionTable("128-bit encryption", b(&ArgParser::argEnd128BitEncryption)); this->ap.addBare("cleartext-metadata", [this](){c_enc->cleartextMetadata();}); this->ap.addBare("force-V4", [this](){c_enc->forceV4();}); -this->ap.addChoices("accessibility", [this](char *x){c_enc->accessibility(x);}, true, yn_choices); -this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices); -this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, print128_choices); -this->ap.addChoices("assemble", [this](char *x){c_enc->assemble(x);}, true, yn_choices); -this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices); -this->ap.addChoices("form", [this](char *x){c_enc->form(x);}, true, yn_choices); -this->ap.addChoices("modify-other", [this](char *x){c_enc->modifyOther(x);}, true, yn_choices); -this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, modify128_choices); -this->ap.addChoices("use-aes", [this](char *x){c_enc->useAes(x);}, true, yn_choices); +this->ap.addChoices("accessibility", [this](std::string const& x){c_enc->accessibility(x);}, true, yn_choices); +this->ap.addChoices("extract", [this](std::string const& x){c_enc->extract(x);}, true, yn_choices); +this->ap.addChoices("print", [this](std::string const& x){c_enc->print(x);}, true, print128_choices); +this->ap.addChoices("assemble", [this](std::string const& x){c_enc->assemble(x);}, true, yn_choices); +this->ap.addChoices("annotate", [this](std::string const& x){c_enc->annotate(x);}, true, yn_choices); +this->ap.addChoices("form", [this](std::string const& x){c_enc->form(x);}, true, yn_choices); +this->ap.addChoices("modify-other", [this](std::string const& x){c_enc->modifyOther(x);}, true, yn_choices); +this->ap.addChoices("modify", [this](std::string const& x){c_enc->modify(x);}, true, modify128_choices); +this->ap.addChoices("use-aes", [this](std::string const& x){c_enc->useAes(x);}, true, yn_choices); this->ap.registerOptionTable("256-bit encryption", b(&ArgParser::argEnd256BitEncryption)); this->ap.addBare("cleartext-metadata", [this](){c_enc->cleartextMetadata();}); this->ap.addBare("force-R5", [this](){c_enc->forceR5();}); this->ap.addBare("allow-insecure", [this](){c_enc->allowInsecure();}); -this->ap.addChoices("accessibility", [this](char *x){c_enc->accessibility(x);}, true, yn_choices); -this->ap.addChoices("extract", [this](char *x){c_enc->extract(x);}, true, yn_choices); -this->ap.addChoices("print", [this](char *x){c_enc->print(x);}, true, print128_choices); -this->ap.addChoices("assemble", [this](char *x){c_enc->assemble(x);}, true, yn_choices); -this->ap.addChoices("annotate", [this](char *x){c_enc->annotate(x);}, true, yn_choices); -this->ap.addChoices("form", [this](char *x){c_enc->form(x);}, true, yn_choices); -this->ap.addChoices("modify-other", [this](char *x){c_enc->modifyOther(x);}, true, yn_choices); -this->ap.addChoices("modify", [this](char *x){c_enc->modify(x);}, true, modify128_choices); +this->ap.addChoices("accessibility", [this](std::string const& x){c_enc->accessibility(x);}, true, yn_choices); +this->ap.addChoices("extract", [this](std::string const& x){c_enc->extract(x);}, true, yn_choices); +this->ap.addChoices("print", [this](std::string const& x){c_enc->print(x);}, true, print128_choices); +this->ap.addChoices("assemble", [this](std::string const& x){c_enc->assemble(x);}, true, yn_choices); +this->ap.addChoices("annotate", [this](std::string const& x){c_enc->annotate(x);}, true, yn_choices); +this->ap.addChoices("form", [this](std::string const& x){c_enc->form(x);}, true, yn_choices); +this->ap.addChoices("modify-other", [this](std::string const& x){c_enc->modifyOther(x);}, true, yn_choices); +this->ap.addChoices("modify", [this](std::string const& x){c_enc->modify(x);}, true, modify128_choices); this->ap.registerOptionTable("underlay/overlay", b(&ArgParser::argEndUnderlayOverlay)); this->ap.addPositional(p(&ArgParser::argUOPositional)); -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.addRequiredParameter("to", [this](std::string const& x){c_uo->to(x);}, "page-range"); +this->ap.addRequiredParameter("from", [this](std::string const& x){c_uo->from(x);}, "page-range"); +this->ap.addRequiredParameter("repeat", [this](std::string const& x){c_uo->repeat(x);}, "page-range"); +this->ap.addRequiredParameter("password", [this](std::string const& 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();}); -this->ap.addRequiredParameter("key", [this](char *x){c_att->key(x);}, "attachment-key"); -this->ap.addRequiredParameter("filename", [this](char *x){c_att->filename(x);}, "filename"); -this->ap.addRequiredParameter("creationdate", [this](char *x){c_att->creationdate(x);}, "creation-date"); -this->ap.addRequiredParameter("moddate", [this](char *x){c_att->moddate(x);}, "modification-date"); -this->ap.addRequiredParameter("mimetype", [this](char *x){c_att->mimetype(x);}, "mime/type"); -this->ap.addRequiredParameter("description", [this](char *x){c_att->description(x);}, "description"); +this->ap.addRequiredParameter("key", [this](std::string const& x){c_att->key(x);}, "attachment-key"); +this->ap.addRequiredParameter("filename", [this](std::string const& x){c_att->filename(x);}, "filename"); +this->ap.addRequiredParameter("creationdate", [this](std::string const& x){c_att->creationdate(x);}, "creation-date"); +this->ap.addRequiredParameter("moddate", [this](std::string const& x){c_att->moddate(x);}, "modification-date"); +this->ap.addRequiredParameter("mimetype", [this](std::string const& x){c_att->mimetype(x);}, "mime/type"); +this->ap.addRequiredParameter("description", [this](std::string const& x){c_att->description(x);}, "description"); this->ap.registerOptionTable("copy attachment", b(&ArgParser::argEndCopyAttachment)); this->ap.addPositional(p(&ArgParser::argCopyAttPositional)); -this->ap.addRequiredParameter("prefix", [this](char *x){c_copy_att->prefix(x);}, "prefix"); -this->ap.addRequiredParameter("password", [this](char *x){c_copy_att->password(x);}, "password"); +this->ap.addRequiredParameter("prefix", [this](std::string const& x){c_copy_att->prefix(x);}, "prefix"); +this->ap.addRequiredParameter("password", [this](std::string const& x){c_copy_att->password(x);}, "password"); diff --git a/libqpdf/qpdf/auto_job_json_init.hh b/libqpdf/qpdf/auto_job_json_init.hh index 833d5471..01a22167 100644 --- a/libqpdf/qpdf/auto_job_json_init.hh +++ b/libqpdf/qpdf/auto_job_json_init.hh @@ -22,7 +22,7 @@ pushKey("password"); setupPassword(); popHandler(); // key: password pushKey("passwordFile"); -addParameter([this](char const* p) { c_main->passwordFile(p); }); +addParameter([this](std::string const& p) { c_main->passwordFile(p); }); popHandler(); // key: passwordFile pushKey("empty"); setupEmpty(); @@ -43,19 +43,19 @@ pushKey("newlineBeforeEndstream"); addBare([this]() { c_main->newlineBeforeEndstream(); }); popHandler(); // key: newlineBeforeEndstream pushKey("normalizeContent"); -addChoices(yn_choices, true, [this](char const* p) { c_main->normalizeContent(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_main->normalizeContent(p); }); popHandler(); // key: normalizeContent pushKey("streamData"); -addChoices(stream_data_choices, true, [this](char const* p) { c_main->streamData(p); }); +addChoices(stream_data_choices, true, [this](std::string const& p) { c_main->streamData(p); }); popHandler(); // key: streamData pushKey("compressStreams"); -addChoices(yn_choices, true, [this](char const* p) { c_main->compressStreams(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_main->compressStreams(p); }); popHandler(); // key: compressStreams pushKey("recompressFlate"); addBare([this]() { c_main->recompressFlate(); }); popHandler(); // key: recompressFlate pushKey("decodeLevel"); -addChoices(decode_level_choices, true, [this](char const* p) { c_main->decodeLevel(p); }); +addChoices(decode_level_choices, true, [this](std::string const& p) { c_main->decodeLevel(p); }); popHandler(); // key: decodeLevel pushKey("decrypt"); addBare([this]() { c_main->decrypt(); }); @@ -73,31 +73,31 @@ pushKey("noOriginalObjectIds"); addBare([this]() { c_main->noOriginalObjectIds(); }); popHandler(); // key: noOriginalObjectIds pushKey("copyEncryption"); -addParameter([this](char const* p) { c_main->copyEncryption(p); }); +addParameter([this](std::string const& p) { c_main->copyEncryption(p); }); popHandler(); // key: copyEncryption pushKey("encryptionFilePassword"); -addParameter([this](char const* p) { c_main->encryptionFilePassword(p); }); +addParameter([this](std::string const& p) { c_main->encryptionFilePassword(p); }); popHandler(); // key: encryptionFilePassword pushKey("linearize"); addBare([this]() { c_main->linearize(); }); popHandler(); // key: linearize pushKey("linearizePass1"); -addParameter([this](char const* p) { c_main->linearizePass1(p); }); +addParameter([this](std::string const& p) { c_main->linearizePass1(p); }); popHandler(); // key: linearizePass1 pushKey("objectStreams"); -addChoices(object_streams_choices, true, [this](char const* p) { c_main->objectStreams(p); }); +addChoices(object_streams_choices, true, [this](std::string const& p) { c_main->objectStreams(p); }); popHandler(); // key: objectStreams pushKey("minVersion"); -addParameter([this](char const* p) { c_main->minVersion(p); }); +addParameter([this](std::string const& p) { c_main->minVersion(p); }); popHandler(); // key: minVersion pushKey("forceVersion"); -addParameter([this](char const* p) { c_main->forceVersion(p); }); +addParameter([this](std::string const& p) { c_main->forceVersion(p); }); popHandler(); // key: forceVersion pushKey("progress"); addBare([this]() { c_main->progress(); }); popHandler(); // key: progress pushKey("splitPages"); -addParameter([this](char const* p) { c_main->splitPages(p); }); +addParameter([this](std::string const& p) { c_main->splitPages(p); }); popHandler(); // key: splitPages pushKey("encrypt"); beginDict(bindJSON(&Handlers::beginEncrypt), bindBare(&Handlers::endEncrypt)); // .encrypt @@ -110,82 +110,82 @@ popHandler(); // key: ownerPassword pushKey("40bit"); beginDict(bindJSON(&Handlers::beginEncrypt40bit), bindBare(&Handlers::endEncrypt40bit)); // .encrypt.40bit pushKey("annotate"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->annotate(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->annotate(p); }); popHandler(); // key: annotate pushKey("extract"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->extract(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->extract(p); }); popHandler(); // key: extract pushKey("modify"); -addChoices(modify128_choices, true, [this](char const* p) { c_enc->modify(p); }); +addChoices(modify128_choices, true, [this](std::string const& p) { c_enc->modify(p); }); popHandler(); // key: modify pushKey("print"); -addChoices(print128_choices, true, [this](char const* p) { c_enc->print(p); }); +addChoices(print128_choices, true, [this](std::string const& p) { c_enc->print(p); }); popHandler(); // key: print popHandler(); // key: 40bit pushKey("128bit"); beginDict(bindJSON(&Handlers::beginEncrypt128bit), bindBare(&Handlers::endEncrypt128bit)); // .encrypt.128bit pushKey("accessibility"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->accessibility(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->accessibility(p); }); popHandler(); // key: accessibility pushKey("annotate"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->annotate(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->annotate(p); }); popHandler(); // key: annotate pushKey("assemble"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->assemble(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->assemble(p); }); popHandler(); // key: assemble pushKey("cleartextMetadata"); addBare([this]() { c_enc->cleartextMetadata(); }); popHandler(); // key: cleartextMetadata pushKey("extract"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->extract(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->extract(p); }); popHandler(); // key: extract pushKey("form"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->form(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->form(p); }); popHandler(); // key: form pushKey("modifyOther"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->modifyOther(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->modifyOther(p); }); popHandler(); // key: modifyOther pushKey("modify"); -addChoices(modify128_choices, true, [this](char const* p) { c_enc->modify(p); }); +addChoices(modify128_choices, true, [this](std::string const& p) { c_enc->modify(p); }); popHandler(); // key: modify pushKey("print"); -addChoices(print128_choices, true, [this](char const* p) { c_enc->print(p); }); +addChoices(print128_choices, true, [this](std::string const& p) { c_enc->print(p); }); popHandler(); // key: print pushKey("forceV4"); addBare([this]() { c_enc->forceV4(); }); popHandler(); // key: forceV4 pushKey("useAes"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->useAes(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->useAes(p); }); popHandler(); // key: useAes popHandler(); // key: 128bit pushKey("256bit"); beginDict(bindJSON(&Handlers::beginEncrypt256bit), bindBare(&Handlers::endEncrypt256bit)); // .encrypt.256bit pushKey("accessibility"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->accessibility(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->accessibility(p); }); popHandler(); // key: accessibility pushKey("annotate"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->annotate(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->annotate(p); }); popHandler(); // key: annotate pushKey("assemble"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->assemble(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->assemble(p); }); popHandler(); // key: assemble pushKey("cleartextMetadata"); addBare([this]() { c_enc->cleartextMetadata(); }); popHandler(); // key: cleartextMetadata pushKey("extract"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->extract(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->extract(p); }); popHandler(); // key: extract pushKey("form"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->form(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->form(p); }); popHandler(); // key: form pushKey("modifyOther"); -addChoices(yn_choices, true, [this](char const* p) { c_enc->modifyOther(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_enc->modifyOther(p); }); popHandler(); // key: modifyOther pushKey("modify"); -addChoices(modify128_choices, true, [this](char const* p) { c_enc->modify(p); }); +addChoices(modify128_choices, true, [this](std::string const& p) { c_enc->modify(p); }); popHandler(); // key: modify pushKey("print"); -addChoices(print128_choices, true, [this](char const* p) { c_enc->print(p); }); +addChoices(print128_choices, true, [this](std::string const& p) { c_enc->print(p); }); popHandler(); // key: print pushKey("allowInsecure"); addBare([this]() { c_enc->allowInsecure(); }); @@ -220,7 +220,7 @@ pushKey("showNpages"); addBare([this]() { c_main->showNpages(); }); popHandler(); // key: showNpages pushKey("showObject"); -addParameter([this](char const* p) { c_main->showObject(p); }); +addParameter([this](std::string const& p) { c_main->showObject(p); }); popHandler(); // key: showObject pushKey("showPages"); addBare([this]() { c_main->showPages(); }); @@ -235,29 +235,29 @@ pushKey("listAttachments"); addBare([this]() { c_main->listAttachments(); }); popHandler(); // key: listAttachments pushKey("showAttachment"); -addParameter([this](char const* p) { c_main->showAttachment(p); }); +addParameter([this](std::string const& p) { c_main->showAttachment(p); }); popHandler(); // key: showAttachment pushKey("json"); -addChoices(json_version_choices, false, [this](char const* p) { c_main->json(p); }); +addChoices(json_version_choices, false, [this](std::string const& p) { c_main->json(p); }); popHandler(); // key: json pushKey("jsonKey"); beginArray(bindJSON(&Handlers::beginJsonKeyArray), bindBare(&Handlers::endJsonKeyArray)); // .jsonKey[] -addChoices(json_key_choices, true, [this](char const* p) { c_main->jsonKey(p); }); +addChoices(json_key_choices, true, [this](std::string const& p) { c_main->jsonKey(p); }); popHandler(); // array: .jsonKey[] popHandler(); // key: jsonKey pushKey("jsonObject"); beginArray(bindJSON(&Handlers::beginJsonObjectArray), bindBare(&Handlers::endJsonObjectArray)); // .jsonObject[] -addParameter([this](char const* p) { c_main->jsonObject(p); }); +addParameter([this](std::string const& p) { c_main->jsonObject(p); }); popHandler(); // array: .jsonObject[] popHandler(); // key: jsonObject pushKey("allowWeakCrypto"); addBare([this]() { c_main->allowWeakCrypto(); }); popHandler(); // key: allowWeakCrypto pushKey("keepFilesOpen"); -addChoices(yn_choices, true, [this](char const* p) { c_main->keepFilesOpen(p); }); +addChoices(yn_choices, true, [this](std::string const& p) { c_main->keepFilesOpen(p); }); popHandler(); // key: keepFilesOpen pushKey("keepFilesOpenThreshold"); -addParameter([this](char const* p) { c_main->keepFilesOpenThreshold(p); }); +addParameter([this](std::string const& p) { c_main->keepFilesOpenThreshold(p); }); popHandler(); // key: keepFilesOpenThreshold pushKey("noWarn"); addBare([this]() { c_main->noWarn(); }); @@ -272,7 +272,7 @@ pushKey("passwordIsHexKey"); addBare([this]() { c_main->passwordIsHexKey(); }); popHandler(); // key: passwordIsHexKey pushKey("passwordMode"); -addChoices(password_mode_choices, true, [this](char const* p) { c_main->passwordMode(p); }); +addChoices(password_mode_choices, true, [this](std::string const& p) { c_main->passwordMode(p); }); popHandler(); // key: passwordMode pushKey("suppressPasswordRecovery"); addBare([this]() { c_main->suppressPasswordRecovery(); }); @@ -284,16 +284,16 @@ pushKey("coalesceContents"); addBare([this]() { c_main->coalesceContents(); }); popHandler(); // key: coalesceContents pushKey("compressionLevel"); -addParameter([this](char const* p) { c_main->compressionLevel(p); }); +addParameter([this](std::string const& p) { c_main->compressionLevel(p); }); popHandler(); // key: compressionLevel pushKey("externalizeInlineImages"); addBare([this]() { c_main->externalizeInlineImages(); }); popHandler(); // key: externalizeInlineImages pushKey("iiMinBytes"); -addParameter([this](char const* p) { c_main->iiMinBytes(p); }); +addParameter([this](std::string const& p) { c_main->iiMinBytes(p); }); popHandler(); // key: iiMinBytes pushKey("removeUnreferencedResources"); -addChoices(remove_unref_choices, true, [this](char const* p) { c_main->removeUnreferencedResources(p); }); +addChoices(remove_unref_choices, true, [this](std::string const& p) { c_main->removeUnreferencedResources(p); }); popHandler(); // key: removeUnreferencedResources pushKey("addAttachment"); beginArray(bindJSON(&Handlers::beginAddAttachmentArray), bindBare(&Handlers::endAddAttachmentArray)); // .addAttachment[] @@ -302,22 +302,22 @@ pushKey("file"); setupAddAttachmentFile(); popHandler(); // key: file pushKey("creationdate"); -addParameter([this](char const* p) { c_att->creationdate(p); }); +addParameter([this](std::string const& p) { c_att->creationdate(p); }); popHandler(); // key: creationdate pushKey("description"); -addParameter([this](char const* p) { c_att->description(p); }); +addParameter([this](std::string const& p) { c_att->description(p); }); popHandler(); // key: description pushKey("filename"); -addParameter([this](char const* p) { c_att->filename(p); }); +addParameter([this](std::string const& p) { c_att->filename(p); }); popHandler(); // key: filename pushKey("key"); -addParameter([this](char const* p) { c_att->key(p); }); +addParameter([this](std::string const& p) { c_att->key(p); }); popHandler(); // key: key pushKey("mimetype"); -addParameter([this](char const* p) { c_att->mimetype(p); }); +addParameter([this](std::string const& p) { c_att->mimetype(p); }); popHandler(); // key: mimetype pushKey("moddate"); -addParameter([this](char const* p) { c_att->moddate(p); }); +addParameter([this](std::string const& p) { c_att->moddate(p); }); popHandler(); // key: moddate pushKey("replace"); addBare([this]() { c_att->replace(); }); @@ -325,7 +325,7 @@ popHandler(); // key: replace popHandler(); // array: .addAttachment[] popHandler(); // key: addAttachment pushKey("removeAttachment"); -addParameter([this](char const* p) { c_main->removeAttachment(p); }); +addParameter([this](std::string const& p) { c_main->removeAttachment(p); }); popHandler(); // key: removeAttachment pushKey("copyAttachmentsFrom"); beginArray(bindJSON(&Handlers::beginCopyAttachmentsFromArray), bindBare(&Handlers::endCopyAttachmentsFromArray)); // .copyAttachmentsFrom[] @@ -337,15 +337,15 @@ pushKey("password"); setupCopyAttachmentsFromPassword(); popHandler(); // key: password pushKey("prefix"); -addParameter([this](char const* p) { c_copy_att->prefix(p); }); +addParameter([this](std::string const& p) { c_copy_att->prefix(p); }); popHandler(); // key: prefix popHandler(); // array: .copyAttachmentsFrom[] popHandler(); // key: copyAttachmentsFrom pushKey("collate"); -addParameter([this](char const* p) { c_main->collate(p); }); +addParameter([this](std::string const& p) { c_main->collate(p); }); popHandler(); // key: collate pushKey("flattenAnnotations"); -addChoices(flatten_choices, true, [this](char const* p) { c_main->flattenAnnotations(p); }); +addChoices(flatten_choices, true, [this](std::string const& p) { c_main->flattenAnnotations(p); }); popHandler(); // key: flattenAnnotations pushKey("flattenRotation"); addBare([this]() { c_main->flattenRotation(); }); @@ -357,13 +357,13 @@ pushKey("keepInlineImages"); addBare([this]() { c_main->keepInlineImages(); }); popHandler(); // key: keepInlineImages pushKey("oiMinArea"); -addParameter([this](char const* p) { c_main->oiMinArea(p); }); +addParameter([this](std::string const& p) { c_main->oiMinArea(p); }); popHandler(); // key: oiMinArea pushKey("oiMinHeight"); -addParameter([this](char const* p) { c_main->oiMinHeight(p); }); +addParameter([this](std::string const& p) { c_main->oiMinHeight(p); }); popHandler(); // key: oiMinHeight pushKey("oiMinWidth"); -addParameter([this](char const* p) { c_main->oiMinWidth(p); }); +addParameter([this](std::string const& p) { c_main->oiMinWidth(p); }); popHandler(); // key: oiMinWidth pushKey("optimizeImages"); addBare([this]() { c_main->optimizeImages(); }); @@ -386,7 +386,7 @@ pushKey("removePageLabels"); addBare([this]() { c_main->removePageLabels(); }); popHandler(); // key: removePageLabels pushKey("rotate"); -addParameter([this](char const* p) { c_main->rotate(p); }); +addParameter([this](std::string const& p) { c_main->rotate(p); }); popHandler(); // key: rotate pushKey("overlay"); beginDict(bindJSON(&Handlers::beginOverlay), bindBare(&Handlers::endOverlay)); // .overlay @@ -397,13 +397,13 @@ pushKey("password"); setupOverlayPassword(); popHandler(); // key: password pushKey("from"); -addParameter([this](char const* p) { c_uo->from(p); }); +addParameter([this](std::string const& p) { c_uo->from(p); }); popHandler(); // key: from pushKey("repeat"); -addParameter([this](char const* p) { c_uo->repeat(p); }); +addParameter([this](std::string const& p) { c_uo->repeat(p); }); popHandler(); // key: repeat pushKey("to"); -addParameter([this](char const* p) { c_uo->to(p); }); +addParameter([this](std::string const& p) { c_uo->to(p); }); popHandler(); // key: to popHandler(); // key: overlay pushKey("underlay"); @@ -415,20 +415,20 @@ pushKey("password"); setupUnderlayPassword(); popHandler(); // key: password pushKey("from"); -addParameter([this](char const* p) { c_uo->from(p); }); +addParameter([this](std::string const& p) { c_uo->from(p); }); popHandler(); // key: from pushKey("repeat"); -addParameter([this](char const* p) { c_uo->repeat(p); }); +addParameter([this](std::string const& p) { c_uo->repeat(p); }); popHandler(); // key: repeat pushKey("to"); -addParameter([this](char const* p) { c_uo->to(p); }); +addParameter([this](std::string const& p) { c_uo->to(p); }); popHandler(); // key: to popHandler(); // key: underlay pushKey("warningExit0"); addBare([this]() { c_main->warningExit0(); }); popHandler(); // key: warningExit0 pushKey("jobJsonFile"); -addParameter([this](char const* p) { c_main->jobJsonFile(p); }); +addParameter([this](std::string const& p) { c_main->jobJsonFile(p); }); popHandler(); // key: jobJsonFile pushKey("preserveUnreferencedResources"); addBare([this]() { c_main->preserveUnreferencedResources(); }); diff --git a/libqpdf/qpdfjob-c.cc b/libqpdf/qpdfjob-c.cc index 7b3f6b60..e1c76477 100644 --- a/libqpdf/qpdfjob-c.cc +++ b/libqpdf/qpdfjob-c.cc @@ -7,9 +7,10 @@ #include #include -int qpdfjob_run_from_argv(int argc, char* argv[]) +int qpdfjob_run_from_argv(int argc, char const* const argv[]) { - auto whoami = QUtil::getWhoami(argv[0]); + auto whoami_p = QUtil::make_shared_cstr(argv[0]); + auto whoami = QUtil::getWhoami(whoami_p.get()); QUtil::setLineBuf(stdout); QPDFJob j; @@ -27,7 +28,7 @@ int qpdfjob_run_from_argv(int argc, char* argv[]) } #ifndef QPDF_NO_WCHAR_T -int qpdfjob_run_from_wide_argv(int argc, wchar_t* argv[]) +int qpdfjob_run_from_wide_argv(int argc, wchar_t const* const argv[]) { return QUtil::call_main_from_wmain(argc, argv, qpdfjob_run_from_argv); } diff --git a/libtests/arg_parser.cc b/libtests/arg_parser.cc index e17ebdd1..0c7e6787 100644 --- a/libtests/arg_parser.cc +++ b/libtests/arg_parser.cc @@ -15,12 +15,12 @@ class ArgParser private: void handlePotato(); - void handleSalad(char* p); - void handleMoo(char* p); - void handleOink(char* p); - void handleQuack(char* p); + void handleSalad(std::string const& p); + void handleMoo(std::string const& p); + void handleOink(std::string const& p); + void handleQuack(std::string const& p); void startQuack(); - void getQuack(char* p); + void getQuack(std::string const& p); void endQuack(); void finalChecks(); @@ -44,7 +44,7 @@ ArgParser::initOptions() auto b = [this](void (ArgParser::*f)()) { return QPDFArgParser::bindBare(f, this); }; - auto p = [this](void (ArgParser::*f)(char *)) { + auto p = [this](void (ArgParser::*f)(std::string const&)) { return QPDFArgParser::bindParam(f, this); }; @@ -98,19 +98,19 @@ ArgParser::handlePotato() } void -ArgParser::handleSalad(char* p) +ArgParser::handleSalad(std::string const& p) { output(std::string("got salad=") + p); } void -ArgParser::handleMoo(char* p) +ArgParser::handleMoo(std::string const& p) { - output(std::string("got moo=") + (p ? p : "(none)")); + output(std::string("got moo=") + (p.empty() ? "(none)" : p)); } void -ArgParser::handleOink(char* p) +ArgParser::handleOink(std::string const& p) { output(std::string("got oink=") + p); } @@ -137,7 +137,7 @@ ArgParser::startQuack() } void -ArgParser::getQuack(char* p) +ArgParser::getQuack(std::string const& p) { ++this->quacks; if (this->ap.isCompleting() && (this->ap.argsLeft() == 0)) @@ -210,7 +210,7 @@ ArgParser::test_exceptions() }); err("invalid choice handler to unknown", [this]() { ap.addInvalidChoiceHandler( - "elephant", [](char*){}); + "elephant", [](std::string const&){}); }); } diff --git a/libtests/main_from_wmain.cc b/libtests/main_from_wmain.cc index c3e2a716..6b8a9c05 100644 --- a/libtests/main_from_wmain.cc +++ b/libtests/main_from_wmain.cc @@ -4,17 +4,37 @@ #ifndef QPDF_NO_WCHAR_T void wmain_test() { + // writable args and function args auto realmain = [](int argc, char* argv[]) { - for (int i = 0; i < argc; ++i) { - std::cout << argv[i] << std::endl; - } return 0; - }; + for (int i = 0; i < argc; ++i) { + std::cout << argv[i] << std::endl; + } return 0; + }; wchar_t* argv[3]; + // This works because call_main_from_wmain doesn't actually write + // to the arguments and neither does our function. Otherwise, this + // cast would be unsafe. argv[0] = const_cast(L"ascii"); argv[1] = const_cast(L"10 \xf7 2 = 5"); argv[2] = const_cast(L"qwww\xf7\x03c0"); QUtil::call_main_from_wmain(3, argv, realmain); } + +void cwmain_test() +{ + // const args and function args + auto realmain = [](int argc, char const* const argv[]) { + for (int i = 0; i < argc; ++i) { + std::cout << "const " << argv[i] << std::endl; + } return 0; + }; + wchar_t const* argv[3] = { + L"ascii", + L"10 \xf7 2 = 5", + L"qwww\xf7\x03c0", + }; + QUtil::call_main_from_wmain(3, argv, realmain); +} #endif // QPDF_NO_WCHAR_T int main(int argc, char* argv[]) @@ -23,6 +43,7 @@ int main(int argc, char* argv[]) try { wmain_test(); + cwmain_test(); } catch (std::exception& e) { diff --git a/libtests/qtest/qutil/wmain.out b/libtests/qtest/qutil/wmain.out index 261b1c56..5a1eb6f3 100644 --- a/libtests/qtest/qutil/wmain.out +++ b/libtests/qtest/qutil/wmain.out @@ -1,3 +1,6 @@ ascii 10 ÷ 2 = 5 qwww÷π +const ascii +const 10 ÷ 2 = 5 +const qwww÷π diff --git a/qpdf/qpdfjob-ctest.c b/qpdf/qpdfjob-ctest.c index 3de2fa96..73605f8a 100644 --- a/qpdf/qpdfjob-ctest.c +++ b/qpdf/qpdfjob-ctest.c @@ -7,11 +7,11 @@ #ifndef QPDF_NO_WCHAR_T static void wide_test() { - wchar_t* argv[5]; - argv[0] = (wchar_t*)(L"qpdfjob"); - argv[1] = (wchar_t*)(L"minimal.pdf"); - argv[2] = (wchar_t*)(L"a.pdf"); - argv[3] = (wchar_t*)(L"--static-id"); + wchar_t const* argv[5]; + argv[0] = L"qpdfjob"; + argv[1] = L"minimal.pdf"; + argv[2] = L"a.pdf"; + argv[3] = L"--static-id"; argv[4] = NULL; assert(qpdfjob_run_from_wide_argv(4, argv) == 0); printf("wide test passed\n"); @@ -22,11 +22,11 @@ static void run_tests() { /* Be sure to use a different output file for each test. */ - char* argv[5]; - argv[0] = (char*)("qpdfjob"); - argv[1] = (char*)("minimal.pdf"); - argv[2] = (char*)("a.pdf"); - argv[3] = (char*)("--deterministic-id"); + char const* argv[5]; + argv[0] = "qpdfjob"; + argv[1] = "minimal.pdf"; + argv[2] = "a.pdf"; + argv[3] = "--deterministic-id"; argv[4] = NULL; assert(qpdfjob_run_from_argv(4, argv) == 0); printf("argv test passed\n"); -- cgit v1.2.3-70-g09d2