30#include "app/optionparser/optionparser.h"
35int Option::type()
const
37 return desc == 0 ? 0 : desc->type;
40int Option::index()
const
42 return desc == 0 ? -1 : (int)desc->index;
47 int c = ( desc == 0 ? 0 : 1 );
57bool Option::isFirst()
const
59 return isTagged( prev_ );
62bool Option::isLast()
const
64 return isTagged( next_ );
67Option *Option::first()
70 while( !p->isFirst() )
77 return first()->prevwrap();
82 return isFirst() ? 0 : prev_;
85Option *Option::prevwrap()
87 return untag( prev_ );
92 return isLast() ? 0 : next_;
95const Option *Option::next()
const
97 return isLast() ? 0 : next_;
100Option *Option::nextwrap()
102 return untag( next_ );
105void Option::append( Option *new_last )
111 new_last->next_ = tag( f );
112 f->prev_ = tag( new_last );
115Option::Option() : desc( 0 ), name( 0 ), arg( 0 ), namelen( 0 )
121Option::Option(
const Descriptor *desc_,
const char *name_,
const char *arg_ )
123 init( desc_, name_, arg_ );
126void Option::operator=(
const Option &orig )
128 init( orig.desc, orig.name, orig.arg );
131Option::Option(
const Option &orig )
133 init( orig.desc, orig.name, orig.arg );
136void Option::init(
const Descriptor *desc_,
const char *name_,
const char *arg_ )
149 while( name[namelen] != 0 && name[namelen] !=
'=' )
153Option *Option::tag( Option *ptr )
155 return (Option *)( (
unsigned long long)ptr | 1 );
158Option *Option::untag( Option *ptr )
160 return (Option *)( (
unsigned long long)ptr & ~1ull );
163bool Option::isTagged( Option *ptr )
165 return ( (
unsigned long long)ptr & 1 );
168Stats::Stats() : buffer_max( 1 ), options_max( 1 )
173 bool gnu,
const Descriptor usage[],
int argc,
const char **argv,
int min_abbr_len,
bool single_minus_longopt )
174 : buffer_max( 1 ), options_max( 1 )
176 add( gnu, usage, argc, argv, min_abbr_len, single_minus_longopt );
179Stats::Stats(
bool gnu,
const Descriptor usage[],
int argc,
char **argv,
int min_abbr_len,
bool single_minus_longopt )
180 : buffer_max( 1 ), options_max( 1 )
182 add( gnu, usage, argc, (
const char **)argv, min_abbr_len, single_minus_longopt );
185Stats::Stats(
const Descriptor usage[],
int argc,
const char **argv,
int min_abbr_len,
bool single_minus_longopt )
186 : buffer_max( 1 ), options_max( 1 )
188 add(
false, usage, argc, argv, min_abbr_len, single_minus_longopt );
191Stats::Stats(
const Descriptor usage[],
int argc,
char **argv,
int min_abbr_len,
bool single_minus_longopt )
192 : buffer_max( 1 ), options_max( 1 )
194 add(
false, usage, argc, (
const char **)argv, min_abbr_len, single_minus_longopt );
198 bool gnu,
const Descriptor usage[],
int argc,
const char **argv,
int min_abbr_len,
bool single_minus_longopt )
202 while( usage[i].shortopt != 0 )
204 if( usage[i].index + 1 >= options_max )
205 options_max = ( usage[i].index + 1 ) + 1;
210 CountOptionsAction action( &buffer_max );
211 Parser::workhorse( gnu, usage, argc, argv, action, single_minus_longopt,
false, min_abbr_len );
215 bool gnu,
const Descriptor usage[],
int argc,
char **argv,
int min_abbr_len,
bool single_minus_longopt )
217 add( gnu, usage, argc, (
const char **)argv, min_abbr_len, single_minus_longopt );
220void Stats::add(
const Descriptor usage[],
int argc,
const char **argv,
int min_abbr_len,
bool single_minus_longopt )
222 add(
false, usage, argc, argv, min_abbr_len, single_minus_longopt );
225void Stats::add(
const Descriptor usage[],
int argc,
char **argv,
int min_abbr_len,
bool single_minus_longopt )
227 add(
false, usage, argc, (
const char **)argv, min_abbr_len, single_minus_longopt );
230void Parser::parse(
bool gnu,
231 const Descriptor usage[],
237 bool single_minus_longopt,
240 StoreOptionAction action( *
this, options, buffer, bufmax );
241 err = !workhorse( gnu, usage, argc, argv, action, single_minus_longopt,
true, min_abbr_len );
244bool Parser::workhorse(
bool gnu,
245 const Descriptor usage[],
249 bool single_minus_longopt,
259 while( numargs != 0 && *args != 0 )
261 const char *param = *args;
265 if( param[0] !=
'-' || param[1] == 0 )
280 if( param[1] ==
'-' && param[2] == 0 )
282 shift( args, nonops );
289 bool handle_short_options;
290 const char *longopt_name;
291 if( param[1] ==
'-' )
293 handle_short_options =
false;
294 longopt_name = param + 2;
298 handle_short_options =
true;
299 longopt_name = param + 1;
302 bool try_single_minus_longopt = single_minus_longopt;
303 bool have_more_args = ( numargs > 1 || numargs < 0 );
309 const char *optarg = 0;
312 if( handle_short_options ==
false || try_single_minus_longopt )
315 while( usage[idx].longopt != 0 && !streq( usage[idx].longopt, longopt_name ) )
318 if( usage[idx].longopt == 0 && min_abbr_len > 0 )
321 while( usage[i1].longopt != 0 && !streqabbr( usage[i1].longopt, longopt_name, min_abbr_len ) )
323 if( usage[i1].longopt != 0 )
326 while( usage[i2].longopt != 0 && !streqabbr( usage[i2].longopt, longopt_name, min_abbr_len ) )
329 if( usage[i2].longopt ==
336 if( usage[idx].longopt != 0 )
337 handle_short_options =
false;
339 try_single_minus_longopt =
false;
341 optarg = longopt_name;
342 while( *optarg != 0 && *optarg !=
'=' )
348 optarg = ( have_more_args ? args[1] : 0 );
352 if( handle_short_options )
358 while( usage[idx].shortopt != 0 && !instr( *param, usage[idx].shortopt ) )
362 optarg = ( have_more_args ? args[1] : 0 );
368 const Descriptor *descriptor = &usage[idx];
370 if( descriptor->shortopt == 0 )
374 while( usage[idx].shortopt != 0 && ( usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0 ) )
376 descriptor = ( usage[idx].shortopt == 0 ? 0 : &usage[idx] );
379 if( descriptor != 0 )
381 Option option( descriptor, param, optarg );
382 switch( descriptor->check_arg( option, print_errors ) )
388 if( optarg != 0 && have_more_args && optarg == args[1] )
390 shift( args, nonops );
397 handle_short_options =
false;
406 if( !action.perform( option ) )
410 }
while( handle_short_options );
412 shift( args, nonops );
419 if( numargs > 0 && *args == 0 )
425 while( args[numargs] != 0 )
429 return action.finished( numargs + nonops, args - nonops );
constexpr units::realT c()
The speed of light.