sexp: replace logging with log crate trace macro
This commit is contained in:
Generated
+3
@@ -879,6 +879,9 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sexp"
|
name = "sexp"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha-1"
|
name = "sha-1"
|
||||||
|
|||||||
@@ -14,3 +14,6 @@ keywords = [ "sexp", "parsing", "s-expression", "file-format" ]
|
|||||||
description = "A small, simple, self-contained, s-expression parser and pretty-printer."
|
description = "A small, simple, self-contained, s-expression parser and pretty-printer."
|
||||||
|
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = "0.4.11"
|
||||||
|
|||||||
+14
-88
@@ -5,12 +5,18 @@
|
|||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::{self, FromStr};
|
use std::str::{self, FromStr};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test;
|
||||||
|
|
||||||
/// A single data element in an s-expression. Floats are excluded to ensure
|
/// A single data element in an s-expression. Floats are excluded to ensure
|
||||||
/// atoms may be used as keys in ordered and hashed data structures.
|
/// atoms may be used as keys in ordered and hashed data structures.
|
||||||
///
|
///
|
||||||
@@ -102,13 +108,6 @@ fn err<T>(message: &'static str, s: &str, pos: &usize) -> ERes<T> {
|
|||||||
Err(err_impl(message, s, pos))
|
Err(err_impl(message, s, pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A helpful utility to trace the execution of a parser while testing. It will
|
|
||||||
/// be compiled out in release builds.
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn dbg(msg: &str, pos: &usize) {
|
|
||||||
//println!("{} @ {}", msg, pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn atom_of_string(s: String) -> Atom {
|
fn atom_of_string(s: String) -> Atom {
|
||||||
match FromStr::from_str(&s) {
|
match FromStr::from_str(&s) {
|
||||||
Ok(i) => return Atom::I(i),
|
Ok(i) => return Atom::I(i),
|
||||||
@@ -125,7 +124,7 @@ fn atom_of_string(s: String) -> Atom {
|
|||||||
|
|
||||||
// returns the char it found, and the new size if you wish to consume that char
|
// returns the char it found, and the new size if you wish to consume that char
|
||||||
fn peek(s: &str, pos: &usize) -> ERes<(char, usize)> {
|
fn peek(s: &str, pos: &usize) -> ERes<(char, usize)> {
|
||||||
dbg("peek", pos);
|
trace!("peek {}", pos);
|
||||||
if *pos == s.len() { return err("unexpected eof", s, pos); }
|
if *pos == s.len() { return err("unexpected eof", s, pos); }
|
||||||
if s.is_char_boundary(*pos) {
|
if s.is_char_boundary(*pos) {
|
||||||
let ch = s[*pos..].chars().next().unwrap();
|
let ch = s[*pos..].chars().next().unwrap();
|
||||||
@@ -138,7 +137,7 @@ fn peek(s: &str, pos: &usize) -> ERes<(char, usize)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expect(s: &str, pos: &mut usize, c: char) -> ERes<()> {
|
fn expect(s: &str, pos: &mut usize, c: char) -> ERes<()> {
|
||||||
dbg("expect", pos);
|
trace!("expect {}", pos);
|
||||||
let (ch, next) = peek(s, pos)?;
|
let (ch, next) = peek(s, pos)?;
|
||||||
*pos = next;
|
*pos = next;
|
||||||
if ch == c { Ok(()) } else { err("unexpected character", s, pos) }
|
if ch == c { Ok(()) } else { err("unexpected character", s, pos) }
|
||||||
@@ -155,7 +154,7 @@ fn consume_until_newline(s: &str, pos: &mut usize) -> ERes<()> {
|
|||||||
|
|
||||||
// zero or more spaces
|
// zero or more spaces
|
||||||
fn zspace(s: &str, pos: &mut usize) -> ERes<()> {
|
fn zspace(s: &str, pos: &mut usize) -> ERes<()> {
|
||||||
dbg("zspace", pos);
|
trace!("zspace {}", pos);
|
||||||
loop {
|
loop {
|
||||||
if *pos == s.len() { return Ok(()); }
|
if *pos == s.len() { return Ok(()); }
|
||||||
let (ch, next) = peek(s, pos)?;
|
let (ch, next) = peek(s, pos)?;
|
||||||
@@ -165,7 +164,7 @@ fn zspace(s: &str, pos: &mut usize) -> ERes<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_quoted_atom(s: &str, pos: &mut usize) -> ERes<Atom> {
|
fn parse_quoted_atom(s: &str, pos: &mut usize) -> ERes<Atom> {
|
||||||
dbg("parse_quoted_atom", pos);
|
trace!("parse_quoted_atom {}", pos);
|
||||||
let mut cs: String = String::new();
|
let mut cs: String = String::new();
|
||||||
|
|
||||||
expect(s, pos, '"')?;
|
expect(s, pos, '"')?;
|
||||||
@@ -195,7 +194,7 @@ fn parse_quoted_atom(s: &str, pos: &mut usize) -> ERes<Atom> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_unquoted_atom(s: &str, pos: &mut usize) -> ERes<Atom> {
|
fn parse_unquoted_atom(s: &str, pos: &mut usize) -> ERes<Atom> {
|
||||||
dbg("parse_unquoted_atom", pos);
|
trace!("parse_unquoted_atom {}", pos);
|
||||||
let mut cs: String = String::new();
|
let mut cs: String = String::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@@ -215,14 +214,14 @@ fn parse_unquoted_atom(s: &str, pos: &mut usize) -> ERes<Atom> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_atom(s: &str, pos: &mut usize) -> ERes<Atom> {
|
fn parse_atom(s: &str, pos: &mut usize) -> ERes<Atom> {
|
||||||
dbg("parse_atom", pos);
|
trace!("parse_atom {}", pos);
|
||||||
let (ch, _) = peek(s, pos)?;
|
let (ch, _) = peek(s, pos)?;
|
||||||
|
|
||||||
if ch == '"' { parse_quoted_atom(s, pos) } else { parse_unquoted_atom(s, pos) }
|
if ch == '"' { parse_quoted_atom(s, pos) } else { parse_unquoted_atom(s, pos) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_list(s: &str, pos: &mut usize) -> ERes<Vec<Sexp>> {
|
fn parse_list(s: &str, pos: &mut usize) -> ERes<Vec<Sexp>> {
|
||||||
dbg("parse_list", pos);
|
trace!("parse_list {}", pos);
|
||||||
zspace(s, pos)?;
|
zspace(s, pos)?;
|
||||||
expect(s, pos, '(')?;
|
expect(s, pos, '(')?;
|
||||||
|
|
||||||
@@ -244,7 +243,7 @@ fn parse_list(s: &str, pos: &mut usize) -> ERes<Vec<Sexp>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_sexp(s: &str, pos: &mut usize) -> ERes<Sexp> {
|
fn parse_sexp(s: &str, pos: &mut usize) -> ERes<Sexp> {
|
||||||
dbg("parse_sexp", pos);
|
trace!("parse_sexp {}", pos);
|
||||||
zspace(s, pos)?;
|
zspace(s, pos)?;
|
||||||
let (c, _) = peek(s, pos)?;
|
let (c, _) = peek(s, pos)?;
|
||||||
let r =
|
let r =
|
||||||
@@ -347,76 +346,3 @@ impl fmt::Debug for Sexp {
|
|||||||
write!(f, "{}", self)
|
write!(f, "{}", self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_hello_world() {
|
|
||||||
assert_eq!(
|
|
||||||
parse("(hello -42\n\t -4.0 \"world\") ; comment").unwrap(),
|
|
||||||
list(&[atom_s("hello"), atom_i(-42), atom_f(-4.0), atom_s("world")]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_escaping() {
|
|
||||||
assert_eq!(
|
|
||||||
parse("(\"\\\"\\q\" \"1234\" 1234)").unwrap(),
|
|
||||||
list(&[atom_s("\"\\q"), atom_s("1234"), atom_i(1234)]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pp() {
|
|
||||||
let s = "(hello world (what is (up) (4 6.4 you \"123\\\\ \\\"\")))";
|
|
||||||
let sexp = parse(s).unwrap();
|
|
||||||
assert_eq!(s, sexp.to_string());
|
|
||||||
assert_eq!(s, format!("{:?}", sexp));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tight_parens() {
|
|
||||||
let s = "(hello(world))";
|
|
||||||
let sexp = parse(s).unwrap();
|
|
||||||
assert_eq!(sexp, Sexp::List(vec![Sexp::Atom(Atom::S("hello".into())),
|
|
||||||
Sexp::List(vec![Sexp::Atom(Atom::S("world".into()))])]));
|
|
||||||
let s = "(this (has)tight(parens))";
|
|
||||||
let s2 = "( this ( has ) tight ( parens ) )";
|
|
||||||
assert_eq!(parse(s).unwrap(), parse(s2).unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_space_in_atom() {
|
|
||||||
let sexp = list(&[atom_s("hello world")]);
|
|
||||||
let sexp_as_string = sexp.to_string();
|
|
||||||
assert_eq!("(\"hello world\")", sexp_as_string);
|
|
||||||
assert_eq!(sexp, parse(&sexp_as_string).unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn show_an_error() {
|
|
||||||
assert_eq!(format!("{:?}", parse("(aaaa").unwrap_err()), "1:4: unexpected eof");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn line_and_col_test() {
|
|
||||||
let s = "0123456789\n0123456789\n\n6";
|
|
||||||
assert_eq!(get_line_and_column(s, 4), (1, 4));
|
|
||||||
|
|
||||||
assert_eq!(get_line_and_column(s, 10), (2, 0));
|
|
||||||
assert_eq!(get_line_and_column(s, 11), (2, 0));
|
|
||||||
assert_eq!(get_line_and_column(s, 15), (2, 4));
|
|
||||||
|
|
||||||
assert_eq!(get_line_and_column(s, 21), (3, 0));
|
|
||||||
assert_eq!(get_line_and_column(s, 22), (4, 0));
|
|
||||||
assert_eq!(get_line_and_column(s, 23), (4, 0));
|
|
||||||
assert_eq!(get_line_and_column(s, 500), (4, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sexp_size() {
|
|
||||||
// I just want to see when this changes, in the diff.
|
|
||||||
use std::mem;
|
|
||||||
assert_eq!(mem::size_of::<Sexp>(), mem::size_of::<isize>() * 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_hello_world() {
|
||||||
|
assert_eq!(
|
||||||
|
parse("(hello -42\n\t -4.0 \"world\") ; comment").unwrap(),
|
||||||
|
list(&[atom_s("hello"), atom_i(-42), atom_f(-4.0), atom_s("world")]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_escaping() {
|
||||||
|
assert_eq!(
|
||||||
|
parse("(\"\\\"\\q\" \"1234\" 1234)").unwrap(),
|
||||||
|
list(&[atom_s("\"\\q"), atom_s("1234"), atom_i(1234)]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pp() {
|
||||||
|
let s = "(hello world (what is (up) (4 6.4 you \"123\\\\ \\\"\")))";
|
||||||
|
let sexp = parse(s).unwrap();
|
||||||
|
assert_eq!(s, sexp.to_string());
|
||||||
|
assert_eq!(s, format!("{:?}", sexp));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tight_parens() {
|
||||||
|
let s = "(hello(world))";
|
||||||
|
let sexp = parse(s).unwrap();
|
||||||
|
assert_eq!(sexp, Sexp::List(vec![Sexp::Atom(Atom::S("hello".into())),
|
||||||
|
Sexp::List(vec![Sexp::Atom(Atom::S("world".into()))])]));
|
||||||
|
let s = "(this (has)tight(parens))";
|
||||||
|
let s2 = "( this ( has ) tight ( parens ) )";
|
||||||
|
assert_eq!(parse(s).unwrap(), parse(s2).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_space_in_atom() {
|
||||||
|
let sexp = list(&[atom_s("hello world")]);
|
||||||
|
let sexp_as_string = sexp.to_string();
|
||||||
|
assert_eq!("(\"hello world\")", sexp_as_string);
|
||||||
|
assert_eq!(sexp, parse(&sexp_as_string).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn show_an_error() {
|
||||||
|
assert_eq!(format!("{:?}", parse("(aaaa").unwrap_err()), "1:4: unexpected eof");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn line_and_col_test() {
|
||||||
|
let s = "0123456789\n0123456789\n\n6";
|
||||||
|
assert_eq!(get_line_and_column(s, 4), (1, 4));
|
||||||
|
|
||||||
|
assert_eq!(get_line_and_column(s, 10), (2, 0));
|
||||||
|
assert_eq!(get_line_and_column(s, 11), (2, 0));
|
||||||
|
assert_eq!(get_line_and_column(s, 15), (2, 4));
|
||||||
|
|
||||||
|
assert_eq!(get_line_and_column(s, 21), (3, 0));
|
||||||
|
assert_eq!(get_line_and_column(s, 22), (4, 0));
|
||||||
|
assert_eq!(get_line_and_column(s, 23), (4, 0));
|
||||||
|
assert_eq!(get_line_and_column(s, 500), (4, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sexp_size() {
|
||||||
|
// I just want to see when this changes, in the diff.
|
||||||
|
use std::mem;
|
||||||
|
assert_eq!(mem::size_of::<Sexp>(), mem::size_of::<isize>() * 5);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user