-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.ml
152 lines (110 loc) · 2.77 KB
/
utils.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
open Batteries
let compare_on f x y = Pervasives.compare (f x) (f y)
let compare_first (x,_) (y,_) = Pervasives.compare x y
let compare_on_first f (x,_) (y,_) = Pervasives.compare (f x) (f y)
let equal_on f x y = (f x) = (f y)
let apply_if cond f x =
if cond
then f x
else x
let instr_same_loc = equal_on Cil.get_instrLoc
let match_pair = function
| [a;b] -> (a,b)
| ____ -> Error.panic_with "match_pair: not a 2-element list"
let colored cd str = Printf.sprintf "\027[%sm%s\027[0m" cd str
let green = colored "0;32"
let purple = colored "0;35"
let cyan = colored "0;36"
module Option = struct
let (<|>) opt1 opt2 = fun x ->
match opt1 x with
| Some _ as r -> r
| None -> opt2 x
let (=>?) guard v =
if guard then Some v else None
let fold_left_break ~f y0 xs =
let open Option.Infix in
let open Return in
label (fun break ->
List.fold_left (fun y_opt x ->
y_opt >>= fun y ->
match f y x with
| None -> return break None
| Some y1 -> Some y1
)
(Some y0)
xs
)
end
let string_of_cil ppr x :string =
let x_doc = ppr () x in
Pretty.sprint ~width:60 x_doc
let pp_upto max sep pp_el els =
let open PP in
let max_els = Enum.take max els in
let more_els = not Enum.(is_empty (skip max els)) in
let els_docs = max_els |> Enum.map pp_el |> List.of_enum in
let ending =
if more_els
then [!^ "..."]
else []
in
separate sep (els_docs @ ending)
let is_zero_arg_proc typ =
assert (Cil.isFunctionType typ);
let _, args, varargs, _ = Cil.splitFunctionType typ in
match args with
| None
| Some []
-> not varargs
| _else
-> false
module Varinfo =
struct
open Cil
type t = varinfo
let vid x = x.vid
let compare x y = Int.compare x.vid y.vid
let equal x y = compare x y = 0
let hash = Hashtbl.hash
let loc_of x = x.vdecl
end
module Exp =
struct
type t = Cil.exp
(* Convert from CIL's Pretty.doc to our PP.doc *)
let pp e :PP.doc =
let open Cil in
let e_doc =
match e with
| Lval (Var x,NoOffset)
(* HACK to recognize CIL temporary variables *)
when x.vname = "tmp"
|| String.starts_with x.vname "tmp___" ->
x.vdescr
| _else ->
Cil.d_exp () e
in
let e_str = Pretty.sprint ~width:60 e_doc in
PP.(!^ e_str)
let to_string = PP.to_string % pp
end
module Location =
struct
open Tuple
type t = Cil.location
let compare = Cil.compareLoc
let equal x y = compare x y = 0
let hash = Hashtbl.hash
(* Convert from CIL's Pretty.doc to our PP.doc *)
let pp l :PP.doc =
let l_doc = Cil.d_loc () l in
let l_str = Pretty.sprint ~width:60 l_doc in
PP.(!^ l_str)
let to_string = PP.to_string % pp
let pp_with_loc :(Cil.location * PP.doc) list -> PP.doc =
let with_loc (loc,x_pp) = PP.(pp loc ++ x_pp) in
PP.separate PP.newline %
List.map with_loc %
List.sort (compare_on Tuple2.first)
end