making the invalid escape sequence fully explain the sintax
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
6f94ae2b2a
commit
da5bd3d36a
|
@ -36,6 +36,7 @@ pub use fs::*;
|
||||||
use {
|
use {
|
||||||
self::{ty::Builtin, utils::Ent},
|
self::{ty::Builtin, utils::Ent},
|
||||||
alloc::vec::Vec,
|
alloc::vec::Vec,
|
||||||
|
core::{fmt::Arguments, format_args as fa},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -316,9 +317,9 @@ impl Ident {
|
||||||
fn endoce_string(
|
fn endoce_string(
|
||||||
literal: &str,
|
literal: &str,
|
||||||
str: &mut Vec<u8>,
|
str: &mut Vec<u8>,
|
||||||
report: impl Fn(&core::str::Bytes, &str),
|
report: impl Fn(&core::str::Bytes, Arguments),
|
||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
let report = |bytes: &core::str::Bytes, msg: &_| {
|
let report = |bytes: &core::str::Bytes, msg: Arguments| {
|
||||||
report(bytes, msg);
|
report(bytes, msg);
|
||||||
None::<u8>
|
None::<u8>
|
||||||
};
|
};
|
||||||
|
@ -327,13 +328,13 @@ fn endoce_string(
|
||||||
while let Some(b) = bytes.next()
|
while let Some(b) = bytes.next()
|
||||||
&& b != b'}'
|
&& b != b'}'
|
||||||
{
|
{
|
||||||
let c = bytes.next().or_else(|| report(bytes, "incomplete escape sequence"))?;
|
let c = bytes.next().or_else(|| report(bytes, fa!("incomplete escape sequence")))?;
|
||||||
let decode = |b: u8| {
|
let decode = |b: u8| {
|
||||||
Some(match b {
|
Some(match b {
|
||||||
b'0'..=b'9' => b - b'0',
|
b'0'..=b'9' => b - b'0',
|
||||||
b'a'..=b'f' => b - b'a' + 10,
|
b'a'..=b'f' => b - b'a' + 10,
|
||||||
b'A'..=b'F' => b - b'A' + 10,
|
b'A'..=b'F' => b - b'A' + 10,
|
||||||
_ => report(bytes, "expected hex digit or '}'")?,
|
_ => report(bytes, fa!("expected hex digit or '}}'"))?,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
str.push(decode(b)? << 4 | decode(c)?);
|
str.push(decode(b)? << 4 | decode(c)?);
|
||||||
|
@ -350,19 +351,27 @@ fn endoce_string(
|
||||||
str.push(b);
|
str.push(b);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let b = match bytes.next().or_else(|| report(&bytes, "incomplete escape sequence"))? {
|
|
||||||
b'n' => b'\n',
|
const SPECIAL_CHARS: &str = "nrt\\'\"0";
|
||||||
b'r' => b'\r',
|
const TO_BYTES: &[u8] = b"\n\r\t\\'\"\0";
|
||||||
b't' => b'\t',
|
const _: () = assert!(SPECIAL_CHARS.len() == TO_BYTES.len());
|
||||||
b'\\' => b'\\',
|
|
||||||
b'\'' => b'\'',
|
let b = match bytes.next().or_else(|| report(&bytes, fa!("incomplete escape sequence")))? {
|
||||||
b'"' => b'"',
|
b if let Some((_, &i)) = SPECIAL_CHARS.bytes().zip(TO_BYTES).find(|&(i, _)| i == b) => {
|
||||||
b'0' => b'\0',
|
i
|
||||||
|
}
|
||||||
b'{' => {
|
b'{' => {
|
||||||
decode_braces(str, &mut bytes);
|
decode_braces(str, &mut bytes);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_ => report(&bytes, "unknown escape sequence, expected [nrt\\\"'{0]")?,
|
_ => report(
|
||||||
|
&bytes,
|
||||||
|
format_args!(
|
||||||
|
"unknown escape sequence, \
|
||||||
|
expected one of special characters (regex /[{SPECIAL_CHARS}]/), \
|
||||||
|
or arbitrary byte sequence in hex (regex /\\{{[0-9a-f]{{2}}+\\/}})"
|
||||||
|
),
|
||||||
|
)?,
|
||||||
};
|
};
|
||||||
str.push(b);
|
str.push(b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ use {
|
||||||
assert_matches::debug_assert_matches,
|
assert_matches::debug_assert_matches,
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
error,
|
error,
|
||||||
fmt::{self, Debug, Display, Write},
|
fmt::{self, Arguments, Debug, Display, Write},
|
||||||
format_args as fa, mem,
|
format_args as fa, mem,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -887,7 +887,7 @@ impl<'a> Codegen<'a> {
|
||||||
let mut data = core::mem::take(&mut self.pool.lit_buf);
|
let mut data = core::mem::take(&mut self.pool.lit_buf);
|
||||||
debug_assert!(data.is_empty());
|
debug_assert!(data.is_empty());
|
||||||
|
|
||||||
let report = |bytes: &core::str::Bytes, message: &str| {
|
let report = |bytes: &core::str::Bytes, message: Arguments| {
|
||||||
self.error(pos + (literal.len() - bytes.len()) as u32 - 1, message);
|
self.error(pos + (literal.len() - bytes.len()) as u32 - 1, message);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue