| 235 | | this( |
|---|
| 236 | | char[][] shorts, char[][] longs, ArgType type, |
|---|
| 237 | | Action act, char[] name, char[] const_value, |
|---|
| 238 | | OptionCallbackArg dga, OptionCallback dg, |
|---|
| 239 | | OptionCallbackInt dgi, |
|---|
| 240 | | OptionCallbackFancyArg fdga, |
|---|
| 241 | | OptionCallbackFancyInt fdgi, |
|---|
| 242 | | OptionCallbackFancy fdg |
|---|
| 243 | | ) { |
|---|
| 244 | | this.shortopts = shorts; |
|---|
| 245 | | this.longopts = longs; |
|---|
| 246 | | this.action = act; |
|---|
| 247 | | this.type = type; |
|---|
| 248 | | this.name = name; |
|---|
| 249 | | this.argname = toupper(name.dup); |
|---|
| 250 | | this.default_string = ""; |
|---|
| 251 | | this.default_value = 0; |
|---|
| 252 | | this.default_flag = false; |
|---|
| 253 | | |
|---|
| 254 | | // Perform sanity checks. |
|---|
| 255 | | assert (name !is null); |
|---|
| 256 | | switch (act) { |
|---|
| 257 | | case Action.Store, Action.Append: |
|---|
| 258 | | assert(type != ArgType.None); |
|---|
| 259 | | break; |
|---|
| 260 | | case Action.StoreConst, Action.AppendConst: |
|---|
| 261 | | assert(type == ArgType.None); |
|---|
| 262 | | assert(const_value !is null); |
|---|
| 263 | | break; |
|---|
| 264 | | case Action.Callback: |
|---|
| 265 | | //assert(type != ArgType.None); |
|---|
| 266 | | switch (type) { |
|---|
| 267 | | case ArgType.String: |
|---|
| 268 | | assert(dga !is null); |
|---|
| 269 | | break; |
|---|
| 270 | | case ArgType.Integer: |
|---|
| 271 | | assert(dgi !is null); |
|---|
| 272 | | break; |
|---|
| 273 | | case ArgType.None: |
|---|
| 274 | | assert(dg !is null); |
|---|
| 275 | | break; |
|---|
| 276 | | default: |
|---|
| 277 | | break; |
|---|
| 278 | | } |
|---|
| 279 | | break; |
|---|
| 280 | | case Action.CallbackFancy: |
|---|
| 281 | | switch (type) { |
|---|
| 282 | | case ArgType.String: |
|---|
| 283 | | assert(fdga !is null); |
|---|
| 284 | | break; |
|---|
| 285 | | case ArgType.Integer: |
|---|
| 286 | | assert(fdgi !is null); |
|---|
| 287 | | break; |
|---|
| 288 | | case ArgType.None: |
|---|
| 289 | | assert(fdg !is null); |
|---|
| 290 | | break; |
|---|
| 291 | | default: |
|---|
| 292 | | break; |
|---|
| 293 | | } |
|---|
| 294 | | default: |
|---|
| 295 | | break; |
|---|
| 296 | | } |
|---|
| 297 | | this.const_value = const_value; |
|---|
| 298 | | this.callback = dga; |
|---|
| 299 | | this.int_callback = dgi; |
|---|
| 300 | | this.void_callback = dg; |
|---|
| 301 | | this.fancy_callback = fdga; |
|---|
| 302 | | this.fancy_int_callback = fdgi; |
|---|
| 303 | | this.fancy_void_callback = fdg; |
|---|
| | 222 | this(char[][] options, char[] name) { |
|---|
| | 223 | dchar[] opt; |
|---|
| | 224 | foreach (_opt; options) { |
|---|
| | 225 | // (Unicode note: We convert to dchar[] so the length checks work |
|---|
| | 226 | // out in the event of a short opt with a >127 character.) |
|---|
| | 227 | opt = toUTF32(_opt); |
|---|
| | 228 | if (opt.length < 2) { |
|---|
| | 229 | throw new OptionError( |
|---|
| | 230 | "invalid option string '" ~ _opt ~ "': must be at least two characters long" |
|---|
| | 231 | ); |
|---|
| | 232 | } else if (opt.length > 2) { |
|---|
| | 233 | if (opt[0 .. 2] != "--" || opt[2] == '-') |
|---|
| | 234 | throw new OptionError( |
|---|
| | 235 | "invalid long option string '" ~ _opt ~ "': must start with --, followed by non-dash" |
|---|
| | 236 | ); |
|---|
| | 237 | longopts ~= _opt; |
|---|
| | 238 | } else { |
|---|
| | 239 | if (opt[0] != '-' || opt[1] == '-') |
|---|
| | 240 | throw new OptionError( |
|---|
| | 241 | "invalid short option string '" ~ _opt ~ "': must be of the form -x, where x is non-dash" |
|---|
| | 242 | ); |
|---|
| | 243 | shortopts ~= _opt; |
|---|
| | 244 | } |
|---|
| | 245 | } |
|---|
| | 246 | if (name is null) { |
|---|
| | 247 | // (Unicode note: We know '-' is a single code unit, so these |
|---|
| | 248 | // slices are okay.) |
|---|
| | 249 | if (longopts.length > 0) |
|---|
| | 250 | this.name = longopts[0][2 .. $]; |
|---|
| | 251 | else if (shortopts.length > 0) |
|---|
| | 252 | this.name = shortopts[0][1 .. 2]; |
|---|
| | 253 | else |
|---|
| | 254 | throw new OptionError( |
|---|
| | 255 | "No options provided to addOption!" |
|---|
| | 256 | ); |
|---|
| | 257 | } else { |
|---|
| | 258 | this.name = name; |
|---|
| | 259 | } |
|---|
| | 260 | argname = toupper(this.name.dup); |
|---|
| 321 | | // Only set the default if the option doesn't already have a value. |
|---|
| 322 | | char[][]* val = this.name in results.opts; |
|---|
| 323 | | switch (this.action) { |
|---|
| 324 | | case Action.Store, Action.Append: |
|---|
| 325 | | if (val !is null) return; |
|---|
| 326 | | if (this.type == ArgType.String) { |
|---|
| 327 | | results.opts[name] = [default_string]; |
|---|
| 328 | | } else { |
|---|
| 329 | | results.opts[name] = [.toString(default_value)]; |
|---|
| 330 | | } |
|---|
| 331 | | break; |
|---|
| 332 | | case Action.StoreConst, Action.AppendConst: |
|---|
| 333 | | if (val !is null) return; |
|---|
| 334 | | results.opts[name] = [default_string]; |
|---|
| 335 | | break; |
|---|
| 336 | | case Action.SetTrue, Action.SetFalse: |
|---|
| 337 | | if (val !is null) return; |
|---|
| 338 | | if (default_flag) { |
|---|
| 339 | | results.opts[name] = ["1"]; |
|---|
| 340 | | } else { |
|---|
| 341 | | results.opts[name] = ["0"]; |
|---|
| 342 | | } |
|---|
| 343 | | break; |
|---|
| 344 | | default: |
|---|
| 345 | | return; |
|---|
| 346 | | } |
|---|
| 347 | | } |
|---|
| 348 | | // Does whatever this option is supposed to do. |
|---|
| 349 | | void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| 350 | | int i; |
|---|
| 351 | | if (this.type == ArgType.Integer) { |
|---|
| 352 | | // Verify that it's an int. |
|---|
| 353 | | i = parser.toOptInt(arg); |
|---|
| 354 | | } |
|---|
| 355 | | switch (this.action) { |
|---|
| 356 | | case Action.Store: |
|---|
| 357 | | results.opts[name] = [arg]; |
|---|
| 358 | | break; |
|---|
| 359 | | case Action.Append: |
|---|
| 360 | | results.opts[name] ~= arg; |
|---|
| 361 | | break; |
|---|
| 362 | | case Action.StoreConst: |
|---|
| 363 | | assert(arg is null, "Got unexpected argument for '"~name~"' option."); |
|---|
| 364 | | results.opts[name] = [const_value]; |
|---|
| 365 | | break; |
|---|
| 366 | | case Action.AppendConst: |
|---|
| 367 | | assert(arg is null, "Got unexpected argument for '"~name~"' option."); |
|---|
| 368 | | results.opts[name] ~= const_value; |
|---|
| 369 | | break; |
|---|
| 370 | | case Action.Count: |
|---|
| 371 | | assert(arg is null, "Got unexpected argument for '"~name~"' option."); |
|---|
| 372 | | ++results.counted_opts[name]; |
|---|
| 373 | | break; |
|---|
| 374 | | case Action.SetTrue: |
|---|
| 375 | | results.opts[name] = ["1"]; |
|---|
| 376 | | break; |
|---|
| 377 | | case Action.SetFalse: |
|---|
| 378 | | results.opts[name] = ["0"]; |
|---|
| 379 | | break; |
|---|
| 380 | | case Action.Callback: |
|---|
| 381 | | switch (type) { |
|---|
| 382 | | case ArgType.String: |
|---|
| 383 | | callback(arg); |
|---|
| 384 | | break; |
|---|
| 385 | | case ArgType.Integer: |
|---|
| 386 | | int_callback(i); |
|---|
| 387 | | break; |
|---|
| 388 | | case ArgType.None: |
|---|
| 389 | | void_callback(); |
|---|
| 390 | | break; |
|---|
| 391 | | default: |
|---|
| 392 | | break; |
|---|
| 393 | | } |
|---|
| 394 | | break; |
|---|
| 395 | | case Action.CallbackFancy: |
|---|
| 396 | | switch (type) { |
|---|
| 397 | | case ArgType.String: |
|---|
| 398 | | fancy_callback(results, args, idx, name, arg); |
|---|
| 399 | | break; |
|---|
| 400 | | case ArgType.Integer: |
|---|
| 401 | | fancy_int_callback(results, args, idx, name, i); |
|---|
| 402 | | break; |
|---|
| 403 | | case ArgType.None: |
|---|
| 404 | | fancy_void_callback(results, args, idx, name); |
|---|
| 405 | | break; |
|---|
| 406 | | default: |
|---|
| 407 | | break; |
|---|
| 408 | | } |
|---|
| 409 | | break; |
|---|
| 410 | | case Action.Help: |
|---|
| 411 | | parser.helpText(); |
|---|
| 412 | | exit(EXIT_SUCCESS); |
|---|
| 413 | | break; |
|---|
| 414 | | default: |
|---|
| 415 | | break; |
|---|
| 416 | | } |
|---|
| 417 | | } |
|---|
| | 278 | return; |
|---|
| | 279 | } |
|---|
| | 280 | /// Does whatever this option is supposed to do. |
|---|
| | 281 | abstract void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg); |
|---|
| | 329 | } |
|---|
| | 330 | } |
|---|
| | 331 | |
|---|
| | 332 | abstract class ArgOption : Option { |
|---|
| | 333 | static const ArgType default_type = ArgType.String; |
|---|
| | 334 | ArgType type; |
|---|
| | 335 | bool has_default = false; |
|---|
| | 336 | char[] default_string; |
|---|
| | 337 | this(char[][] options, char[] name, ArgType type) { |
|---|
| | 338 | super(options, name); |
|---|
| | 339 | this.type = type; |
|---|
| | 340 | } |
|---|
| | 341 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 342 | if (this.type == ArgType.Integer) { |
|---|
| | 343 | // Verify that it's an int. |
|---|
| | 344 | int i = parser.toOptInt(arg); |
|---|
| | 345 | } |
|---|
| | 346 | } |
|---|
| | 347 | override Option def(char[] val) { |
|---|
| | 348 | if (this.type != ArgType.String) |
|---|
| | 349 | super.def(val); |
|---|
| | 350 | this.has_default = true; |
|---|
| | 351 | this.default_string = val; |
|---|
| | 352 | return this; |
|---|
| | 353 | } |
|---|
| | 354 | override Option def(int val) { |
|---|
| | 355 | if (this.type != ArgType.Integer) |
|---|
| | 356 | super.def(val); |
|---|
| | 357 | this.has_default = true; |
|---|
| | 358 | this.default_string = .toString(val); |
|---|
| | 359 | return this; |
|---|
| | 360 | } |
|---|
| | 361 | override void issue_default(Options results) { |
|---|
| | 362 | if (has_default) results.storeArg(this.name, this.default_string); |
|---|
| | 363 | } |
|---|
| | 364 | override bool hasArg() { |
|---|
| | 365 | return true; |
|---|
| | 366 | } |
|---|
| | 367 | } |
|---|
| | 368 | |
|---|
| | 369 | class Store : ArgOption { |
|---|
| | 370 | this(char[][] options, char[] name, ArgType type=Store.default_type) { |
|---|
| | 371 | super(options, name, type); |
|---|
| | 372 | } |
|---|
| | 373 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 374 | super.performAction(parser, results, args, idx, arg); |
|---|
| | 375 | results.storeArg(this.name, arg); |
|---|
| | 376 | } |
|---|
| | 377 | } |
|---|
| | 378 | class Append : ArgOption { |
|---|
| | 379 | this(char[][] options, char[] name, ArgType type=Append.default_type) { |
|---|
| | 380 | super(options, name, type); |
|---|
| | 381 | } |
|---|
| | 382 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 383 | super.performAction(parser, results, args, idx, arg); |
|---|
| | 384 | results.appendArg(this.name, arg); |
|---|
| | 385 | } |
|---|
| | 386 | } |
|---|
| | 387 | abstract class ConstOption : Option { |
|---|
| | 388 | bool has_default = false; |
|---|
| | 389 | char[] default_value; |
|---|
| | 390 | char[] const_value; |
|---|
| | 391 | this(char[][] options, char[] name, char[] const_value) { |
|---|
| | 392 | super(options, name); |
|---|
| | 393 | this.const_value = const_value; |
|---|
| | 394 | } |
|---|
| | 395 | override Option def(char[] val) { |
|---|
| | 396 | this.has_default = true; |
|---|
| | 397 | this.default_value = val; |
|---|
| | 398 | return this; |
|---|
| | 399 | } |
|---|
| | 400 | override void issue_default(Options results) { |
|---|
| | 401 | if (has_default) results.storeArg(this.name, this.default_value); |
|---|
| | 402 | } |
|---|
| | 403 | } |
|---|
| | 404 | class StoreConst : ConstOption { |
|---|
| | 405 | this(char[][] options, char[] name, char[] const_value) { |
|---|
| | 406 | super(options, name, const_value); |
|---|
| | 407 | } |
|---|
| | 408 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 409 | results.storeArg(this.name, this.const_value); |
|---|
| | 410 | } |
|---|
| | 411 | } |
|---|
| | 412 | class AppendConst : ConstOption { |
|---|
| | 413 | this(char[][] options, char[] name, char[] const_value) { |
|---|
| | 414 | super(options, name, const_value); |
|---|
| | 415 | } |
|---|
| | 416 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 417 | results.appendArg(this.name, this.const_value); |
|---|
| | 418 | } |
|---|
| | 419 | } |
|---|
| | 420 | abstract class SetBool : Option { |
|---|
| | 421 | bool has_default = false; |
|---|
| | 422 | bool default_flag = false; |
|---|
| | 423 | this(char[][] options, char[] name) { |
|---|
| | 424 | super(options, name); |
|---|
| | 425 | } |
|---|
| | 426 | override Option def(bool val) { |
|---|
| | 427 | this.has_default = true; |
|---|
| | 428 | this.default_flag = val; |
|---|
| | 429 | return this; |
|---|
| | 430 | } |
|---|
| | 431 | override void issue_default(Options results) { |
|---|
| | 432 | if (has_default) results.storeArg(this.name, this.default_flag); |
|---|
| | 433 | } |
|---|
| | 434 | } |
|---|
| | 435 | class SetTrue : SetBool { |
|---|
| | 436 | this(char[][] options, char[] name) { |
|---|
| | 437 | super(options, name); |
|---|
| | 438 | } |
|---|
| | 439 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 440 | results.storeArg(this.name, true); |
|---|
| | 441 | } |
|---|
| | 442 | } |
|---|
| | 443 | class SetFalse : SetBool { |
|---|
| | 444 | this(char[][] options, char[] name) { |
|---|
| | 445 | super(options, name); |
|---|
| | 446 | } |
|---|
| | 447 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 448 | results.storeArg(this.name, false); |
|---|
| | 449 | } |
|---|
| | 450 | } |
|---|
| | 451 | class Count : Option { |
|---|
| | 452 | this(char[][] options, char[] name) { |
|---|
| | 453 | super(options, name); |
|---|
| | 454 | } |
|---|
| | 455 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 456 | results.increment(this.name); |
|---|
| | 457 | } |
|---|
| | 458 | } |
|---|
| | 459 | class Callback : Option { |
|---|
| | 460 | OptionCallback cb; |
|---|
| | 461 | this(char[][] options, OptionCallback cb) { |
|---|
| | 462 | super(options, null); |
|---|
| | 463 | this.cb = cb; |
|---|
| | 464 | } |
|---|
| | 465 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 466 | this.cb(); |
|---|
| | 467 | } |
|---|
| | 468 | } |
|---|
| | 469 | class CallbackArg : Option { |
|---|
| | 470 | OptionCallbackArg cb; |
|---|
| | 471 | this(char[][] options, OptionCallbackArg cb) { |
|---|
| | 472 | super(options, null); |
|---|
| | 473 | this.cb = cb; |
|---|
| | 474 | } |
|---|
| | 475 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 476 | this.cb(arg); |
|---|
| | 477 | } |
|---|
| | 478 | override bool hasArg() { |
|---|
| | 479 | return true; |
|---|
| | 480 | } |
|---|
| | 481 | } |
|---|
| | 482 | class CallbackInt : Option { |
|---|
| | 483 | OptionCallbackInt cb; |
|---|
| | 484 | this(char[][] options, OptionCallbackInt cb) { |
|---|
| | 485 | super(options, null); |
|---|
| | 486 | this.cb = cb; |
|---|
| | 487 | } |
|---|
| | 488 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 489 | int i = parser.toOptInt(arg); |
|---|
| | 490 | this.cb(i); |
|---|
| | 491 | } |
|---|
| | 492 | override bool hasArg() { |
|---|
| | 493 | return true; |
|---|
| | 494 | } |
|---|
| | 495 | } |
|---|
| | 496 | class FancyCallback : Option { |
|---|
| | 497 | OptionCallbackFancy cb; |
|---|
| | 498 | this(char[][] options, char[] name, OptionCallbackFancy cb) { |
|---|
| | 499 | super(options, name); |
|---|
| | 500 | this.cb = cb; |
|---|
| | 501 | } |
|---|
| | 502 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 503 | this.cb(results, args, idx, this.name); |
|---|
| | 504 | } |
|---|
| | 505 | } |
|---|
| | 506 | class FancyCallbackArg : Option { |
|---|
| | 507 | OptionCallbackFancyArg cb; |
|---|
| | 508 | this(char[][] options, char[] name, OptionCallbackFancyArg cb) { |
|---|
| | 509 | super(options, name); |
|---|
| | 510 | this.cb = cb; |
|---|
| | 511 | } |
|---|
| | 512 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 513 | this.cb(results, args, idx, this.name, arg); |
|---|
| | 514 | } |
|---|
| | 515 | override bool hasArg() { |
|---|
| | 516 | return true; |
|---|
| | 517 | } |
|---|
| | 518 | } |
|---|
| | 519 | class FancyCallbackInt : Option { |
|---|
| | 520 | OptionCallbackFancyInt cb; |
|---|
| | 521 | this(char[][] options, char[] name, OptionCallbackFancyInt cb) { |
|---|
| | 522 | super(options, name); |
|---|
| | 523 | this.cb = cb; |
|---|
| | 524 | } |
|---|
| | 525 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 526 | int i = parser.toOptInt(arg); |
|---|
| | 527 | this.cb(results, args, idx, this.name, i); |
|---|
| | 528 | } |
|---|
| | 529 | override bool hasArg() { |
|---|
| | 530 | return true; |
|---|
| | 531 | } |
|---|
| | 532 | } |
|---|
| | 533 | class Help : Option { |
|---|
| | 534 | this(char[][] options) { |
|---|
| | 535 | super(options, null); |
|---|
| | 536 | } |
|---|
| | 537 | override void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { |
|---|
| | 538 | parser.helpText(); |
|---|
| | 539 | exit(EXIT_SUCCESS); |
|---|
| 733 | | /// |
|---|
| | 793 | private void wrong_args(char[][] options) { |
|---|
| | 794 | if (options.length > 0) { |
|---|
| | 795 | throw new OptionError( |
|---|
| | 796 | "Wrong arguments to addOption for option '" |
|---|
| | 797 | ~options[0]~"'." |
|---|
| | 798 | ); |
|---|
| | 799 | } else { |
|---|
| | 800 | throw new OptionError("Found an empty option!"); |
|---|
| | 801 | } |
|---|
| | 802 | } |
|---|
| | 803 | /// |
|---|
| | 804 | Option addOption(char[][] options ...) { |
|---|
| | 805 | return addOption(new Store(options, null)); |
|---|
| | 806 | } |
|---|
| | 807 | /// |
|---|
| | 808 | Option addOption(char[][] options, char[] name) { |
|---|
| | 809 | return addOption(new Store(options, name)); |
|---|
| | 810 | } |
|---|
| | 811 | /// |
|---|
| | 812 | Option addOption(char[][] options, Action action) { |
|---|
| | 813 | Option o; |
|---|
| | 814 | switch (action) { |
|---|
| | 815 | case Action.Store, Action.Append: |
|---|
| | 816 | return addOption(options, null, action, ArgOption.default_type); |
|---|
| | 817 | case Action.Count: |
|---|
| | 818 | return addOption(options, null, action); |
|---|
| | 819 | case Action.Help: |
|---|
| | 820 | return addOption(new Help(options)); |
|---|
| | 821 | default: |
|---|
| | 822 | wrong_args(options); |
|---|
| | 823 | break; |
|---|
| | 824 | } |
|---|
| | 825 | return addOption(o); |
|---|
| | 826 | } |
|---|
| | 827 | /// |
|---|
| | 828 | Option addOption(char[][] options, ArgType type) { |
|---|
| | 829 | return addOption(new Store(options, null, type)); |
|---|
| | 830 | } |
|---|
| | 831 | /// |
|---|
| | 832 | Option addOption(char[][] options, Action action, ArgType type) { |
|---|
| | 833 | return addOption(options, null, action, type); |
|---|
| | 834 | } |
|---|
| | 835 | /// |
|---|
| | 836 | Option addOption(char[][] options, char[] name, Action action) { |
|---|
| | 837 | Option o; |
|---|
| | 838 | switch (action) { |
|---|
| | 839 | case Action.Store, Action.Append: |
|---|
| | 840 | return addOption(options, name, action, ArgOption.default_type); |
|---|
| | 841 | case Action.Count: |
|---|
| | 842 | o = new Count(options, name); |
|---|
| | 843 | break; |
|---|
| | 844 | case Action.SetTrue: |
|---|
| | 845 | o = new SetTrue(options, name); |
|---|
| | 846 | break; |
|---|
| | 847 | case Action.SetFalse: |
|---|
| | 848 | o = new SetFalse(options, name); |
|---|
| | 849 | break; |
|---|
| | 850 | default: |
|---|
| | 851 | wrong_args(options); |
|---|
| | 852 | break; |
|---|
| | 853 | } |
|---|
| | 854 | return addOption(o); |
|---|
| | 855 | } |
|---|
| | 856 | /// |
|---|
| | 857 | Option addOption(char[][] options, char[] name, Action action, ArgType type) { |
|---|
| | 858 | Option o; |
|---|
| | 859 | switch (action) { |
|---|
| | 860 | case Action.Store: |
|---|
| | 861 | o = new Store(options, name, type); |
|---|
| | 862 | break; |
|---|
| | 863 | case Action.Append: |
|---|
| | 864 | o = new Append(options, name, type); |
|---|
| | 865 | break; |
|---|
| | 866 | default: |
|---|
| | 867 | wrong_args(options); |
|---|
| | 868 | break; |
|---|
| | 869 | } |
|---|
| | 870 | return addOption(o); |
|---|
| | 871 | } |
|---|
| | 872 | /// |
|---|
| | 873 | Option addOption(char[][] options, Action action, char[] const_value) { |
|---|
| | 874 | return addOption(options, null, action, const_value); |
|---|
| | 875 | } |
|---|
| | 876 | /// |
|---|
| | 877 | Option addOption(char[][] options, char[] name, char[] const_value) { |
|---|
| | 878 | return addOption(options, name, Action.StoreConst, const_value); |
|---|
| | 879 | } |
|---|
| | 880 | /// |
|---|
| | 881 | Option addOption(char[][] options, char[] name, Action action, char[] const_value) { |
|---|
| | 882 | Option o; |
|---|
| | 883 | switch (action) { |
|---|
| | 884 | case Action.StoreConst: |
|---|
| | 885 | o = new StoreConst(options, name, const_value); |
|---|
| | 886 | break; |
|---|
| | 887 | case Action.AppendConst: |
|---|
| | 888 | o = new AppendConst(options, name, const_value); |
|---|
| | 889 | break; |
|---|
| | 890 | default: |
|---|
| | 891 | wrong_args(options); |
|---|
| | 892 | break; |
|---|
| | 893 | } |
|---|
| | 894 | return addOption(o); |
|---|
| | 895 | } |
|---|
| | 896 | /// |
|---|
| | 897 | Option addOption(char[][] options, OptionCallback dg) { |
|---|
| | 898 | return addOption(new Callback(options, dg)); |
|---|
| | 899 | } |
|---|
| | 900 | /// |
|---|
| | 901 | Option addOption(char[][] options, OptionCallbackArg dg) { |
|---|
| | 902 | return addOption(new CallbackArg(options, dg)); |
|---|
| | 903 | } |
|---|
| | 904 | /// |
|---|
| | 905 | Option addOption(char[][] options, OptionCallbackInt dg) { |
|---|
| | 906 | return addOption(new CallbackInt(options, dg)); |
|---|
| | 907 | } |
|---|
| | 908 | /// |
|---|
| | 909 | Option addOption(char[][] options, OptionCallbackFancy dg) { |
|---|
| | 910 | return addOption(new FancyCallback(options, null, dg)); |
|---|
| | 911 | } |
|---|
| | 912 | /// |
|---|
| | 913 | Option addOption(char[][] options, OptionCallbackFancyArg dg) { |
|---|
| | 914 | return addOption(new FancyCallbackArg(options, null, dg)); |
|---|
| | 915 | } |
|---|
| | 916 | /// |
|---|
| | 917 | Option addOption(char[][] options, OptionCallbackFancyInt dg) { |
|---|
| | 918 | return addOption(new FancyCallbackInt(options, null, dg)); |
|---|
| | 919 | } |
|---|
| | 920 | /// |
|---|
| | 921 | Option addOption(char[][] options, char[] name, OptionCallbackFancy dg) { |
|---|
| | 922 | return addOption(new FancyCallback(options, name, dg)); |
|---|
| | 923 | } |
|---|
| | 924 | /// |
|---|
| | 925 | Option addOption(char[][] options, char[] name, OptionCallbackFancyArg dg) { |
|---|
| | 926 | return addOption(new FancyCallbackArg(options, name, dg)); |
|---|
| | 927 | } |
|---|
| | 928 | /// |
|---|
| | 929 | Option addOption(char[][] options, char[] name, OptionCallbackFancyInt dg) { |
|---|
| | 930 | return addOption(new FancyCallbackInt(options, name, dg)); |
|---|
| | 931 | } |
|---|
| | 932 | // Although users certainly /can/ call this, all those overloads are there |
|---|
| | 933 | // for a reason. |
|---|
| 738 | | // options action name type const_value dga dgv dgi fdga fdgi fdg |
|---|
| 739 | | /// |
|---|
| 740 | | Option addOption(char[][] options ...) { |
|---|
| 741 | | return addOption(options, Action.Store, null, defaultType(Action.Store), null, null, null, null, null, null, null); |
|---|
| 742 | | } |
|---|
| 743 | | /// |
|---|
| 744 | | Option addOption(char[][] options, char[] name) { |
|---|
| 745 | | return addOption(options, Action.Store, name, defaultType(Action.Store), null, null, null, null, null, null, null); |
|---|
| 746 | | } |
|---|
| 747 | | /// |
|---|
| 748 | | Option addOption(char[][] options, Action action) { |
|---|
| 749 | | return addOption(options, action, null, defaultType(action), null, null, null, null, null, null, null); |
|---|
| 750 | | } |
|---|
| 751 | | /// |
|---|
| 752 | | Option addOption(char[][] options, ArgType type) { |
|---|
| 753 | | return addOption(options, Action.Store, null, type, null, null, null, null, null, null, null); |
|---|
| 754 | | } |
|---|
| 755 | | /// |
|---|
| 756 | | Option addOption(char[][] options, Action action, ArgType type) { |
|---|
| 757 | | return addOption(options, action, null, type, null, null, null, null, null, null, null); |
|---|
| 758 | | } |
|---|
| 759 | | /// |
|---|
| 760 | | Option addOption(char[][] options, char[] name, Action action) { |
|---|
| 761 | | return addOption(options, action, name, defaultType(action), null, null, null, null, null, null, null); |
|---|
| 762 | | } |
|---|
| 763 | | /// |
|---|
| 764 | | Option addOption(char[][] options, char[] name, Action action, ArgType type) { |
|---|
| 765 | | return addOption(options, action, name, type, null, null, null, null, null, null, null); |
|---|
| 766 | | } |
|---|
| 767 | | /// |
|---|
| 768 | | Option addOption(char[][] options, Action action, char[] const_value) { |
|---|
| 769 | | return addOption(options, action, null, defaultType(action), const_value, null, null, null, null, null, null); |
|---|
| 770 | | } |
|---|
| 771 | | /// |
|---|
| 772 | | Option addOption(char[][] options, char[] name, char[] const_value) { |
|---|
| 773 | | return addOption(options, Action.StoreConst, name, defaultType(Action.Store), const_value, null, null, null, null, null, null); |
|---|
| 774 | | } |
|---|
| 775 | | /// |
|---|
| 776 | | Option addOption(char[][] options, char[] name, Action action, char[] const_value) { |
|---|
| 777 | | return addOption(options, action, name, defaultType(action), const_value, null, null, null, null, null, null); |
|---|
| 778 | | } |
|---|
| 779 | | /// |
|---|
| 780 | | Option addOption(char[][] options, OptionCallbackArg dg) { |
|---|
| 781 | | return addOption(options, Action.Callback, null, ArgType.String, null, dg, null, null, null, null, null); |
|---|
| 782 | | } |
|---|
| 783 | | /// |
|---|
| 784 | | Option addOption(char[][] options, OptionCallback dg) { |
|---|
| 785 | | return addOption(options, Action.Callback, null, ArgType.None, null, null, dg, null, null, null, null); |
|---|
| 786 | | } |
|---|
| 787 | | /// |
|---|
| 788 | | Option addOption(char[][] options, OptionCallbackInt dg) { |
|---|
| 789 | | return addOption(options, Action.Callback, null, ArgType.Integer, null, null, null, dg, null, null, null); |
|---|
| 790 | | } |
|---|
| 791 | | /// |
|---|
| 792 | | Option addOption(char[][] options, OptionCallbackFancyArg dg) { |
|---|
| 793 | | return addOption(options, Action.CallbackFancy, null, ArgType.String, null, null, null, null, dg, null, null); |
|---|
| 794 | | } |
|---|
| 795 | | /// |
|---|
| 796 | | Option addOption(char[][] options, OptionCallbackFancy dg) { |
|---|
| 797 | | return addOption(options, Action.CallbackFancy, null, ArgType.None, null, null, null, null, null, null, dg); |
|---|
| 798 | | } |
|---|
| 799 | | /// |
|---|
| 800 | | Option addOption(char[][] options, OptionCallbackFancyInt dg) { |
|---|
| 801 | | return addOption(options, Action.CallbackFancy, null, ArgType.Integer, null, null, null, null, null, dg, null); |
|---|
| 802 | | } |
|---|
| 803 | | /// |
|---|
| 804 | | Option addOption(char[][] options, char[] name, OptionCallbackFancyArg dg) { |
|---|
| 805 | | return addOption(options, Action.CallbackFancy, name, ArgType.String, null, null, null, null, dg, null, null); |
|---|
| 806 | | } |
|---|
| 807 | | /// |
|---|
| 808 | | Option addOption(char[][] options, char[] name, OptionCallbackFancy dg) { |
|---|
| 809 | | return addOption(options, Action.CallbackFancy, name, ArgType.None, null, null, null, null, null, null, dg); |
|---|
| 810 | | } |
|---|
| 811 | | /// |
|---|
| 812 | | Option addOption(char[][] options, char[] name, OptionCallbackFancyInt dg) { |
|---|
| 813 | | return addOption(options, Action.CallbackFancy, name, ArgType.Integer, null, null, null, null, null, dg, null); |
|---|
| 814 | | } |
|---|
| 815 | | // Although users certainly /can/ call this, all those overloads are there |
|---|
| 816 | | // for a reason. |
|---|
| 817 | | Option addOption( |
|---|
| 818 | | char[][] options, |
|---|
| 819 | | Action action, char[] name, ArgType type, char[] const_value, |
|---|
| 820 | | OptionCallbackArg callback, OptionCallback vcall, |
|---|
| 821 | | OptionCallbackInt icall, |
|---|
| 822 | | OptionCallbackFancyArg fdga, |
|---|
| 823 | | OptionCallbackFancyInt fdgi, |
|---|
| 824 | | OptionCallbackFancy fdg |
|---|
| 825 | | ) { |
|---|
| 826 | | char[][] shortopts; |
|---|
| 827 | | char[][] longopts; |
|---|
| 828 | | dchar[] opt; |
|---|
| 829 | | Option option; |
|---|
| 830 | | foreach (_opt; options) { |
|---|
| 831 | | // (Unicode note: We convert to dchar[] so the length checks work |
|---|
| 832 | | // out in the event of a short opt with a >127 character.) |
|---|
| 833 | | opt = toUTF32(_opt); |
|---|
| 834 | | if (opt.length < 2) { |
|---|
| 835 | | throw new OptionError( |
|---|
| 836 | | "invalid option string '" ~ _opt ~ "': must be at least two characters long" |
|---|
| 837 | | ); |
|---|
| 838 | | } else if (opt.length > 2) { |
|---|
| 839 | | if (opt[0 .. 2] != "--" || opt[2] == '-') |
|---|
| 840 | | throw new OptionError( |
|---|
| 841 | | "invalid long option string '" ~ _opt ~ "': must start with --, followed by non-dash" |
|---|
| 842 | | ); |
|---|
| 843 | | longopts ~= _opt; |
|---|
| 844 | | } else { |
|---|
| 845 | | if (opt[0] != '-' || opt[1] == '-') |
|---|
| 846 | | throw new OptionError( |
|---|
| 847 | | "invalid short option string '" ~ _opt ~ "': must be of the form -x, where x is non-dash" |
|---|
| 848 | | ); |
|---|
| 849 | | shortopts ~= _opt; |
|---|
| 850 | | } |
|---|
| 851 | | } |
|---|
| 852 | | if (name is null) { |
|---|
| 853 | | // (Unicode note: We know '-' is a single code unit, so these |
|---|
| 854 | | // slices are okay.) |
|---|
| 855 | | if (longopts.length > 0) |
|---|
| 856 | | name = longopts[0][2 .. $]; |
|---|
| 857 | | else if (shortopts.length > 0) |
|---|
| 858 | | name = shortopts[0][1 .. 2]; |
|---|
| 859 | | else |
|---|
| 860 | | throw new OptionError( |
|---|
| 861 | | "No options provided to addOption!" |
|---|
| 862 | | ); |
|---|
| 863 | | } |
|---|
| 864 | | option = new Option(shortopts, longopts, type, action, name, const_value, callback, vcall, icall, fdga, fdgi, fdg); |
|---|
| 865 | | this.options ~= option; |
|---|
| 866 | | return option; |
|---|
| 867 | | } |
|---|
| 868 | | } |
|---|
| 869 | | |
|---|
| | 938 | } |
|---|
| | 939 | |
|---|