feat: finish ArgParser help text output
This commit is contained in:
parent
d1c1743dc9
commit
e8a0299fbc
|
@ -1,6 +1,7 @@
|
|||
#include "ArgParser.hpp"
|
||||
|
||||
#include "EncodingHelper.hpp"
|
||||
#include "ConsoleHelper.hpp"
|
||||
|
||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||
#include "WinImportPrefix.hpp"
|
||||
|
@ -63,7 +64,7 @@ namespace YYCC::ArgParser {
|
|||
++m_ArgumentsIterator;
|
||||
}
|
||||
|
||||
const yycc_u8string& ArgumentList::Current() const {
|
||||
const yycc_u8string& ArgumentList::Argument() const {
|
||||
if (IsEOF()) throw std::runtime_error("attempt to get data on the tail of iterator.");
|
||||
return *m_ArgumentsIterator;
|
||||
}
|
||||
|
@ -114,7 +115,7 @@ namespace YYCC::ArgParser {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ArgumentList::IsValue(yycc_u8string* val) const {
|
||||
bool ArgumentList::IsParameter(yycc_u8string* val) const {
|
||||
bool is_value = !IsSwitch();
|
||||
if (is_value && val != nullptr)
|
||||
*val = *m_ArgumentsIterator;
|
||||
|
@ -240,7 +241,7 @@ namespace YYCC::ArgParser {
|
|||
while (!al.IsEOF()) {
|
||||
// if we can not find any switches, return with error
|
||||
if (!al.IsSwitch(&is_long_name, &long_name, &short_name)) return false;
|
||||
|
||||
|
||||
// find corresponding argument by long name or short name.
|
||||
// if we can not find it, return with error.
|
||||
AbstractArgument* arg;
|
||||
|
@ -288,6 +289,60 @@ namespace YYCC::ArgParser {
|
|||
}
|
||||
}
|
||||
|
||||
void OptionContext::Help() const {
|
||||
// print summary and description if necessary
|
||||
if (!m_Summary.empty())
|
||||
YYCC::ConsoleHelper::WriteLine(m_Summary.c_str());
|
||||
if (!m_Description.empty())
|
||||
YYCC::ConsoleHelper::WriteLine(m_Description.c_str());
|
||||
|
||||
// blank line
|
||||
YYCC::ConsoleHelper::WriteLine(YYCC_U8(""));
|
||||
|
||||
// print argument list
|
||||
for (const auto* arg : m_Arguments) {
|
||||
yycc_u8string argstr;
|
||||
|
||||
// print indent
|
||||
argstr += YYCC_U8("\t");
|
||||
// print optional head
|
||||
bool is_optional = arg->IsOptional();
|
||||
if (is_optional) argstr += YYCC_U8("[");
|
||||
|
||||
// switch name
|
||||
bool short_name = arg->HasShortName(), long_name = arg->HasLongName();
|
||||
if (short_name) {
|
||||
argstr += YYCC_U8("-");
|
||||
argstr += arg->GetShortName();
|
||||
}
|
||||
if (long_name) {
|
||||
if (short_name) argstr += YYCC_U8(", ");
|
||||
argstr += YYCC_U8("--");
|
||||
argstr += arg->GetLongName();
|
||||
}
|
||||
|
||||
// argument example
|
||||
if (arg->HasArgumentExample()) {
|
||||
argstr += YYCC_U8(" ");
|
||||
argstr += arg->GetArgumentExample();
|
||||
}
|
||||
|
||||
// optional tail
|
||||
if (is_optional) argstr += YYCC_U8("]");
|
||||
|
||||
// argument description
|
||||
if (arg->HasDescription()) {
|
||||
// eol and double indent
|
||||
argstr += YYCC_U8("\n\t\t");
|
||||
// description
|
||||
argstr += arg->GetDescription();
|
||||
}
|
||||
|
||||
// write into console
|
||||
YYCC::ConsoleHelper::WriteLine(argstr.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
}
|
||||
|
|
|
@ -28,12 +28,12 @@ namespace YYCC::ArgParser {
|
|||
public:
|
||||
void Prev();
|
||||
void Next();
|
||||
const yycc_u8string& Current() const;
|
||||
const yycc_u8string& Argument() const;
|
||||
bool IsSwitch(
|
||||
bool* is_long_name = nullptr,
|
||||
yycc_u8string* long_name = nullptr,
|
||||
yycc_char8_t* short_name = nullptr) const;
|
||||
bool IsValue(yycc_u8string* val = nullptr) const;
|
||||
bool IsParameter(yycc_u8string* val = nullptr) const;
|
||||
bool IsEOF() const;
|
||||
void Reset();
|
||||
private:
|
||||
|
@ -104,6 +104,7 @@ namespace YYCC::ArgParser {
|
|||
public:
|
||||
bool Parse(ArgumentList& al);
|
||||
void Reset();
|
||||
void Help() const;
|
||||
|
||||
private:
|
||||
yycc_u8string m_Summary;
|
||||
|
@ -138,7 +139,7 @@ namespace YYCC::ArgParser {
|
|||
// try get corresponding value
|
||||
yycc_u8string strval;
|
||||
al.Next();
|
||||
if (al.IsEOF() || !al.IsValue(&strval)) {
|
||||
if (al.IsEOF() || !al.IsParameter(&strval)) {
|
||||
al.Prev();
|
||||
return false;
|
||||
}
|
||||
|
@ -163,8 +164,10 @@ namespace YYCC::ArgParser {
|
|||
public:
|
||||
SwitchArgument(
|
||||
const yycc_char8_t* long_name, yycc_char8_t short_name,
|
||||
const yycc_char8_t* description = nullptr, const yycc_char8_t* argument_example = nullptr) :
|
||||
AbstractArgument(long_name, short_name, description, argument_example, true), m_Data(false) {} // bool switch must be optional, because it is false if no given switch.
|
||||
const yycc_char8_t* description = nullptr) :
|
||||
// bool switch must be optional, because it is false if no given switch.
|
||||
// bool switch doesn't have argument, so it doesn't have example property.
|
||||
AbstractArgument(long_name, short_name, description, nullptr, true), m_Data(false) {}
|
||||
virtual ~SwitchArgument() {}
|
||||
|
||||
public:
|
||||
|
@ -201,7 +204,7 @@ namespace YYCC::ArgParser {
|
|||
virtual bool Parse(ArgumentList& al) override {
|
||||
// try get corresponding value
|
||||
al.Next();
|
||||
if (al.IsEOF() || !al.IsValue(&m_Data)) {
|
||||
if (al.IsEOF() || !al.IsParameter(&m_Data)) {
|
||||
al.Prev();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -487,7 +487,7 @@ namespace YYCCTestbench {
|
|||
m_IntArgument(YYCC_U8("int"), YYCC_U8_CHAR('i'), YYCC_U8("integral argument"), YYCC_U8("114514")),
|
||||
m_FloatArgument(nullptr, YYCC_U8_CHAR('f'), nullptr, nullptr, true),
|
||||
m_StringArgument(YYCC_U8("string"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, nullptr, nullptr, true),
|
||||
m_BoolArgument(nullptr, YYCC_U8_CHAR('b'), nullptr, nullptr),
|
||||
m_BoolArgument(nullptr, YYCC_U8_CHAR('b'), nullptr),
|
||||
m_ClampedFloatArgument(YYCC_U8("clamped-float"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, nullptr, nullptr, true, YYCC::Constraints::GetMinMaxRangeConstraint<float>(-1.0f, 1.0f)),
|
||||
m_OptionContext(YYCC_U8("TestArgParser"), YYCC_U8("This is the testbench of argument parser."), {
|
||||
&m_IntArgument, &m_FloatArgument, &m_StringArgument,
|
||||
|
@ -511,7 +511,7 @@ namespace YYCCTestbench {
|
|||
YYCC::ConsoleHelper::WriteLine(YYCC_U8("YYCC::ArgParser::ArgumentList::CreateFromStd"));
|
||||
auto result = YYCC::ArgParser::ArgumentList::CreateFromStd(argc, argv);
|
||||
for (result.Reset(); !result.IsEOF(); result.Next()) {
|
||||
YYCC::ConsoleHelper::FormatLine(YYCC_U8("\t%s"), result.Current().c_str());
|
||||
YYCC::ConsoleHelper::FormatLine(YYCC_U8("\t%s"), result.Argument().c_str());
|
||||
}
|
||||
}
|
||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||
|
@ -519,7 +519,7 @@ namespace YYCCTestbench {
|
|||
YYCC::ConsoleHelper::WriteLine(YYCC_U8("YYCC::ArgParser::ArgumentList::CreateFromWin32"));
|
||||
auto result = YYCC::ArgParser::ArgumentList::CreateFromWin32();
|
||||
for (result.Reset(); !result.IsEOF(); result.Next()) {
|
||||
YYCC::ConsoleHelper::FormatLine(YYCC_U8("\t%s"), result.Current().c_str());
|
||||
YYCC::ConsoleHelper::FormatLine(YYCC_U8("\t%s"), result.Argument().c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -581,6 +581,9 @@ auto al = YYCC::ArgParser::ArgumentList::CreateFromStd(sizeof(test_argv) / sizeo
|
|||
test.m_OptionContext.Reset();
|
||||
}
|
||||
|
||||
// Help text
|
||||
test.m_OptionContext.Help();
|
||||
|
||||
#undef PREPARE_DATA
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user