diff --git a/ProgramOptions.cc b/ProgramOptions.cc index 0250b6c..6c6d759 100644 --- a/ProgramOptions.cc +++ b/ProgramOptions.cc @@ -7,6 +7,7 @@ static_assert( __cplusplus > 2020'99 ); #include #include +#include #include #include @@ -32,15 +33,6 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m { 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 @@ -202,10 +194,14 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m // Inspect and print each option. 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; - // How much unused of the max width there will be - const std::size_t padding= alignmentWidth - name.size() - 2; VariableMap substitutions= { @@ -221,33 +217,36 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m substitutions[ "canonical-name"s ]= lambaste<=canonicalProgramName.value(); } - std::string substitutionTemplate= name + ": " + std::string( padding, ' ' ) - + helpText.str() + "\n"; + AutoRAII substitution + { + [&]{ 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. - substitutionTemplate+= buildIncompatibleHelpText( name, domains, exclusivityMembers ); - - std::cout << expandVariables( substitutionTemplate, substitutions, '!' ); - std::cout << EndWrap; - std::cout << std::endl; + std::cout << buildIncompatibleHelpText( name, domains, exclusivityMembers ); } // Check for required options, and print a summary of those: if( not requiredOptions().empty() ) for( const auto &[ _, group ]: requiredOptions() ) { - std::ostream &oss= std::cout; - oss << StartWrap{ width }; - oss << "At least one of the options in this group are required: "; + std::cout << StartWrap{ width }; + std::cout << "At least one of the options in this group are required: "; bool first= true; for( const auto &required: group ) { - if( not first ) oss << ", "; + if( not first ) std::cout << ", "; 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(); - 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 ); ::exit( EXIT_SUCCESS ); } diff --git a/ProgramOptions.h b/ProgramOptions.h index 1b51ced..2e4a459 100644 --- a/ProgramOptions.h +++ b/ProgramOptions.h @@ -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; }; namespace exports::inline literals