Changeset 78
- Timestamp:
- 01/12/07 19:11:37 (2 years ago)
- Files:
-
- misc/optparse.d (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
misc/optparse.d
r77 r78 30 30 import std.conv : toInt, ConvError; 31 31 import std.path : getName, getBaseName; 32 import std.utf : toUTF8, toUTF32; 32 33 33 34 /* … … 67 68 if (s.length < start.length) return false; 68 69 return s[0 .. start.length] == start; 70 } 71 bool endswith(char[] s, char[] end) { 72 if (s.length < end.length) return false; 73 return s[$ - end.length .. $] == end; 69 74 } 70 75 … … 293 298 } 294 299 // Returns true if the passed option string matches this option. 295 bool matches(char[] arg) { 300 bool matches(char[] _arg) { 301 dchar[] arg = toUTF32(_arg); 296 302 if ( 297 303 arg.length < 2 || … … 303 309 if (arg.length == 2) { 304 310 foreach (opt; shortopts) { 305 if ( arg == opt) {311 if (_arg == opt) { 306 312 return true; 307 313 } … … 309 315 } else { 310 316 foreach (opt; longopts) { 311 if ( arg == opt) {317 if (_arg == opt) { 312 318 return true; 313 319 } … … 385 391 char[] result; 386 392 version(Windows) { 393 // (Unicode note: ".exe" only contains 4 code units, so this slice 394 // should Just Work.) (Although it remains to be seen how robust 395 // this code actually is.) 387 396 assert(path[$-4 .. $] == ".exe"); 388 397 result = path[0 .. $-4]; … … 415 424 */ 416 425 char[] opt, newopt, arg; 426 dchar[] opt32; 417 427 int idx; 418 428 Option match; … … 422 432 // -- ends the option list, the remainder is dumped into args 423 433 if (opt == "--") { 424 if (this.leftover_cb is null) {425 foreach(a rg; args[i+1 .. $]) {426 this.leftover_cb(a rg);434 if (this.leftover_cb !is null) { 435 foreach(a; args[i+1 .. $]) { 436 this.leftover_cb(a); 427 437 } 428 438 } else { … … 435 445 newopt = opt[0 .. idx]; 436 446 // Stitch out the old arg, stitch in the newopt, arg pair. 447 // (Unicode note: idx+1 works, since we know '=' is a 448 // single code unit.) 437 449 args = args[0 .. i] ~ [newopt, opt[idx+1 .. $]] ~ args[i+1 .. $]; 438 450 } else { … … 453 465 } else if (opt.startswith("-")) { 454 466 if (opt.length >= 2) { 455 foreach (j, c; opt[1 .. $]) { 456 newopt = "-" ~ c; 467 opt32 = toUTF32(opt[1 .. $]); 468 foreach (j, c; opt32) { 469 newopt = toUTF8("-" ~ [c]); 457 470 match = matches(newopt); 458 471 if (match is null) { … … 462 475 // This is the last char in the group, look to the 463 476 // next element of args for the arg. 464 if (j == opt .length-2) {477 if (j == opt32.length-1) { 465 478 if (i == args.length-1) expected_arg_error(match.name); 466 479 arg = args[i+1]; … … 469 482 // the arg. 470 483 } else { 471 arg = opt[j+2 .. $];484 arg = toUTF8(opt32[j+1 .. $]); 472 485 match.perform_action(this, options, arg); 473 486 break; … … 478 491 match.perform_action(this, options, arg); 479 492 } 493 } else { 494 unknown_opt_error(opt); 480 495 } 481 496 } else { … … 548 563 char[][] shortopts; 549 564 char[][] longopts; 565 dchar[] opt; 550 566 Option option; 551 foreach (opt; options) { 567 foreach (_opt; options) { 568 // (Unicode note: We convert to dchar[] so the length checks work 569 // out in the event of a short opt with a >127 character.) 570 opt = toUTF32(_opt); 552 571 if (opt.length < 2) { 553 572 throw new OptionError( 554 "invalid option string '" ~ opt ~ "': must be at least two characters long"573 "invalid option string '" ~ _opt ~ "': must be at least two characters long" 555 574 ); 556 575 } else if (opt.length > 2) { 557 576 if (opt[0 .. 2] != "--" || opt[2] == '-') 558 577 throw new OptionError( 559 "invalid long option string '" ~ opt ~ "': must start with --, followed by non-dash"578 "invalid long option string '" ~ _opt ~ "': must start with --, followed by non-dash" 560 579 ); 561 longopts ~= opt;580 longopts ~= _opt; 562 581 } else { 563 582 if (opt[0] != '-' || opt[1] == '-') 564 583 throw new OptionError( 565 "invalid short option string '" ~ opt ~ "': must be of the form -x, where x is non-dash"584 "invalid short option string '" ~ _opt ~ "': must be of the form -x, where x is non-dash" 566 585 ); 567 shortopts ~= opt;586 shortopts ~= _opt; 568 587 } 569 588 } 570 589 if (name is null) { 590 // (Unicode note: We know '-' is a single code unit, so these 591 // slices are okay.) 571 592 if (longopts.length > 0) 572 593 name = longopts[0][2 .. $];
