Skip to content

Commit 8dffd26

Browse files
committed
Parse options without names vector
The only time the names vector has more than one `Name` in it is when parsing contiguous short options (`-abc`). We would continue putting `Name`s into the vector until we hit a short option that takes an argument. At that point, we break, so we can process the argument. So there's no point to reprocess the head of that vector, we already know they don't take arguments. Only the last one matters.
1 parent be919b8 commit 8dffd26

File tree

1 file changed

+20
-25
lines changed

1 file changed

+20
-25
lines changed

src/lib.rs

+20-25
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ impl Options {
372372
free.extend(args);
373373
break;
374374
} else {
375-
let mut names;
375+
let mut name = None;
376376
let mut i_arg = None;
377377
let mut was_long = true;
378378
if cur.as_bytes()[1] == b'-' || self.long_only {
@@ -383,57 +383,53 @@ impl Options {
383383
&cur[1..]
384384
};
385385
let mut parts = tail.splitn(2, '=');
386-
names = vec![Name::from_str(parts.next().unwrap())];
386+
name = Some(Name::from_str(parts.next().unwrap()));
387387
if let Some(rest) = parts.next() {
388388
i_arg = Some(rest.to_string());
389389
}
390390
} else {
391391
was_long = false;
392-
names = Vec::new();
393392
for (j, ch) in cur.char_indices().skip(1) {
394393
let opt = Short(ch);
395394

396-
/* In a series of potential options (eg. -aheJ), if we
397-
see one which takes an argument, we assume all
398-
subsequent characters make up the argument. This
399-
allows options such as -L/usr/local/lib/foo to be
400-
interpreted correctly
401-
*/
402-
403395
let opt_id = match find_opt(&opts, &opt) {
404396
Some(id) => id,
405397
None => return Err(UnrecognizedOption(opt.to_string())),
406398
};
407399

408-
names.push(opt);
409-
400+
// In a series of potential options (eg. -aheJ), if we
401+
// see one which takes an argument, we assume all
402+
// subsequent characters make up the argument. This
403+
// allows options such as -L/usr/local/lib/foo to be
404+
// interpreted correctly
410405
let arg_follows = match opts[opt_id].hasarg {
411406
Yes | Maybe => true,
412407
No => false,
413408
};
414409

415410
if arg_follows {
411+
name = Some(opt);
416412
let next = j + ch.len_utf8();
417413
if next < cur.len() {
418414
i_arg = Some(cur[next..].to_string());
419415
break;
420416
}
417+
} else {
418+
vals[opt_id].push((arg_pos, Given));
421419
}
422420
}
423421
}
424-
let mut name_pos = 0;
425-
for nm in names.iter() {
426-
name_pos += 1;
427-
let optid = match find_opt(&opts, &nm) {
422+
if let Some(nm) = name {
423+
let opt_id = match find_opt(&opts, &nm) {
428424
Some(id) => id,
429425
None => return Err(UnrecognizedOption(nm.to_string())),
430426
};
431-
match opts[optid].hasarg {
427+
match opts[opt_id].hasarg {
432428
No => {
433-
if name_pos == names.len() && i_arg.is_some() {
429+
if i_arg.is_some() {
434430
return Err(UnexpectedArgument(nm.to_string()));
435431
}
436-
vals[optid].push((arg_pos, Given));
432+
vals[opt_id].push((arg_pos, Given));
437433
}
438434
Maybe => {
439435
// Note that here we do not handle `--arg value`.
@@ -443,21 +439,20 @@ impl Options {
443439
// option at the end of the arguments when
444440
// FloatingFrees is in use.
445441
if let Some(i_arg) = i_arg.take() {
446-
vals[optid].push((arg_pos, Val(i_arg)));
442+
vals[opt_id].push((arg_pos, Val(i_arg)));
447443
} else if was_long
448-
|| name_pos < names.len()
449444
|| args.peek().map_or(true, |n| is_arg(&n))
450445
{
451-
vals[optid].push((arg_pos, Given));
446+
vals[opt_id].push((arg_pos, Given));
452447
} else {
453-
vals[optid].push((arg_pos, Val(args.next().unwrap())));
448+
vals[opt_id].push((arg_pos, Val(args.next().unwrap())));
454449
}
455450
}
456451
Yes => {
457452
if let Some(i_arg) = i_arg.take() {
458-
vals[optid].push((arg_pos, Val(i_arg)));
453+
vals[opt_id].push((arg_pos, Val(i_arg)));
459454
} else if let Some(n) = args.next() {
460-
vals[optid].push((arg_pos, Val(n)));
455+
vals[opt_id].push((arg_pos, Val(n)));
461456
} else {
462457
return Err(ArgumentMissing(nm.to_string()));
463458
}

0 commit comments

Comments
 (0)