Skip to content

Commit dffd3f0

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 baeaab6 commit dffd3f0

File tree

1 file changed

+19
-23
lines changed

1 file changed

+19
-23
lines changed

src/lib.rs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ impl Options {
380380
free.extend(args);
381381
break;
382382
} else {
383-
let mut names;
383+
let mut name = None;
384384
let mut i_arg = None;
385385
if cur.as_bytes()[1] == b'-' || self.long_only {
386386
let tail = if cur.as_bytes()[1] == b'-' {
@@ -390,56 +390,52 @@ impl Options {
390390
&cur[1..]
391391
};
392392
let mut parts = tail.splitn(2, '=');
393-
names = vec![Name::from_str(parts.next().unwrap())];
393+
name = Some(Name::from_str(parts.next().unwrap()));
394394
if let Some(rest) = parts.next() {
395395
i_arg = Some(rest.to_string());
396396
}
397397
} else {
398-
names = Vec::new();
399398
for (j, ch) in cur.char_indices().skip(1) {
400399
let opt = Short(ch);
401400

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

414-
names.push(opt);
415-
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
416411
let arg_follows = match opts[opt_id].hasarg {
417412
Yes | Maybe => true,
418413
No => false,
419414
};
420415

421416
if arg_follows {
417+
name = Some(opt);
422418
let next = j + ch.len_utf8();
423419
if next < cur.len() {
424420
i_arg = Some(cur[next..].to_string());
425421
break;
426422
}
423+
} else {
424+
vals[opt_id].push((arg_pos, Given));
427425
}
428426
}
429427
}
430-
let mut name_pos = 0;
431-
for nm in names.iter() {
432-
name_pos += 1;
433-
let optid = match find_opt(&opts, &nm) {
428+
if let Some(nm) = name {
429+
let opt_id = match find_opt(&opts, &nm) {
434430
Some(id) => id,
435431
None => return Err(UnrecognizedOption(nm.to_string())),
436432
};
437-
match opts[optid].hasarg {
433+
match opts[opt_id].hasarg {
438434
No => {
439-
if name_pos == names.len() && i_arg.is_some() {
435+
if i_arg.is_some() {
440436
return Err(UnexpectedArgument(nm.to_string()));
441437
}
442-
vals[optid].push((arg_pos, Given));
438+
vals[opt_id].push((arg_pos, Given));
443439
}
444440
Maybe => {
445441
// Note that here we do not handle `--arg value` or
@@ -449,16 +445,16 @@ impl Options {
449445
// the end of the arguments when FloatingFrees is in
450446
// use.
451447
if let Some(i_arg) = i_arg.take() {
452-
vals[optid].push((arg_pos, Val(i_arg)));
448+
vals[opt_id].push((arg_pos, Val(i_arg)));
453449
} else {
454-
vals[optid].push((arg_pos, Given));
450+
vals[opt_id].push((arg_pos, Given));
455451
}
456452
}
457453
Yes => {
458454
if let Some(i_arg) = i_arg.take() {
459-
vals[optid].push((arg_pos, Val(i_arg)));
455+
vals[opt_id].push((arg_pos, Val(i_arg)));
460456
} else if let Some(n) = args.next() {
461-
vals[optid].push((arg_pos, Val(n)));
457+
vals[opt_id].push((arg_pos, Val(n)));
462458
} else {
463459
return Err(ArgumentMissing(nm.to_string()));
464460
}

0 commit comments

Comments
 (0)