1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* vim: set ts=2 et sw=2 tw=80: */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
- // Generic command line flags system for NSS BoGo shim. This class
- // could actually in principle handle other programs. The flags are
- // defined in the consumer code.
- #ifndef config_h_
- #define config_h_
- #include <cassert>
- #include <iostream>
- #include <map>
- #include <memory>
- #include <queue>
- #include <string>
- #include <typeinfo>
- // Abstract base class for a given config flag.
- class ConfigEntryBase {
- public:
- ConfigEntryBase(const std::string& nm, const std::string& typ)
- : name_(nm), type_(typ) {}
- virtual ~ConfigEntryBase() {}
- const std::string& type() const { return type_; }
- virtual bool Parse(std::queue<const char*>& args) = 0;
- protected:
- bool ParseInternal(std::queue<const char*>& args, std::vector<int>& out);
- bool ParseInternal(std::queue<const char*>& args, std::string& out);
- bool ParseInternal(std::queue<const char*>& args, int& out);
- bool ParseInternal(std::queue<const char*>& args, bool& out);
- const std::string name_;
- const std::string type_;
- };
- // Template specializations for the concrete flag types.
- template <typename T>
- class ConfigEntry : public ConfigEntryBase {
- public:
- ConfigEntry(const std::string& name, T init)
- : ConfigEntryBase(name, typeid(T).name()), value_(init) {}
- T get() const { return value_; }
- bool Parse(std::queue<const char*>& args) {
- return ParseInternal(args, value_);
- }
- private:
- T value_;
- };
- // The overall configuration (I.e., the total set of flags).
- class Config {
- public:
- enum Status { kOK, kUnknownFlag, kMalformedArgument, kMissingValue };
- Config() : entries_() {}
- template <typename T>
- void AddEntry(const std::string& name, T init) {
- entries_[name] =
- std::unique_ptr<ConfigEntryBase>(new ConfigEntry<T>(name, init));
- }
- Status ParseArgs(int argc, char** argv);
- template <typename T>
- T get(const std::string& key) const {
- auto e = entry(key);
- assert(e->type() == typeid(T).name());
- return static_cast<const ConfigEntry<T>*>(e)->get();
- }
- private:
- static std::string XformFlag(const std::string& arg);
- std::map<std::string, std::unique_ptr<ConfigEntryBase>> entries_;
- const ConfigEntryBase* entry(const std::string& key) const {
- auto e = entries_.find(key);
- if (e == entries_.end()) return nullptr;
- return e->second.get();
- }
- };
- #endif // config_h_
|