diff options
Diffstat (limited to 'cpp/src/qpid')
-rw-r--r-- | cpp/src/qpid/CommonOptions.cpp | 95 | ||||
-rw-r--r-- | cpp/src/qpid/CommonOptions.h | 121 | ||||
-rw-r--r-- | cpp/src/qpid/Options.cpp | 92 | ||||
-rw-r--r-- | cpp/src/qpid/Options.h | 148 | ||||
-rw-r--r-- | cpp/src/qpid/Url.h | 8 | ||||
-rw-r--r-- | cpp/src/qpid/broker/Broker.cpp | 17 | ||||
-rw-r--r-- | cpp/src/qpid/broker/Broker.h | 12 | ||||
-rw-r--r-- | cpp/src/qpid/log/Logger.cpp | 5 | ||||
-rw-r--r-- | cpp/src/qpid/log/Options.cpp | 21 | ||||
-rw-r--r-- | cpp/src/qpid/log/Options.h | 8 |
10 files changed, 275 insertions, 252 deletions
diff --git a/cpp/src/qpid/CommonOptions.cpp b/cpp/src/qpid/CommonOptions.cpp deleted file mode 100644 index 2224f0e75b..0000000000 --- a/cpp/src/qpid/CommonOptions.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * Copyright (c) 2006 The Apache Software Foundation - * - * 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. - * - */ - -#include "CommonOptions.h" -#include "qpid/Exception.h" -#include <fstream> -#include <algorithm> -#include <iostream> - -namespace qpid { -namespace program_options { - -char env2optchar(char env) { - return (env=='_') ? '-' : tolower(env); -} - -const std::string envPrefix("QPID_"); - -std::string env2option(const std::string& env) { - if (env.find(envPrefix) == 0) { - std::string opt = env.substr(envPrefix.size()); - std::transform(opt.begin(), opt.end(), opt.begin(), env2optchar); - return opt; - } - return std::string(); -} - -std::string prettyArg(const std::string& name, const std::string& value) { - return value.empty() ? name : name+" (="+value+")"; -} - -} // namespace program_options - -const int CommonOptions::DEFAULT_PORT=5672; - -CommonOptions::CommonOptions() : trace(false), port(DEFAULT_PORT) {} - -void CommonOptions::addTo(po::options_description& desc) -{ - using namespace po; - desc.add_options() - ("trace,t", optValue(trace), "Enable debug tracing" ) - ("port,p", optValue(port,"PORT"), "Use PORT for AMQP connections."); -} - -void parseOptions( - po::options_description& desc, int argc, char** argv, - const std::string& configFile) -{ - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - try { - po::store(po::parse_environment(desc, po::env2option), vm); - } - catch (const po::unknown_option& e) { - std::cerr << e.what() << std::endl; - } - catch (const po::error& e) { - throw po::error(std::string("parsing environment variables: ") - + e.what()); - } - po::notify(vm); // configFile may be updated from arg/env options. - if (!configFile.empty()) { - try { - using namespace std; - ifstream conf(configFile.c_str()); - if (conf.good()) { - conf.exceptions(ifstream::failbit|ifstream::badbit); - po::store(po::parse_config_file(conf, desc), vm); - } - } - catch (const std::exception& e) { - throw Exception(std::string("error parsing config file: ")+ e.what()); - } - } - po::notify(vm); -} - -} // namespace qpid - diff --git a/cpp/src/qpid/CommonOptions.h b/cpp/src/qpid/CommonOptions.h deleted file mode 100644 index 8a67babfde..0000000000 --- a/cpp/src/qpid/CommonOptions.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef QPID_COMMONOPTIONS_H -#define QPID_COMMONOPTIONS_H - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - * - */ - -#include <boost/program_options.hpp> -#include <boost/format.hpp> -#include <sstream> -#include <iterator> -#include <algorithm> - -namespace qpid { - -/**@Qpid extensions to boost::program_options */ -namespace program_options { - -using namespace boost::program_options; - -/** @internal Normally only constructed by optValue() */ -template <class T> -class OptionValue : public typed_value<T> { - public: - OptionValue(T& value, const std::string& arg) - : typed_value<T>(&value), argName(arg) {} - std::string name() const { return argName; } - private: - std::string argName; -}; - -///@internal -std::string prettyArg(const std::string& name, const std::string& value); - -/** - * Like boost::program_options::value() with more convenient signature - * for updating a value by reference and prettier help formatting. - * - *@param value displayed as default in help, updated from options. - * Must support ostream << operator. - *@param arg name for arguments in help. - * - *@see CommonOptions.cpp for example of use. - */ -template<class T> -value_semantic* optValue(T& value, const char* name) { - std::string valstr(boost::lexical_cast<std::string>(value)); - return new OptionValue<T>(value, prettyArg(name, valstr)); -} - -template <class T> -value_semantic* optValue(std::vector<T>& value, const char* name) { - using namespace std; - ostringstream os; - copy(value.begin(), value.end(), ostream_iterator<T>(os, " ")); - string val=os.str(); - if (!val.empty()) - val.erase(val.end()-1); // Remove trailing " " - return (new OptionValue<vector<T> >(value, prettyArg(name, val))); -} - -/** Environment-to-option name mapping. - * Maps env variable "QPID_SOME_VAR" to option "some-var" - */ -std::string env2option(const std::string& env); - -/** - * Like boost::program_options::bool_switch but takes reference, not pointer. - */ -inline value_semantic* optValue(bool& value) { return bool_switch(&value); } - -} // namespace program_options - -namespace po=program_options; // Convenience alias. - -/** - * Common options for client and broker - */ -struct CommonOptions { - static const int DEFAULT_PORT; - - CommonOptions(); - - bool trace; - int port; - - /** Add members to program_options to be updated */ - void addTo(po::options_description&); - -}; - -/** Convenience function to parse an options_description. - * Parses argc/argv, environment variables and config file. - * Note the filename argument can reference a variable that - * is updated by argc/argv or environment variable parsing. - */ -void parseOptions(po::options_description&, - int argc, char** argv, - const std::string& filename=std::string()); - - -} // namespace qpid - -#endif /*!QPID_COMMONOPTIONS_H*/ diff --git a/cpp/src/qpid/Options.cpp b/cpp/src/qpid/Options.cpp new file mode 100644 index 0000000000..18a3f726f9 --- /dev/null +++ b/cpp/src/qpid/Options.cpp @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * 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. + * + */ + +#include "Options.h" +#include "qpid/Exception.h" +#include <fstream> +#include <algorithm> +#include <iostream> + +namespace qpid { + +using namespace std; + +namespace { +const std::string prefix("QPID_"); +char env2optchar(char env) { return (env=='_') ? '-' : tolower(env); } + +struct Mapper { + Mapper(const Options& o) : opts(o) {} + string operator()(const string& env) { + if (env.substr(0, prefix.size()) == prefix) { + string opt = env.substr(prefix.size()); + transform(opt.begin(), opt.end(), opt.begin(), env2optchar); + // Ignore env vars that don't match to known options. + if (opts.find_nothrow(opt, false)) + return opt; + } + return string(); + } + const Options& opts; +}; + +} +std::string prettyArg(const std::string& name, const std::string& value) { + return value.empty() ? name : name+" (="+value+")"; +} + +Options::Options(const string& name) : po::options_description(name) {} + +void Options::parse(int argc, char** argv, const std::string& configFile) +{ + string parsing; + try { + po::variables_map vm; + parsing="command line options"; + po::store(po::parse_command_line(argc, argv, *this), vm); + parsing="environment variables"; + po::store(po::parse_environment(*this, Mapper(*this)), vm); + po::notify(vm); // configFile may be updated from arg/env options. + if (!configFile.empty()) { + parsing="configuration file "+configFile; + ifstream conf(configFile.c_str()); + if (conf.good()) { + conf.exceptions(ifstream::failbit|ifstream::badbit); + po::store(po::parse_config_file(conf, *this), vm); + } + } + po::notify(vm); + } + catch (const std::exception& e) { + ostringstream msg; + msg << "Error in " << parsing << ": " << e.what() << endl; + if (find_nothrow("help", false)) + msg << "Use --help to see valid options" << endl; + throw Exception(msg.str()); + } +} + +CommonOptions::CommonOptions(const string& name) : Options(name) { + addOptions() + ("help,h", optValue(help), "Print help message.") + ("version,v", optValue(version), "Print version information.") + ("config", optValue(config, "FILE"), "Configuation file."); +} + +} // namespace qpid + diff --git a/cpp/src/qpid/Options.h b/cpp/src/qpid/Options.h new file mode 100644 index 0000000000..0821dca7e5 --- /dev/null +++ b/cpp/src/qpid/Options.h @@ -0,0 +1,148 @@ +#ifndef QPID_COMMONOPTIONS_H +#define QPID_COMMONOPTIONS_H + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#include "qpid/Exception.h" +#include <boost/program_options.hpp> +#include <boost/format.hpp> +#include <sstream> +#include <iterator> +#include <algorithm> + +namespace qpid { +namespace po=boost::program_options; + +///@internal +std::string prettyArg(const std::string&, const std::string&); + +/** @internal Normally only constructed by optValue() */ +template <class T> +class OptionValue : public po::typed_value<T> { + public: + OptionValue(T& value, const std::string& arg) + : po::typed_value<T>(&value), argName(arg) {} + std::string name() const { return argName; } + + private: + std::string argName; +}; + + +/** Create an option value. + * name, value appear after the option name in help like this: + * <name> (=<value>) + * T must support operator <<. + *@see Options for example of use. + */ +template<class T> +po::value_semantic* optValue(T& value, const char* name) { + std::string valstr(boost::lexical_cast<std::string>(value)); + return new OptionValue<T>(value, prettyArg(name, valstr)); +} + +/** Create a vector value. Multiple occurences of the option are + * accumulated into the vector + */ +template <class T> +po::value_semantic* optValue(std::vector<T>& value, const char* name) { + using namespace std; + ostringstream os; + copy(value.begin(), value.end(), ostream_iterator<T>(os, " ")); + string val=os.str(); + if (!val.empty()) + val.erase(val.end()-1); // Remove trailing " " + return (new OptionValue<vector<T> >(value, prettyArg(name, val))); +} + +/** Create a boolean switch value. Presence of the option sets the value. */ +inline po::value_semantic* optValue(bool& value) { return po::bool_switch(&value); } + +/** + * Base class for options. + * Example of use: + @code + struct MySubOptions : public Options { + int x; + string y; + MySubOptions() : Options("Sub options") { + addOptions() + ("x", optValue(x,"XUNIT"), "Option X") + ("y", optValue(y, "YUNIT"), "Option Y"); + } + }; + + struct MyOptions : public Options { + bool z; + vector<string> foo; + MySubOptions subOptions; + MyOptions() : Options("My Options") { + addOptions() + ("z", boolSwitch(z), "Option Z") + ("foo", optValue(foo), "Multiple option foo."); + add(subOptions); + } + + main(int argc, char** argv) { + Options opts; + opts.parse(argc, char** argv); + // Use values + dosomething(opts.subOptions.x); + if (error) + cout << opts << end; // Help message. + } + + @endcode + */ +struct Options : public po::options_description { + struct Exception : public qpid::Exception { + Exception(const std::string& msg) : qpid::Exception(msg) {} + }; + + Options(const std::string& name=std::string()); + + boost::program_options::options_description_easy_init addOptions() { + return add_options(); + } + + /** + * Parses options from argc/argv, environment variables and config file. + * Note the filename argument can reference an options variable that + * is updated by argc/argv or environment variable parsing. + */ + void parse(int argc, char** argv, + const std::string& configfile=std::string()); +}; + +/** + * Standard options for configuration + */ +struct CommonOptions : public Options { + CommonOptions(const std::string& name=std::string()); + bool help; + bool version; + std::string config; +}; + +} // namespace qpid + +#endif /*!QPID_COMMONOPTIONS_H*/ diff --git a/cpp/src/qpid/Url.h b/cpp/src/qpid/Url.h index f45192ce23..93a53afde6 100644 --- a/cpp/src/qpid/Url.h +++ b/cpp/src/qpid/Url.h @@ -30,19 +30,19 @@ namespace qpid { /** TCP address of a broker - host:port */ struct TcpAddress { - static const uint16_t defaultPort=5672; + static const uint16_t DEFAULT_PORT=5672; TcpAddress(const std::string& host_=std::string(), - uint16_t port_=defaultPort) + uint16_t port_=DEFAULT_PORT) : host(host_), port(port_) {} std::string host; uint16_t port; }; -bool operator==(const TcpAddress& x, const TcpAddress& y) { +inline bool operator==(const TcpAddress& x, const TcpAddress& y) { return y.host==x.host && y.port == x.port; } -std::ostream& operator<<(std::ostream& os, const TcpAddress& a) { +inline std::ostream& operator<<(std::ostream& os, const TcpAddress& a) { return os << "tcp:" << a.host << ":" << a.port; } diff --git a/cpp/src/qpid/broker/Broker.cpp b/cpp/src/qpid/broker/Broker.cpp index 01e049bdda..4354f6d38a 100644 --- a/cpp/src/qpid/broker/Broker.cpp +++ b/cpp/src/qpid/broker/Broker.cpp @@ -35,6 +35,7 @@ #include "qpid/sys/ConnectionInputHandler.h" #include "qpid/sys/ConnectionInputHandlerFactory.h" #include "qpid/sys/TimeoutHandler.h" +#include "qpid/Url.h" #include <iostream> #include <memory> @@ -44,19 +45,17 @@ using qpid::sys::Acceptor; namespace qpid { namespace broker { -Broker::Options::Options() : +Broker::Options::Options(const std::string& name) : + qpid::Options(name), + port(TcpAddress::DEFAULT_PORT), workerThreads(5), maxConnections(500), connectionBacklog(10), store(), stagingThreshold(5000000) -{} - -void Broker::Options::addTo(po::options_description& desc) { - using namespace po; - CommonOptions::addTo(desc); - desc.add_options() + addOptions() + ("port,p", optValue(port,"PORT"), "Use PORT for AMQP connections.") ("worker-threads", optValue(workerThreads, "N"), "Broker thread pool size") ("max-connections", optValue(maxConnections, "N"), @@ -114,7 +113,7 @@ Broker::shared_ptr Broker::create(const Options& config) { MessageStore* Broker::createStore(const Options& config) { if (config.store.empty()) - return new NullMessageStore(config.trace); + return new NullMessageStore(false); else return new MessageStoreModule(config.store); } @@ -141,7 +140,7 @@ Acceptor& Broker::getAcceptor() const { Acceptor::create(config.port, config.connectionBacklog, config.workerThreads, - config.trace); + false); return *acceptor; } diff --git a/cpp/src/qpid/broker/Broker.h b/cpp/src/qpid/broker/Broker.h index 187167ebe7..efefbd2e3e 100644 --- a/cpp/src/qpid/broker/Broker.h +++ b/cpp/src/qpid/broker/Broker.h @@ -23,6 +23,7 @@ */ #include "ConnectionFactory.h" +#include "qpid/Url.h" #include "qpid/sys/Runnable.h" #include "qpid/sys/Acceptor.h" #include "qpid/SharedObject.h" @@ -35,7 +36,7 @@ #include "qpid/framing/OutputHandler.h" #include "qpid/framing/ProtocolInitiation.h" #include "QueueRegistry.h" -#include "qpid/CommonOptions.h" +#include "qpid/Options.h" namespace qpid { namespace broker { @@ -46,9 +47,10 @@ class Broker : public sys::Runnable, public SharedObject<Broker> { public: - struct Options : public CommonOptions { - Options(); - void addTo(po::options_description&); + struct Options : public qpid::Options { + Options(const std::string& name="Broker Options"); + + uint16_t port; int workerThreads; int maxConnections; int connectionBacklog; @@ -62,7 +64,7 @@ class Broker : public sys::Runnable, * Create a broker. * @param port Port to listen on or 0 to pick a port dynamically. */ - static shared_ptr create(int16_t port = CommonOptions::DEFAULT_PORT); + static shared_ptr create(int16_t port = TcpAddress::DEFAULT_PORT); /** * Create a broker with the options in config. diff --git a/cpp/src/qpid/log/Logger.cpp b/cpp/src/qpid/log/Logger.cpp index 065d4508c7..ceb3977106 100644 --- a/cpp/src/qpid/log/Logger.cpp +++ b/cpp/src/qpid/log/Logger.cpp @@ -188,8 +188,11 @@ void Logger::remove(Statement& s) { statements.erase(&s); } -void Logger::configure(const Options& o, const std::string& prog) +void Logger::configure(const Options& opts, const std::string& prog) { + Options o(opts); + if (o.trace) + o.selectors.push_back("trace+"); { ScopedLock l(lock); syslogName=prog; diff --git a/cpp/src/qpid/log/Options.cpp b/cpp/src/qpid/log/Options.cpp index 3e117663ff..b15630ebb2 100644 --- a/cpp/src/qpid/log/Options.cpp +++ b/cpp/src/qpid/log/Options.cpp @@ -18,36 +18,34 @@ #include "Options.h" #include "Statement.h" -#include "qpid/CommonOptions.h" +#include "qpid/Options.h" namespace qpid { namespace log { using namespace std; -Options::Options() : - time(true), level(true), thread(false), source(false), function(false) +Options::Options(const std::string& name) : qpid::Options(name), + time(true), level(true), thread(false), source(false), function(false), trace(false) { outputs.push_back("stderr"); selectors.push_back("error+"); -} -void Options::addTo(po::options_description& desc) { - using namespace po; ostringstream levels; levels << LevelTraits::name(Level(0)); for (int i = 1; i < LevelTraits::COUNT; ++i) levels << " " << LevelTraits::name(Level(i)); - desc.add_options() + addOptions() + ("trace,t", optValue(trace), "Enable full debug tracing." ) ("log.enable", optValue(selectors, "RULE"), - "You can specify this option mutliple times.\n" + ("You can specify this option mutliple times.\n" "RULE is of the form 'LEVEL[+][:COMPONENT]'" - "Levels are: trace, debug, info, notice, warning, error, critical." + "Levels are: "+levels.str()+"\n" "For example:\n" "\t'--log.enable warning+' " "enables all warning, error and critical messages.\n" "\t'--log.enable debug:framing' " - "enables debug messages from the framing component.") + "enables debug messages from the framing component.").c_str()) ("log.output", optValue(outputs, "FILE"), "File to receive log output, or one of these special values: " "'stderr', 'stdout', 'syslog'.") @@ -61,9 +59,6 @@ void Options::addTo(po::options_description& desc) { "Include thread ID in log messages") ("log.function", optValue(function,"yes|no"), "Include function signature in log messages"); - } - - }} // namespace qpid::log diff --git a/cpp/src/qpid/log/Options.h b/cpp/src/qpid/log/Options.h index 39261c9b5d..441c6e8a8d 100644 --- a/cpp/src/qpid/log/Options.h +++ b/cpp/src/qpid/log/Options.h @@ -18,20 +18,20 @@ * limitations under the License. * */ -#include "qpid/CommonOptions.h" +#include "qpid/Options.h" namespace qpid { namespace log { /** Logging options for config parser. */ -struct Options { - Options(); - void addTo(po::options_description&); +struct Options : public qpid::Options { + Options(const std::string& name="Logging options"); std::vector<std::string> selectors; std::vector<std::string> outputs; bool time, level, thread, source, function; + bool trace; }; |