Skip to content

Commit

Permalink
fix(UsageParser): Handle non-ascii names / options.
Browse files Browse the repository at this point in the history
Closes clap-rs#664 and should make it faster too.
  • Loading branch information
tormol committed Sep 27, 2016
1 parent 5c7a219 commit e3426d6
Showing 1 changed file with 30 additions and 25 deletions.
55 changes: 30 additions & 25 deletions src/usage_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,12 @@ impl<'a> UsageParser<'a> {
loop {
debugln!("iter; pos={};", self.pos);
self.stop_at(token);
if self.pos < self.usage.len() {
if let Some(c) = self.usage.chars().nth(self.pos) {
match c {
'-' => self.short_or_long(&mut arg),
'.' => self.multiple(&mut arg),
'\'' => self.help(&mut arg),
_ => self.name(&mut arg),
}
if let Some(&c) = self.usage.as_bytes().get(self.pos) {
match c {
b'-' => self.short_or_long(&mut arg),
b'.' => self.multiple(&mut arg),
b'\'' => self.help(&mut arg),
_ => self.name(&mut arg),
}
} else {
break;
Expand Down Expand Up @@ -113,17 +111,12 @@ impl<'a> UsageParser<'a> {
}

fn stop_at<F>(&mut self, f: F)
where F: Fn(u32) -> bool
where F: Fn(u8) -> bool
{
debugln!("fn=stop_at;");
self.start = self.pos;
for c in self.usage[self.start..].chars() {
if f(c as u32) {
self.pos += 1;
continue;
}
break;
}
self.pos += self.usage[self.start..].bytes()
.take_while(|&b| f(b) ).count();
}

fn short_or_long(&mut self, arg: &mut Arg<'a, 'a>) {
Expand Down Expand Up @@ -204,28 +197,27 @@ impl<'a> UsageParser<'a> {
}

#[inline]
fn name_end(b: u32) -> bool {
fn name_end(b: u8) -> bool {
// 93(]), 62(>)
b > b']' as u32 || b < b'>' as u32 || (b > b'>' as u32 && b < b']' as u32)
b > b']' || b < b'>' || (b > b'>' && b < b']')
}

#[inline]
fn token(b: u32) -> bool {
fn token(b: u8) -> bool {
// 39('), 45(-), 46(.), 60(<), 91([)
b < 39 || b > 91 || (b > 46 && b < 91 && b != b'<' as u32) || (b > 39 && b < 45)
b < 39 || b > 91 || (b > 46 && b < 91 && b != b'<') || (b > 39 && b < 45)
}

#[inline]
fn long_end(b: u32) -> bool {
fn long_end(b: u8) -> bool {
// 39('), 46(.), 60(<), 61(=), 91([)
(b < 39 && (b > 13 && b != b' ' as u32)) || b > 91 || (b > 61 && b < 91) ||
(b < 39 && (b > 13 && b != b' ')) || b > 91 || (b > 61 && b < 91) ||
(b > 39 && b < 60 && b != 46)
}

#[inline]
fn help_start(b: u32) -> bool {
// 39(')
b < 39 || b > 39
fn help_start(b: u8) -> bool {
b != b'\''
}

#[cfg(test)]
Expand Down Expand Up @@ -1220,4 +1212,17 @@ mod test {
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
}

#[test]
fn nonascii() {
let a = Arg::from_usage("<ASCII> 'bø'");
assert_eq!(a.name, "ASCII");
assert_eq!(a.help, Some("bø"));
let a = Arg::from_usage("<bø> 'ASCII'");
assert_eq!(a.name, "bø");
assert_eq!(a.help, Some("ASCII"));
let a = Arg::from_usage("<bø> 'bø'");
assert_eq!(a.name, "bø");
assert_eq!(a.help, Some("bø"));
}
}

0 comments on commit e3426d6

Please sign in to comment.