LineParser &LineParser::parse( int argn, char *const *argv ) { int val, arg, diff; Mixed optional; const option_s *begin = &(*this->lp_data.pd_options.begin()); while( (val = getopt_long(argn, argv, this->lp_data.pd_optstring.c_str(), begin, NULL)) != EOF ) { if( val == 'h' ) { this->lp_data.pd_progname.assign( argv[0] ); throw ShowHelp( this->lp_data ); } else if( val == '?' ) { this->lp_data.pd_progname.assign( argv[0] ); throw InvalidOption( this->lp_data, optopt ); } else if( this->lp_data.pd_argmap.count(val) != 0 ) { switch( this->lp_data.pd_argmap[val] ) { case no_argument: this->lp_map.insert( map<char, Mixed>::value_type((char) val, Mixed(true)) ); break; case required_argument: this->lp_map.insert( map<char, Mixed>::value_type((char) val, Mixed(optarg)) ); break; case optional_argument: default: if( optarg == NULL ) { if( (optind < argn) && (argv[optind][0] != '-') ) { optional.setStringValue( argv[optind] ); optind += 1; } else optional.setLogicalValue( true ); } else optional.setStringValue( optarg ); this->lp_map.insert( map<char, Mixed>::value_type((char) val, optional) ); break; } } } diff = argn - optind; if( (((this->lp_data.pd_paramnumber == (int) ParserData::one_or_more) && (diff > 0)) || ((this->lp_data.pd_paramnumber == (int) ParserData::zero_or_more) && (diff >= 0)) || ((this->lp_data.pd_paramnumber >= 0) && (diff == this->lp_data.pd_paramnumber))) ) { for( arg = optind; arg < argn; arg++ ) this->lp_arguments.push_back( argv[arg] ); } else { this->lp_data.pd_progname.assign( argv[0] ); throw InvalidArgNumber( this->lp_data, diff ); } return *this; }