diff options
Diffstat (limited to 'src/parse/mod.rs')
| -rw-r--r-- | src/parse/mod.rs | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 4c19c96..f08426e 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -454,7 +454,7 @@ impl Parse for ExpString { let mut delim = b.peek(); if delim == b'\'' || delim == b'"' { b.adv(); - } else if is_symbol(delim) && delim != b'$' { + } else if is_symbol(delim) && delim != b'$' && delim != b'\\' { return if already_parsed { Ok(Self { parts }) } else { @@ -475,10 +475,30 @@ impl Parse for ExpString { b'r' => b'\r', b't' => b'\t', b'e' => 0x1b, // escape + b'x' => { + // parse two hex digits + b.adv(); + if b.buf.len() < 2 { + Err(ParseError::Eof)?; + } + let x1 = b.peek(); + b.adv(); + let x2 = b.peek(); + + if !x1.is_ascii_hexdigit() || !x2.is_ascii_hexdigit() { + Err(ParseError::NotHexDigit)?; + } + + let x1 = (x1 as char).to_digit(16).unwrap_or(0); + let x2 = (x2 as char).to_digit(16).unwrap_or(0); + + ((x1 << 4) | x2) as u8 + } _ => x, }; add_char(p, x); escaping = false; + already_parsed = true; b.adv(); continue; } @@ -650,6 +670,8 @@ pub enum ParseError { NotAFunDecl, NotAVarAssign, + + NotHexDigit, } type Result<T> = std::result::Result<T, ParseError>; |
