forked from Alepha/Alepha
Initial draft of how short options work.
I went with expansion here, as it was easier to implement, given the complexities of how the options parsing code works. Rather than try to maintain state machines and parsing for both forms of argument, we can transform the short options into the long form options. This, then, might lead to some issues when the code is expanded to handle arguments to those options. I'll probably just add a state tracking bit to that parameter to say that it was expanded from a specific short form. It might be worth it to permit a short form to expand to a long form _with_ specific hardcoded option. This gets into defaults, which might be the better way to underpin that. For expanding these into the automatic help documentation, the Long options (the main option definition struct) should maintain a list of the short forms that it supports. I also need to add a neat syntax. Something like: ``` -'o'_option <= --"long-option"_option ``` It might be beneficial to auto generate something like: ``` -'O'_option <= --"no-long-option"_option ``` for boolean toggles. Should it always be so? Maybe an extra sigil to allow both?
This commit is contained in:
@ -142,6 +142,9 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
|
||||
|
||||
namespace exports
|
||||
{
|
||||
enum class ArgumentStance { None, Required };
|
||||
using ShortAliases= std::map< char, std::string >;
|
||||
|
||||
/*!
|
||||
* This is used to build groups of mutually exclusive options.
|
||||
*
|
||||
@ -199,7 +202,7 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
|
||||
const auto &self() const { return *this; }
|
||||
|
||||
using option_handler= std::function< void ( std::optional< std::string > ) >;
|
||||
[[nodiscard]] std::ostream ®isterHandler( option_handler handler ) const;
|
||||
[[nodiscard]] std::ostream ®isterHandler( option_handler handler, ArgumentStance argumentStance ) const;
|
||||
|
||||
void setDefaultBuilder( std::function< std::string () > ) const;
|
||||
|
||||
@ -311,7 +314,7 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
|
||||
};
|
||||
handler( parsed );
|
||||
};
|
||||
return registerHandler( wrapped );
|
||||
return registerHandler( wrapped, ArgumentStance::Required );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -322,7 +325,7 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
|
||||
const auto value= argumentFromString< arg_type >( argument.value(), name, name + "=" + argument.value() );
|
||||
return handler( value );
|
||||
};
|
||||
return registerHandler( wrapped );
|
||||
return registerHandler( wrapped, ArgumentStance::Required );
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -348,7 +351,7 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
|
||||
namespace impl
|
||||
{
|
||||
[[noreturn]] void usage( const std::string &, const std::optional< std::string > & );
|
||||
[[nodiscard]] std::vector< std::string > handleOptions( const std::vector< std::string > &, std::function< void () > );
|
||||
[[nodiscard]] std::vector< std::string > handleOptions( const std::vector< std::string > &, std::function< void () >, const ShortAliases &shortAliases );
|
||||
}
|
||||
|
||||
template< typename Supplement >
|
||||
@ -364,28 +367,28 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
|
||||
|
||||
template< typename Supplement >
|
||||
auto
|
||||
handleOptions( const std::vector< std::string > &args )
|
||||
handleOptions( const std::vector< std::string > &args, const ShortAliases &shortAliases= {} )
|
||||
{
|
||||
return impl::handleOptions( args, usageWrap< Supplement > );
|
||||
return impl::handleOptions( args, usageWrap< Supplement >, shortAliases );
|
||||
}
|
||||
|
||||
template< typename Supplement >
|
||||
auto
|
||||
handleOptions( const int argcnt, const char *const *const argvec )
|
||||
handleOptions( const int argcnt, const char *const *const argvec, const ShortAliases &shortAliases= {} )
|
||||
{
|
||||
return handleOptions< Supplement >( { argvec + 1, argvec + argcnt } );
|
||||
return handleOptions< Supplement >( { argvec + 1, argvec + argcnt }, shortAliases );
|
||||
}
|
||||
|
||||
inline auto
|
||||
handleOptions( const std::vector< std::string > &args )
|
||||
handleOptions( const std::vector< std::string > &args, const ShortAliases &shortAliases= {} )
|
||||
{
|
||||
return handleOptions< ProgramDescription >( args );
|
||||
return handleOptions< ProgramDescription >( args, shortAliases );
|
||||
}
|
||||
|
||||
inline auto
|
||||
handleOptions( const int argcnt, const char *const *const argvec )
|
||||
handleOptions( const int argcnt, const char *const *const argvec, const ShortAliases &shortAliases= {} )
|
||||
{
|
||||
return handleOptions< ProgramDescription >( argcnt, argvec );
|
||||
return handleOptions< ProgramDescription >( argcnt, argvec, shortAliases );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user