示例#1
0
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;
}