summaryrefslogtreecommitdiffstats
path: root/third_party/rust/nom/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/nom/src/util.rs')
-rw-r--r--third_party/rust/nom/src/util.rs214
1 files changed, 214 insertions, 0 deletions
diff --git a/third_party/rust/nom/src/util.rs b/third_party/rust/nom/src/util.rs
new file mode 100644
index 0000000000..488bbfb7d1
--- /dev/null
+++ b/third_party/rust/nom/src/util.rs
@@ -0,0 +1,214 @@
+#[cfg(feature = "std")]
+use crate::internal::IResult;
+#[cfg(feature = "std")]
+use std::fmt::Debug;
+
+#[cfg(feature = "std")]
+/// Helper trait to show a byte slice as a hex dump
+pub trait HexDisplay {
+ /// Converts the value of `self` to a hex dump, returning the owned
+ /// string.
+ fn to_hex(&self, chunk_size: usize) -> String;
+
+ /// Converts the value of `self` to a hex dump beginning at `from` address, returning the owned
+ /// string.
+ fn to_hex_from(&self, chunk_size: usize, from: usize) -> String;
+}
+
+#[cfg(feature = "std")]
+static CHARS: &'static [u8] = b"0123456789abcdef";
+
+#[cfg(feature = "std")]
+impl HexDisplay for [u8] {
+ #[allow(unused_variables)]
+ fn to_hex(&self, chunk_size: usize) -> String {
+ self.to_hex_from(chunk_size, 0)
+ }
+
+ #[allow(unused_variables)]
+ fn to_hex_from(&self, chunk_size: usize, from: usize) -> String {
+ let mut v = Vec::with_capacity(self.len() * 3);
+ let mut i = from;
+ for chunk in self.chunks(chunk_size) {
+ let s = format!("{:08x}", i);
+ for &ch in s.as_bytes().iter() {
+ v.push(ch);
+ }
+ v.push(b'\t');
+
+ i += chunk_size;
+
+ for &byte in chunk {
+ v.push(CHARS[(byte >> 4) as usize]);
+ v.push(CHARS[(byte & 0xf) as usize]);
+ v.push(b' ');
+ }
+ if chunk_size > chunk.len() {
+ for j in 0..(chunk_size - chunk.len()) {
+ v.push(b' ');
+ v.push(b' ');
+ v.push(b' ');
+ }
+ }
+ v.push(b'\t');
+
+ for &byte in chunk {
+ if (byte >= 32 && byte <= 126) || byte >= 128 {
+ v.push(byte);
+ } else {
+ v.push(b'.');
+ }
+ }
+ v.push(b'\n');
+ }
+
+ String::from_utf8_lossy(&v[..]).into_owned()
+ }
+}
+
+#[cfg(feature = "std")]
+impl HexDisplay for str {
+ #[allow(unused_variables)]
+ fn to_hex(&self, chunk_size: usize) -> String {
+ self.to_hex_from(chunk_size, 0)
+ }
+
+ #[allow(unused_variables)]
+ fn to_hex_from(&self, chunk_size: usize, from: usize) -> String {
+ self.as_bytes().to_hex_from(chunk_size, from)
+ }
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! nom_line (
+ () => (line!());
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! nom_println (
+ ($($args:tt)*) => (println!($($args)*));
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! nom_stringify (
+ ($($args:tt)*) => (stringify!($($args)*));
+);
+
+
+/// Prints a message if the parser fails
+///
+/// The message prints the `Error` or `Incomplete`
+/// and the parser's calling code
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # fn main() {
+/// named!(f, dbg!( tag!( "abcd" ) ) );
+///
+/// let a = &b"efgh"[..];
+///
+/// // Will print the following message:
+/// // Error(Position(0, [101, 102, 103, 104])) at l.5 by ' tag ! ( "abcd" ) '
+/// f(a);
+/// # }
+/// ```
+#[macro_export(local_inner_macros)]
+macro_rules! dbg (
+ ($i: expr, $submac:ident!( $($args:tt)* )) => (
+ {
+ use $crate::lib::std::result::Result::*;
+ let l = nom_line!();
+ match $submac!($i, $($args)*) {
+ Err(e) => {
+ nom_println!("Err({:?}) at l.{} by ' {} '", e, l, nom_stringify!($submac!($($args)*)));
+ Err(e)
+ },
+ a => a,
+ }
+ }
+ );
+
+ ($i:expr, $f:ident) => (
+ dbg!($i, call!($f));
+ );
+);
+
+/// Prints a message and the input if the parser fails
+///
+/// The message prints the `Error` or `Incomplete`
+/// and the parser's calling code.
+///
+/// It also displays the input in hexdump format
+///
+/// ```rust
+/// use nom::{IResult, dbg_dmp, bytes::complete::tag};
+///
+/// fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
+/// dbg_dmp(tag("abcd"), "tag")(i)
+/// }
+///
+/// let a = &b"efghijkl"[..];
+///
+/// // Will print the following message:
+/// // Error(Position(0, [101, 102, 103, 104, 105, 106, 107, 108])) at l.5 by ' tag ! ( "abcd" ) '
+/// // 00000000 65 66 67 68 69 6a 6b 6c efghijkl
+/// f(a);
+/// ```
+#[cfg(feature = "std")]
+pub fn dbg_dmp<'a, F, O, E: Debug>(f: F, context: &'static str) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O, E>
+ where F: Fn(&'a [u8]) -> IResult<&'a [u8], O, E> {
+ move |i: &'a [u8]| {
+ match f(i) {
+ Err(e) => {
+ println!("{}: Error({:?}) at:\n{}", context, e, i.to_hex(8));
+ Err(e)
+ },
+ a => a,
+ }
+ }
+}
+
+/// Prints a message and the input if the parser fails
+///
+/// The message prints the `Error` or `Incomplete`
+/// and the parser's calling code.
+///
+/// It also displays the input in hexdump format
+///
+/// ```ignore
+/// # #[macro_use] extern crate nom;
+/// # fn main() {
+/// named!(f, dbg_dmp!( tag!( "abcd" ) ) );
+///
+/// let a = &b"efghijkl"[..];
+///
+/// // Will print the following message:
+/// // Error(Position(0, [101, 102, 103, 104, 105, 106, 107, 108])) at l.5 by ' tag ! ( "abcd" ) '
+/// // 00000000 65 66 67 68 69 6a 6b 6c efghijkl
+/// f(a);
+/// # }
+#[macro_export(local_inner_macros)]
+#[cfg(feature = "std")]
+macro_rules! dbg_dmp (
+ ($i: expr, $submac:ident!( $($args:tt)* )) => (
+ {
+ use $crate::HexDisplay;
+ let l = nom_line!();
+ match $submac!($i, $($args)*) {
+ Err(e) => {
+ nom_println!("Error({:?}) at l.{} by ' {} '\n{}", e, l, nom_stringify!($submac!($($args)*)), $i.to_hex(8));
+ Err(e)
+ },
+ a => a,
+ }
+ }
+ );
+
+ ($i:expr, $f:ident) => (
+ dbg_dmp!($i, call!($f));
+ );
+);
+