Repository: Geal/nom
Pull request #230 (2016-03-02 00:30:39)

Add fold_many combinators
`fold_many0!`, `fold_many1!` and `fold_many_m_n!` are similar to their `many*` pendants, but add two additional parameters (an initial value and a function) to allow folding into a custom type, like you can with Iterator::fold.


Patch:
diff --git a/.travis.yml b/.travis.yml
index adcb4e0..ba60978 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,13 +18,10 @@ before_script:
 
 script:
   - |
-      travis-cargo --only 1.2     test  -- --features regexp &&
-      travis-cargo --only stable  test  -- --features "regexp regexp_macros" &&
-      travis-cargo --only beta    test  -- --features "regexp regexp_macros" &&
-      travis-cargo --only nightly build -- --features "nightly core regexp" &&
-      travis-cargo --only nightly test  -- --features "regexp regexp_macros" &&
+      travis-cargo build &&
+      travis-cargo test &&
       travis-cargo bench &&
-      travis-cargo --only stable doc -- --features "regexp regexp_macros"
+      travis-cargo --only stable doc
 
 after_success:
   - travis-cargo coveralls --no-sudo
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a3c3062..9dc8750 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,27 +4,6 @@
 
 ### Changed
 
-## 1.2.1 - 2016-02-23
-
-### Thanks
-- @sourrust for adding methods to `IResult`
-- @tstorch for the test refactoring, and for adding methods to `IResult` and `Needed`
-- @joelself for fixing the method system
-
-### Added
-
-- mapping methods over `IResult` and `Needed`
-
-### Changed
-
-- `apply_rf` is renamed to `apply_m`. This will not warrant a major version, since it is part missing from the methods feture added in the 1.2.0 release
-- the `regexp_macros` feature that used `regex!` to precompile regular expressions has been replaced by the normal regex engine combined with `lazy_static`
-
-### Fixed
-
-- when a parser or combinator was returning an empty buffer as remaining part, it was generating one from a static empty string. This was messing with buffer offset calculation. Now, that empty slice is taken like this: `&input[input.len()..]`.
-- The `regexp_macros` and `no_std` feature build again and are now tested with Travis CI
-
 ## 1.2.0 - 2016-02-08
 
 ### Thanks
@@ -450,8 +429,7 @@ Considering the number of changes since the last release, this version can conta
 
 ## Compare code
 
-* [unreleased]: https://github.com/Geal/nom/compare/1.2.1...HEAD
-* [1.2.0]: https://github.com/Geal/nom/compare/1.2.0...1.2.1
+* [unreleased]: https://github.com/Geal/nom/compare/1.2.0...HEAD
 * [1.2.0]: https://github.com/Geal/nom/compare/1.1.0...1.2.0
 * [1.1.0]: https://github.com/Geal/nom/compare/1.0.1...1.1.0
 * [1.0.1]: https://github.com/Geal/nom/compare/1.0.0...1.0.1
diff --git a/Cargo.toml b/Cargo.toml
index d01ab40..e25ad5a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 
 name = "nom"
-version = "1.2.1"
+version = "1.2.0"
 authors = [ "contact@geoffroycouprie.com" ]
 description = "A byte-oriented, zero-copy, parser combinators library"
 license = "MIT"
@@ -25,14 +25,14 @@ core = []
 nightly = []
 default = ["stream"]
 regexp = ["regex"]
-regexp_macros = ["regexp", "lazy_static"]
+regexp_macros = ["regexp", "regex_macros"]
 stream = []
 
 [dependencies.regex]
 version = "^0.1.41"
 optional = true
 
-[dependencies.lazy_static]
-version = "^0.1.15"
+[dependencies.regex_macros]
+version = "^0.1.21"
 optional = true
 
diff --git a/README.md b/README.md
index 4d92ca7..4e2209c 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@ nom is available on [crates.io](https://crates.io/crates/nom) and can be include
 
 ```toml
 [dependencies]
-nom = "~1.2.1"
+nom = "~1.2.0"
 ```
 
 Then include it in your code like this:
@@ -267,7 +267,7 @@ Here are some basic combining macros available:
 
 Please refer to the documentation for an exhaustive list of combinators.
 
-There are more complex (and more useful) parsers like `chain!` and `tuple!`, which are used to apply a series of parsers then assemble their results.
+There are more complex (and more useful) parsers like `chain!` and `tuple!`, which are used to apply a serie of parsers then assemble their results.
 
 Example with `tuple!`:
 
diff --git a/src/bytes.rs b/src/bytes.rs
index ee74bb1..1418da6 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -69,9 +69,10 @@ macro_rules! tag (
 macro_rules! tag_bytes (
   ($i:expr, $bytes: expr) => (
     {
+      use std::cmp::min;
       let len = $i.len();
       let blen = $bytes.len();
-      let m   = if len < blen { len } else { blen };
+      let m   = min(len, blen);
       let reduced = &$i[..m];
       let b       = &$bytes[..m];
 
@@ -122,7 +123,6 @@ macro_rules! is_not(
 macro_rules! is_not_bytes (
   ($input:expr, $bytes:expr) => (
     {
-      use $crate::InputLength;
       let res: $crate::IResult<_,_> = match $input.iter().position(|c| {
         for &i in $bytes.iter() {
           if *c == i { return true }
@@ -135,7 +135,7 @@ macro_rules! is_not_bytes (
           res
         },
         None    => {
-          $crate::IResult::Done(&$input[$input.input_len()..], $input)
+          $crate::IResult::Done(&b""[..], $input)
         }
       };
       res
@@ -181,7 +181,6 @@ macro_rules! is_a (
 macro_rules! is_a_bytes (
   ($input:expr, $bytes:expr) => (
     {
-      use $crate::InputLength;
       let res: $crate::IResult<_,_> = match $input.iter().position(|c| {
         for &i in $bytes.iter() {
           if *c == i { return false }
@@ -194,7 +193,7 @@ macro_rules! is_a_bytes (
           res
         },
         None    => {
-          $crate::IResult::Done(&$input[($input).input_len()..], $input)
+          $crate::IResult::Done(&b""[..], $input)
         }
       };
       res
@@ -250,7 +249,6 @@ macro_rules! escaped1 (
 macro_rules! escaped_impl (
   ($i: expr, $normal:ident!(  $($args:tt)* ), $control_char: expr, $escapable:ident!(  $($args2:tt)* )) => (
     {
-      use $crate::InputLength;
       let cl = || {
         use $crate::HexDisplay;
         let mut index  = 0;
@@ -258,7 +256,7 @@ macro_rules! escaped_impl (
         while index < $i.len() {
           if let $crate::IResult::Done(i,_) = $normal!(&$i[index..], $($args)*) {
             if i.is_empty() {
-              return $crate::IResult::Done(&$i[$i.input_len()..], $i)
+              return $crate::IResult::Done(&b""[..], $i)
             } else {
               index = $i.offset(i);
             }
@@ -269,7 +267,7 @@ macro_rules! escaped_impl (
               match $escapable!(&$i[index+1..], $($args2)*) {
                 $crate::IResult::Done(i,_) => {
                   if i.is_empty() {
-                    return $crate::IResult::Done(&$i[$i.input_len()..], $i)
+                    return $crate::IResult::Done(&b""[..], $i)
                   } else {
                     index = $i.offset(i);
                   }
@@ -363,7 +361,6 @@ macro_rules! escaped_transform1 (
 macro_rules! escaped_transform_impl (
   ($i: expr, $normal:ident!(  $($args:tt)* ), $control_char: expr, $transform:ident!(  $($args2:tt)* )) => (
     {
-      use $crate::InputLength;
       let cl = || {
         use $crate::HexDisplay;
         let mut index  = 0;
@@ -373,7 +370,7 @@ macro_rules! escaped_transform_impl (
           if let $crate::IResult::Done(i,o) = $normal!(&$i[index..], $($args)*) {
             res.extend(o.iter().cloned());
             if i.is_empty() {
-              return $crate::IResult::Done(&$i[$i.input_len()..], res)
+              return $crate::IResult::Done(&b""[..], res)
             } else {
               index = $i.offset(i);
             }
@@ -385,7 +382,7 @@ macro_rules! escaped_transform_impl (
                 $crate::IResult::Done(i,o) => {
                   res.extend(o.iter().cloned());
                   if i.is_empty() {
-                    return $crate::IResult::Done(&$i[$i.input_len()..], res)
+                    return $crate::IResult::Done(&b""[..], res)
                   } else {
                     index = $i.offset(i);
                   }
@@ -491,7 +488,7 @@ macro_rules! take_till (
     {
       match $input.iter().position(|c| $submac!(c, $($args)*)) {
         Some(n) => $crate::IResult::Done(&$input[n..], &$input[..n]),
-        None    => $crate::IResult::Done(&$input[($input).input_len()..], $input)
+        None    => $crate::IResult::Done(&b""[..], $input)
       }
     }
   );
@@ -779,7 +776,7 @@ mod tests {
   use internal::IResult::*;
   use internal::Err::*;
   use util::ErrorKind;
-  use nom::{alpha, digit, hex_digit, oct_digit, alphanumeric, space, multispace};
+  use nom::{alpha, digit, hex_digit, alphanumeric, space, multispace};
 
   #[test]
   fn is_a() {
@@ -951,10 +948,6 @@ mod tests {
     let rhd = yhd(&b"123abcDEF"[..]);
     assert_eq!(rhd, Done(empty, &b"123abcDEF"[..]));
 
-    named!(yod, recognize!(oct_digit));
-    let rod = yod(&b"1234567"[..]);
-    assert_eq!(rod, Done(empty, &b"1234567"[..]));
-
     named!(yan, recognize!(alphanumeric));
     let ran = yan(&b"123abc"[..]);
     assert_eq!(ran, Done(empty, &b"123abc"[..]));
diff --git a/src/internal.rs b/src/internal.rs
index e7b1585..eb6cd34 100644
--- a/src/internal.rs
+++ b/src/internal.rs
@@ -1,7 +1,6 @@
 //! Basic types to build the parsers
 
 use self::IResult::*;
-use self::Needed::*;
 use util::ErrorKind;
 
 #[cfg(feature = "core")]
@@ -33,21 +32,6 @@ pub enum Needed {
   Size(usize)
 }
 
-impl Needed {
-  pub fn is_known(&self) -> bool {
-    *self != Unknown
-  }
-
-  /// Maps a `Needed` to `Needed` by appling a function to a contained `Size` value.
-  #[inline]
-  pub fn map<F: FnOnce(usize) -> usize>(self, f: F) -> Needed {
-    match self {
-      Unknown => Unknown,
-      Size(n) => Size(f(n)),
-    }
-  }
-}
-
 /// Holds the result of parsing functions
 ///
 /// It depends on I, the input type, O, the output type, and E, the error type (by default u32)
@@ -83,44 +67,6 @@ impl<I,O,E> IResult<I,O,E> {
       _             => false
     }
   }
-
-  /// Maps a `IResult<I, O, E>` to `IResult<I, N, E>` by appling a function
-  /// to a contained `Done` value, leaving `Error` and `Incomplete` value
-  /// untouched.
-  #[inline]
-  pub fn map<N, F: FnOnce(O) -> N>(self, f: F) -> IResult<I, N, E> {
-    match self {
-      Done(i, o)    => Done(i, f(o)),
-      Error(e)      => Error(e),
-      Incomplete(n) => Incomplete(n),
-    }
-  }
-
-  /// Maps a `IResult<I, O, E>` to `IResult<I, O, E>` by appling a function
-  /// to a contained `Incomplete` value, leaving `Done` and `Error` value
-  /// untouched.
-  #[inline]
-  pub fn map_inc<F>(self, f: F) -> IResult<I, O, E>
-   where F: FnOnce(Needed) -> Needed {
-    match self {
-      Error(e)      => Error(e),
-      Incomplete(n) => Incomplete(f(n)),
-      Done(i, o)    => Done(i, o),
-    }
-  }
-
-  /// Maps a `IResult<I, O, E>` to `IResult<I, O, N>` by appling a function
-  /// to a contained `Error` value, leaving `Done` and `Incomplete` value
-  /// untouched.
-  #[inline]
-  pub fn map_err<N, F>(self, f: F) -> IResult<I, O, N>
-   where F: FnOnce(Err<I, E>) -> Err<I, N> {
-    match self {
-      Error(e)      => Error(f(e)),
-      Incomplete(n) => Incomplete(n),
-      Done(i, o)    => Done(i, o),
-    }
-  }
 }
 
 pub trait GetInput<I> {
@@ -184,58 +130,3 @@ impl<'a,I,E> GetOutput<&'a str> for IResult<I,&'a str,E> {
     }
   }
 }
-
-#[cfg(test)]
-mod tests {
-  use super::*;
-  use util::ErrorKind;
-
-  #[test]
-  fn needed_map() {
-    let unknown = Needed::Unknown;
-    let size = Needed::Size(5);
-
-    assert_eq!(size.map(|x| x * 2), Needed::Size(10));
-    assert_eq!(unknown.map(|x| x * 2), Needed::Unknown);
-  }
-
-  #[test]
-  fn iresult_map() {
-    let done: IResult<&[u8], u32> = IResult::Done(&b""[..], 5);
-    let error: IResult<&[u8], u32> = IResult::Error(Err::Code(ErrorKind::Tag));
-    let incomplete: IResult<&[u8], u32> = IResult::Incomplete(Needed::Unknown);
-
-    assert_eq!(done.map(|x| x * 2), IResult::Done(&b""[..], 10));
-    assert_eq!(error.map(|x| x * 2), IResult::Error(Err::Code(ErrorKind::Tag)));
-    assert_eq!(incomplete.map(|x| x * 2), IResult::Incomplete(Needed::Unknown));
-  }
-
-  #[test]
-  fn iresult_map_inc() {
-    let done: IResult<&[u8], u32> = IResult::Done(&b""[..], 5);
-    let error: IResult<&[u8], u32> = IResult::Error(Err::Code(ErrorKind::Tag));
-    let inc_unknown: IResult<&[u8], u32> = IResult::Incomplete(Needed::Unknown);
-    let inc_size: IResult<&[u8], u32> = IResult::Incomplete(Needed::Size(5));
-
-    assert_eq!(done.map_inc(|n| if let Needed::Size(i) = n {Needed::Size(i+1)} else {n}), IResult::Done(&b""[..], 5));
-    assert_eq!(error.map_inc(|n| if let Needed::Size(i) = n {Needed::Size(i+1)} else {n}), IResult::Error(Err::Code(ErrorKind::Tag)));
-    assert_eq!(inc_unknown.map_inc(|n| if let Needed::Size(i) = n {Needed::Size(i+1)} else {n}), IResult::Incomplete(Needed::Unknown));
-    assert_eq!(inc_size.map_inc(|n| if let Needed::Size(i) = n {Needed::Size(i+1)} else {n}), IResult::Incomplete(Needed::Size(6)));
-  }
-
-  #[test]
-  fn iresult_map_err() {
-    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
-    struct Error(u32);
-
-    let error_kind = Err::Code(ErrorKind::Custom(Error(5)));
-
-    let done: IResult<&[u8], u32> = IResult::Done(&b""[..], 5);
-    let error: IResult<&[u8], u32> = IResult::Error(Err::Code(ErrorKind::Tag));
-    let incomplete: IResult<&[u8], u32> = IResult::Incomplete(Needed::Unknown);
-
-    assert_eq!(done.map_err(|_| error_kind.clone()), IResult::Done(&b""[..], 5));
-    assert_eq!(error.map_err(|x| {println!("err: {:?}", x); error_kind.clone()}), IResult::Error(error_kind.clone()));
-    assert_eq!(incomplete.map_err(|x| {println!("err: {:?}", x); error_kind.clone()}), IResult::Incomplete(Needed::Unknown));
-  }
-}
diff --git a/src/lib.rs b/src/lib.rs
index 11b475d..12cec1b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -87,15 +87,14 @@
 #![cfg_attr(feature = "core", feature(no_std))]
 #![cfg_attr(feature = "core", feature(collections))]
 #![cfg_attr(feature = "core", no_std)]
+#![cfg_attr(feature = "regexp_macros", feature(plugin))]
+#![cfg_attr(feature = "regexp_macros", plugin(regex_macros))]
 #![cfg_attr(feature = "nightly", feature(test))]
-#![cfg_attr(feature = "nightly", feature(const_fn))]
 
 #[cfg(feature = "core")]
 extern crate collections;
 #[cfg(feature = "regexp")]
 extern crate regex;
-#[cfg(feature = "regexp_macros")]
-#[macro_use] extern crate lazy_static;
 #[cfg(feature = "nightly")]
 extern crate test;
 
diff --git a/src/macros.rs b/src/macros.rs
index 6048820..f138eee 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -534,6 +534,7 @@ macro_rules! map_opt_impl (
 macro_rules! value (
   ($i:expr, $res:expr, $submac:ident!( $($args:tt)* )) => (
     {
+      use $crate::HexDisplay;
       match $submac!($i, $($args)*) {
         $crate::IResult::Done(i,_)     => {
           $crate::IResult::Done(i, $res)
@@ -1624,7 +1625,19 @@ macro_rules! tap (
 macro_rules! pair(
   ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
     {
-      tuple!($i, $submac!($($args)*), $submac2!($($args2)*))
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i1,o1)   => {
+          match $submac2!(i1, $($args2)*) {
+            $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+            $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+            $crate::IResult::Done(i2,o2)   => {
+              $crate::IResult::Done(i2, (o1, o2))
+            }
+          }
+        },
+      }
     }
   );
 
@@ -1647,11 +1660,11 @@ macro_rules! pair(
 macro_rules! separated_pair(
   ($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)+) => (
     {
-      match tuple_parser!($i, 0usize, (), $submac!($($args)*), $($rest)*) {
+      match $submac!($i, $($args)*) {
         $crate::IResult::Error(a)      => $crate::IResult::Error(a),
         $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-        $crate::IResult::Done(i1, (o1, _, o2))   => {
-          $crate::IResult::Done(i1, (o1, o2))
+        $crate::IResult::Done(i1,o1)   => {
+          separated_pair1!(i1, o1,  $($rest)*)
         }
       }
     }
@@ -1662,18 +1675,65 @@ macro_rules! separated_pair(
   );
 );
 
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! separated_pair1(
+  ($i:expr, $res1:ident, $submac2:ident!( $($args2:tt)* ), $($rest:tt)+) => (
+    {
+      match $submac2!($i, $($args2)*) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i2,_)    => {
+          separated_pair2!(i2, $res1,  $($rest)*)
+        }
+      }
+    }
+  );
+  ($i:expr, $res1:ident, $g:expr, $($rest:tt)+) => (
+    separated_pair1!($i, $res1, call!($g), $($rest)*);
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! separated_pair2(
+  ($i:expr, $res1:ident, $submac3:ident!( $($args3:tt)* )) => (
+    {
+      match $submac3!($i, $($args3)*) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i3,o3)   => {
+          $crate::IResult::Done(i3, ($res1, o3))
+        }
+      }
+    }
+  );
+
+  ($i:expr, $res1:ident, $h:expr) => (
+    separated_pair2!($i, $res1, call!($h));
+  );
+);
+
 /// `preceded!(I -> IResult<I,T>, I -> IResult<I,O>) => I -> IResult<I, O>`
 /// preceded(opening, X) returns X
 #[macro_export]
 macro_rules! preceded(
   ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
     {
-      match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) {
+      match $submac!($i, $($args)*) {
         $crate::IResult::Error(a)      => $crate::IResult::Error(a),
         $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-        $crate::IResult::Done(remaining, (_,o))    => {
-          $crate::IResult::Done(remaining, o)
-        }
+        $crate::IResult::Done(i1,_)    => {
+          match $submac2!(i1, $($args2)*) {
+            $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+            $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+            $crate::IResult::Done(i2,o2)   => {
+              $crate::IResult::Done(i2, o2)
+            }
+          }
+        },
       }
     }
   );
@@ -1697,12 +1757,18 @@ macro_rules! preceded(
 macro_rules! terminated(
   ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
     {
-      match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) {
+      match $submac!($i, $($args)*) {
         $crate::IResult::Error(a)      => $crate::IResult::Error(a),
         $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-        $crate::IResult::Done(remaining, (o,_))    => {
-          $crate::IResult::Done(remaining, o)
-        }
+        $crate::IResult::Done(i1,o1)   => {
+          match $submac2!(i1, $($args2)*) {
+            $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+            $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+            $crate::IResult::Done(i2,_)    => {
+              $crate::IResult::Done(i2, o1)
+            }
+          }
+        },
       }
     }
   );
@@ -1726,11 +1792,11 @@ macro_rules! terminated(
 macro_rules! delimited(
   ($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)+) => (
     {
-      match tuple_parser!($i, 0usize, (), $submac!($($args)*), $($rest)*) {
+      match $submac!($i, $($args)*) {
         $crate::IResult::Error(a)      => $crate::IResult::Error(a),
         $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-        $crate::IResult::Done(i1, (_, o, _))   => {
-          $crate::IResult::Done(i1, o)
+        $crate::IResult::Done(i1,_)    => {
+          delimited1!(i1,  $($rest)*)
         }
       }
     }
@@ -1741,6 +1807,47 @@ macro_rules! delimited(
   );
 );
 
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! delimited1(
+  ($i:expr, $submac2:ident!( $($args2:tt)* ), $($rest:tt)+) => (
+    {
+      match $submac2!($i, $($args2)*) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i2,o2)   => {
+          delimited2!(i2, o2,  $($rest)*)
+        }
+      }
+    }
+  );
+  ($i:expr, $g:expr, $($rest:tt)+) => (
+    delimited1!($i, call!($g), $($rest)*);
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! delimited2(
+  ($i:expr, $res2:ident, $submac3:ident!( $($args3:tt)* )) => (
+    {
+      match $submac3!($i, $($args3)*) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i3,_)    => {
+          $crate::IResult::Done(i3, $res2)
+        }
+      }
+    }
+  );
+
+  ($i:expr, $res2:ident, $h:expr) => (
+    delimited2!($i, $res2, call!($h));
+  );
+);
+
 /// `separated_list!(I -> IResult<I,T>, I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
 /// separated_list(sep, X) returns Vec<X>
 #[macro_export]
@@ -1882,57 +1989,40 @@ macro_rules! many0(
   ($i:expr, $submac:ident!( $($args:tt)* )) => (
     {
       use $crate::InputLength;
-      if ($i).input_len() == 0 {
-        $crate::IResult::Done($i, ::std::vec::Vec::new())
-      } else {
-        match $submac!($i, $($args)*) {
-          $crate::IResult::Error(_)      => {
-            $crate::IResult::Done($i, ::std::vec::Vec::new())
-          },
-          $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-          $crate::IResult::Done(i1,o1)   => {
-            if i1.input_len() == 0 {
-              $crate::IResult::Done(i1,vec![o1])
-            } else {
-              let mut res    = ::std::vec::Vec::with_capacity(4);
-              res.push(o1);
-              let mut input  = i1;
-              let mut incomplete: ::std::option::Option<$crate::Needed> = ::std::option::Option::None;
-              loop {
-                match $submac!(input, $($args)*) {
-                  $crate::IResult::Done(i, o) => {
-                    // do not allow parsers that do not consume input (causes infinite loops)
-                    if i.input_len() == input.input_len() {
-                      break;
-                    }
-                    res.push(o);
-                    input = i;
-                  }
-                  $crate::IResult::Error(_)                    => {
-                    break;
-                  },
-                  $crate::IResult::Incomplete($crate::Needed::Unknown) => {
-                    incomplete = ::std::option::Option::Some($crate::Needed::Unknown);
-                    break;
-                  },
-                  $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
-                    incomplete = ::std::option::Option::Some($crate::Needed::Size(i + ($i).input_len() - input.input_len()));
-                    break;
-                  },
-                }
-                if input.input_len() == 0 {
-                  break;
-                }
-              }
 
-              match incomplete {
-                ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
-                ::std::option::Option::None    => $crate::IResult::Done(input, res)
-              }
+      let ret;
+      let mut res   = ::std::vec::Vec::new();
+      let mut input = $i;
+
+      loop {
+        if input.input_len() == 0 {
+          ret = $crate::IResult::Done(input, res); break;
+        }
+
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Error(_)                            => {
+            ret = $crate::IResult::Done(input, res); break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+            ret = $crate::IResult::Incomplete($crate::Needed::Unknown); break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            let size = i + ($i).input_len() - input.input_len();
+            ret = $crate::IResult::Incomplete($crate::Needed::Size(size)); break;
+          },
+          $crate::IResult::Done(i, o)                          => {
+            // loop trip must always consume (otherwise infinite loops)
+            if i == input {
+              ret = $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Many0,input)); break;
             }
+
+            res.push(o);
+            input = i;
           }
         }
       }
+
+      ret
     }
   );
   ($i:expr, $f:expr) => (
@@ -2304,6 +2394,246 @@ macro_rules! length_value(
   );
 );
 
+/// `fold_many0!(I -> IResult<I,O>, R, Fn(R, O) -> R) => I -> IResult<I, R>`
+/// Applies the parser 0 or more times and folds the list of return values
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, fold_many0!( tag!( "abcd" ), Vec::new(), |mut acc: Vec<_>, item| {
+///      acc.push(item);
+///      acc
+///  }));
+///
+///  let a = b"abcdabcdefgh";
+///  let b = b"azerty";
+///
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&a[..]), Done(&b"efgh"[..], res));
+///  assert_eq!(multi(&b[..]), Done(&b"azerty"[..], Vec::new()));
+/// # }
+/// ```
+/// 0 or more
+#[macro_export]
+macro_rules! fold_many0(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $init:expr, $f:expr) => (
+    {
+      use $crate::InputLength;
+      let ret;
+      let f         = $f;
+      let mut res   = $init;
+      let mut input = $i;
+
+      loop {
+        if input.input_len() == 0 {
+          ret = $crate::IResult::Done(input, res); break;
+        }
+
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Error(_)                            => {
+            ret = $crate::IResult::Done(input, res); break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+            ret = $crate::IResult::Incomplete($crate::Needed::Unknown); break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            let size = i + ($i).input_len() - input.input_len();
+            ret = $crate::IResult::Incomplete($crate::Needed::Size(size)); break;
+          },
+          $crate::IResult::Done(i, o)                          => {
+            // loop trip must always consume (otherwise infinite loops)
+            if i == input {
+              ret = $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Many0,input)); break;
+            }
+
+            res = f(res, o);
+            input = i;
+          }
+        }
+      }
+
+      ret
+    }
+  );
+  ($i:expr, $f:expr, $init:expr, $fold_f:expr) => (
+    fold_many0!($i, call!($f), $init, $fold_f);
+  );
+);
+
+/// `fold_many1!(I -> IResult<I,O>, R, Fn(R, O) -> R) => I -> IResult<I, R>`
+/// Applies the parser 1 or more times and folds the list of return values
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, fold_many1!( tag!( "abcd" ), Vec::new(), |mut acc: Vec<_>, item| {
+///      acc.push(item);
+///      acc
+///  }));
+///
+///  let a = b"abcdabcdefgh";
+///  let b = b"azerty";
+///
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&a[..]), Done(&b"efgh"[..], res));
+///  assert_eq!(multi(&b[..]), Error(Position(ErrorKind::Many1,&b[..])));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! fold_many1(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $init:expr, $f:expr) => (
+    {
+      use $crate::InputLength;
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Error(_)      => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Many1,$i)),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i1,o1)   => {
+          let acc = $init;
+          let f = $f;
+          if i1.len() == 0 {
+            let acc = f(acc, o1);
+            $crate::IResult::Done(i1,acc)
+          } else {
+            let mut acc = f(acc, o1);
+            let mut input  = i1;
+            let mut incomplete: ::std::option::Option<$crate::Needed> = ::std::option::Option::None;
+            loop {
+              if input.input_len() == 0 {
+                break;
+              }
+              match $submac!(input, $($args)*) {
+                $crate::IResult::Error(_)                    => {
+                  break;
+                },
+                $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+                  incomplete = ::std::option::Option::Some($crate::Needed::Unknown);
+                  break;
+                },
+                $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+                  incomplete = ::std::option::Option::Some($crate::Needed::Size(i + ($i).input_len() - input.input_len()));
+                  break;
+                },
+                $crate::IResult::Done(i, o) => {
+                  if i.input_len() == input.input_len() {
+                    break;
+                  }
+                  acc = f(acc, o);
+                  input = i;
+                }
+              }
+            }
+
+            match incomplete {
+              ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+              ::std::option::Option::None    => $crate::IResult::Done(input, acc)
+            }
+          }
+        }
+      }
+    }
+  );
+  ($i:expr, $f:expr, $init:expr, $fold_f:expr) => (
+    fold_many1!($i, call!($f), $init, $fold_f);
+  );
+);
+
+/// `fold_many_m_n!(usize, usize, I -> IResult<I,O>, R, Fn(R, O) -> R) => I -> IResult<I, R>`
+/// Applies the parser between m and n times (n included) and folds the list of return value
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, fold_many_m_n!(2, 4, tag!( "abcd" ), Vec::new(), |mut acc: Vec<_>, item| {
+///      acc.push(item);
+///      acc
+///  }));
+///
+///  let a = b"abcdefgh";
+///  let b = b"abcdabcdefgh";
+///  let c = b"abcdabcdabcdabcdabcdefgh";
+///
+///  assert_eq!(multi(&a[..]),Error(Position(ErrorKind::ManyMN,&a[..])));
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&b[..]), Done(&b"efgh"[..], res));
+///  let res2 = vec![&b"abcd"[..], &b"abcd"[..], &b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&c[..]), Done(&b"abcdefgh"[..], res2));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! fold_many_m_n(
+  ($i:expr, $m:expr, $n: expr, $submac:ident!( $($args:tt)* ), $init:expr, $f:expr) => (
+    {
+      use $crate::InputLength;
+      let mut acc          = $init;
+      let     f            = $f;
+      let mut input        = $i;
+      let mut count: usize = 0;
+      let mut err          = false;
+      let mut incomplete: ::std::option::Option<$crate::Needed> = ::std::option::Option::None;
+      loop {
+        if count == $n { break }
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Done(i, o) => {
+            // do not allow parsers that do not consume input (causes infinite loops)
+            if i.input_len() == input.input_len() {
+              break;
+            }
+            acc = f(acc, o);
+            input  = i;
+            count += 1;
+          }
+          $crate::IResult::Error(_)                    => {
+            err = true;
+            break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+            incomplete = ::std::option::Option::Some($crate::Needed::Unknown);
+            break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            incomplete = ::std::option::Option::Some($crate::Needed::Size(i + ($i).input_len() - input.input_len()));
+            break;
+          },
+        }
+        if input.input_len() == 0 {
+          break;
+        }
+      }
+
+      if count < $m {
+        if err {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::ManyMN,$i))
+        } else {
+          match incomplete {
+            ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+            ::std::option::Option::None    => $crate::IResult::Incomplete($crate::Needed::Unknown)
+          }
+        }
+      } else {
+        match incomplete {
+          ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+          ::std::option::Option::None    => $crate::IResult::Done(input, acc)
+        }
+      }
+    }
+  );
+  ($i:expr, $m:expr, $n: expr, $f:expr, $init:expr, $fold_f:expr) => (
+    fold_many_m_n!($i, $m, $n, call!($f), $init, $fold_f);
+  );
+);
 
 #[cfg(test)]
 mod tests {
@@ -2398,8 +2728,7 @@ mod tests {
   fn chain2() {
     fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
     fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Done(i,2) };
-
-    named!(chain_parser<&[u8],B>,
+    named!(f<&[u8],B>,
       chain!(
         tag!("abcd")   ~
         tag!("abcd")?  ~
@@ -2411,18 +2740,18 @@ mod tests {
       )
     );
 
-    assert_eq!(chain_parser(&b"abcdabcdefghefghX"[..]), Done(&b"X"[..], B{a: 1, b: 2}));
-    assert_eq!(chain_parser(&b"abcdefghefghX"[..]), Done(&b"X"[..], B{a: 1, b: 2}));
-    assert_eq!(chain_parser(&b"abcdab"[..]), Incomplete(Needed::Size(8)));
-    assert_eq!(chain_parser(&b"abcdefghef"[..]), Incomplete(Needed::Size(12)));
+    let r = f(&b"abcdabcdefghefghX"[..]);
+    assert_eq!(r, Done(&b"X"[..], B{a: 1, b: 2}));
+
+    let r2 = f(&b"abcdefghefghX"[..]);
+    assert_eq!(r2, Done(&b"X"[..], B{a: 1, b: 2}));
   }
 
   #[test]
   fn nested_chain() {
     fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
     fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Done(i,2) };
-
-    named!(chain_parser<&[u8],B>,
+    named!(f<&[u8],B>,
       chain!(
         chain!(
           tag!("abcd")   ~
@@ -2437,10 +2766,11 @@ mod tests {
       )
     );
 
-    assert_eq!(chain_parser(&b"abcdabcdefghefghX"[..]), Done(&b"X"[..], B{a: 1, b: 2}));
-    assert_eq!(chain_parser(&b"abcdefghefghX"[..]), Done(&b"X"[..], B{a: 1, b: 2}));
-    assert_eq!(chain_parser(&b"abcdab"[..]), Incomplete(Needed::Size(8)));
-    assert_eq!(chain_parser(&b"abcdefghef"[..]), Incomplete(Needed::Size(12)));
+    let r = f(&b"abcdabcdefghefghX"[..]);
+    assert_eq!(r, Done(&b"X"[..], B{a: 1, b: 2}));
+
+    let r2 = f(&b"abcdefghefghX"[..]);
+    assert_eq!(r2, Done(&b"X"[..], B{a: 1, b: 2}));
   }
 
   #[derive(PartialEq,Eq,Debug)]
@@ -2476,7 +2806,7 @@ mod tests {
     fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
     named!(ret_y<&[u8], u8>, map!(y, |_| 2));
 
-    named!(chain_parser<&[u8],C>,
+    named!(f<&[u8],C>,
       chain!(
         tag!("abcd") ~
         aa: ret_int1 ~
@@ -2485,10 +2815,14 @@ mod tests {
       )
     );
 
-    assert_eq!(chain_parser(&b"abcdefghX"[..]), Done(&b"X"[..], C{a: 1, b: Some(2)}));
-    assert_eq!(chain_parser(&b"abcdWXYZ"[..]), Done(&b"WXYZ"[..], C{a: 1, b: None}));
-    assert_eq!(chain_parser(&b"abcdX"[..]), Done(&b"X"[..], C{ a: 1, b: None }));
-    assert_eq!(chain_parser(&b"abcdef"[..]), Incomplete(Needed::Size(8)));
+    let r = f(&b"abcdefghX"[..]);
+    assert_eq!(r, Done(&b"X"[..], C{a: 1, b: Some(2)}));
+
+    let r2 = f(&b"abcdWXYZ"[..]);
+    assert_eq!(r2, Done(&b"WXYZ"[..], C{a: 1, b: None}));
+
+    let r3 = f(&b"abcdX"[..]);
+    assert_eq!(r3, Done(&b"X"[..], C{a: 1, b: None}));
   }
 
   use util::{error_to_list, add_error_pattern, print_error};
@@ -2741,117 +3075,80 @@ mod tests {
 
   #[test]
   fn cond() {
-    let f_true: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( true, tag!("abcd") ) ));
-    let f_false: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( false, tag!("abcd") ) ));
-    //let f_false = closure!(&'static [u8], cond!( false, tag!("abcd") ) );
+    let b = true;
+    let f: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( b, tag!("abcd") ) ));
 
-    assert_eq!(f_true(&b"abcdef"[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
-    assert_eq!(f_true(&b"ab"[..]), Incomplete(Needed::Size(4)));
-    assert_eq!(f_true(&b"xxx"[..]), Done(&b"xxx"[..], None));
+    let a = b"abcdef";
+    assert_eq!(f(&a[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
 
-    assert_eq!(f_false(&b"abcdef"[..]), Done(&b"abcdef"[..], None));
-    assert_eq!(f_false(&b"ab"[..]), Done(&b"ab"[..], None));
-    assert_eq!(f_false(&b"xxx"[..]), Done(&b"xxx"[..], None));
+    let b2 = false;
+    let f2: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( b2, tag!("abcd") ) ));
+    //let f2 = closure!(&'static [u8], cond!( b2, tag!("abcd") ) );
+
+    assert_eq!(f2(&a[..]), Done(&b"abcdef"[..], None));
   }
 
   #[test]
   fn cond_wrapping() {
     // Test that cond!() will wrap a given identifier in the call!() macro.
-    named!( tag_abcd, tag!("abcd") );
-    let f_true: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( true, tag_abcd ) ));
-    let f_false: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( false, tag_abcd ) ));
-    //let f_false = closure!(&'static [u8], cond!( b2, tag!("abcd") ) );
 
-    assert_eq!(f_true(&b"abcdef"[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
-    assert_eq!(f_true(&b"ab"[..]), Incomplete(Needed::Size(4)));
-    assert_eq!(f_true(&b"xxx"[..]), Done(&b"xxx"[..], None));
+    named!(silly, tag!("foo"));
 
-    assert_eq!(f_false(&b"abcdef"[..]), Done(&b"abcdef"[..], None));
-    assert_eq!(f_false(&b"ab"[..]), Done(&b"ab"[..], None));
-    assert_eq!(f_false(&b"xxx"[..]), Done(&b"xxx"[..], None));
+    let b = true;
+    //let f = closure!(&'static [u8], cond!( b, silly ) );
+    let f: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( b, silly ) ));
+    assert_eq!(f(b"foobar"), Done(&b"bar"[..], Some(&b"foo"[..])));
   }
 
   #[test]
   fn peek() {
-    named!(peek_tag<&[u8],&[u8]>, peek!(tag!("abcd")));
+    named!(ptag<&[u8],&[u8]>, peek!(tag!("abcd")));
+
+    let r1 = ptag(&b"abcdefgh"[..]);
+    assert_eq!(r1, Done(&b"abcdefgh"[..], &b"abcd"[..]));
 
-    assert_eq!(peek_tag(&b"abcdef"[..]), Done(&b"abcdef"[..], &b"abcd"[..]));
-    assert_eq!(peek_tag(&b"ab"[..]), Incomplete(Needed::Size(4)));
-    assert_eq!(peek_tag(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    let r1 = ptag(&b"efgh"[..]);
+    assert_eq!(r1, Error(Position(ErrorKind::Tag,&b"efgh"[..])));
   }
 
   #[test]
   fn pair() {
-    named!( tag_abc, tag!("abc") );
-    named!( tag_def, tag!("def") );
-    named!( pair_abc_def<&[u8],(&[u8], &[u8])>, pair!(tag_abc, tag_def) );
-
-    assert_eq!(pair_abc_def(&b"abcdefghijkl"[..]), Done(&b"ghijkl"[..], (&b"abc"[..], &b"def"[..])));
-    assert_eq!(pair_abc_def(&b"ab"[..]), Incomplete(Needed::Size(3)));
-    assert_eq!(pair_abc_def(&b"abcd"[..]), Incomplete(Needed::Size(6)));
-    assert_eq!(pair_abc_def(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
-    assert_eq!(pair_abc_def(&b"xxxdef"[..]), Error(Position(ErrorKind::Tag, &b"xxxdef"[..])));
-    assert_eq!(pair_abc_def(&b"abcxxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    named!(p<&[u8],(&[u8], &[u8])>, pair!(tag!("abcd"), tag!("efgh")));
+
+    let r1 = p(&b"abcdefghijkl"[..]);
+    assert_eq!(r1, Done(&b"ijkl"[..], (&b"abcd"[..], &b"efgh"[..])));
   }
 
   #[test]
   fn separated_pair() {
-    named!( tag_abc, tag!("abc") );
-    named!( tag_def, tag!("def") );
-    named!( tag_separator, tag!(",") );
-    named!( sep_pair_abc_def<&[u8],(&[u8], &[u8])>, separated_pair!(tag_abc, tag_separator, tag_def) );
-
-    assert_eq!(sep_pair_abc_def(&b"abc,defghijkl"[..]), Done(&b"ghijkl"[..], (&b"abc"[..], &b"def"[..])));
-    assert_eq!(sep_pair_abc_def(&b"ab"[..]), Incomplete(Needed::Size(3)));
-    assert_eq!(sep_pair_abc_def(&b"abc,d"[..]), Incomplete(Needed::Size(7)));
-    assert_eq!(sep_pair_abc_def(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
-    assert_eq!(sep_pair_abc_def(&b"xxx,def"[..]), Error(Position(ErrorKind::Tag, &b"xxx,def"[..])));
-    assert_eq!(sep_pair_abc_def(&b"abc,xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    named!(p<&[u8],(&[u8], &[u8])>, separated_pair!(tag!("abcd"), tag!(","), tag!("efgh")));
+
+    let r1 = p(&b"abcd,efghijkl"[..]);
+    assert_eq!(r1, Done(&b"ijkl"[..], (&b"abcd"[..], &b"efgh"[..])));
   }
 
   #[test]
   fn preceded() {
-    named!( tag_abcd, tag!("abcd") );
-    named!( tag_efgh, tag!("efgh") );
-    named!( preceded_abcd_efgh<&[u8], &[u8]>, preceded!(tag_abcd, tag_efgh) );
-
-    assert_eq!(preceded_abcd_efgh(&b"abcdefghijkl"[..]), Done(&b"ijkl"[..], &b"efgh"[..]));
-    assert_eq!(preceded_abcd_efgh(&b"ab"[..]), Incomplete(Needed::Size(4)));
-    assert_eq!(preceded_abcd_efgh(&b"abcde"[..]), Incomplete(Needed::Size(8)));
-    assert_eq!(preceded_abcd_efgh(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
-    assert_eq!(preceded_abcd_efgh(&b"xxxxdef"[..]), Error(Position(ErrorKind::Tag, &b"xxxxdef"[..])));
-    assert_eq!(preceded_abcd_efgh(&b"abcdxxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    named!(p<&[u8], &[u8]>, preceded!(tag!("abcd"), tag!("efgh")));
+
+    let r1 = p(&b"abcdefghijkl"[..]);
+    assert_eq!(r1, Done(&b"ijkl"[..], &b"efgh"[..]));
   }
 
   #[test]
   fn terminated() {
-    named!( tag_abcd, tag!("abcd") );
-    named!( tag_efgh, tag!("efgh") );
-    named!( terminated_abcd_efgh<&[u8], &[u8]>, terminated!(tag_abcd, tag_efgh) );
-
-    assert_eq!(terminated_abcd_efgh(&b"abcdefghijkl"[..]), Done(&b"ijkl"[..], &b"abcd"[..]));
-    assert_eq!(terminated_abcd_efgh(&b"ab"[..]), Incomplete(Needed::Size(4)));
-    assert_eq!(terminated_abcd_efgh(&b"abcde"[..]), Incomplete(Needed::Size(8)));
-    assert_eq!(terminated_abcd_efgh(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
-    assert_eq!(terminated_abcd_efgh(&b"xxxxdef"[..]), Error(Position(ErrorKind::Tag, &b"xxxxdef"[..])));
-    assert_eq!(terminated_abcd_efgh(&b"abcdxxxx"[..]), Error(Position(ErrorKind::Tag, &b"xxxx"[..])));
+    named!(p<&[u8], &[u8]>, terminated!(tag!("abcd"), tag!("efgh")));
+
+    let r1 = p(&b"abcdefghijkl"[..]);
+    assert_eq!(r1, Done(&b"ijkl"[..], &b"abcd"[..]));
   }
 
   #[test]
   fn delimited() {
-    named!( tag_abc, tag!("abc") );
-    named!( tag_def, tag!("def") );
-    named!( tag_ghi, tag!("ghi") );
-    named!( delimited_abc_def_ghi<&[u8], &[u8]>, delimited!(tag_abc, tag_def, tag_ghi) );
-
-    assert_eq!(delimited_abc_def_ghi(&b"abcdefghijkl"[..]), Done(&b"jkl"[..], &b"def"[..]));
-    assert_eq!(delimited_abc_def_ghi(&b"ab"[..]), Incomplete(Needed::Size(3)));
-    assert_eq!(delimited_abc_def_ghi(&b"abcde"[..]), Incomplete(Needed::Size(6)));
-    assert_eq!(delimited_abc_def_ghi(&b"abcdefgh"[..]), Incomplete(Needed::Size(9)));
-    assert_eq!(delimited_abc_def_ghi(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
-    assert_eq!(delimited_abc_def_ghi(&b"xxxdefghi"[..]), Error(Position(ErrorKind::Tag, &b"xxxdefghi"[..])));
-    assert_eq!(delimited_abc_def_ghi(&b"abcxxxghi"[..]), Error(Position(ErrorKind::Tag, &b"xxxghi"[..])));
-    assert_eq!(delimited_abc_def_ghi(&b"abcdefxxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    named!(p<&[u8], &[u8]>, delimited!(tag!("abcd"), tag!("efgh"), tag!("ij")));
+
+    let r1 = p(&b"abcdefghijkl"[..]);
+    assert_eq!(r1, Done(&b"kl"[..], &b"efgh"[..]));
   }
 
   #[test]
@@ -2890,19 +3187,18 @@ mod tests {
 
   #[test]
   fn many0() {
-    named!(multi<&[u8],Vec<&[u8]> >, many0!(tag!("abcd")));
-
-    let a = &b"abcdef"[..];
-    let b = &b"abcdabcdefgh"[..];
-    let c = &b"azerty"[..];
-    let d = &b"abcdab"[..];
-
-    let res1 = vec![&b"abcd"[..]];
-    assert_eq!(multi(a), Done(&b"ef"[..], res1));
-    let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
-    assert_eq!(multi(b), Done(&b"efgh"[..], res2));
-    assert_eq!(multi(c), Done(&b"azerty"[..], Vec::new()));
-    assert_eq!(multi(d), Incomplete(Needed::Size(8)));
+    named!( tag_abcd, tag!("abcd") );
+    named!( tag_empty, tag!("") );
+    named!( multi<&[u8],Vec<&[u8]> >, many0!(tag_abcd) );
+    named!( multi_empty<&[u8],Vec<&[u8]> >, many0!(tag_empty) );
+
+    assert_eq!(multi(&b"abcdef"[..]), Done(&b"ef"[..], vec![&b"abcd"[..]]));
+    assert_eq!(multi(&b"abcdabcdefgh"[..]), Done(&b"efgh"[..], vec![&b"abcd"[..], &b"abcd"[..]]));
+    assert_eq!(multi(&b"azerty"[..]), Done(&b"azerty"[..], Vec::new()));
+    assert_eq!(multi(&b"abcdab"[..]), Incomplete(Needed::Size(8)));
+    assert_eq!(multi(&b"abcd"[..]), Done(&b""[..], vec![&b"abcd"[..]]));
+    assert_eq!(multi(&b""[..]), Done(&b""[..], Vec::new()));
+    assert_eq!(multi_empty(&b"abcdef"[..]), Error(Position(ErrorKind::Many0, &b"abcdef"[..])));
   }
 
   #[cfg(feature = "nightly")]
@@ -2973,16 +3269,17 @@ mod tests {
 
   #[test]
   fn count() {
-    const TIMES: usize = 2;
-    named!( tag_abc, tag!("abc") );
-    named!( cnt_2<&[u8], Vec<&[u8]> >, count!(tag_abc, TIMES ) );
-
-    assert_eq!(cnt_2(&b"abcabcabcdef"[..]), Done(&b"abcdef"[..], vec![&b"abc"[..], &b"abc"[..]]));
-    assert_eq!(cnt_2(&b"ab"[..]), Incomplete(Needed::Unknown));
-    assert_eq!(cnt_2(&b"abcab"[..]), Incomplete(Needed::Unknown));
-    assert_eq!(cnt_2(&b"xxx"[..]), Error(Position(ErrorKind::Count, &b"xxx"[..])));
-    assert_eq!(cnt_2(&b"xxxabcabcdef"[..]), Error(Position(ErrorKind::Count, &b"xxxabcabcdef"[..])));
-    assert_eq!(cnt_2(&b"abcxxxabcdef"[..]), Error(Position(ErrorKind::Count, &b"abcxxxabcdef"[..])));
+    fn counter(input: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
+      let size: usize = 2;
+      count!(input, tag!( "abcd" ), size )
+    }
+
+    let a = b"abcdabcdabcdef";
+    let b = b"abcdefgh";
+    let res = vec![&b"abcd"[..], &b"abcd"[..]];
+
+    assert_eq!(counter(&a[..]), Done(&b"abcdef"[..], res));
+    assert_eq!(counter(&b[..]), Error(Position(ErrorKind::Count, &b[..])));
   }
 
   #[test]
@@ -3018,16 +3315,17 @@ mod tests {
 
   #[test]
   fn count_fixed() {
-    const TIMES: usize = 2;
-    named!( tag_abc, tag!("abc") );
-    named!( cnt_2<&[u8], [&[u8]; TIMES] >, count_fixed!(&[u8], tag_abc, TIMES ) );
-
-    assert_eq!(cnt_2(&b"abcabcabcdef"[..]), Done(&b"abcdef"[..], [&b"abc"[..], &b"abc"[..]]));
-    assert_eq!(cnt_2(&b"ab"[..]), Incomplete(Needed::Unknown));
-    assert_eq!(cnt_2(&b"abcab"[..]), Incomplete(Needed::Unknown));
-    assert_eq!(cnt_2(&b"xxx"[..]), Error(Position(ErrorKind::Count, &b"xxx"[..])));
-    assert_eq!(cnt_2(&b"xxxabcabcdef"[..]), Error(Position(ErrorKind::Count, &b"xxxabcabcdef"[..])));
-    assert_eq!(cnt_2(&b"abcxxxabcdef"[..]), Error(Position(ErrorKind::Count, &b"abcxxxabcdef"[..])));
+    //named!(counter< [&[u8]; 2], u32 >, count_fixed!( &[u8], tag!( "abcd" ), 2 ) );
+    fn counter(input:&[u8]) -> IResult<&[u8], [&[u8]; 2], () > {
+      count_fixed!(input, &[u8], tag!( "abcd" ), 2 )
+    }
+
+    let a = b"abcdabcdabcdef";
+    let b = b"abcdefgh";
+    let res = [&b"abcd"[..], &b"abcd"[..]];
+
+    assert_eq!(counter(&a[..]), Done(&b"abcdef"[..], res));
+    assert_eq!(counter(&b[..]), Error(Position(ErrorKind::Count, &b[..])));
   }
 
   use nom::{le_u16,eof};
@@ -3069,38 +3367,124 @@ mod tests {
   use nom::{be_u8,be_u16};
   #[test]
   fn length_value_test() {
-    named!(length_value_1<&[u8], Vec<u16> >, length_value!(be_u8, be_u16));
-    named!(length_value_2<&[u8], Vec<u16> >, length_value!(be_u8, be_u16, 2));
+    named!(tst1<&[u8], Vec<u16> >, length_value!(be_u8, be_u16));
+    named!(tst2<&[u8], Vec<u16> >, length_value!(be_u8, be_u16, 2));
 
     let i1 = vec![0, 5, 6];
-    assert_eq!(length_value_1(&i1), IResult::Done(&i1[1..], vec![]));
-    assert_eq!(length_value_2(&i1), IResult::Done(&i1[1..], vec![]));
-
     let i2 = vec![1, 5, 6, 3];
-    assert_eq!(length_value_1(&i2), IResult::Done(&i2[3..], vec![1286]));
-    assert_eq!(length_value_2(&i2), IResult::Done(&i2[3..], vec![1286]));
+    let i3 = vec![2, 5, 6, 3];
+    let i4 = vec![2, 5, 6, 3, 4, 5, 7];
+    let i5 = vec![3, 5, 6, 3, 4, 5];
 
-    let i3 = vec![2, 5, 6, 3, 4, 5, 7];
-    assert_eq!(length_value_1(&i3), IResult::Done(&i3[5..], vec![1286, 772]));
-    assert_eq!(length_value_2(&i3), IResult::Done(&i3[5..], vec![1286, 772]));
+    let r1: Vec<u16> = Vec::new();
+    let r2: Vec<u16> = vec![1286];
+    let r4: Vec<u16> = vec![1286, 772];
+    assert_eq!(tst1(&i1), IResult::Done(&i1[1..], r1));
+    assert_eq!(tst1(&i2), IResult::Done(&i2[3..], r2));
+    assert_eq!(tst1(&i3), IResult::Incomplete(Needed::Size(5)));
+    assert_eq!(tst1(&i4), IResult::Done(&i4[5..], r4));
+    assert_eq!(tst1(&i5), IResult::Incomplete(Needed::Size(7)));
+
+    let r6: Vec<u16> = Vec::new();
+    let r7: Vec<u16> = vec![1286];
+    let r9: Vec<u16> = vec![1286, 772];
+    assert_eq!(tst2(&i1), IResult::Done(&i1[1..], r6));
+    assert_eq!(tst2(&i2), IResult::Done(&i2[3..], r7));
+    assert_eq!(tst2(&i3), IResult::Incomplete(Needed::Size(5)));
+    assert_eq!(tst2(&i4), IResult::Done(&i4[5..], r9));
+    assert_eq!(tst1(&i5), IResult::Incomplete(Needed::Size(7)));
+  }
 
-    let i4 = vec![2, 5, 6, 3];
-    assert_eq!(length_value_1(&i4), IResult::Incomplete(Needed::Size(5)));
-    assert_eq!(length_value_2(&i4), IResult::Incomplete(Needed::Size(5)));
+  #[test]
+  fn fold_many0() {
+    fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> {
+      acc.push(item);
+      acc
+    };
+    named!( tag_abcd, tag!("abcd") );
+    named!( tag_empty, tag!("") );
+    named!( multi<&[u8],Vec<&[u8]> >, fold_many0!(tag_abcd, Vec::new(), fold_into_vec) );
+    named!( multi_empty<&[u8],Vec<&[u8]> >, fold_many0!(tag_empty, Vec::new(), fold_into_vec) );
+
+    assert_eq!(multi(&b"abcdef"[..]), Done(&b"ef"[..], vec![&b"abcd"[..]]));
+    assert_eq!(multi(&b"abcdabcdefgh"[..]), Done(&b"efgh"[..], vec![&b"abcd"[..], &b"abcd"[..]]));
+    assert_eq!(multi(&b"azerty"[..]), Done(&b"azerty"[..], Vec::new()));
+    assert_eq!(multi(&b"abcdab"[..]), Incomplete(Needed::Size(8)));
+    assert_eq!(multi(&b"abcd"[..]), Done(&b""[..], vec![&b"abcd"[..]]));
+    assert_eq!(multi(&b""[..]), Done(&b""[..], Vec::new()));
+    assert_eq!(multi_empty(&b"abcdef"[..]), Error(Position(ErrorKind::Many0, &b"abcdef"[..])));
+  }
 
-    let i5 = vec![3, 5, 6, 3, 4, 5];
-    assert_eq!(length_value_1(&i5), IResult::Incomplete(Needed::Size(7)));
-    assert_eq!(length_value_2(&i5), IResult::Incomplete(Needed::Size(7)));
+  #[test]
+  fn fold_many1() {
+    fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> {
+      acc.push(item);
+      acc
+    };
+    named!(multi<&[u8],Vec<&[u8]> >, fold_many1!(tag!("abcd"), Vec::new(), fold_into_vec));
+
+    let a = &b"abcdef"[..];
+    let b = &b"abcdabcdefgh"[..];
+    let c = &b"azerty"[..];
+    let d = &b"abcdab"[..];
+
+    let res1 = vec![&b"abcd"[..]];
+    assert_eq!(multi(a), Done(&b"ef"[..], res1));
+    let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
+    assert_eq!(multi(b), Done(&b"efgh"[..], res2));
+    assert_eq!(multi(c), Error(Position(ErrorKind::Many1,c)));
+    assert_eq!(multi(d), Incomplete(Needed::Size(8)));
+  }
+
+  #[test]
+  fn fold_many_m_n() {
+    fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> {
+      acc.push(item);
+      acc
+    };
+    named!(multi<&[u8],Vec<&[u8]> >, fold_many_m_n!(2, 4, tag!("Abcd"), Vec::new(), fold_into_vec));
+
+    let a = &b"Abcdef"[..];
+    let b = &b"AbcdAbcdefgh"[..];
+    let c = &b"AbcdAbcdAbcdAbcdefgh"[..];
+    let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..];
+    let e = &b"AbcdAb"[..];
+
+    assert_eq!(multi(a), Error(Err::Position(ErrorKind::ManyMN,a)));
+    let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(b), Done(&b"efgh"[..], res1));
+    let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(c), Done(&b"efgh"[..], res2));
+    let res3 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(d), Done(&b"Abcdefgh"[..], res3));
+    assert_eq!(multi(e), Incomplete(Needed::Size(8)));
+  }
+
+  #[test]
+  fn chain_incomplete() {
+    let res = chain!(&b"abcdefgh"[..],
+      a: take!(4) ~
+      b: take!(8),
+      ||{(a,b )}
+    );
+
+    assert_eq!(res, IResult::Incomplete(Needed::Size(12)));
   }
 
   #[test]
   fn tuple_test() {
-    named!(tuple_3<&[u8], (u16, &[u8], &[u8]) >,
-    tuple!( be_u16 , take!(3), tag!("fg") ) );
+    named!(tpl<&[u8], (u16, &[u8], &[u8]) >,
+      tuple!(
+        be_u16 ,
+        take!(3),
+        tag!("fg")
+      )
+    );
 
-    assert_eq!(tuple_3(&b"abcdefgh"[..]), Done(&b"h"[..], (0x6162u16, &b"cde"[..], &b"fg"[..])));
-    assert_eq!(tuple_3(&b"abcd"[..]), Incomplete(Needed::Size(5)));
-    assert_eq!(tuple_3(&b"abcde"[..]), Incomplete(Needed::Size(7)));
-    assert_eq!(tuple_3(&b"abcdejk"[..]), Error(Position(ErrorKind::Tag, &b"jk"[..])));
+    assert_eq!(tpl(&b"abcdefgh"[..]), Done(&b"h"[..], (0x6162u16, &b"cde"[..], &b"fg"[..])));
+    assert_eq!(tpl(&b"abcd"[..]), Incomplete(Needed::Size(5)));
+    assert_eq!(tpl(&b"abcde"[..]), Incomplete(Needed::Size(7)));
+    let input = &b"abcdejk"[..];
+    assert_eq!(tpl(input), Error(Position(ErrorKind::Tag, &input[5..])));
   }
 }
diff --git a/src/methods.rs b/src/methods.rs
index 2286854..6ca3a8d 100644
--- a/src/methods.rs
+++ b/src/methods.rs
@@ -256,7 +256,7 @@ macro_rules! call_m (
 ///
 /// Supports up to 6 arguments
 #[macro_export]
-macro_rules! apply_m (
+macro_rules! apply_rf (
   ($i:expr, $self_:ident.$method:ident, $($args:expr),* ) => ( { let (tmp, res) = $self_.$method( $i, $($args),* ); $self_ = tmp; res } );
 );
 
@@ -337,7 +337,7 @@ mod tests {
       self = tmp;
       (self, res)
     }
-    method!(use_apply<Parser<'a>, &'a str, &'a str>, mut self, apply_m!(self.tag_stuff, "βçδ"));
+    method!(use_apply<Parser<'a>, &'a str, &'a str>, mut self, apply_rf!(self.tag_stuff, "βçδ"));
   }
 
   #[test]
@@ -425,7 +425,7 @@ mod tests {
   }
 
   #[test]
-  fn test_apply_m() {
+  fn test_apply_rf() {
     let mut p = Parser::new();
     let input: &str = "áβçδèƒϱλïJƙ";
     let consumed: &str = "áβç";
@@ -441,7 +441,7 @@ mod tests {
       other => panic!("`Parser.use_apply` didn't succeed when it should have. \
                              Got `{:?}`.", other),
     }
-  } 
+  }
 
   #[test]
   fn test_method_call_peek() {
diff --git a/src/nom.rs b/src/nom.rs
index cba3a21..7b6f217 100644
--- a/src/nom.rs
+++ b/src/nom.rs
@@ -51,7 +51,7 @@ pub fn not_line_ending(input:&[u8]) -> IResult<&[u8], &[u8]> {
       }
     }
   }
-  Done(&input[input.len()..], input)
+  Done(b"", input)
 }
 
 named!(tag_ln, tag!("\n"));
@@ -79,11 +79,6 @@ pub fn is_hex_digit(chr: u8) -> bool {
   (chr >= 0x61 && chr <= 0x66)
 }
 
-#[inline]
-pub fn is_oct_digit(chr: u8) -> bool {
-  chr >= 0x30 && chr <= 0x37
-}
-
 #[inline]
 pub fn is_alphanumeric(chr: u8) -> bool {
   is_alphabetic(chr) || is_digit(chr)
@@ -98,7 +93,6 @@ pub fn is_space(chr:u8) -> bool {
 //pub filter!(alpha is_alphabetic)
 //pub filter!(digit is_digit)
 //pub filter!(hex_digit is_hex_digit)
-//pub filter!(oct_digit is_oct_digit)
 //pub filter!(alphanumeric is_alphanumeric)
 
 use std::ops::{Index,Range,RangeFrom};
@@ -165,27 +159,6 @@ pub fn hex_digit<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
   Done(&input[input_length..], input)
 }
 
-/// Recognizes octal characters: 0-7
-pub fn oct_digit<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
-    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
-    &'a T: IterIndices+InputLength {
-  let input_length = input.input_len();
-  if input_length == 0 {
-    return Error(Position(ErrorKind::OctDigit, input))
-  }
-
-  for (idx, item) in input.iter_indices() {
-    if ! item.is_oct_digit() {
-      if idx == 0 {
-        return Error(Position(ErrorKind::OctDigit, input))
-      } else {
-        return Done(&input[idx..], &input[0..idx])
-      }
-    }
-  }
-  Done(&input[input_length..], input)
-}
-
 /// Recognizes numerical and alphabetic characters: 0-9a-zA-Z
 pub fn alphanumeric<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
     T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
@@ -510,14 +483,14 @@ pub fn non_empty<'a, T:?Sized>(input: &'a T) -> IResult<&'a T,&'a T> where
   if input.input_len() == 0 {
     Error(Position(ErrorKind::NonEmpty, input))
   } else {
-    Done(&input[input.input_len()..], input)
+    Done(&input[0..0], input)
   }
 }
 
 /// Return the remaining input.
 #[inline]
-pub fn rest(input: &[u8]) -> IResult<&[u8], &[u8]> {
-    IResult::Done(&input[input.len()..], input)
+pub fn rest(i: &[u8]) -> IResult<&[u8], &[u8]> {
+    IResult::Done(b"", i)
 }
 
 #[cfg(test)]
@@ -559,10 +532,6 @@ mod tests {
     assert_eq!(hex_digit(c), Done(empty, c));
     assert_eq!(hex_digit(d), Done("zé12".as_bytes(), &b"a"[..]));
     assert_eq!(hex_digit(e), Error(Position(ErrorKind::HexDigit,e)));
-    assert_eq!(oct_digit(a), Error(Position(ErrorKind::OctDigit,a)));
-    assert_eq!(oct_digit(b), Done(empty, b));
-    assert_eq!(oct_digit(c), Error(Position(ErrorKind::OctDigit,c)));
-    assert_eq!(oct_digit(d), Error(Position(ErrorKind::OctDigit,d)));
     assert_eq!(alphanumeric(a), Done(empty, a));
     assert_eq!(fix_error!(b,(), alphanumeric), Done(empty, b));
     assert_eq!(alphanumeric(c), Done(empty, c));
@@ -591,10 +560,6 @@ mod tests {
     assert_eq!(hex_digit(c), Done(empty, c));
     assert_eq!(hex_digit(d), Done("zé12", &"a"[..]));
     assert_eq!(hex_digit(e), Error(Position(ErrorKind::HexDigit,e)));
-    assert_eq!(oct_digit(a), Error(Position(ErrorKind::OctDigit,a)));
-    assert_eq!(oct_digit(b), Done(empty, b));
-    assert_eq!(oct_digit(c), Error(Position(ErrorKind::OctDigit,c)));
-    assert_eq!(oct_digit(d), Error(Position(ErrorKind::OctDigit,d)));
     assert_eq!(alphanumeric(a), Done(empty, a));
     assert_eq!(fix_error!(b,(), alphanumeric), Done(empty, b));
     assert_eq!(alphanumeric(c), Done(empty, c));
@@ -636,10 +601,6 @@ mod tests {
         Done(i, _)  => { assert_eq!(f.offset(i) + i.len(), f.len()); }
         _           => { panic!("wrong return type in offset test for hex_digit") }
     }
-    match oct_digit(f) {
-        Done(i, _)  => { assert_eq!(f.offset(i) + i.len(), f.len()); }
-        _           => { panic!("wrong return type in offset test for oct_digit") }
-    }
   }
 
   #[test]
@@ -854,26 +815,4 @@ mod tests {
     assert!(!is_hex_digit(b'@'));
     assert!(!is_hex_digit(b'\x60'));
   }
-
-  #[test]
-  fn oct_digit_test() {
-    let empty = &b""[..];
-
-    let i = &b"01234567"[..];
-    assert_eq!(oct_digit(i), Done(empty, i));
-
-    let i = &b"8"[..];
-    assert_eq!(oct_digit(i), Error(Position(ErrorKind::OctDigit,i)));
-
-    assert!(is_oct_digit(b'0'));
-    assert!(is_hex_digit(b'7'));
-    assert!(!is_oct_digit(b'8'));
-    assert!(!is_oct_digit(b'9'));
-    assert!(!is_oct_digit(b'a'));
-    assert!(!is_oct_digit(b'A'));
-    assert!(!is_oct_digit(b'/'));
-    assert!(!is_oct_digit(b':'));
-    assert!(!is_oct_digit(b'@'));
-    assert!(!is_oct_digit(b'\x60'));
-  }
 }
diff --git a/src/regexp.rs b/src/regexp.rs
index 986f1a2..8b150be 100644
--- a/src/regexp.rs
+++ b/src/regexp.rs
@@ -1,14 +1,3 @@
-#[doc(hidden)]
-#[macro_export]
-macro_rules! regex (
-  ($re: ident, $s:expr) => (
-    lazy_static! {
-      static ref $re: ::regex::Regex = ::regex::Regex::new($s).unwrap();
-    }
-  );
-);
-
-
 /// `re_match!(regexp) => &[T] -> IResult<&[T], &[T]>`
 /// Returns the whole input if a match is found
 ///
@@ -17,10 +6,9 @@ macro_rules! regex (
 macro_rules! re_match (
   ($i:expr, $re:expr) => (
     {
-      use $crate::InputLength;
       let re = ::regex::Regex::new($re).unwrap();
       if re.is_match($i) {
-        $crate::IResult::Done(&$i[$i.input_len()..], $i)
+        $crate::IResult::Done(&""[..], $i)
       } else {
         $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatch))
       }
@@ -37,10 +25,9 @@ macro_rules! re_match (
 macro_rules! re_match_static (
   ($i:expr, $re:expr) => (
     {
-      use $crate::InputLength;
-      regex!(RE, $re);
-      if RE.is_match($i) {
-        $crate::IResult::Done(&$i[$i.input_len()..], $i)
+      let re = regex!($re);
+      if re.is_match($i) {
+        $crate::IResult::Done(&""[..], $i)
       } else {
         $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatch))
       }
@@ -76,8 +63,8 @@ macro_rules! re_find (
 macro_rules! re_find_static (
   ($i:expr, $re:expr) => (
     {
-      regex!(RE, $re);
-      if let Some((begin, end)) = RE.find($i) {
+      let re = regex!($re);
+      if let Some((begin, end)) = re.find($i) {
         $crate::IResult::Done(&$i[end..], &$i[begin..end])
       } else {
         $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpFind))
@@ -119,8 +106,8 @@ macro_rules! re_matches (
 macro_rules! re_matches_static (
   ($i:expr, $re:expr) => (
     {
-      regex!(RE, $re);
-      let v: Vec<&str> = RE.find_iter($i).map(|(begin,end)| &$i[begin..end]).collect();
+      let re = regex!($re);
+      let v: Vec<&str> = re.find_iter($i).map(|(begin,end)| &$i[begin..end]).collect();
       if v.len() != 0 {
         let offset = {
           let end = v.last().unwrap();
@@ -166,8 +153,8 @@ macro_rules! re_capture (
 macro_rules! re_capture_static (
   ($i:expr, $re:expr) => (
     {
-      regex!(RE, $re);
-      if let Some(c) = RE.captures($i) {
+      let re = regex!($re);
+      if let Some(c) = re.captures($i) {
         let v:Vec<&str> = c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect();
         let offset = {
           let end = v.last().unwrap();
@@ -213,8 +200,8 @@ macro_rules! re_captures (
 macro_rules! re_captures_static (
   ($i:expr, $re:expr) => (
     {
-      regex!(RE, $re);
-      let v:Vec<Vec<&str>> = RE.captures_iter($i).map(|c| c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect()).collect();
+      let re = regex!($re);
+      let v:Vec<Vec<&str>> = re.captures_iter($i).map(|c| c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect()).collect();
       if v.len() != 0 {
         let offset = {
           let end = v.last().unwrap().last().unwrap();
diff --git a/src/util.rs b/src/util.rs
index 541b247..752c0dc 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -53,7 +53,6 @@ impl<'a> InputLength for (&'a [u8], usize) {
 }
 
 use std::iter::Enumerate;
-#[cfg(not(feature = "core"))]
 use std::str::CharIndices;
 
 pub trait AsChar {
@@ -67,8 +66,6 @@ pub trait AsChar {
     fn is_0_to_9(self)   -> bool;
     #[inline]
     fn is_hex_digit(self) -> bool;
-    #[inline]
-    fn is_oct_digit(self) -> bool;
 }
 
 impl<'a> AsChar for &'a u8 {
@@ -90,10 +87,6 @@ impl<'a> AsChar for &'a u8 {
       (*self >= 0x41 && *self <= 0x46) ||
       (*self >= 0x61 && *self <= 0x66)
     }
-    #[inline]
-    fn is_oct_digit(self)   -> bool {
-      *self >= 0x30 && *self <= 0x37
-    }
 }
 
 impl AsChar for char {
@@ -107,8 +100,6 @@ impl AsChar for char {
     fn is_0_to_9(self)   -> bool { self.is_digit(10) }
     #[inline]
     fn is_hex_digit(self) -> bool { self.is_digit(16) }
-    #[inline]
-    fn is_oct_digit(self) -> bool { self.is_digit(8) }
 }
 
 pub trait IterIndices {
@@ -126,7 +117,6 @@ impl<'a> IterIndices for &'a [u8] {
     }
 }
 
-#[cfg(not(feature = "core"))]
 impl<'a> IterIndices for &'a str {
     type Item = char;
     type Iter = CharIndices<'a>;
@@ -299,8 +289,6 @@ pub fn compare_error_paths<P,E:Clone+PartialEq>(e1:&Err<P,E>, e2:&Err<P,E>) -> b
   error_to_list(e1) == error_to_list(e2)
 }
 
-
-#[cfg(not(feature = "core"))]
 use std::hash::Hash;
 
 #[cfg(not(feature = "core"))]
@@ -597,6 +585,7 @@ pub enum ErrorKind<E=u32> {
   IsA,
   SeparatedList,
   SeparatedNonEmptyList,
+  Many0,
   Many1,
   Count,
   TakeUntilAndConsume,
@@ -608,7 +597,6 @@ pub enum ErrorKind<E=u32> {
   Alpha,
   Digit,
   HexDigit,
-  OctDigit,
   AlphaNumeric,
   Space,
   MultiSpace,
@@ -654,28 +642,29 @@ pub fn error_to_u32<E>(e: &ErrorKind<E>) -> u32 {
     ErrorKind::IsA                       => 6,
     ErrorKind::SeparatedList             => 7,
     ErrorKind::SeparatedNonEmptyList     => 8,
-    ErrorKind::Many1                     => 9,
-    ErrorKind::Count                     => 10,
-    ErrorKind::TakeUntilAndConsume       => 11,
-    ErrorKind::TakeUntil                 => 12,
-    ErrorKind::TakeUntilEitherAndConsume => 13,
-    ErrorKind::TakeUntilEither           => 14,
-    ErrorKind::LengthValue               => 15,
-    ErrorKind::TagClosure                => 16,
-    ErrorKind::Alpha                     => 17,
-    ErrorKind::Digit                     => 18,
-    ErrorKind::AlphaNumeric              => 19,
-    ErrorKind::Space                     => 20,
-    ErrorKind::MultiSpace                => 21,
-    ErrorKind::LengthValueFn             => 22,
-    ErrorKind::Eof                       => 23,
-    ErrorKind::ExprOpt                   => 24,
-    ErrorKind::ExprRes                   => 25,
-    ErrorKind::CondReduce                => 26,
-    ErrorKind::Switch                    => 27,
-    ErrorKind::TagBits                   => 28,
-    ErrorKind::OneOf                     => 29,
-    ErrorKind::NoneOf                    => 30,
+    ErrorKind::Many0                     => 9,
+    ErrorKind::Many1                     => 10,
+    ErrorKind::Count                     => 11,
+    ErrorKind::TakeUntilAndConsume       => 12,
+    ErrorKind::TakeUntil                 => 13,
+    ErrorKind::TakeUntilEitherAndConsume => 14,
+    ErrorKind::TakeUntilEither           => 15,
+    ErrorKind::LengthValue               => 16,
+    ErrorKind::TagClosure                => 17,
+    ErrorKind::Alpha                     => 18,
+    ErrorKind::Digit                     => 19,
+    ErrorKind::AlphaNumeric              => 20,
+    ErrorKind::Space                     => 21,
+    ErrorKind::MultiSpace                => 22,
+    ErrorKind::LengthValueFn             => 23,
+    ErrorKind::Eof                       => 24,
+    ErrorKind::ExprOpt                   => 25,
+    ErrorKind::ExprRes                   => 26,
+    ErrorKind::CondReduce                => 27,
+    ErrorKind::Switch                    => 28,
+    ErrorKind::TagBits                   => 29,
+    ErrorKind::OneOf                     => 30,
+    ErrorKind::NoneOf                    => 31,
     ErrorKind::Char                      => 40,
     ErrorKind::CrLf                      => 41,
     ErrorKind::RegexpMatch               => 42,
@@ -697,6 +686,5 @@ pub fn error_to_u32<E>(e: &ErrorKind<E>) -> u32 {
     ErrorKind::TakeUntilAndConsumeStr    => 58,
     ErrorKind::HexDigit                  => 59,
     ErrorKind::TakeUntilStr              => 60,
-    ErrorKind::OctDigit                  => 61,
   }
 }


Test patch:
diff --git a/tests/cross_function_backtracking.rs b/tests/cross_function_backtracking.rs
deleted file mode 100644
index edbf910..0000000
--- a/tests/cross_function_backtracking.rs
+++ /dev/null
@@ -1,142 +0,0 @@
-/// this file tests a different backtracking behaviour. With the current
-/// `error!` macro, an early return is done in the current function, but
-/// backtracking continues normally outside of that function.
-///
-/// The solution here wraps `IResult` in a `Result`: a `Ok` indicates usual
-/// backtracking, `Err` indicates that we must "cut".
-
-#[macro_use]
-extern crate nom;
-
-use nom::IResult;
-
-macro_rules! n (
-    ($name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
-        fn $name( i: $i ) -> std::result::Result<nom::IResult<$i,$o,u32>, nom::Err<$i, u32>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    ($name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
-        fn $name( i: $i ) -> std::result::Result<nom::IResult<$i, $o, $e>, nom::Err<$i, $e>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    ($name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
-        fn $name( i: $i ) -> std::result::Result<nom::IResult<$i, $o, u32>, nom::Err<$i, u32>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    ($name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
-        fn $name<'a>( i: &'a[u8] ) -> std::result::Result<nom::IResult<&'a [u8], $o, u32>, nom::Err<&'a [u8], u32>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    ($name:ident, $submac:ident!( $($args:tt)* )) => (
-        fn $name( i: &[u8] ) -> std::result::Result<nom::IResult<&[u8], &[u8], u32>, nom::Err<&[u8], u32>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    (pub $name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
-        pub fn $name( i: $i ) -> std::result::Result<nom::IResult<$i,$o, u32>, nom::Err<$i, u32>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    (pub $name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
-        pub fn $name( i: $i ) -> std::result::Result<nom::IResult<$i, $o, $e>, nom::Err<$i, $e>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    (pub $name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
-        pub fn $name( i: $i ) -> std::result::Result<nom::IResult<$i, $o, u32>, nom::Err<$i, u32>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    (pub $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
-        pub fn $name( i: &[u8] ) -> std::result::Result<nom::IResult<&[u8], $o, u32>, nom::Err<&[u8], u32>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-    (pub $name:ident, $submac:ident!( $($args:tt)* )) => (
-        pub fn $name<'a>( i: &'a [u8] ) -> std::result::Result<nom::IResult<&[u8], &[u8], u32>, nom::Err<&[u8], u32>> {
-            std::result::Result::Ok($submac!(i, $($args)*))
-        }
-    );
-);
-
-macro_rules! cut (
-  ($i:expr, $code:expr, $submac:ident!( $($args:tt)* )) => (
-    {
-      let cl = || {
-        Ok($submac!($i, $($args)*))
-      };
-
-      match cl() {
-        std::result::Result::Ok(nom::IResult::Incomplete(x)) => nom::IResult::Incomplete(x),
-        std::result::Result::Ok(nom::IResult::Done(i, o))    => nom::IResult::Done(i, o),
-        std::result::Result::Ok(nom::IResult::Error(e)) | std::result::Result::Err(e)  => {
-          return std::result::Result::Err(nom::Err::NodePosition($code, $i, Box::new(e)))
-        }
-      }
-    }
-  );
-  ($i:expr, $code:expr, $f:expr) => (
-    cut!($i, $code, call!($f));
-  );
-);
-
-macro_rules! c (
-  ($i:expr, $f:expr) => (
-    {
-      match $f($i) {
-        std::result::Result::Ok(nom::IResult::Incomplete(x)) => nom::IResult::Incomplete(x),
-        std::result::Result::Ok(nom::IResult::Done(i, o))    => nom::IResult::Done(i, o),
-        std::result::Result::Ok(nom::IResult::Error(e))      => nom::IResult::Error(e),
-        std::result::Result::Err(e)     => {
-          return std::result::Result::Err(e)
-        }
-      }
-    }
-  );
-);
-
-n!(pub foo< bool >,
-    chain!(
-        tag!("a") ~
-        cut!(nom::ErrorKind::Custom(42),dbg_dmp!(tag!("b"))) ,
-        || { true }
-    )
-);
-
-n!(pub foos< Vec<bool> >,
-    delimited!(
-        tag!("("),
-        many0!(c!(foo)),
-        tag!(")")
-    )
-);
-
-#[test]
-fn test_ok() {
-    let r = foos(b"(abab)");
-    println!("result: {:?}", r);
-    match r {
-        Ok(nom::IResult::Done(_,result)) => assert_eq!(result,vec![true,true]),
-        res => panic!("Oops {:?}.",res)
-    }
-}
-
-#[test]
-fn test_err() {
-    let input = b"(ac)";
-    let r = foos(&input[..]);
-    println!("result: {:?}", r);
-    match r {
-        //Ok(nom::IResult::Error(nom::Err::Position(kind,_))) => assert_eq!(kind,nom::ErrorKind::Custom(42)),
-        Err(nom::Err::NodePosition(kind, position, _)) => {
-          assert_eq!(kind, nom::ErrorKind::Custom(42));
-          assert_eq!(position, &input[2..]);
-        }
-        res => panic!("Oops, {:?}",res)
-    }
-}
-