2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 10:58:58 +00:00

Use QPDFUsage exception for cli, json, and QPDFJob errors

This commit is contained in:
Jay Berkenbilt 2022-01-28 07:46:04 -05:00
parent 764feb0f8e
commit 0364024781
18 changed files with 99 additions and 81 deletions

View File

@ -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> 2022-01-22 Jay Berkenbilt <ejb@ql.org>
* Add QUtil::make_shared_cstr to return a std::shared_ptr<char> * Add QUtil::make_shared_cstr to return a std::shared_ptr<char>

View File

@ -28,7 +28,6 @@
#include <string> #include <string>
#include <map> #include <map>
#include <functional> #include <functional>
#include <stdexcept>
#include <memory> #include <memory>
// This class allows a sax-like walk through a JSON object with // This class allows a sax-like walk through a JSON object with
@ -39,15 +38,8 @@
class JSONHandler class JSONHandler
{ {
public: public:
// Error exception is thrown if there are any errors validating // A QPDFUsage exception is thrown if there are any errors
// the JSON object. // validating the JSON object.
class QPDF_DLL_CLASS Error: public std::runtime_error
{
public:
QPDF_DLL
Error(std::string const&);
};
QPDF_DLL QPDF_DLL
JSONHandler(); JSONHandler();
@ -55,10 +47,10 @@ class JSONHandler
~JSONHandler() = default; ~JSONHandler() = default;
// Based on the type of handler, expect the object to be of a // Based on the type of handler, expect the object to be of a
// certain type. JSONHandler::Error is thrown otherwise. Multiple // certain type. QPDFUsage is thrown otherwise. Multiple handlers
// handlers may be registered, which allows the object to be of // may be registered, which allows the object to be of various
// various types. If an anyHandler is added, no other handler will // types. If an anyHandler is added, no other handler will be
// be called. There is no "final" handler -- if the top-level is a // called. There is no "final" handler -- if the top-level is a
// dictionary or array, just use its end handler. // dictionary or array, just use its end handler.
typedef std::function<void( typedef std::function<void(
@ -106,6 +98,8 @@ class JSONHandler
private: private:
JSONHandler(JSONHandler const&) = delete; JSONHandler(JSONHandler const&) = delete;
static void usage(std::string const& msg);
struct Handlers struct Handlers
{ {
Handlers() : Handlers() :

View File

@ -29,7 +29,6 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <stdexcept>
#include <sstream> #include <sstream>
// This is not a general-purpose argument parser. It is tightly // This is not a general-purpose argument parser. It is tightly
@ -56,15 +55,6 @@
class QPDFArgParser class QPDFArgParser
{ {
public: 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 // progname_env is used to override argv[0] when figuring out the
// name of the executable for setting up completion. This may be // name of the executable for setting up completion. This may be
// needed if the program is invoked by a wrapper. // needed if the program is invoked by a wrapper.
@ -72,8 +62,8 @@ class QPDFArgParser
QPDFArgParser(int argc, char* argv[], char const* progname_env); QPDFArgParser(int argc, char* argv[], char const* progname_env);
// Calls exit(0) if a help option is given or if in completion // Calls exit(0) if a help option is given or if in completion
// mode. If there are argument parsing errors, // mode. If there are argument parsing errors, QPDFUsage is
// QPDFArgParser::Usage is thrown. // thrown.
QPDF_DLL QPDF_DLL
void parseArgs(); void parseArgs();

View File

@ -39,7 +39,7 @@ class QPDF_DLL_CLASS QPDFExc: public std::runtime_error
qpdf_offset_t offset, qpdf_offset_t offset,
std::string const& message); std::string const& message);
QPDF_DLL QPDF_DLL
virtual ~QPDFExc() throw () virtual ~QPDFExc() noexcept
{ {
} }

View File

@ -43,15 +43,8 @@ class QPDFWriter;
class QPDFJob class QPDFJob
{ {
public: public:
// ConfigError exception is thrown if there are any usage-like // QPDFUsage is thrown if there are any usage-like errors when
// errors when calling Config methods. // calling Config methods.
class QPDF_DLL_CLASS ConfigError: public std::runtime_error
{
public:
QPDF_DLL
ConfigError(std::string const&);
};
QPDF_DLL QPDF_DLL
QPDFJob(); QPDFJob();
@ -318,7 +311,9 @@ class QPDFJob
friend class Config; friend class Config;
// Return a top-level configuration item. See CONFIGURATION above // 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 QPDF_DLL
std::shared_ptr<Config> config(); std::shared_ptr<Config> config();
@ -404,6 +399,7 @@ class QPDFJob
}; };
// Helper functions // Helper functions
static void usage(std::string const& msg);
static JSON json_schema(std::set<std::string>* keys = 0); static JSON json_schema(std::set<std::string>* keys = 0);
static void parse_object_id( static void parse_object_id(
std::string const& objspec, bool& trailer, int& obj, int& gen); std::string const& objspec, bool& trailer, int& obj, int& gen);

View File

@ -36,7 +36,7 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error
QPDFSystemError(std::string const& description, QPDFSystemError(std::string const& description,
int system_errno); int system_errno);
QPDF_DLL QPDF_DLL
virtual ~QPDFSystemError() throw (); virtual ~QPDFSystemError() noexcept;
// To get a complete error string, call what(), provided by // To get a complete error string, call what(), provided by
// std::exception. The accessors below return the original values // std::exception. The accessors below return the original values

39
include/qpdf/QPDFUsage.hh Normal file
View File

@ -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

View File

@ -1,11 +1,7 @@
#include <qpdf/JSONHandler.hh> #include <qpdf/JSONHandler.hh>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/QTC.hh> #include <qpdf/QTC.hh>
#include <qpdf/QPDFUsage.hh>
JSONHandler::Error::Error(std::string const& msg) :
std::runtime_error(msg)
{
}
JSONHandler::JSONHandler() : JSONHandler::JSONHandler() :
m(new Members()) m(new Members())
@ -16,6 +12,12 @@ JSONHandler::Members::Members()
{ {
} }
void
JSONHandler::usage(std::string const& msg)
{
throw QPDFUsage(msg);
}
void void
JSONHandler::addAnyHandler(json_handler_t fn) JSONHandler::addAnyHandler(json_handler_t fn)
{ {
@ -128,9 +130,8 @@ JSONHandler::handle(std::string const& path, JSON j)
else else
{ {
QTC::TC("libtests", "JSONHandler unexpected key"); QTC::TC("libtests", "JSONHandler unexpected key");
throw Error( usage("JSON handler found unexpected key " + k +
"JSON handler found unexpected key " + k + " in object at " + path);
" in object at " + path);
} }
} }
else else
@ -163,7 +164,6 @@ JSONHandler::handle(std::string const& path, JSON j)
// different if this code were trying to be part of a // different if this code were trying to be part of a
// general-purpose JSON package. // general-purpose JSON package.
QTC::TC("libtests", "JSONHandler unhandled value"); QTC::TC("libtests", "JSONHandler unhandled value");
throw Error("JSON handler: value at " + path + usage("JSON handler: value at " + path + " is not of expected type");
" is not of expected type");
} }
} }

View File

@ -2,15 +2,11 @@
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/QIntC.hh> #include <qpdf/QIntC.hh>
#include <qpdf/QTC.hh> #include <qpdf/QTC.hh>
#include <qpdf/QPDFUsage.hh>
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
QPDFArgParser::Usage::Usage(std::string const& msg) :
std::runtime_error(msg)
{
}
QPDFArgParser::Members::Members( QPDFArgParser::Members::Members(
int argc, char* argv[], char const* progname_env) : 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. // This will cause bash to fall back to regular file completion.
exit(0); exit(0);
} }
throw Usage(message); throw QPDFUsage(message);
} }
void void

View File

@ -25,21 +25,16 @@
#include <qpdf/QPDFOutlineDocumentHelper.hh> #include <qpdf/QPDFOutlineDocumentHelper.hh>
#include <qpdf/QPDFAcroFormDocumentHelper.hh> #include <qpdf/QPDFAcroFormDocumentHelper.hh>
#include <qpdf/QPDFExc.hh> #include <qpdf/QPDFExc.hh>
#include <qpdf/QPDFUsage.hh>
#include <qpdf/QPDFSystemError.hh> #include <qpdf/QPDFSystemError.hh>
#include <qpdf/QPDFCryptoProvider.hh> #include <qpdf/QPDFCryptoProvider.hh>
#include <qpdf/QPDFEmbeddedFileDocumentHelper.hh> #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh>
#include <qpdf/QPDFArgParser.hh> #include <qpdf/QPDFArgParser.hh>
#include <qpdf/QPDFWriter.hh> #include <qpdf/QPDFWriter.hh>
#include <qpdf/QIntC.hh> #include <qpdf/QIntC.hh>
#include <qpdf/auto_job_schema.hh> // JOB_SCHEMA_DATA #include <qpdf/auto_job_schema.hh> // JOB_SCHEMA_DATA
QPDFJob::ConfigError::ConfigError(std::string const& msg) :
std::runtime_error(msg)
{
}
namespace namespace
{ {
class ImageOptimizer: public QPDFObjectHandle::StreamDataProvider class ImageOptimizer: public QPDFObjectHandle::StreamDataProvider
@ -451,6 +446,12 @@ QPDFJob::QPDFJob() :
} }
void
QPDFJob::usage(std::string const& msg)
{
throw QPDFUsage(msg);
}
void void
QPDFJob::setMessagePrefix(std::string const& message_prefix) QPDFJob::setMessagePrefix(std::string const& message_prefix)
{ {
@ -548,7 +549,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter)
} }
else 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) catch (std::runtime_error& e)
{ {
throw ConfigError(e.what()); usage(e.what());
} }
return std::vector<int>(); return std::vector<int>();
} }
@ -645,10 +646,6 @@ QPDFJob::createsOutput() const
void void
QPDFJob::checkConfiguration() QPDFJob::checkConfiguration()
{ {
auto usage = [](char const* msg){
throw QPDFJob::ConfigError(msg);
};
// QXXXQ messages are CLI-centric // QXXXQ messages are CLI-centric
if (m->replace_input) if (m->replace_input)
{ {

View File

@ -480,7 +480,7 @@ ArgParser::parseOptions()
{ {
this->ap.parseArgs(); this->ap.parseArgs();
} }
catch (QPDFArgParser::Usage& e) catch (std::runtime_error& e)
{ {
usage(e.what()); usage(e.what());
} }

View File

@ -3,11 +3,6 @@
#include <qpdf/QTC.hh> #include <qpdf/QTC.hh>
#include <cstring> #include <cstring>
static void usage(std::string const& msg)
{
throw QPDFJob::ConfigError(msg);
}
QPDFJob::Config* QPDFJob::Config*
QPDFJob::Config::inputFile(char const* filename) QPDFJob::Config::inputFile(char const* filename)
{ {

View File

@ -10,7 +10,7 @@ QPDFSystemError::QPDFSystemError(std::string const& description,
{ {
} }
QPDFSystemError::~QPDFSystemError() throw () QPDFSystemError::~QPDFSystemError() noexcept
{ {
} }

6
libqpdf/QPDFUsage.cc Normal file
View File

@ -0,0 +1,6 @@
#include <qpdf/QPDFUsage.hh>
QPDFUsage::QPDFUsage(std::string const& msg) :
std::runtime_error(msg)
{
}

View File

@ -89,6 +89,7 @@ SRCS_libqpdf = \
libqpdf/QPDFStreamFilter.cc \ libqpdf/QPDFStreamFilter.cc \
libqpdf/QPDFSystemError.cc \ libqpdf/QPDFSystemError.cc \
libqpdf/QPDFTokenizer.cc \ libqpdf/QPDFTokenizer.cc \
libqpdf/QPDFUsage.cc \
libqpdf/QPDFWriter.cc \ libqpdf/QPDFWriter.cc \
libqpdf/QPDFXRefEntry.cc \ libqpdf/QPDFXRefEntry.cc \
libqpdf/QPDF_Array.cc \ libqpdf/QPDF_Array.cc \

View File

@ -1,5 +1,6 @@
#include <qpdf/QPDFArgParser.hh> #include <qpdf/QPDFArgParser.hh>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/QPDFUsage.hh>
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include <cassert> #include <cassert>
@ -225,7 +226,7 @@ int main(int argc, char* argv[])
{ {
ap.parseArgs(); ap.parseArgs();
} }
catch (QPDFArgParser::Usage& e) catch (QPDFUsage& e)
{ {
std::cerr << "usage: " << e.what() << std::endl; std::cerr << "usage: " << e.what() << std::endl;
exit(2); exit(2);

View File

@ -1,5 +1,6 @@
#include <qpdf/JSONHandler.hh> #include <qpdf/JSONHandler.hh>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/QPDFUsage.hh>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
@ -120,7 +121,7 @@ static void test_errors()
fn(); fn();
assert(false); assert(false);
} }
catch (JSONHandler::Error& e) catch (QPDFUsage& e)
{ {
std::cout << msg << ": " << e.what() << std::endl; std::cout << msg << ": " << e.what() << std::endl;
} }

View File

@ -1,7 +1,7 @@
#include <qpdf/QPDFJob.hh> #include <qpdf/QPDFJob.hh>
#include <qpdf/QTC.hh> #include <qpdf/QTC.hh>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/QPDFArgParser.hh> #include <qpdf/QPDFUsage.hh>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
@ -48,11 +48,7 @@ int realmain(int argc, char* argv[])
j.initializeFromArgv(argc, argv); j.initializeFromArgv(argc, argv);
j.run(); j.run();
} }
catch (QPDFArgParser::Usage& e) catch (QPDFUsage& e)
{
usageExit(e.what());
}
catch (QPDFJob::ConfigError& e)
{ {
usageExit(e.what()); usageExit(e.what());
} }