1
0
forked from Alepha/Alepha

Modernize some of how program options emits help.

Alepha IOStreams supports adaptors for most of what used to be
temporary string functions.
This commit is contained in:
2024-04-03 14:24:03 -04:00
parent 7410245314
commit 8250680e6c
2 changed files with 37 additions and 30 deletions

View File

@ -7,6 +7,7 @@ static_assert( __cplusplus > 2020'99 );
#include <Alepha/Console.h> #include <Alepha/Console.h>
#include <Alepha/word_wrap.h> #include <Alepha/word_wrap.h>
#include <Alepha/AutoRAII.h>
#include <Alepha/error.h> #include <Alepha/error.h>
#include <Alepha/Utility/StaticValue.h> #include <Alepha/Utility/StaticValue.h>
@ -32,15 +33,6 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
{ {
using std::runtime_error::runtime_error; using std::runtime_error::runtime_error;
}; };
// Print the string with wrapping to the terminal and the specified indent
// for subsequent lines.
void
printString( const std::string &s, const std::size_t indent )
{
const std::size_t width= getConsoleWidth();
std::cout << wordWrap( s, width, indent ) << std::endl;
}
} }
struct impl::ProgramOption struct impl::ProgramOption
@ -202,10 +194,14 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
// Inspect and print each option. // Inspect and print each option.
for( const auto &[ name, def ]: programOptions() ) for( const auto &[ name, def ]: programOptions() )
{ {
std::cout << StartWrap{ width, alignmentWidth }; // When turning off wrapping, here, we also emit a newline between entries.
AutoRAII wrapping
{
[&] { std::cout << StartWrap{ width, alignmentWidth }; },
[] { std::cout << EndWrap << std::endl; }
};
const auto &[ _, helpText, defaultBuilder, domains ]= def; const auto &[ _, helpText, defaultBuilder, domains ]= def;
// How much unused of the max width there will be
const std::size_t padding= alignmentWidth - name.size() - 2;
VariableMap substitutions= VariableMap substitutions=
{ {
@ -221,33 +217,36 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
substitutions[ "canonical-name"s ]= lambaste<=canonicalProgramName.value(); substitutions[ "canonical-name"s ]= lambaste<=canonicalProgramName.value();
} }
std::string substitutionTemplate= name + ": " + std::string( padding, ' ' ) AutoRAII substitution
+ helpText.str() + "\n"; {
[&]{ std::cout << StartSubstitutions{ '!', substitutions }; },
[] { std::cout << EndSubstitutions; }
};
// How much unused of the max width there will be
const std::size_t padding= alignmentWidth - name.size() - 2;
std::cout << name << ": " << std::string( padding, ' ' ) << helpText.str() << '\n';
// Append the incompatibility text, when we see mutually-exclusive options. // Append the incompatibility text, when we see mutually-exclusive options.
substitutionTemplate+= buildIncompatibleHelpText( name, domains, exclusivityMembers ); std::cout << buildIncompatibleHelpText( name, domains, exclusivityMembers );
std::cout << expandVariables( substitutionTemplate, substitutions, '!' );
std::cout << EndWrap;
std::cout << std::endl;
} }
// Check for required options, and print a summary of those: // Check for required options, and print a summary of those:
if( not requiredOptions().empty() ) for( const auto &[ _, group ]: requiredOptions() ) if( not requiredOptions().empty() ) for( const auto &[ _, group ]: requiredOptions() )
{ {
std::ostream &oss= std::cout; std::cout << StartWrap{ width };
oss << StartWrap{ width }; std::cout << "At least one of the options in this group are required: ";
oss << "At least one of the options in this group are required: ";
bool first= true; bool first= true;
for( const auto &required: group ) for( const auto &required: group )
{ {
if( not first ) oss << ", "; if( not first ) std::cout << ", ";
first= false; first= false;
oss << '`' << required << '`'; std::cout << '`' << required << '`';
} }
oss << std::endl; std::cout << std::endl;
} }
} }
} }
@ -289,10 +288,20 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
}; };
if( canonicalName.has_value() ) substitutions[ "canonical-name"s ]= lambaste<=canonicalName.value(); if( canonicalName.has_value() ) substitutions[ "canonical-name"s ]= lambaste<=canonicalName.value();
std::cout << wordWrap( expandVariables( helpMessage, substitutions, '!' ), getConsoleWidth() )
<< std::endl << std::endl;
}
AutoRAII wrapping
{
[] { std::cout << StartWrap{ getConsoleWidth() }; },
[] { std::cout << EndWrap; }
};
AutoRAII substitution
{
[&]{ std::cout << StartSubstitutions{ '!', substitutions }; },
[] { std::cout << EndSubstitutions; }
};
std::cout << helpMessage << std::endl << std::endl;
}
printAllOptionsHelp( canonicalName ); printAllOptionsHelp( canonicalName );
::exit( EXIT_SUCCESS ); ::exit( EXIT_SUCCESS );
} }

View File

@ -327,8 +327,6 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m
} }
}; };
void printString( const std::string &s, const std::size_t indent );
struct OptionString { std::string name; }; struct OptionString { std::string name; };
namespace exports::inline literals namespace exports::inline literals