diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | include/qpdf/JSONHandler.hh | 22 | ||||
-rw-r--r-- | include/qpdf/QPDFArgParser.hh | 14 | ||||
-rw-r--r-- | include/qpdf/QPDFExc.hh | 2 | ||||
-rw-r--r-- | include/qpdf/QPDFJob.hh | 16 | ||||
-rw-r--r-- | include/qpdf/QPDFSystemError.hh | 2 | ||||
-rw-r--r-- | include/qpdf/QPDFUsage.hh | 39 | ||||
-rw-r--r-- | libqpdf/JSONHandler.cc | 20 | ||||
-rw-r--r-- | libqpdf/QPDFArgParser.cc | 8 | ||||
-rw-r--r-- | libqpdf/QPDFJob.cc | 21 | ||||
-rw-r--r-- | libqpdf/QPDFJob_argv.cc | 2 | ||||
-rw-r--r-- | libqpdf/QPDFJob_config.cc | 5 | ||||
-rw-r--r-- | libqpdf/QPDFSystemError.cc | 2 | ||||
-rw-r--r-- | libqpdf/QPDFUsage.cc | 6 | ||||
-rw-r--r-- | libqpdf/build.mk | 1 | ||||
-rw-r--r-- | libtests/arg_parser.cc | 3 | ||||
-rw-r--r-- | libtests/json_handler.cc | 3 | ||||
-rw-r--r-- | qpdf/qpdf.cc | 8 |
18 files changed, 99 insertions, 81 deletions
@@ -1,3 +1,9 @@ +2022-01-28 Jay Berkenbilt <ejb@ql.org> + + * Add QPDFUsage exception, which is thrown by JSONHandler, + QPDFArgParser, and QPDFJob to indicate command-line usage or job + configuration errors. + 2022-01-22 Jay Berkenbilt <ejb@ql.org> * Add QUtil::make_shared_cstr to return a std::shared_ptr<char> diff --git a/include/qpdf/JSONHandler.hh b/include/qpdf/JSONHandler.hh index 0f75f946..73e8295f 100644 --- a/include/qpdf/JSONHandler.hh +++ b/include/qpdf/JSONHandler.hh @@ -28,7 +28,6 @@ #include <string> #include <map> #include <functional> -#include <stdexcept> #include <memory> // This class allows a sax-like walk through a JSON object with @@ -39,15 +38,8 @@ class JSONHandler { public: - // Error exception is thrown if there are any errors validating - // the JSON object. - class QPDF_DLL_CLASS Error: public std::runtime_error - { - public: - QPDF_DLL - Error(std::string const&); - }; - + // A QPDFUsage exception is thrown if there are any errors + // validating the JSON object. QPDF_DLL JSONHandler(); @@ -55,10 +47,10 @@ class JSONHandler ~JSONHandler() = default; // Based on the type of handler, expect the object to be of a - // certain type. JSONHandler::Error is thrown otherwise. Multiple - // handlers may be registered, which allows the object to be of - // various types. If an anyHandler is added, no other handler will - // be called. There is no "final" handler -- if the top-level is a + // certain type. QPDFUsage is thrown otherwise. Multiple handlers + // may be registered, which allows the object to be of various + // types. If an anyHandler is added, no other handler will be + // called. There is no "final" handler -- if the top-level is a // dictionary or array, just use its end handler. typedef std::function<void( @@ -106,6 +98,8 @@ class JSONHandler private: JSONHandler(JSONHandler const&) = delete; + static void usage(std::string const& msg); + struct Handlers { Handlers() : diff --git a/include/qpdf/QPDFArgParser.hh b/include/qpdf/QPDFArgParser.hh index 931170d8..8075781e 100644 --- a/include/qpdf/QPDFArgParser.hh +++ b/include/qpdf/QPDFArgParser.hh @@ -29,7 +29,6 @@ #include <map> #include <vector> #include <functional> -#include <stdexcept> #include <sstream> // This is not a general-purpose argument parser. It is tightly @@ -56,15 +55,6 @@ class QPDFArgParser { public: - // Usage exception is thrown if there are any errors parsing - // arguments - class QPDF_DLL_CLASS Usage: public std::runtime_error - { - public: - QPDF_DLL - Usage(std::string const&); - }; - // progname_env is used to override argv[0] when figuring out the // name of the executable for setting up completion. This may be // needed if the program is invoked by a wrapper. @@ -72,8 +62,8 @@ class QPDFArgParser QPDFArgParser(int argc, char* 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, - // QPDFArgParser::Usage is thrown. + // mode. If there are argument parsing errors, QPDFUsage is + // thrown. QPDF_DLL void parseArgs(); diff --git a/include/qpdf/QPDFExc.hh b/include/qpdf/QPDFExc.hh index a156412b..faf5ddf6 100644 --- a/include/qpdf/QPDFExc.hh +++ b/include/qpdf/QPDFExc.hh @@ -39,7 +39,7 @@ class QPDF_DLL_CLASS QPDFExc: public std::runtime_error qpdf_offset_t offset, std::string const& message); QPDF_DLL - virtual ~QPDFExc() throw () + virtual ~QPDFExc() noexcept { } diff --git a/include/qpdf/QPDFJob.hh b/include/qpdf/QPDFJob.hh index 076501ff..e56626a7 100644 --- a/include/qpdf/QPDFJob.hh +++ b/include/qpdf/QPDFJob.hh @@ -43,15 +43,8 @@ class QPDFWriter; class QPDFJob { public: - // ConfigError exception is thrown if there are any usage-like - // errors when calling Config methods. - class QPDF_DLL_CLASS ConfigError: public std::runtime_error - { - public: - QPDF_DLL - ConfigError(std::string const&); - }; - + // QPDFUsage is thrown if there are any usage-like errors when + // calling Config methods. QPDF_DLL QPDFJob(); @@ -318,7 +311,9 @@ class QPDFJob friend class Config; // Return a top-level configuration item. See CONFIGURATION above - // for details. + // for details. If an invalid configuration is created (such as + // supplying contradictory options, omitting an input file, etc.), + // QPDFUsage is thrown. QPDF_DLL std::shared_ptr<Config> config(); @@ -404,6 +399,7 @@ class QPDFJob }; // Helper functions + static void usage(std::string const& msg); static JSON json_schema(std::set<std::string>* keys = 0); static void parse_object_id( std::string const& objspec, bool& trailer, int& obj, int& gen); diff --git a/include/qpdf/QPDFSystemError.hh b/include/qpdf/QPDFSystemError.hh index 5d631b8b..16eb3583 100644 --- a/include/qpdf/QPDFSystemError.hh +++ b/include/qpdf/QPDFSystemError.hh @@ -36,7 +36,7 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error QPDFSystemError(std::string const& description, int system_errno); QPDF_DLL - virtual ~QPDFSystemError() throw (); + virtual ~QPDFSystemError() noexcept; // To get a complete error string, call what(), provided by // std::exception. The accessors below return the original values diff --git a/include/qpdf/QPDFUsage.hh b/include/qpdf/QPDFUsage.hh new file mode 100644 index 00000000..124bf188 --- /dev/null +++ b/include/qpdf/QPDFUsage.hh @@ -0,0 +1,39 @@ +// Copyright (c) 2005-2021 Jay Berkenbilt +// +// This file is part of qpdf. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Versions of qpdf prior to version 7 were released under the terms +// of version 2.0 of the Artistic License. At your option, you may +// continue to consider qpdf to be licensed under those terms. Please +// see the manual for additional information. + +#ifndef QPDFUSAGE_HH +#define QPDFUSAGE_HH + +#include <qpdf/DLL.h> + +#include <string> +#include <stdexcept> + +class QPDF_DLL_CLASS QPDFUsage: public std::runtime_error +{ + public: + QPDF_DLL + QPDFUsage(std::string const& msg); + QPDF_DLL + virtual ~QPDFUsage() noexcept = default; +}; + +#endif // QPDFUSAGE_HH diff --git a/libqpdf/JSONHandler.cc b/libqpdf/JSONHandler.cc index 5e3d9a8d..1d374e6a 100644 --- a/libqpdf/JSONHandler.cc +++ b/libqpdf/JSONHandler.cc @@ -1,11 +1,7 @@ #include <qpdf/JSONHandler.hh> #include <qpdf/QUtil.hh> #include <qpdf/QTC.hh> - -JSONHandler::Error::Error(std::string const& msg) : - std::runtime_error(msg) -{ -} +#include <qpdf/QPDFUsage.hh> JSONHandler::JSONHandler() : m(new Members()) @@ -17,6 +13,12 @@ JSONHandler::Members::Members() } void +JSONHandler::usage(std::string const& msg) +{ + throw QPDFUsage(msg); +} + +void JSONHandler::addAnyHandler(json_handler_t fn) { this->m->h.any_handler = fn; @@ -128,9 +130,8 @@ JSONHandler::handle(std::string const& path, JSON j) else { QTC::TC("libtests", "JSONHandler unexpected key"); - throw Error( - "JSON handler found unexpected key " + k + - " in object at " + path); + usage("JSON handler found unexpected key " + k + + " in object at " + path); } } else @@ -163,7 +164,6 @@ JSONHandler::handle(std::string const& path, JSON j) // different if this code were trying to be part of a // general-purpose JSON package. QTC::TC("libtests", "JSONHandler unhandled value"); - throw Error("JSON handler: value at " + path + - " is not of expected type"); + usage("JSON handler: value at " + path + " is not of expected type"); } } diff --git a/libqpdf/QPDFArgParser.cc b/libqpdf/QPDFArgParser.cc index c423c7d3..4018d4e1 100644 --- a/libqpdf/QPDFArgParser.cc +++ b/libqpdf/QPDFArgParser.cc @@ -2,15 +2,11 @@ #include <qpdf/QUtil.hh> #include <qpdf/QIntC.hh> #include <qpdf/QTC.hh> +#include <qpdf/QPDFUsage.hh> #include <iostream> #include <cstring> #include <cstdlib> -QPDFArgParser::Usage::Usage(std::string const& msg) : - std::runtime_error(msg) -{ -} - QPDFArgParser::Members::Members( int argc, char* argv[], char const* progname_env) : @@ -424,7 +420,7 @@ QPDFArgParser::usage(std::string const& message) // This will cause bash to fall back to regular file completion. exit(0); } - throw Usage(message); + throw QPDFUsage(message); } void diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index b0143449..8c4efc41 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -25,21 +25,16 @@ #include <qpdf/QPDFOutlineDocumentHelper.hh> #include <qpdf/QPDFAcroFormDocumentHelper.hh> #include <qpdf/QPDFExc.hh> +#include <qpdf/QPDFUsage.hh> #include <qpdf/QPDFSystemError.hh> #include <qpdf/QPDFCryptoProvider.hh> #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh> #include <qpdf/QPDFArgParser.hh> - #include <qpdf/QPDFWriter.hh> #include <qpdf/QIntC.hh> #include <qpdf/auto_job_schema.hh> // JOB_SCHEMA_DATA -QPDFJob::ConfigError::ConfigError(std::string const& msg) : - std::runtime_error(msg) -{ -} - namespace { class ImageOptimizer: public QPDFObjectHandle::StreamDataProvider @@ -452,6 +447,12 @@ QPDFJob::QPDFJob() : void +QPDFJob::usage(std::string const& msg) +{ + throw QPDFUsage(msg); +} + +void QPDFJob::setMessagePrefix(std::string const& message_prefix) { this->m->message_prefix = message_prefix; @@ -548,7 +549,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter) } else { - throw ConfigError("invalid parameter to rotate: " + parameter); + usage("invalid parameter to rotate: " + parameter); } } @@ -561,7 +562,7 @@ QPDFJob::parseNumrange(char const* range, int max) } catch (std::runtime_error& e) { - throw ConfigError(e.what()); + usage(e.what()); } return std::vector<int>(); } @@ -645,10 +646,6 @@ QPDFJob::createsOutput() const void QPDFJob::checkConfiguration() { - auto usage = [](char const* msg){ - throw QPDFJob::ConfigError(msg); - }; - // QXXXQ messages are CLI-centric if (m->replace_input) { diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index 36a2a2a6..8bf4c48b 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -480,7 +480,7 @@ ArgParser::parseOptions() { this->ap.parseArgs(); } - catch (QPDFArgParser::Usage& e) + catch (std::runtime_error& e) { usage(e.what()); } diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index 74fff62d..53032cea 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -3,11 +3,6 @@ #include <qpdf/QTC.hh> #include <cstring> -static void usage(std::string const& msg) -{ - throw QPDFJob::ConfigError(msg); -} - QPDFJob::Config* QPDFJob::Config::inputFile(char const* filename) { diff --git a/libqpdf/QPDFSystemError.cc b/libqpdf/QPDFSystemError.cc index 65aeaab7..73bad61e 100644 --- a/libqpdf/QPDFSystemError.cc +++ b/libqpdf/QPDFSystemError.cc @@ -10,7 +10,7 @@ QPDFSystemError::QPDFSystemError(std::string const& description, { } -QPDFSystemError::~QPDFSystemError() throw () +QPDFSystemError::~QPDFSystemError() noexcept { } diff --git a/libqpdf/QPDFUsage.cc b/libqpdf/QPDFUsage.cc new file mode 100644 index 00000000..5390b388 --- /dev/null +++ b/libqpdf/QPDFUsage.cc @@ -0,0 +1,6 @@ +#include <qpdf/QPDFUsage.hh> + +QPDFUsage::QPDFUsage(std::string const& msg) : + std::runtime_error(msg) +{ +} diff --git a/libqpdf/build.mk b/libqpdf/build.mk index 8cedb44a..e16ba5e1 100644 --- a/libqpdf/build.mk +++ b/libqpdf/build.mk @@ -89,6 +89,7 @@ SRCS_libqpdf = \ libqpdf/QPDFStreamFilter.cc \ libqpdf/QPDFSystemError.cc \ libqpdf/QPDFTokenizer.cc \ + libqpdf/QPDFUsage.cc \ libqpdf/QPDFWriter.cc \ libqpdf/QPDFXRefEntry.cc \ libqpdf/QPDF_Array.cc \ diff --git a/libtests/arg_parser.cc b/libtests/arg_parser.cc index 602a0f3f..e17ebdd1 100644 --- a/libtests/arg_parser.cc +++ b/libtests/arg_parser.cc @@ -1,5 +1,6 @@ #include <qpdf/QPDFArgParser.hh> #include <qpdf/QUtil.hh> +#include <qpdf/QPDFUsage.hh> #include <iostream> #include <cstring> #include <cassert> @@ -225,7 +226,7 @@ int main(int argc, char* argv[]) { ap.parseArgs(); } - catch (QPDFArgParser::Usage& e) + catch (QPDFUsage& e) { std::cerr << "usage: " << e.what() << std::endl; exit(2); diff --git a/libtests/json_handler.cc b/libtests/json_handler.cc index 7f6349f9..c1af238f 100644 --- a/libtests/json_handler.cc +++ b/libtests/json_handler.cc @@ -1,5 +1,6 @@ #include <qpdf/JSONHandler.hh> #include <qpdf/QUtil.hh> +#include <qpdf/QPDFUsage.hh> #include <iostream> #include <cassert> @@ -120,7 +121,7 @@ static void test_errors() fn(); assert(false); } - catch (JSONHandler::Error& e) + catch (QPDFUsage& e) { std::cout << msg << ": " << e.what() << std::endl; } diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc index 0e7eaf65..508fb579 100644 --- a/qpdf/qpdf.cc +++ b/qpdf/qpdf.cc @@ -1,7 +1,7 @@ #include <qpdf/QPDFJob.hh> #include <qpdf/QTC.hh> #include <qpdf/QUtil.hh> -#include <qpdf/QPDFArgParser.hh> +#include <qpdf/QPDFUsage.hh> #include <cstdio> #include <cstdlib> @@ -48,11 +48,7 @@ int realmain(int argc, char* argv[]) j.initializeFromArgv(argc, argv); j.run(); } - catch (QPDFArgParser::Usage& e) - { - usageExit(e.what()); - } - catch (QPDFJob::ConfigError& e) + catch (QPDFUsage& e) { usageExit(e.what()); } |