start option description

This commit is contained in:
Jarryd Beck 2014-09-27 17:04:58 +10:00
parent db5477ddd8
commit b89953f42b
3 changed files with 126 additions and 10 deletions

61
src/cxxopts.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "cxxopts.hpp"
namespace cxxopts
{
std::basic_regex<char> option_matcher
("--([[:alpha:]][-_[:alpha:]]+)(=(.*))?|-([a-zA-Z]+)");
std::basic_regex<char> option_specifier
("(([a-zA-Z]),)?([a-zA-Z][-_a-zA-Z]+)");
OptionAdder
Options::add_options()
{
return OptionAdder(*this);
}
OptionAdder&
OptionAdder::operator()
(
const std::string& opts,
const std::string& desc
)
{
std::match_results<const char*> result;
std::regex_match(opts.c_str(), result, option_specifier);
if (result.empty())
{
throw invalid_option_format_error(opts);
}
const auto& s = result[2];
const auto& l = result[3];
auto option = std::make_shared<OptionDetails>(desc);
if (s.length() != 0)
{
auto result = m_options.m_short.insert(std::make_pair(s.str()[0], option));
if (!result.second)
{
throw option_exists_error(s.str());
}
}
if (l.length() != 0)
{
auto result = m_options.m_long.insert(std::make_pair(l, option));
if (!result.second)
{
throw option_exists_error(l.str());
}
}
return *this;
}
}

View File

@ -1,5 +1,7 @@
#include <regex>
#include <set>
#include <map>
#include <exception>
namespace cxxopts
{
@ -7,8 +9,60 @@ namespace cxxopts
extern std::basic_regex<char> option_specifier;
class OptionException : public std::exception
{
};
class option_exists_error : public OptionException
{
public:
option_exists_error(const std::string& option)
{
m_message = u8"Option " + option + u8" already exists";
}
const char*
what() const noexcept
{
return m_message.c_str();
}
private:
std::string m_message;
};
class invalid_option_format_error : public OptionException
{
public:
invalid_option_format_error(const std::string& format)
{
m_message = u8"Invalid option format " + format + u8"";
}
const char*
what() const noexcept
{
return m_message.c_str();
}
private:
std::string m_message;
};
class OptionAdder;
class OptionDetails
{
public:
OptionDetails(const std::string& description)
: m_desc(description)
{
}
private:
std::string m_desc;
};
class Options
{
public:
@ -22,8 +76,8 @@ namespace cxxopts
private:
friend class OptionAdder;
std::set<char32_t> m_short;
std::set<std::string> m_long;
std::map<char, std::shared_ptr<OptionDetails>> m_short;
std::map<std::string, std::shared_ptr<OptionDetails>> m_long;
};
class OptionAdder

View File

@ -1,21 +1,15 @@
#include <codecvt>
#include <iostream>
#include <locale>
#include <sstream>
#include "cxxopts.hpp"
int main(int argc, char* argv[])
{
std::locale::global(std::locale(""));
try
{
cxxopts::option_matcher.imbue(std::locale(""));
cxxopts::option_matcher.assign
("--([[:alpha:]][-_[:alpha:]]+)(=(.*))?|-([a-zA-Z]+)",
std::regex_constants::extended | std::regex_constants::ECMAScript |
std::regex_constants::collate);
std::cout << cxxopts::option_matcher.getloc().name() << std::endl;
std::match_results<const char*> result;
for (int i = 1; i < argc; ++i)
@ -32,6 +26,13 @@ int main(int argc, char* argv[])
}
}
cxxopts::Options options;
options.add_options()
("a,apple", "an apple")
("b,bob", "Bob")
;
} catch (const std::regex_error& e)
{
std::cout << "regex_error: " << e.what() << std::endl;