forked from rescript-lang/rescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjs_dump_string.ml
116 lines (107 loc) · 3.6 KB
/
js_dump_string.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
(* Copyright (C) 2017 - Hongbo Zhang, Authors of ReScript
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition to the permissions granted to you by the LGPL, you may combine
* or link a "work that uses the Library" with a publicly distributed version
* of this file to produce a combined library or application, then distribute
* that combined work under the terms of your choosing, with no requirement
* to comply with the obligations normally placed on you by section 4 of the
* LGPL version 3 (or the corresponding section of a later version of the LGPL
* should you choose to use a later version).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
module P = Ext_pp
(** Avoid to allocate single char string too many times*)
let array_str1 = Array.init 256 (fun i -> String.make 1 (Char.chr i))
(** For conveting
*)
let array_conv =
[|
"0";
"1";
"2";
"3";
"4";
"5";
"6";
"7";
"8";
"9";
"a";
"b";
"c";
"d";
"e";
"f";
|]
(* https://mathiasbynens.be/notes/javascript-escapes *)
let ( +> ) = Ext_buffer.add_string
let escape_to_buffer f (* ?(utf=false)*) s =
let pp_raw_string f (* ?(utf=false)*) s =
let l = String.length s in
for i = 0 to l - 1 do
let c = String.unsafe_get s i in
match c with
| '\b' -> f +> "\\b"
| '\012' -> f +> "\\f"
| '\n' -> f +> "\\n"
| '\r' -> f +> "\\r"
| '\t' -> f +> "\\t"
(* This escape sequence is not supported by IE < 9
| '\011' -> "\\v"
IE < 9 treats '\v' as 'v' instead of a vertical tab ('\x0B').
If cross-browser compatibility is a concern, use \x0B instead of \v.
Another thing to note is that the \v and \0 escapes are not allowed in JSON strings.
*)
| '\000'
when i = l - 1
||
let next = String.unsafe_get s (i + 1) in
next < '0' || next > '9' ->
f +> "\\0"
| '\\' (* when not utf*) -> f +> "\\\\"
| '\000' .. '\031' | '\127' ->
let c = Char.code c in
f +> "\\x";
f +> Array.unsafe_get array_conv (c lsr 4);
f +> Array.unsafe_get array_conv (c land 0xf)
| '\128' .. '\255' (* when not utf*) ->
let c = Char.code c in
f +> "\\x";
f +> Array.unsafe_get array_conv (c lsr 4);
f +> Array.unsafe_get array_conv (c land 0xf)
| '\"' -> f +> "\\\"" (* quote*)
| _ -> f +> Array.unsafe_get array_str1 (Char.code c)
done
in
f +> "\"";
pp_raw_string f (*~utf*) s;
f +> "\""
let escape_to_string s =
let buf = Ext_buffer.create (String.length s * 2) in
escape_to_buffer buf s;
Ext_buffer.contents buf
let pp_string f s = P.string f (escape_to_string s)
(* let _best_string_quote s =
let simple = ref 0 in
let double = ref 0 in
for i = 0 to String.length s - 1 do
match s.[i] with
| '\'' -> incr simple
| '"' -> incr double
| _ -> ()
done;
if !simple < !double
then '\''
else '"' *)