feat: finish ArgParser help text output
This commit is contained in:
parent
d1c1743dc9
commit
e8a0299fbc
|
@ -1,6 +1,7 @@
|
||||||
#include "ArgParser.hpp"
|
#include "ArgParser.hpp"
|
||||||
|
|
||||||
#include "EncodingHelper.hpp"
|
#include "EncodingHelper.hpp"
|
||||||
|
#include "ConsoleHelper.hpp"
|
||||||
|
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
#include "WinImportPrefix.hpp"
|
#include "WinImportPrefix.hpp"
|
||||||
|
@ -63,7 +64,7 @@ namespace YYCC::ArgParser {
|
||||||
++m_ArgumentsIterator;
|
++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.");
|
if (IsEOF()) throw std::runtime_error("attempt to get data on the tail of iterator.");
|
||||||
return *m_ArgumentsIterator;
|
return *m_ArgumentsIterator;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +115,7 @@ namespace YYCC::ArgParser {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArgumentList::IsValue(yycc_u8string* val) const {
|
bool ArgumentList::IsParameter(yycc_u8string* val) const {
|
||||||
bool is_value = !IsSwitch();
|
bool is_value = !IsSwitch();
|
||||||
if (is_value && val != nullptr)
|
if (is_value && val != nullptr)
|
||||||
*val = *m_ArgumentsIterator;
|
*val = *m_ArgumentsIterator;
|
||||||
|
@ -240,7 +241,7 @@ namespace YYCC::ArgParser {
|
||||||
while (!al.IsEOF()) {
|
while (!al.IsEOF()) {
|
||||||
// if we can not find any switches, return with error
|
// if we can not find any switches, return with error
|
||||||
if (!al.IsSwitch(&is_long_name, &long_name, &short_name)) return false;
|
if (!al.IsSwitch(&is_long_name, &long_name, &short_name)) return false;
|
||||||
|
|
||||||
// find corresponding argument by long name or short name.
|
// find corresponding argument by long name or short name.
|
||||||
// if we can not find it, return with error.
|
// if we can not find it, return with error.
|
||||||
AbstractArgument* arg;
|
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
|
#pragma endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,12 @@ namespace YYCC::ArgParser {
|
||||||
public:
|
public:
|
||||||
void Prev();
|
void Prev();
|
||||||
void Next();
|
void Next();
|
||||||
const yycc_u8string& Current() const;
|
const yycc_u8string& Argument() const;
|
||||||
bool IsSwitch(
|
bool IsSwitch(
|
||||||
bool* is_long_name = nullptr,
|
bool* is_long_name = nullptr,
|
||||||
yycc_u8string* long_name = nullptr,
|
yycc_u8string* long_name = nullptr,
|
||||||
yycc_char8_t* short_name = nullptr) const;
|
yycc_char8_t* short_name = nullptr) const;
|
||||||
bool IsValue(yycc_u8string* val = nullptr) const;
|
bool IsParameter(yycc_u8string* val = nullptr) const;
|
||||||
bool IsEOF() const;
|
bool IsEOF() const;
|
||||||
void Reset();
|
void Reset();
|
||||||
private:
|
private:
|
||||||
|
@ -104,6 +104,7 @@ namespace YYCC::ArgParser {
|
||||||
public:
|
public:
|
||||||
bool Parse(ArgumentList& al);
|
bool Parse(ArgumentList& al);
|
||||||
void Reset();
|
void Reset();
|
||||||
|
void Help() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
yycc_u8string m_Summary;
|
yycc_u8string m_Summary;
|
||||||
|
@ -138,7 +139,7 @@ namespace YYCC::ArgParser {
|
||||||
// try get corresponding value
|
// try get corresponding value
|
||||||
yycc_u8string strval;
|
yycc_u8string strval;
|
||||||
al.Next();
|
al.Next();
|
||||||
if (al.IsEOF() || !al.IsValue(&strval)) {
|
if (al.IsEOF() || !al.IsParameter(&strval)) {
|
||||||
al.Prev();
|
al.Prev();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -163,8 +164,10 @@ namespace YYCC::ArgParser {
|
||||||
public:
|
public:
|
||||||
SwitchArgument(
|
SwitchArgument(
|
||||||
const yycc_char8_t* long_name, yycc_char8_t short_name,
|
const yycc_char8_t* long_name, yycc_char8_t short_name,
|
||||||
const yycc_char8_t* description = nullptr, const yycc_char8_t* argument_example = nullptr) :
|
const yycc_char8_t* description = 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.
|
// 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() {}
|
virtual ~SwitchArgument() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -201,7 +204,7 @@ namespace YYCC::ArgParser {
|
||||||
virtual bool Parse(ArgumentList& al) override {
|
virtual bool Parse(ArgumentList& al) override {
|
||||||
// try get corresponding value
|
// try get corresponding value
|
||||||
al.Next();
|
al.Next();
|
||||||
if (al.IsEOF() || !al.IsValue(&m_Data)) {
|
if (al.IsEOF() || !al.IsParameter(&m_Data)) {
|
||||||
al.Prev();
|
al.Prev();
|
||||||
return false;
|
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_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_FloatArgument(nullptr, YYCC_U8_CHAR('f'), nullptr, nullptr, true),
|
||||||
m_StringArgument(YYCC_U8("string"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, 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_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_OptionContext(YYCC_U8("TestArgParser"), YYCC_U8("This is the testbench of argument parser."), {
|
||||||
&m_IntArgument, &m_FloatArgument, &m_StringArgument,
|
&m_IntArgument, &m_FloatArgument, &m_StringArgument,
|
||||||
|
@ -511,7 +511,7 @@ namespace YYCCTestbench {
|
||||||
YYCC::ConsoleHelper::WriteLine(YYCC_U8("YYCC::ArgParser::ArgumentList::CreateFromStd"));
|
YYCC::ConsoleHelper::WriteLine(YYCC_U8("YYCC::ArgParser::ArgumentList::CreateFromStd"));
|
||||||
auto result = YYCC::ArgParser::ArgumentList::CreateFromStd(argc, argv);
|
auto result = YYCC::ArgParser::ArgumentList::CreateFromStd(argc, argv);
|
||||||
for (result.Reset(); !result.IsEOF(); result.Next()) {
|
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
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
@ -519,7 +519,7 @@ namespace YYCCTestbench {
|
||||||
YYCC::ConsoleHelper::WriteLine(YYCC_U8("YYCC::ArgParser::ArgumentList::CreateFromWin32"));
|
YYCC::ConsoleHelper::WriteLine(YYCC_U8("YYCC::ArgParser::ArgumentList::CreateFromWin32"));
|
||||||
auto result = YYCC::ArgParser::ArgumentList::CreateFromWin32();
|
auto result = YYCC::ArgParser::ArgumentList::CreateFromWin32();
|
||||||
for (result.Reset(); !result.IsEOF(); result.Next()) {
|
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
|
#endif
|
||||||
|
@ -581,6 +581,9 @@ auto al = YYCC::ArgParser::ArgumentList::CreateFromStd(sizeof(test_argv) / sizeo
|
||||||
test.m_OptionContext.Reset();
|
test.m_OptionContext.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Help text
|
||||||
|
test.m_OptionContext.Help();
|
||||||
|
|
||||||
#undef PREPARE_DATA
|
#undef PREPARE_DATA
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user