@@ -288,9 +288,10 @@ class cmdline_processor
288
288
callback0 handler0;
289
289
callback1 handler1;
290
290
std::string synonym;
291
+ bool opt_out;
291
292
292
- flag (int g, std::string_view n, std::string_view d, callback0 h0, callback1 h1, std::string_view s)
293
- : group{g}, name{n}, description{d}, handler0{h0}, handler1{h1}, synonym{s}
293
+ flag (int g, std::string_view n, std::string_view d, callback0 h0, callback1 h1, std::string_view s, bool o )
294
+ : group{g}, name{n}, description{d}, handler0{h0}, handler1{h1}, synonym{s}, opt_out{o}
294
295
{ }
295
296
};
296
297
std::vector<flag> flags;
@@ -341,6 +342,10 @@ class cmdline_processor
341
342
342
343
for (auto & flag : flags) {
343
344
auto length_to_match = std::max (flag.unique_prefix , as<int >(arg->text .length ())-1 );
345
+ if (flag.opt_out && arg->text .ends_with (" -" )) {
346
+ length_to_match = std::max (flag.unique_prefix , as<int >(arg->text .length ())-2 );
347
+ }
348
+
344
349
// Allow a switch to start with either - or /
345
350
if (arg->text .starts_with (" -" + flag.name .substr (0 , length_to_match)) ||
346
351
arg->text .starts_with (" /" + flag.name .substr (0 , length_to_match)) ||
@@ -355,30 +360,28 @@ class cmdline_processor
355
360
flag.handler0 ();
356
361
}
357
362
358
- // Else this is a switch that takes the next arg as its value, so pass that
363
+ // Else
359
364
else {
360
- if (arg+1 == args.end ()) {
361
- print (" Missing argument to option " + arg->text + " (try -help)\n " );
362
- help_requested = true ;
365
+ // If this is a switch that could be suffixed with "-" to opt out
366
+ if (flag.opt_out ) {
367
+ flag.handler1 ( arg->text .ends_with (" -" ) ? " -" : " " );
368
+ }
369
+ // Else this is a switch that takes the next arg as its value, so pass that
370
+ else {
371
+ if (arg+1 == args.end ()) {
372
+ print (" Missing argument to option " + arg->text + " (try -help)\n " );
373
+ help_requested = true ;
374
+ }
375
+ arg->pos = processed;
376
+ ++arg; // move to next argument, which is the argument to this switch
377
+ flag.handler1 (arg->text );
363
378
}
364
- arg->pos = processed;
365
- ++arg; // move to next argument, which is the argument to this switch
366
- flag.handler1 (arg->text );
367
379
}
368
380
369
381
arg->pos = processed;
370
382
break ;
371
383
}
372
384
}
373
-
374
- // For now comment this out to try leaving unmatched switches alone, so that
375
- // Unix absolute filenames work... and in case an absolute filename collides
376
- // with a legit switch name, also added "--" above... let's see how this works
377
- // if (arg->pos != processed && (arg->text.starts_with("-") || arg->text.starts_with("/"))) {
378
- // arg->pos = processed;
379
- // print("Unknown option: " + arg->text + " (try -help)\n");
380
- // help_requested = true;
381
- // }
382
385
}
383
386
384
387
std::erase_if ( args, [=](auto & arg){ return arg.pos == processed; } );
@@ -408,6 +411,9 @@ class cmdline_processor
408
411
n += flag.name .substr (flag.unique_prefix );
409
412
n += " ]" ;
410
413
}
414
+ if (flag.opt_out ) {
415
+ n += " [-]" ;
416
+ }
411
417
if (!flag.synonym .empty ()) {
412
418
n += " , -" + flag.synonym ;
413
419
}
@@ -417,14 +423,16 @@ class cmdline_processor
417
423
}
418
424
}
419
425
420
- auto add_flag (int group, std::string_view name, std::string_view description, callback0 handler0, callback1 handler1, std::string_view synonym) {
421
- flags.emplace_back ( group, name, description, handler0, handler1, synonym );
422
- if (max_flag_length < std::ssize (name)) {
423
- max_flag_length = std::ssize (name);
426
+ auto add_flag (int group, std::string_view name, std::string_view description, callback0 handler0, callback1 handler1, std::string_view synonym, bool opt_out) {
427
+ flags.emplace_back ( group, name, description, handler0, handler1, synonym, opt_out );
428
+ auto length = std::ssize (name);
429
+ if (opt_out) { length += 3 ; } // space to print "[-]"
430
+ if (max_flag_length < length) {
431
+ max_flag_length = length;
424
432
}
425
433
}
426
434
struct register_flag {
427
- register_flag (int group, std::string_view name, std::string_view description, callback0 handler0, callback1 handler1 = nullptr , std::string_view synonym = {});
435
+ register_flag (int group, std::string_view name, std::string_view description, callback0 handler0, callback1 handler1 = nullptr , std::string_view synonym = {}, bool opt_out = false );
428
436
};
429
437
430
438
auto set_args (int argc, char * argv[]) -> void {
@@ -457,8 +465,16 @@ class cmdline_processor
457
465
458
466
} cmdline;
459
467
460
- cmdline_processor::register_flag::register_flag (int group, std::string_view name, std::string_view description, callback0 handler0, callback1 handler1, std::string_view synonym) {
461
- cmdline.add_flag ( group, name, description, handler0, handler1, synonym );
468
+ cmdline_processor::register_flag::register_flag (
469
+ int group,
470
+ std::string_view name,
471
+ std::string_view description,
472
+ callback0 handler0,
473
+ callback1 handler1,
474
+ std::string_view synonym,
475
+ bool opt_out
476
+ ) {
477
+ cmdline.add_flag ( group, name, description, handler0, handler1, synonym, opt_out );
462
478
}
463
479
464
480
static cmdline_processor::register_flag cmd_help (
0 commit comments