Skip to content

Commit f524a2f

Browse files
committed
Actually revert #81, #82, #83
Fixes a git mistake with #84
1 parent 5a81dde commit f524a2f

File tree

2 files changed

+61
-60
lines changed

2 files changed

+61
-60
lines changed

src/lib.rs

+44-38
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ impl Options {
364364
.ok_or_else(|| Fail::UnrecognizedOption(format!("{:?}", i.as_ref())))
365365
.map(|s| s.to_owned())
366366
}).collect::<::std::result::Result<Vec<_>, _>>()?;
367-
let mut args = args.into_iter();
367+
let mut args = args.into_iter().peekable();
368368
let mut arg_pos = 0;
369369
while let Some(cur) = args.next() {
370370
if !is_arg(&cur) {
@@ -380,8 +380,9 @@ impl Options {
380380
free.extend(args);
381381
break;
382382
} else {
383-
let mut name = None;
383+
let mut names;
384384
let mut i_arg = None;
385+
let mut was_long = true;
385386
if cur.as_bytes()[1] == b'-' || self.long_only {
386387
let tail = if cur.as_bytes()[1] == b'-' {
387388
&cur[2..]
@@ -390,71 +391,81 @@ impl Options {
390391
&cur[1..]
391392
};
392393
let mut parts = tail.splitn(2, '=');
393-
name = Some(Name::from_str(parts.next().unwrap()));
394+
names = vec![Name::from_str(parts.next().unwrap())];
394395
if let Some(rest) = parts.next() {
395396
i_arg = Some(rest.to_string());
396397
}
397398
} else {
399+
was_long = false;
400+
names = Vec::new();
398401
for (j, ch) in cur.char_indices().skip(1) {
399402
let opt = Short(ch);
400403

404+
/* In a series of potential options (eg. -aheJ), if we
405+
see one which takes an argument, we assume all
406+
subsequent characters make up the argument. This
407+
allows options such as -L/usr/local/lib/foo to be
408+
interpreted correctly
409+
*/
410+
401411
let opt_id = match find_opt(&opts, &opt) {
402412
Some(id) => id,
403413
None => return Err(UnrecognizedOption(opt.to_string())),
404414
};
405415

406-
// In a series of potential options (eg. -aheJ), if we
407-
// see one which takes an argument, we assume all
408-
// subsequent characters make up the argument. This
409-
// allows options such as -L/usr/local/lib/foo to be
410-
// interpreted correctly
416+
names.push(opt);
417+
411418
let arg_follows = match opts[opt_id].hasarg {
412419
Yes | Maybe => true,
413420
No => false,
414421
};
415422

416423
if arg_follows {
417-
name = Some(opt);
418424
let next = j + ch.len_utf8();
419425
if next < cur.len() {
420426
i_arg = Some(cur[next..].to_string());
421427
break;
422428
}
423-
} else {
424-
vals[opt_id].push((arg_pos, Given));
425429
}
426430
}
427431
}
428-
if let Some(nm) = name {
429-
let opt_id = match find_opt(&opts, &nm) {
432+
let mut name_pos = 0;
433+
for nm in names.iter() {
434+
name_pos += 1;
435+
let optid = match find_opt(&opts, &nm) {
430436
Some(id) => id,
431437
None => return Err(UnrecognizedOption(nm.to_string())),
432438
};
433-
match opts[opt_id].hasarg {
439+
match opts[optid].hasarg {
434440
No => {
435-
if i_arg.is_some() {
441+
if name_pos == names.len() && i_arg.is_some() {
436442
return Err(UnexpectedArgument(nm.to_string()));
437443
}
438-
vals[opt_id].push((arg_pos, Given));
444+
vals[optid].push((arg_pos, Given));
439445
}
440446
Maybe => {
441-
// Note that here we do not handle `--arg value` or
442-
// `-a value`. This matches GNU getopt behavior; but
443-
// also makes sense, because if this were accepted,
444-
// then users could only write a "Maybe" option at
445-
// the end of the arguments when FloatingFrees is in
446-
// use.
447+
// Note that here we do not handle `--arg value`.
448+
// This matches GNU getopt behavior; but also
449+
// makes sense, because if this were accepted,
450+
// then users could only write a "Maybe" long
451+
// option at the end of the arguments when
452+
// FloatingFrees is in use.
447453
if let Some(i_arg) = i_arg.take() {
448-
vals[opt_id].push((arg_pos, Val(i_arg)));
454+
vals[optid].push((arg_pos, Val(i_arg)));
455+
} else if was_long
456+
|| name_pos < names.len()
457+
|| args.peek().map_or(true, |n| is_arg(&n))
458+
{
459+
vals[optid].push((arg_pos, Given));
449460
} else {
450-
vals[opt_id].push((arg_pos, Given));
461+
vals[optid].push((arg_pos, Val(args.next().unwrap())));
451462
}
452463
}
453464
Yes => {
454465
if let Some(i_arg) = i_arg.take() {
455-
vals[opt_id].push((arg_pos, Val(i_arg)));
466+
vals[optid].push((arg_pos, Val(i_arg)));
456467
} else if let Some(n) = args.next() {
457-
vals[opt_id].push((arg_pos, Val(n)));
468+
vals[optid].push((arg_pos, Val(n)));
458469
} else {
459470
return Err(ArgumentMissing(nm.to_string()));
460471
}
@@ -540,6 +551,10 @@ impl Options {
540551
row.push_str(&short_name);
541552
if long_name.width() > 0 {
542553
row.push_str(", ");
554+
} else {
555+
// Only a single space here, so that any
556+
// argument is printed in the correct spot.
557+
row.push(' ');
543558
}
544559
}
545560
// FIXME: refer issue #7.
@@ -552,21 +567,16 @@ impl Options {
552567
_ => {
553568
row.push_str(if self.long_only { "-" } else { "--" });
554569
row.push_str(&long_name);
570+
row.push(' ');
555571
}
556572
}
557573

558574
// arg
559575
match hasarg {
560576
No => {}
561-
Yes => {
562-
row.push(' ');
563-
row.push_str(&hint);
564-
}
577+
Yes => row.push_str(&hint),
565578
Maybe => {
566579
row.push('[');
567-
if !long_name.is_empty() {
568-
row.push('=');
569-
}
570580
row.push_str(&hint);
571581
row.push(']');
572582
}
@@ -969,13 +979,9 @@ fn format_option(opt: &OptGroup) -> String {
969979
}
970980

971981
if opt.hasarg != No {
982+
line.push(' ');
972983
if opt.hasarg == Maybe {
973984
line.push('[');
974-
if opt.short_name.is_empty() {
975-
line.push('=');
976-
}
977-
} else {
978-
line.push(' ');
979985
}
980986
line.push_str(&opt.hint);
981987
if opt.hasarg == Maybe {

src/tests/mod.rs

+17-22
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,8 @@ fn test_optflagopt() {
379379
let short_args = vec!["-t".to_string(), "x".to_string()];
380380
match opts.parse(&short_args) {
381381
Ok(ref m) => {
382-
assert_eq!(m.opt_str("t"), None);
383-
assert_eq!(m.opt_str("test"), None);
382+
assert_eq!(m.opt_str("t").unwrap(), "x");
383+
assert_eq!(m.opt_str("test").unwrap(), "x");
384384
}
385385
_ => panic!(),
386386
}
@@ -763,8 +763,6 @@ fn test_usage() {
763763
opts.optopt("a", "012345678901234567890123456789", "Desc", "VAL");
764764
opts.optflag("k", "kiwi", "Desc");
765765
opts.optflagopt("p", "", "Desc", "VAL");
766-
opts.optflagopt("", "pea", "Desc", "VAL");
767-
opts.optflagopt("c", "cherry", "Desc", "VAL");
768766
opts.optmulti("l", "", "Desc", "VAL");
769767
opts.optflag("", "starfruit", "Starfruit");
770768

@@ -775,9 +773,7 @@ Options:
775773
-a, --012345678901234567890123456789 VAL
776774
Desc
777775
-k, --kiwi Desc
778-
-p[VAL] Desc
779-
--pea[=VAL] Desc
780-
-c, --cherry[=VAL] Desc
776+
-p [VAL] Desc
781777
-l VAL Desc
782778
--starfruit Starfruit
783779
";
@@ -824,7 +820,7 @@ Options:
824820

825821
debug!("expected: <<{}>>", expected);
826822
debug!("generated: <<{}>>", usage);
827-
assert_eq!(usage, expected)
823+
assert!(usage == expected)
828824
}
829825

830826
#[test]
@@ -855,7 +851,7 @@ Options:
855851

856852
debug!("expected: <<{}>>", expected);
857853
debug!("generated: <<{}>>", usage);
858-
assert_eq!(usage, expected)
854+
assert!(usage == expected)
859855
}
860856

861857
#[test]
@@ -886,7 +882,7 @@ Options:
886882

887883
debug!("expected: <<{}>>", expected);
888884
debug!("generated: <<{}>>", usage);
889-
assert_eq!(usage, expected)
885+
assert!(usage == expected)
890886
}
891887

892888
#[test]
@@ -913,7 +909,7 @@ Options:
913909
-c, --brûlée brûlée quite long description
914910
-k, --kiwi€ kiwi description
915911
-o, --orange‹ orange description
916-
-r, --raspberry-but-making-this-option-way-too-long
912+
-r, --raspberry-but-making-this-option-way-too-long\u{0020}
917913
raspberry description is also quite long indeed longer
918914
than every other piece of text we might encounter here
919915
and thus will be automatically broken up
@@ -923,7 +919,7 @@ Options:
923919

924920
debug!("expected: <<{}>>", expected);
925921
debug!("generated: <<{}>>", usage);
926-
assert_eq!(usage, expected)
922+
assert!(usage == expected)
927923
}
928924

929925
#[test]
@@ -938,13 +934,13 @@ fn test_usage_short_only() {
938934
Options:
939935
-k VAL Kiwi
940936
-s Starfruit
941-
-a[TYPE] Apple
937+
-a [TYPE] Apple
942938
";
943939

944940
let usage = opts.usage("Usage: fruits");
945941
debug!("expected: <<{}>>", expected);
946942
debug!("generated: <<{}>>", usage);
947-
assert_eq!(usage, expected)
943+
assert!(usage == expected)
948944
}
949945

950946
#[test]
@@ -959,13 +955,13 @@ fn test_usage_long_only() {
959955
Options:
960956
--kiwi VAL Kiwi
961957
--starfruit Starfruit
962-
--apple[=TYPE] Apple
958+
--apple [TYPE] Apple
963959
";
964960

965961
let usage = opts.usage("Usage: fruits");
966962
debug!("expected: <<{}>>", expected);
967963
debug!("generated: <<{}>>", usage);
968-
assert_eq!(usage, expected)
964+
assert!(usage == expected)
969965
}
970966

971967
#[test]
@@ -975,10 +971,9 @@ fn test_short_usage() {
975971
opts.optopt("a", "012345678901234567890123456789", "Desc", "VAL");
976972
opts.optflag("k", "kiwi", "Desc");
977973
opts.optflagopt("p", "", "Desc", "VAL");
978-
opts.optflagopt("", "pea", "Desc", "VAL");
979-
opts.optflagopt("c", "cherry", "Desc", "VAL");
974+
opts.optmulti("l", "", "Desc", "VAL");
980975

981-
let expected = "Usage: fruits -b VAL [-a VAL] [-k] [-p[VAL]] [--pea[=VAL]] [-c[VAL]]".to_string();
976+
let expected = "Usage: fruits -b VAL [-a VAL] [-k] [-p [VAL]] [-l VAL]..".to_string();
982977
let generated_usage = opts.short_usage("fruits");
983978

984979
debug!("expected: <<{}>>", expected);
@@ -1031,7 +1026,7 @@ Options:
10311026

10321027
debug!("expected: <<{}>>", expected);
10331028
debug!("generated: <<{}>>", usage);
1034-
assert_eq!(usage, expected)
1029+
assert!(usage == expected)
10351030
}
10361031

10371032
#[test]
@@ -1153,7 +1148,7 @@ fn test_opt_get() {
11531148
opts.optflagopt("p", "percent", "Description", "0.0 .. 10.0");
11541149
opts.long_only(false);
11551150

1156-
let args: Vec<String> = ["--ignore=true", "-p1.1"]
1151+
let args: Vec<String> = ["-i", "true", "-p", "1.1"]
11571152
.iter()
11581153
.map(|x| x.to_string())
11591154
.collect();
@@ -1178,7 +1173,7 @@ fn test_opt_get_default() {
11781173
opts.optflagopt("p", "percent", "Description", "0.0 .. 10.0");
11791174
opts.long_only(false);
11801175

1181-
let args: Vec<String> = ["--ignore=true", "-p1.1"]
1176+
let args: Vec<String> = ["-i", "true", "-p", "1.1"]
11821177
.iter()
11831178
.map(|x| x.to_string())
11841179
.collect();

0 commit comments

Comments
 (0)