Commit 7e5c7c06 authored by POTTIER Francois's avatar POTTIER Francois

Work around in bug in [String.escaped] in OCaml 4.02.3. Closes issue #24.

parent 6cefed83
Pipeline #83294 passed with stages
in 25 seconds
# Changes
## 2019/06/20
* When compiled with OCaml 4.02.3, Menhir could produce OCaml code
containing invalid string literals. This was due to a problem in
`String.escaped`. Fixed. (Reported by ELLIOTCABLE.)
## 2019/06/13
* Relax the syntax of point-free actions to allow `< >` (with arbitrary
......
module Bytes = struct
include Bytes
let escaped s =
let n = ref 0 in
for i = 0 to length s - 1 do
n := !n +
(match unsafe_get s i with
| '\"' | '\\' | '\n' | '\t' | '\r' | '\b' -> 2
| ' ' .. '~' -> 1
| _ -> 4)
done;
if !n = length s then copy s else begin
let s' = create !n in
n := 0;
for i = 0 to length s - 1 do
begin match unsafe_get s i with
| ('\"' | '\\') as c ->
unsafe_set s' !n '\\'; incr n; unsafe_set s' !n c
| '\n' ->
unsafe_set s' !n '\\'; incr n; unsafe_set s' !n 'n'
| '\t' ->
unsafe_set s' !n '\\'; incr n; unsafe_set s' !n 't'
| '\r' ->
unsafe_set s' !n '\\'; incr n; unsafe_set s' !n 'r'
| '\b' ->
unsafe_set s' !n '\\'; incr n; unsafe_set s' !n 'b'
| (' ' .. '~') as c -> unsafe_set s' !n c
| c ->
let a = Char.code c in
unsafe_set s' !n '\\';
incr n;
unsafe_set s' !n (Char.chr (48 + a / 100));
incr n;
unsafe_set s' !n (Char.chr (48 + (a / 10) mod 10));
incr n;
unsafe_set s' !n (Char.chr (48 + a mod 10));
end;
incr n
done;
s'
end
end
module String = struct
open String
let escaped s =
let rec escape_if_needed s n i =
if i >= n then s else
match unsafe_get s i with
| '\"' | '\\' | '\000'..'\031' | '\127'.. '\255' ->
Bytes.unsafe_to_string (Bytes.escaped (Bytes.unsafe_of_string s))
| _ -> escape_if_needed s n (i+1)
in
escape_if_needed s (length s) 0
end
(* The standard library function [String.escaped] in OCaml 4.02.3 depends
on the operating system function [isprint] and therefore can have OS-
dependent, locale-dependent behavior. This issue has been fixed in OCaml
4.03. We use a copy of the code found in OCaml 4.03 and higher, so as to
avoid this issue. *)
module Bytes : sig
val escaped: bytes -> bytes
end
module String : sig
val escaped: string -> string
end
......@@ -398,7 +398,7 @@ and exprk k f e =
else
fprintf f "(%d)" k
| EStringConst s ->
fprintf f "\"%s\"" (String.escaped s)
fprintf f "\"%s\"" (Compatibility.String.escaped s)
| ETuple [] ->
assert false
| ETuple [ e ] ->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment