16C_EZArgs::C_FlagDef &C_EZArgs::create_flag_def(std::string_view name,
char short_name, std::string_view description)
24 auto &dst = m_flags.emplace_back();
25 if (!name.empty() && name[0] ==
'-')
27 dst.m_name = name.substr(2);
31 throw std::runtime_error{
"Invalid flag name: " + (std::string)name};
36 dst.m_descOneLiner = description;
37 dst.m_shortName = short_name;
38 if (dst.m_name ==
"help")
39 m_helpShielded =
true;
40 if (dst.m_shortName ==
'h')
46std::string C_EZArgs::retro_path(
const char *
const argv[])
const
48 std::vector<const char*> polish_args;
49 for (
auto cur =
this; cur; cur = cur->m_owner)
50 polish_args.emplace_back(*(argv--));
53 for (
auto i = polish_args.rbegin(); i != polish_args.rend(); ++i)
56 ret = std::filesystem::path{*i}.filename().string();
69 std::string help =
"USAGE: " + retro_path(argv);
70 std::string validActions;
71 switch (m_up2u.index())
77 auto &lo = std::get<UP2U_LAYOUT>(m_up2u);
78 const auto minPosArgs = lo.m_posCounts.empty()? lo.m_posArgs.size(): lo.m_posCounts.front();
79 for (
size_t i = 0; i < minPosArgs; ++i)
80 ((help +=
" <") += lo.m_posArgs[i]) +=
'>';
82 std::string optionals;
86 size_t ub = lo.m_posArgs.size();
87 for (
auto i: lo.m_posCounts)
90 for (
auto j = i; j < ub; ++j)
91 t += (t.empty()?
"[<":
"> <") + lo.m_posArgs[j];
95 if (optionals.empty())
98 optionals = t +
"> " + optionals +
']';
102 if (!optionals.empty())
103 (help +=
' ') += optionals;
107 validActions +=
"VALID ACTIONS:\n";
109 auto &subcmds = std::get<UP2U_SUBCMD>(m_up2u);
111 size_t positionalCount{};
112 for (
auto &i: subcmds)
114 actions += actions.empty()?
'(':
'|';
116 ((validActions +=
" ") += i.first) +=
'\n';
117 if (!i.second.m_desc.empty())
118 ((validActions +=
'\t') += i.second.m_desc) +=
'\n';
119 if (i.second.m_up2u.index() != UP2U_NULL)
122 (help +=
' ') += actions;
123 if (!positionalCount)
125 else if (positionalCount < subcmds.size())
132 for (
auto cur =
this; cur; cur = cur->m_owner)
133 for (
auto &def: cur->m_flags)
137 help += def.m_shortName;
139 (help +=
'-') += def.m_name;
142 help += def.m_trigger?
" [ARG]":
" ARG";
148 else if (!m_helpShielded)
161 if (help.back() !=
'\n')
165 if (!validActions.empty())
166 help += validActions;
170 std::string flags = help_flags();
171 const char *help_flag{};
172 switch ((m_hShielded?0:2) + (m_helpShielded?0:1))
175 help_flag =
" --help\n";
181 help_flag =
" -h, --help\n";
185 flags.append(help_flag).append(
"\tDisplay this help and exit\n");
188 "VALID FLAGS:\n" + flags;
191 for (
auto cur = m_owner; cur; cur = cur->m_owner)
192 flags += cur->help_flags();
195 "INHERITED FLAGS:\n" + flags;
199 if (!m_details.empty())
205 if (m_details.back() !=
'\n')
213std::string C_EZArgs::help_flags()
const
216 for (
auto &def: m_flags)
221 help += def.m_shortName;
222 if (!def.m_name.empty())
223 (help +=
", --") += def.m_name;
226 (help +=
'-') += def.m_name;
229 help += def.m_trigger?
" [ARG]":
" ARG";
232 if (!def.m_descOneLiner.empty())
233 (help +=
'\t').
append(def.m_descOneLiner) +=
'\n';
238std::string C_EZArgs::help_tip(
const std::string &error,
const char *
const argv[])
const
240 const char *helpFlag{};
243 else if (!m_helpShielded)
247 return std::format(
"{}\nType \"{} {}\" to read the help", error, retro_path(argv), helpFlag);
252const C_EZArgs::C_FlagDef* C_EZArgs::find_shortname_def(
char sname)
const
254 for (
auto cur =
this; cur; cur = cur->m_owner)
255 for (
auto& def : cur->m_flags)
257 if (def.m_shortName == sname)
264const C_EZArgs::C_FlagDef* C_EZArgs::find_longname_def(std::string_view name)
const
266 for (
auto cur =
this; cur; cur = cur->m_owner)
267 for (
auto& def : cur->m_flags)
269 if (def.m_name == name)
276bool C_EZArgs::is_valid_flag(
const char *
const *argv_rest,
int argc_rest)
const
278 const auto arg = *argv_rest;
285 const auto flag = arg + 2;
286 const auto eqsign = strchr(flag,
'=');
287 const auto flag_name = eqsign ? std::string_view(flag,
size_t(eqsign - flag)) : std::string_view(flag);
288 return nullptr != find_longname_def(flag_name);
292 for (
auto p = arg; *++p;)
293 if (
auto const def = find_shortname_def(*p))
306 if (argc_rest < 2 || is_valid_flag(argv_rest+1, argc_rest-1))
THE common namespace of bux library.
void append(const T &src, std::string &dst)
std::string message() const
std::optional< size_t > m_optIndex