From 90fcadb99082513ac301a4becf928d178262d1f6 Mon Sep 17 00:00:00 2001 From: Spiros Eliopoulos Date: Mon, 22 Jan 2018 20:03:42 +0000 Subject: [PATCH] count_while-bug: fix bug in count_while and couht_while1 On a failed prompt call, the position was not being reset to the position at the start of the count_while or count_while1, rather than taking into account the consumed input. In practice this would be difficult to detect as the end of input was reached, except when checking if the next parser was checking if it was the end of the input! This commit fixes the bug and adds regression tests. --- lib/angstrom.ml | 4 ++-- lib_test/test_angstrom.ml | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/angstrom.ml b/lib/angstrom.ml index cf3b195..987b294 100644 --- a/lib/angstrom.ml +++ b/lib/angstrom.ml @@ -342,7 +342,7 @@ let rec count_while ~init ~f ~with_buffer = let succ' input' pos' more' = (count_while ~init:init' ~f ~with_buffer).run input' pos' more' fail succ and fail' input' pos' more' = - succ input' pos' more' (Input.apply input' pos' init' ~f:with_buffer) + succ input' (pos' + init') more' (Input.apply input' pos' init' ~f:with_buffer) in prompt input pos fail' succ' } @@ -370,7 +370,7 @@ let rec count_while1 ~f ~with_buffer = let succ' input' pos' more' = (count_while ~init:len ~f ~with_buffer).run input' pos' more' fail succ and fail' input' pos' more' = - succ input' pos' more' (Input.apply input' pos' len ~f:with_buffer) + succ input' (pos' + len) more' (Input.apply input' pos' len ~f:with_buffer) in prompt input pos fail' succ' } diff --git a/lib_test/test_angstrom.ml b/lib_test/test_angstrom.ml index 70b5e10..8f6ec54 100644 --- a/lib_test/test_angstrom.ml +++ b/lib_test/test_angstrom.ml @@ -341,6 +341,14 @@ let incremental = (string "thi" *> string "st" *> commit *> string "hat") ["thi"; "st"; "hat"] "hat"; end ] +let count_while_regression = + [ "proper position set after count_while", `Quick, begin fun () -> + check_s ~msg:"take_while then eof" + (take_while (fun _ -> true) <* end_of_input) ["asdf"; ""] "asdf"; + check_s ~msg:"take_while1 then eof" + (take_while1 (fun _ -> true) <* end_of_input) ["asdf"; ""] "asdf"; + end ] + let () = Alcotest.run "test suite" [ "basic constructors" , basic_constructors @@ -350,4 +358,6 @@ let () = ; "applicative interface" , applicative ; "alternative" , alternative ; "combinators" , combinators - ; "incremental input" , incremental ] + ; "incremental input" , incremental + ; "count_while regression", count_while_regression + ]