|
|
@ -3,110 +3,111 @@
|
|
|
|
namespace program_options {
|
|
|
|
namespace program_options {
|
|
|
|
|
|
|
|
|
|
|
|
// class ParseError
|
|
|
|
// class ParseError
|
|
|
|
|
|
|
|
//定义了一个名为ParseError的类
|
|
|
|
ParseError::ParseError(const std::string& msg) : _msg(msg) {}
|
|
|
|
//ParseError类是一个用于处理命令行解析错误的异常类。
|
|
|
|
|
|
|
|
ParseError::ParseError(const std::string& msg) : _msg(msg) {}//是ParseError类的构造函数
|
|
|
|
const char* ParseError::what() const throw() {
|
|
|
|
//它接受一个字符串作为参数,并将这个字符串赋值给成员变量_msg。
|
|
|
|
std::string msg;
|
|
|
|
const char* ParseError::what() const throw() {//是一个成员函数,它返回一个描述错误的字符串
|
|
|
|
msg.append("Command line parse error: ").append(_msg).push_back('.');
|
|
|
|
std::string msg;//首先创建一个新的字符串
|
|
|
|
return msg.c_str();
|
|
|
|
msg.append("Command line parse error: ").append(_msg).push_back('.');//添加一个错误消息前缀,接着添加成员变量_msg,最后添加一个句点。
|
|
|
|
|
|
|
|
return msg.c_str();//返回这个字符串的C风格字符串。
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ParseError::~ParseError() throw() {}
|
|
|
|
ParseError::~ParseError() throw() {}// 是ParseError类的析构函数
|
|
|
|
|
|
|
|
|
|
|
|
// class Generator
|
|
|
|
// class Generator
|
|
|
|
|
|
|
|
//定义了一个名为Generator的类,该类用于生成和管理命令行选项解析器和子程序。
|
|
|
|
Generator::Generator() : parser_(nullptr) {
|
|
|
|
Generator::Generator() : parser_(nullptr) {//Generator类的构造函数
|
|
|
|
current_subroutine_ = Subroutine::get_default_name();
|
|
|
|
current_subroutine_ = Subroutine::get_default_name();//初始化parser_为nullptr,设置当前子程序为默认子程序
|
|
|
|
add_subroutine(current_subroutine_.c_str());
|
|
|
|
add_subroutine(current_subroutine_.c_str());//添加这个子程序。
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Generator::~Generator() {
|
|
|
|
Generator::~Generator() {//Generator类的析构函数
|
|
|
|
if (parser_) {
|
|
|
|
if (parser_) {
|
|
|
|
delete parser_;
|
|
|
|
delete parser_;
|
|
|
|
parser_ = nullptr;
|
|
|
|
parser_ = nullptr;
|
|
|
|
}
|
|
|
|
}//它删除parser_和所有的子程序
|
|
|
|
for (auto it = subroutines_.begin(); it != subroutines_.end(); ++it) {
|
|
|
|
for (auto it = subroutines_.begin(); it != subroutines_.end(); ++it) {
|
|
|
|
if (it->second) {
|
|
|
|
if (it->second) {
|
|
|
|
delete it->second;
|
|
|
|
delete it->second;//它删除所有的子程序,
|
|
|
|
it->second = nullptr;
|
|
|
|
it->second = nullptr;//并将parser_和所有的子程序设置为nullptr。
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Generator& Generator::make_usage(const char* first_line) {
|
|
|
|
Generator& Generator::make_usage(const char* first_line) {//是一个成员函数
|
|
|
|
get_subroutine()->set_first_line(first_line);
|
|
|
|
get_subroutine()->set_first_line(first_line);//它设置当前子程序的第一行
|
|
|
|
return *this;
|
|
|
|
return *this;//并返回this指针。
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Parser* Generator::make_parser() {
|
|
|
|
Parser* Generator::make_parser() {//是一个成员函数
|
|
|
|
if (parser_) delete parser_;
|
|
|
|
if (parser_) delete parser_;
|
|
|
|
parser_ = new Parser;
|
|
|
|
parser_ = new Parser;//它创建一个新的Parser对象
|
|
|
|
parser_->set_usage_subroutines(&subroutines_);
|
|
|
|
parser_->set_usage_subroutines(&subroutines_);//设置其使用的子程序
|
|
|
|
return parser_;
|
|
|
|
return parser_;//并返回这个Parser对象。
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Generator& Generator::add_subroutine(const char* name) {
|
|
|
|
Generator& Generator::add_subroutine(const char* name) {//是成员函数
|
|
|
|
add_subroutine(name, "");
|
|
|
|
add_subroutine(name, "");//它们添加一个新的子程序。
|
|
|
|
return *this;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Generator& Generator::add_subroutine(const char* name,
|
|
|
|
Generator& Generator::add_subroutine(const char* name,
|
|
|
|
const char* description) {
|
|
|
|
const char* description) {//成员函数
|
|
|
|
if (subroutines_.find(name) == subroutines_.end()) {
|
|
|
|
if (subroutines_.find(name) == subroutines_.end()) {//如果子程序已经存在,它们不会添加。
|
|
|
|
// a new subroutine
|
|
|
|
// a new subroutine
|
|
|
|
current_subroutine_ = name;
|
|
|
|
current_subroutine_ = name;//设立新名字
|
|
|
|
Subroutine* routine = new Subroutine(name, description);
|
|
|
|
Subroutine* routine = new Subroutine(name, description);//新建一个子程序。
|
|
|
|
subroutines_.insert({current_subroutine_, routine});
|
|
|
|
subroutines_.insert({current_subroutine_, routine});//添加一个新的子程序。
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::map<std::string, std::string> Generator::get_subroutine_list() {
|
|
|
|
std::map<std::string, std::string> Generator::get_subroutine_list() {//是一个成员函数,它返回一个包含所有子程序名称和描述的映射。
|
|
|
|
std::map<std::string, std::string> kv;
|
|
|
|
std::map<std::string, std::string> kv;
|
|
|
|
for (auto pr : subroutines_) {
|
|
|
|
for (auto pr : subroutines_) {//遍历所有的子程序
|
|
|
|
Subroutine* subroutine = pr.second;
|
|
|
|
Subroutine* subroutine = pr.second;//遍历所有的子程序
|
|
|
|
if (subroutine->get_name() != Subroutine::get_default_name())
|
|
|
|
if (subroutine->get_name() != Subroutine::get_default_name())//如果子程序的名称不是默认名称
|
|
|
|
kv[subroutine->get_name()] = subroutine->get_description();
|
|
|
|
kv[subroutine->get_name()] = subroutine->get_description();//将子程序的名称和描述添加到映射中。
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::move(kv);
|
|
|
|
return std::move(kv);//返回一个包含所有子程序名称和描述的映射
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Generator::add_usage_line(const char* option, const char* default_value,
|
|
|
|
bool Generator::add_usage_line(const char* option, const char* default_value,
|
|
|
|
const char* description) {
|
|
|
|
const char* description) {// 是一个成员函数,它添加一个使用行到当前子程序。
|
|
|
|
std::string option_str(option);
|
|
|
|
std::string option_str(option);
|
|
|
|
auto delimiter_pos = option_str.find(kDelimiter);
|
|
|
|
auto delimiter_pos = option_str.find(kDelimiter);
|
|
|
|
|
|
|
|
//定义新变量,将选项字符串赋给新变量
|
|
|
|
std::string option_short;
|
|
|
|
std::string option_short;
|
|
|
|
std::string option_long;
|
|
|
|
std::string option_long;
|
|
|
|
|
|
|
|
//将选项字符串分割为短选项和长选项
|
|
|
|
if (delimiter_pos != std::string::npos) {
|
|
|
|
if (delimiter_pos != std::string::npos) {
|
|
|
|
option_short.assign(std::move(option_str.substr(0, delimiter_pos)));
|
|
|
|
option_short.assign(std::move(option_str.substr(0, delimiter_pos)));
|
|
|
|
option_long.assign(std::move(option_str.substr(delimiter_pos + 1)));
|
|
|
|
option_long.assign(std::move(option_str.substr(delimiter_pos + 1)));
|
|
|
|
|
|
|
|
|
|
|
|
Row row;
|
|
|
|
Row row;//创建一个Row对象,
|
|
|
|
row.oshort(option_short);
|
|
|
|
row.oshort(option_short);
|
|
|
|
row.olong(option_long);
|
|
|
|
row.olong(option_long);
|
|
|
|
row.value(default_value);
|
|
|
|
row.value(default_value);
|
|
|
|
row.desc(description);
|
|
|
|
row.desc(description);
|
|
|
|
|
|
|
|
////设置其短选项、长选项、默认值和描述
|
|
|
|
get_subroutine()->add_usage_line(row);
|
|
|
|
get_subroutine()->add_usage_line(row);//将这个Row对象添加到当前子程序的使用行中。
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& out, Generator& generator) {
|
|
|
|
std::ostream& operator<<(std::ostream& out, Generator& generator) {// 是一个输出运算符重载函数,它打印所有子程序的名称和描述。
|
|
|
|
for (auto pr : generator.subroutines_) {
|
|
|
|
for (auto pr : generator.subroutines_) {//遍历所有的子程序
|
|
|
|
Subroutine* subroutine = pr.second;
|
|
|
|
Subroutine* subroutine = pr.second;
|
|
|
|
if (subroutine->get_name() != Subroutine::get_default_name()) {
|
|
|
|
if (subroutine->get_name() != Subroutine::get_default_name()) {
|
|
|
|
out << subroutine->get_name() << "\t";
|
|
|
|
out << subroutine->get_name() << "\t";
|
|
|
|
|
|
|
|
}//如果子程序的名称不是默认名称,就打印子程序的名称
|
|
|
|
|
|
|
|
out << subroutine->get_description();//打印子程序的描述
|
|
|
|
|
|
|
|
if (!subroutine->get_usage().empty()) {//如果子程序的使用信息不为空,就打印一个换行符
|
|
|
|
|
|
|
|
out << std::endl;//打印一个换行符
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out << subroutine->get_description();
|
|
|
|
out << *subroutine;//打印子程序的使用信息。
|
|
|
|
if (!subroutine->get_usage().empty()) {
|
|
|
|
|
|
|
|
out << std::endl;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
out << *subroutine;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|