Commit 42bff9f4584362f2084033795896c2e891274631

Authored by Jay Berkenbilt
1 parent a0d9d992

QPDFJob: let initializeFromArgv just take argv, not argc

Let argv be a null-terminated array. There is already code that
assumes this, and it makes it easier to construct the arguments.
examples/qpdf-job.cc
@@ -82,7 +82,7 @@ int main(int argc, char* argv[]) @@ -82,7 +82,7 @@ int main(int argc, char* argv[])
82 nullptr 82 nullptr
83 }; 83 };
84 QPDFJob j; 84 QPDFJob j;
85 - j.initializeFromArgv(9, new_argv); 85 + j.initializeFromArgv(new_argv);
86 j.run(); 86 j.run();
87 std::cout << "out2 status: " << j.getExitCode() << std::endl; 87 std::cout << "out2 status: " << j.getExitCode() << std::endl;
88 } 88 }
examples/qpdfjob-c.c
@@ -57,6 +57,6 @@ int main(int argc, char* argv[]) @@ -57,6 +57,6 @@ int main(int argc, char* argv[])
57 * qpdfjob_run_from_json instead and pass the json string as a 57 * qpdfjob_run_from_json instead and pass the json string as a
58 * single char const* argument. 58 * single char const* argument.
59 */ 59 */
60 - r = qpdfjob_run_from_argv(5, new_argv); 60 + r = qpdfjob_run_from_argv(new_argv);
61 return r; 61 return r;
62 } 62 }
include/qpdf/QPDFJob.hh
@@ -57,27 +57,28 @@ class QPDFJob @@ -57,27 +57,28 @@ class QPDFJob
57 57
58 // SETUP FUNCTIONS 58 // SETUP FUNCTIONS
59 59
60 - // Initialize a QPDFJob object from argv. The progname_env  
61 - // argument is the name of an environment variable which, if set,  
62 - // overrides the name of the executable for purposes of generating  
63 - // the --completion options. See QPDFArgParser for details. If a  
64 - // null pointer is passed in, the default value of  
65 - // "QPDF_EXECUTABLE" is used. This is used by the QPDF cli, which  
66 - // just initializes a QPDFJob from argv, calls run(), and handles  
67 - // errors and exit status issues. You can perform much of the cli  
68 - // functionality programmatically in this way rather than using  
69 - // the regular API. This is exposed in the C API, which makes it  
70 - // easier to get certain high-level qpdf functionality from other  
71 - // languages. If there are any command-line errors, this method  
72 - // will throw QPDFUsage which is derived from std::runtime_error.  
73 - // Other exceptions may be thrown in some cases. Note that argc,  
74 - // and argv should be UTF-8 encoded. If you are calling this from  
75 - // a Windows Unicode-aware main (wmain), see  
76 - // QUtil::call_main_from_wmain for information about converting  
77 - // arguments to UTF-8. This method will mutate arguments that are  
78 - // passed to it. 60 + // Initialize a QPDFJob object from argv, which must be a
  61 + // null-terminated array of null-terminated UTF-8-encoded C
  62 + // strings. The progname_env argument is the name of an
  63 + // environment variable which, if set, overrides the name of the
  64 + // executable for purposes of generating the --completion options.
  65 + // See QPDFArgParser for details. If a null pointer is passed in,
  66 + // the default value of "QPDF_EXECUTABLE" is used. This is used by
  67 + // the QPDF cli, which just initializes a QPDFJob from argv, calls
  68 + // run(), and handles errors and exit status issues. You can
  69 + // perform much of the cli functionality programmatically in this
  70 + // way rather than using the regular API. This is exposed in the C
  71 + // API, which makes it easier to get certain high-level qpdf
  72 + // functionality from other languages. If there are any
  73 + // command-line errors, this method will throw QPDFUsage which is
  74 + // derived from std::runtime_error. Other exceptions may be thrown
  75 + // in some cases. Note that argc, and argv should be UTF-8
  76 + // encoded. If you are calling this from a Windows Unicode-aware
  77 + // main (wmain), see QUtil::call_main_from_wmain for information
  78 + // about converting arguments to UTF-8. This method will mutate
  79 + // arguments that are passed to it.
79 QPDF_DLL 80 QPDF_DLL
80 - void initializeFromArgv(int argc, char const* const argv[], 81 + void initializeFromArgv(char const* const argv[],
81 char const* progname_env = nullptr); 82 char const* progname_env = nullptr);
82 83
83 // Initialize a QPDFJob from json. Passing partial = true prevents 84 // Initialize a QPDFJob from json. Passing partial = true prevents
include/qpdf/qpdfjob-c.h
@@ -47,12 +47,12 @@ extern &quot;C&quot; { @@ -47,12 +47,12 @@ extern &quot;C&quot; {
47 #endif 47 #endif
48 /* This function does the equivalent of running the qpdf 48 /* This function does the equivalent of running the qpdf
49 * command-line with the given arguments and returns the exit code 49 * command-line with the given arguments and returns the exit code
50 - * that qpdf would use. Note that arguments must be UTF8-encoded.  
51 - * If calling this from wmain on Windows, use  
52 - * qpdfjob_run_from_wide_argv instead. 50 + * that qpdf would use. argv must be a null-terminated array of
  51 + * null-terminated UTF8-encoded strings. If calling this from
  52 + * wmain on Windows, use qpdfjob_run_from_wide_argv instead.
53 */ 53 */
54 QPDF_DLL 54 QPDF_DLL
55 - int qpdfjob_run_from_argv(int argc, char const* const argv[]); 55 + int qpdfjob_run_from_argv(char const* const argv[]);
56 56
57 #ifndef QPDF_NO_WCHAR_T 57 #ifndef QPDF_NO_WCHAR_T
58 /* This function is the same as qpdfjob_run_from_argv except argv 58 /* This function is the same as qpdfjob_run_from_argv except argv
@@ -60,7 +60,7 @@ extern &quot;C&quot; { @@ -60,7 +60,7 @@ extern &quot;C&quot; {
60 * calling from a Windows wmain function. 60 * calling from a Windows wmain function.
61 */ 61 */
62 QPDF_DLL 62 QPDF_DLL
63 - int qpdfjob_run_from_wide_argv(int argc, wchar_t const* const argv[]); 63 + int qpdfjob_run_from_wide_argv(wchar_t const* const argv[]);
64 #endif /* QPDF_NO_WCHAR_T */ 64 #endif /* QPDF_NO_WCHAR_T */
65 65
66 /* This function runs QPDFJob from a job JSON file. See the "QPDF 66 /* This function runs QPDFJob from a job JSON file. See the "QPDF
libqpdf/QPDFJob_argv.cc
@@ -465,13 +465,18 @@ ArgParser::parseOptions() @@ -465,13 +465,18 @@ ArgParser::parseOptions()
465 } 465 }
466 466
467 void 467 void
468 -QPDFJob::initializeFromArgv(int argc, char const* const argv[], 468 +QPDFJob::initializeFromArgv(char const* const argv[],
469 char const* progname_env) 469 char const* progname_env)
470 { 470 {
471 if (progname_env == nullptr) 471 if (progname_env == nullptr)
472 { 472 {
473 progname_env = "QPDF_EXECUTABLE"; 473 progname_env = "QPDF_EXECUTABLE";
474 } 474 }
  475 + int argc = 0;
  476 + for (auto k = argv; *k; ++k)
  477 + {
  478 + ++argc;
  479 + }
475 QPDFArgParser qap(argc, argv, progname_env); 480 QPDFArgParser qap(argc, argv, progname_env);
476 setMessagePrefix(qap.getProgname()); 481 setMessagePrefix(qap.getProgname());
477 ArgParser ap(qap, config()); 482 ArgParser ap(qap, config());
libqpdf/qpdfjob-c.cc
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 #include <cstdio> 7 #include <cstdio>
8 #include <cstring> 8 #include <cstring>
9 9
10 -int qpdfjob_run_from_argv(int argc, char const* const argv[]) 10 +int qpdfjob_run_from_argv(char const* const argv[])
11 { 11 {
12 auto whoami_p = QUtil::make_shared_cstr(argv[0]); 12 auto whoami_p = QUtil::make_shared_cstr(argv[0]);
13 auto whoami = QUtil::getWhoami(whoami_p.get()); 13 auto whoami = QUtil::getWhoami(whoami_p.get());
@@ -16,7 +16,7 @@ int qpdfjob_run_from_argv(int argc, char const* const argv[]) @@ -16,7 +16,7 @@ int qpdfjob_run_from_argv(int argc, char const* const argv[])
16 QPDFJob j; 16 QPDFJob j;
17 try 17 try
18 { 18 {
19 - j.initializeFromArgv(argc, argv); 19 + j.initializeFromArgv(argv);
20 j.run(); 20 j.run();
21 } 21 }
22 catch (std::exception& e) 22 catch (std::exception& e)
@@ -28,9 +28,17 @@ int qpdfjob_run_from_argv(int argc, char const* const argv[]) @@ -28,9 +28,17 @@ int qpdfjob_run_from_argv(int argc, char const* const argv[])
28 } 28 }
29 29
30 #ifndef QPDF_NO_WCHAR_T 30 #ifndef QPDF_NO_WCHAR_T
31 -int qpdfjob_run_from_wide_argv(int argc, wchar_t const* const argv[]) 31 +int qpdfjob_run_from_wide_argv(wchar_t const* const argv[])
32 { 32 {
33 - return QUtil::call_main_from_wmain(argc, argv, qpdfjob_run_from_argv); 33 + int argc = 0;
  34 + for (auto k = argv; *k; ++k)
  35 + {
  36 + ++argc;
  37 + }
  38 + return QUtil::call_main_from_wmain(
  39 + argc, argv, [](int, char const* const new_argv[]) {
  40 + return qpdfjob_run_from_argv(new_argv);
  41 + });
34 } 42 }
35 #endif // QPDF_NO_WCHAR_T 43 #endif // QPDF_NO_WCHAR_T
36 44
qpdf/qpdf.cc
@@ -43,7 +43,7 @@ int realmain(int argc, char* argv[]) @@ -43,7 +43,7 @@ int realmain(int argc, char* argv[])
43 try 43 try
44 { 44 {
45 // See "HOW TO ADD A COMMAND-LINE ARGUMENT" in README-maintainer. 45 // See "HOW TO ADD A COMMAND-LINE ARGUMENT" in README-maintainer.
46 - j.initializeFromArgv(argc, argv); 46 + j.initializeFromArgv(argv);
47 j.run(); 47 j.run();
48 } 48 }
49 catch (QPDFUsage& e) 49 catch (QPDFUsage& e)
qpdf/qpdfjob-ctest.c
@@ -13,7 +13,7 @@ static void wide_test() @@ -13,7 +13,7 @@ static void wide_test()
13 argv[2] = L"a.pdf"; 13 argv[2] = L"a.pdf";
14 argv[3] = L"--static-id"; 14 argv[3] = L"--static-id";
15 argv[4] = NULL; 15 argv[4] = NULL;
16 - assert(qpdfjob_run_from_wide_argv(4, argv) == 0); 16 + assert(qpdfjob_run_from_wide_argv(argv) == 0);
17 printf("wide test passed\n"); 17 printf("wide test passed\n");
18 } 18 }
19 #endif // QPDF_NO_WCHAR_T 19 #endif // QPDF_NO_WCHAR_T
@@ -28,7 +28,7 @@ static void run_tests() @@ -28,7 +28,7 @@ static void run_tests()
28 argv[2] = "a.pdf"; 28 argv[2] = "a.pdf";
29 argv[3] = "--deterministic-id"; 29 argv[3] = "--deterministic-id";
30 argv[4] = NULL; 30 argv[4] = NULL;
31 - assert(qpdfjob_run_from_argv(4, argv) == 0); 31 + assert(qpdfjob_run_from_argv(argv) == 0);
32 printf("argv test passed\n"); 32 printf("argv test passed\n");
33 33
34 assert(qpdfjob_run_from_json("{\n\ 34 assert(qpdfjob_run_from_json("{\n\