start option description
This commit is contained in:
parent
db5477ddd8
commit
b89953f42b
61
src/cxxopts.cpp
Normal file
61
src/cxxopts.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
17
src/main.cpp
17
src/main.cpp
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user