Source file ErrorReports.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
type 'a content =
| Zero
| One of 'a
| Two of 'a * 'a
type 'a buffer =
'a content ref
let update buffer x =
buffer :=
match !buffer, x with
| Zero, _ ->
One x
| One x1, x2
| Two (_, x1), x2 ->
Two (x1, x2)
let show f buffer : string =
match !buffer with
| Zero ->
assert false
| One invalid ->
Printf.sprintf "before '%s'" (f invalid)
| Two (valid, invalid) ->
Printf.sprintf "after '%s' and before '%s'" (f valid) (f invalid)
let last buffer =
match !buffer with
| Zero ->
assert false
| One invalid
| Two (_, invalid) ->
invalid
open Lexing
let wrap lexer =
let buffer = ref Zero in
buffer,
fun lexbuf ->
let token = lexer lexbuf in
update buffer (lexbuf.lex_start_p, lexbuf.lex_curr_p);
token
let wrap_supplier supplier =
let buffer = ref Zero in
buffer,
fun () ->
let (_token, pos1, pos2) as triple = supplier() in
update buffer (pos1, pos2);
triple
let text (pos1, pos2) : string =
let ofs1 = pos1.pos_cnum
and ofs2 = pos2.pos_cnum in
let len = ofs2 - ofs1 in
try
String.sub text ofs1 len
with Invalid_argument _ ->
"???"
let sanitize text =
String.map (fun c ->
if Char.code c < 32 then ' ' else c
) text
let rec compress n b i j skipping =
if j < n then
let c, j = Bytes.get b j, j + 1 in
match c with
| ' ' | '\t' | '\n' | '\r' ->
let i = if not skipping then (Bytes.set b i ' '; i + 1) else i in
let skipping = true in
compress n b i j skipping
| _ ->
let i = Bytes.set b i c; i + 1 in
let skipping = false in
compress n b i j skipping
else
Bytes.sub_string b 0 i
let compress text =
let b = Bytes.of_string text in
let n = Bytes.length b in
compress n b 0 0 false
let shorten k text =
let n = String.length text in
if n <= 2 * k + 3 then
text
else
String.sub text 0 k ^
"..." ^
String.sub text (n - k) k
let is_digit c =
let c = Char.code c in
Char.code '0' <= c && c <= Char.code '9'
exception Copy
let expand f text =
let n = String.length text in
let b = Buffer.create n in
let rec loop i =
if i < n then begin
let c, i = text.[i], i + 1 in
loop (
try
if c <> '$' then raise Copy;
let j = ref i in
while !j < n && is_digit text.[!j] do incr j done;
if i = !j then raise Copy;
let k = int_of_string (String.sub text i (!j - i)) in
Buffer.add_string b (f k);
!j
with Copy ->
Buffer.add_char b c;
i
)
end
else
Buffer.contents b
in
loop 0