Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
LUPI::ArgumentParser Class Reference

#include <LUPI.hpp>

Public Member Functions

 ArgumentParser (std::string const &a_codeName, std::string const &a_descriptor="")
 ~ArgumentParser ()
std::string const & codeName () const
std::string const & descriptor () const
template<typename T>
T * add (std::string const &a_name, std::string const &a_descriptor, int a_minimumNeeded=1, int a_maximumNeeded=1)
ArgumentBaseadd (ArgumentType a_argumentType, std::string const &a_name, std::string const &a_descriptor, int a_minimumNeeded=-2, int a_maximumNeeded=-2)
void addAlias (std::string const &a_name, std::string const &a_alias)
void addAlias (ArgumentBase const *const a_argumentBase, std::string const &a_alias)
bool hasName (std::string const &a_name) const
bool isOptionalArgument (std::string const &a_name) const
void parse (int a_argc, char **a_argv, bool a_printArguments=true)
template<typename T>
T * get (std::size_t a_name)
void help () const
void usage () const
virtual void printStatus (std::string a_indent) const

Detailed Description

The main argument parser class.

Definition at line 132 of file LUPI.hpp.

Constructor & Destructor Documentation

◆ ArgumentParser()

LUPI::ArgumentParser::ArgumentParser ( std::string const & a_codeName,
std::string const & a_descriptor = "" )

ArgumentParser constructor.

Definition at line 455 of file LUPI_argumentParser.cc.

455 :
456 m_codeName( FileInfo::basenameWithoutExtension( a_codeName ) ),
457 m_descriptor( a_descriptor ) {
458
459}
std::string basenameWithoutExtension(std::string const &a_path)
Definition LUPI_file.cc:99

◆ ~ArgumentParser()

LUPI::ArgumentParser::~ArgumentParser ( )

ArgumentParser destructor.

Definition at line 465 of file LUPI_argumentParser.cc.

465 {
466
467 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
468 delete *argumentIterator;
469 }
470}

Member Function Documentation

◆ add() [1/2]

ArgumentBase * LUPI::ArgumentParser::add ( ArgumentType a_argumentType,
std::string const & a_name,
std::string const & a_descriptor,
int a_minimumNeeded = -2,
int a_maximumNeeded = -2 )

Creates an argument instance of type specified by a_argumentType and adds to this.

Parameters
a_argumentType[in] The type of argument to create.
a_name[in] The name of the argument.
a_descriptor[in] The string printed with arugment's help.
a_minimumNeeded[in] The minimum number of times the argument must be entered.
a_maximumNeeded[in] The maximum number of times the argument can be entered.
Returns
Returns a pointer to to the created argument instance.

Definition at line 508 of file LUPI_argumentParser.cc.

509 {
510
511 ArgumentBase *argument = nullptr;
512
513 switch( a_argumentType ) {
514 case ArgumentType::True :
515 argument = new OptionTrue( a_name, a_descriptor );
516 break;
518 argument = new OptionFalse( a_name, a_descriptor );
519 break;
521 argument = new OptionCounter( a_name, a_descriptor );
522 break;
524 argument = new OptionStore( a_name, a_descriptor );
525 break;
527 argument = new OptionAppend( a_name, a_descriptor, a_minimumNeeded, a_maximumNeeded );
528 break;
529 default :
530 argument = new Positional( a_name, a_descriptor, a_minimumNeeded, a_maximumNeeded );
531 }
532
533 add2( argument );
534
535 return( argument );
536}

◆ add() [2/2]

template<typename T>
T * LUPI::ArgumentParser::add ( std::string const & a_name,
std::string const & a_descriptor,
int a_minimumNeeded = 1,
int a_maximumNeeded = 1 )

Creates a new argument, adds the argument to this and returns a pointer the the newly created argument.

Parameters
a_name[in] The name of the argument.
a_descriptor[in] The argument's description, displayed when the help option is enetered.
a_minimumNeeded[in] The minimum number of required time this argument must be entered.
a_maximumNeeded[in] The maximum number of required time this argument must be entered.
Returns
A pointer to the created argument.

Definition at line 172 of file LUPI.hpp.

172 {
173
174 T *argument = new T( a_name, a_descriptor, a_minimumNeeded, a_maximumNeeded );
175 add2( argument );
176
177 return( argument );
178}

◆ addAlias() [1/2]

void LUPI::ArgumentParser::addAlias ( ArgumentBase const *const a_argumentBase,
std::string const & a_alias )

Adds the alias a_alias to the argument a_argumentBase.

Parameters
a_argumentBase[in] The argument to add the alias to.
a_alias[in] The name of the argument to add the alias to.

Definition at line 566 of file LUPI_argumentParser.cc.

566 {
567
568 addAlias( a_argumentBase->name( ), a_alias );
569}
void addAlias(std::string const &a_name, std::string const &a_alias)

◆ addAlias() [2/2]

void LUPI::ArgumentParser::addAlias ( std::string const & a_name,
std::string const & a_alias )

Adds the alias a_alias to the argument named a_name.

Parameters
a_name[in] The name of the argument to add the alias to.
a_alias[in] The alias name to add.

Definition at line 545 of file LUPI_argumentParser.cc.

545 {
546
547 if( hasName( a_alias ) )
548 throw std::runtime_error( "ERROR 1510 in ArgumentParser::addAlias: name '" + a_alias + "' already present." );
549
550 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
551 if( (*argumentIterator)->hasName( a_name ) ) {
552 (*argumentIterator)->addAlias( a_alias );
553 return;
554 }
555 }
556 throw std::runtime_error( "ERROR 1520 in ArgumentParser::addAlias: no such argument named '" + a_name + "'." );
557}
bool hasName(std::string const &a_name) const

Referenced by addAlias().

◆ codeName()

std::string const & LUPI::ArgumentParser::codeName ( ) const
inline

Definition at line 145 of file LUPI.hpp.

145{ return( m_codeName ); }

Referenced by usage().

◆ descriptor()

std::string const & LUPI::ArgumentParser::descriptor ( ) const
inline

Definition at line 146 of file LUPI.hpp.

146{ return( m_descriptor ); }

◆ get()

template<typename T>
T * LUPI::ArgumentParser::get ( std::size_t a_name)

◆ hasName()

bool LUPI::ArgumentParser::hasName ( std::string const & a_name) const

Returns true if name a_name is in this and false otherwise.

Parameters
a_name[in] The name to see check if it exists in this.
Returns
true if name a_name is in this and false otherwise.

Definition at line 596 of file LUPI_argumentParser.cc.

596 {
597
598 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
599 if( (*argumentIterator)->hasName( a_name ) ) return( true );
600 }
601
602 return( false );
603}

Referenced by addAlias().

◆ help()

void LUPI::ArgumentParser::help ( ) const

Prints the help for this.

Definition at line 672 of file LUPI_argumentParser.cc.

672 {
673
674 usage( );
675
676 if( m_descriptor != "" ) {
677 std::cout << std::endl << "Description:" << std::endl;
678 std::cout << " " << m_descriptor << std::endl;
679 }
680
681 bool printHeader = true;
682 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
683 if( (*argumentIterator)->isOptionalArgument( ) ) continue;
684
685 if( printHeader ) std::cout << std::endl << "positional arguments:" << std::endl;
686 printHeader = false;
687
688 std::string line = (*argumentIterator)->name( );
689 if( ( (*argumentIterator)->minimumNeeded( ) != (*argumentIterator)->maximumNeeded( ) ) || ( (*argumentIterator)->maximumNeeded( ) != 1 ) )
690 line += " [" + std::to_string( (*argumentIterator)->minimumNeeded( ) ) + "," + std::to_string( (*argumentIterator)->maximumNeeded( ) ) + "]";
691 printArgumentDescription( line, (*argumentIterator)->descriptor( ) );
692 }
693
694 std::cout << std::endl << "optional arguments:" << std::endl;
695 std::cout << " -h, --help Show this help message and exit." << std::endl;
696 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
697 if( !(*argumentIterator)->isOptionalArgument( ) ) continue;
698
699 std::string line;
700 std::string sep;
701 for( auto namesIterator = (*argumentIterator)->names( ).begin( ); namesIterator != (*argumentIterator)->names( ).end( ); ++namesIterator ) {
702 line += sep + *namesIterator;
703 sep = ", ";
704 }
705 if( (*argumentIterator)->requiresAValue( ) ) line += " VALUE";
706 if( (*argumentIterator)->argumentType( ) == ArgumentType::Append ) {
707 if( ( (*argumentIterator)->minimumNeeded( ) != (*argumentIterator)->maximumNeeded( ) ) || ( (*argumentIterator)->maximumNeeded( ) != 1 ) )
708 line += " [" + std::to_string( (*argumentIterator)->minimumNeeded( ) ) + "," + std::to_string( (*argumentIterator)->maximumNeeded( ) ) + "]";
709 }
710 printArgumentDescription( line, (*argumentIterator)->descriptor( ) );
711 }
712
713 exit( EXIT_SUCCESS );
714}
std::string to_string(G4FermiAtomicMass mass)

Referenced by parse().

◆ isOptionalArgument()

bool LUPI::ArgumentParser::isOptionalArgument ( std::string const & a_name) const

Returns true if name a_name is an optional argument of this and false otherwise.

Parameters
a_name[in] The name to see check if it exists in this.
Returns
true if name a_name is in this and false otherwise.

Definition at line 579 of file LUPI_argumentParser.cc.

579 {
580
581 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
582 if( (*argumentIterator)->hasName( a_name ) ) return( (*argumentIterator)->argumentType( ) != ArgumentType::Positional );
583 }
584
585 return( false );
586}

Referenced by LUPI::ArgumentBase::parse().

◆ parse()

void LUPI::ArgumentParser::parse ( int a_argc,
char ** a_argv,
bool a_printArguments = true )

Parses the list of arguments.

Parameters
a_argc[in] The number of arguments.
a_argv[in] The list of arguments.

Definition at line 612 of file LUPI_argumentParser.cc.

612 {
613
614 for( int iargc = 1; iargc < a_argc; ++iargc ) { // Check is help requested.
615 std::string arg( a_argv[iargc] );
616
617 if( ( arg == "-h" ) || ( arg == "--help" ) ) help( );
618 }
619
620 auto argumentIterator = m_arguments.begin( ); // Find first non-option argument.
621 for( ; argumentIterator != m_arguments.end( ); ++argumentIterator ) {
622 if( !(*argumentIterator)->isOptionalArgument( ) ) break;
623 }
624
625 int iargc = 1;
626 for( ; iargc < a_argc; ) {
627 std::string arg( a_argv[iargc] );
628
629 if( arg[0] == '-' ) { // Need to check if negative number.
630 auto argumentIterator2 = m_arguments.begin( );
631 for( ; argumentIterator2 != m_arguments.end( ); ++argumentIterator2 ) {
632 if( (*argumentIterator2)->hasName( arg ) ) break;
633 }
634 if( argumentIterator2 == m_arguments.end( ) ) throw std::runtime_error( "ERROR 1600 in ArgumentParser::parse: invalid option '" + arg + "'." );
635 iargc = (*argumentIterator2)->parse( *this, iargc, a_argc, a_argv ); }
636 else {
637 if( argumentIterator == m_arguments.end( ) )
638 throw std::runtime_error( "ERROR 1610 in ArgumentParser::parse: additional positional argument found starting at index "
639 + std::to_string( iargc ) + " (" + arg + ")" );
640
641 iargc = (*argumentIterator)->parse( *this, iargc, a_argc, a_argv );
642
643 ++argumentIterator;
644 for( ; argumentIterator != m_arguments.end( ); ++argumentIterator ) { // Find next positional arguments.
645 if( !(*argumentIterator)->isOptionalArgument( ) ) break;
646 }
647 }
648 }
649 for( auto argumentIterator2 = m_arguments.begin( ); argumentIterator2 != m_arguments.end( ); ++argumentIterator2 ) {
650 if( static_cast<int>( (*argumentIterator2)->counts( ) ) < (*argumentIterator2)->minimumNeeded( ) ) {
651 std::string msg( "arguments for" );
652
653 if( (*argumentIterator2)->isOptionalArgument( ) ) msg = "number of option";
654 throw std::runtime_error( "ERROR 1620 in ArgumentParser::parse: insufficient " + msg + " '" + (*argumentIterator2)->name( )
655 + "' entered. Range of " + std::to_string( (*argumentIterator2)->minimumNeeded( ) ) + " to "
656 + std::to_string( (*argumentIterator2)->maximumNeeded( ) ) + " required, "
657 + std::to_string( (*argumentIterator2)->counts( ) ) + " entered." );
658 }
659 }
660
661 if( a_printArguments ) {
662 std::cerr << " " << LUPI::FileInfo::basenameWithoutExtension( m_codeName );
663 for( int i1 = 1; i1 < a_argc; i1++ ) std::cerr << " " << a_argv[i1];
664 std::cerr << std::endl;
665 }
666}

◆ printStatus()

void LUPI::ArgumentParser::printStatus ( std::string a_indent) const
virtual

Returns the usage string for this option.

Parameters
a_indent[in] The amount of indentation to start the first line with.
Returns
The value of a_index + 1.

Definition at line 763 of file LUPI_argumentParser.cc.

763 {
764
765 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
766 (*argumentIterator)->printStatus( a_indent );
767 }
768}

◆ usage()

void LUPI::ArgumentParser::usage ( ) const

Prints the usage for this.

Definition at line 720 of file LUPI_argumentParser.cc.

720 {
721
722 std::string line( "usage: " );
723 line += codeName( );
724 std::string indent( "" );
725 indent.resize( line.size( ), ' ' );
726
727 for( int counter = 0; counter < 2; ++counter ) {
728 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
729 if( (*argumentIterator)->isOptionalArgument( ) ) {
730 std::string optionUsage( (*argumentIterator)->usage( counter == 0 ) );
731
732 if( ( line.size( ) + optionUsage.size( ) ) > maxPrintLineWidth ) {
733 std::cout << line << std::endl;
734 line = indent;
735 }
736 line += optionUsage;
737 }
738 }
739 }
740
741 for( auto argumentIterator = m_arguments.begin( ); argumentIterator != m_arguments.end( ); ++argumentIterator ) {
742 if( (*argumentIterator)->isOptionalArgument( ) ) continue;
743 std::string optionUsage( (*argumentIterator)->usage( false ) );
744
745 if( ( line.size( ) + optionUsage.size( ) ) > maxPrintLineWidth ) {
746 std::cout << line << std::endl;
747 line = indent;
748 }
749 line += optionUsage;
750 }
751 if( line.size( ) > indent.size( ) ) std::cout << line << std::endl;
752 std::cout << std::endl;
753}
std::string const & codeName() const
Definition LUPI.hpp:145

Referenced by help().


The documentation for this class was generated from the following files: