Source file rdbgMain.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
open RdbgArg
open RdbgEvent
open Mypervasives
let info_string () =
let msg = "The current session parameters are:
sut: "^ (String.concat "," (List.map reactive_program_to_string args.suts)) ^ "
env: "^ (String.concat "," (List.map reactive_program_to_string args.envs)) ^ "
oracle: "^ (String.concat "," (List.map reactive_program_to_string args.oracles)) ^ "
test length: " ^ (string_of_int args.step_nb) ^ "
precision: " ^ (string_of_int args.precision) ^ "
verbosity level: " ^ (string_of_int (args.verbose)) ^ "
rif file name: " ^ args.output ^ "
overwrite rif file? "
^ (if args.overwrite_output then "yes" else "no") ^ "
coverage file name: " ^ args.cov_file ^ "
do we stop when an oracle returns false? "
^ (if args.stop_on_oracle_error then "yes" else "no") ^ "
display local var? " ^ (if (args.display_local_var) then "yes" else "no") ^ "
"
in
msg
let info () =
output_string args.ocr (info_string ());
flush args.ocr
let i = info
let run () = RdbgRun.start ()
let _next e = e.next
let _data e = e.data
let _terminate e = e.terminate
let off () = RdbgArg.args.RdbgArg.rdbg <- false
let _on () = RdbgArg.args.RdbgArg.rdbg <- true
let _ =
RdbgArg.args.RdbgArg.rdbg <- true
let (get_val_event : RdbgEvent.t -> unit) =
fun e ->
let nl,vl = List.split e.data in
let nl = List.map (fun n -> String.uncapitalize_ascii n) nl in
let vstrl = List.map (Data.val_to_string (string_of_float)) vl in
let str =
"let " ^ (String.concat "," nl) ^
" = " ^ (String.concat "," vstrl) ^ ";;\n"
in
print_string (str)
let rdbg_lib_dir =
try
let path = Mypervasives.run ("ocamlfind query rdbg") (fun s -> Some s) in
let path = List.hd path in
path
with _ ->
try
let path = Mypervasives.run ("ocamlc -where") (fun s -> Some s) in
let path = List.hd path in
let sep = "/" in
let l = Str.split (Str.regexp sep) path in
let l = "rdbg-plugin"::(List.rev (List.tl l)) in
let l = List.rev l in
String.concat sep l
with _ ->
try
let path = Mypervasives.run ("locate rdbg") (fun s -> Some s) in
let path = List.hd path in
path
with _ -> ""
let rdbg_mli =
try readfile (Filename.concat rdbg_lib_dir "rdbgMain.mli"),"rdbgMain.ml"
with _ -> "",""
let rdbg_utils_mli =
try readfile (Filename.concat rdbg_lib_dir "rdbgStdLib.mli"),"rdbgStdLib.ml"
with _ -> "",""
let callgraph_mli =
try readfile (Filename.concat rdbg_lib_dir "callgraph.mli"),"callgraph.ml"
with _ -> "",""
type docu = string * (string * string * string * string)
let (get_cmd_list: string * string -> docu list) =
fun (mli, file) ->
let rec aux acc i0 =
try
let i3 = Str.search_forward (Str.regexp ("^val ")) mli i0 in
let i1 = Str.search_backward (Str.regexp ("^(\\*\\*")) mli i3 in
let i1bis = (Str.search_forward (Str.regexp (":")) mli i1) - 1 in
let i2 = Str.search_forward (Str.regexp ("\\*)")) mli i1 in
let i4 = (Str.search_forward (Str.regexp ":") mli i3) - 1 in
let i5 = Str.search_forward (Str.regexp "\n") mli i4 in
if i1bis = i4 then (
if args.debug_rdbg then
Printf.eprintf "No category for %s\n%!" (String.sub mli (i3+4) (i4-i3-4));
aux acc i5
)
else if i1 < i0 then (
if args.debug_rdbg then
Printf.eprintf "No help msg for for %s\n%!" (String.sub mli (i3+4) (i4-i3-4));
aux acc i5
) else
(try
let help,cat =
String.sub mli (i1bis+2) (i2-i1bis-2),
String.sub mli (i1+4) (i1bis-i1-3)
in
let cmd = String.sub mli (i3+4) (i4-i3-4) in
let profile = String.sub mli (i4+3) (i5-i4-3) in
if args.debug_rdbg then (
Printf.eprintf
"===> %si: i0=%i i1=%i i1bis=%i i2=%i i3=%i i4=%i i5=%i \n%!"
file i0 i1 i1bis i2 i3 i4 i5;
Printf.eprintf
"\tcmd=%s\n\tprofile=%s\n\thelp=%s\n\tcat=%s\n\tfile=%s\n%!"
cmd profile help cat file;
flush stderr
);
aux ((cmd,(profile,help,cat,file))::acc) i5
with Invalid_argument _ ->
if args.debug_rdbg then Printf.eprintf
"Bad format in comment in %si: i0=%i i1=%i i1bis=%i i2=%i i3=%i i4=%i i5=%i \n%!"
file i0 i1 i1bis i2 i3 i4 i5;
aux acc i5)
with Not_found -> acc
in
List.rev(aux [] 0)
let (cmd_list: docu list) =
get_cmd_list rdbg_mli
let cmd_list_utils = get_cmd_list rdbg_utils_mli
let cmd_callgraph = get_cmd_list callgraph_mli
let all_cmds = ref (cmd_list @ cmd_list_utils @ cmd_callgraph)
let get_doc c = try List.assoc c !all_cmds with Not_found -> "","","",""
let doc_prof c = (fun (x,_,_,_) -> x) (get_doc c)
let doc_msg c = (fun (_, x,_,_) -> x) (get_doc c)
let doc_label c = (fun (_, _, x,_) -> x) (get_doc c)
let doc_file c = (fun (_, _, _, x) -> x) (get_doc c)
let add_doc_entry cmd profile msg cat file =
if List.mem_assoc cmd !all_cmds then (
Printf.printf
"Warning: RdbgMain.add_doc_entry: the '%s' command already exist, and is overwritten\n
%!" cmd ;
all_cmds := List.remove_assoc cmd !all_cmds
);
all_cmds := (cmd,(profile,msg,cat,file))::!all_cmds
let _get_profile str =
try
let i = Str.search_forward (Str.regexp_string ("val "^str)) (fst rdbg_mli) 0 in
let j = Str.search_forward (Str.regexp_string "\n") (fst rdbg_mli) i in
String.sub (fst rdbg_mli) (i+4) (j-i+4)
with Not_found -> ""
let _print_cmd_list =
List.iter
(fun (cmd, (profile,_msg, _cat)) -> Printf.printf "\t%12s : %s\n" cmd profile)
let print_cmd_list2_string l =
List.fold_left
(fun acc (cmd, (_profile,msg, _cat, file)) ->
let msg = try
let i = Str.search_forward (Str.regexp "\n") msg 0 in
(String.sub msg 0 i)
with Not_found -> msg
in
let s = String.length msg in
let msg = if (s) < 45 then msg else
(String.sub msg 0 42) ^ "..."
in
let blank = String.make (max 0 (45-s)) ' ' in
Printf.sprintf "%s\n%16s : %s%s (%s)" acc cmd msg blank file)
""
l
let print_cmd_list2 l =
Printf.printf "%s\n%!" (print_cmd_list2_string l)
let (apropos : string -> unit) =
fun str ->
let l = List.filter
(fun (cmd,(_prof,msg,cat,file)) ->
Str.string_match (Str.regexp (".*"^str^".*")) cmd 0 ||
Str.string_match (Str.regexp (".*"^str^".*")) msg 0 ||
Str.string_match (Str.regexp (".*"^str^".*")) cat 0||
Str.string_match (Str.regexp (".*"^str^".*")) file 0
) !all_cmds
in
print_cmd_list2 l
let (sort_cmd_by_categories: unit -> (string * docu list) list) =
fun () ->
let t = Hashtbl.create 5 in
List.iter
(fun (cmd, (p,m,cat,file)) ->
match Hashtbl.find_opt t cat with
| None -> Hashtbl.add t cat [(cmd,(p,m,cat,file))]
| Some l -> Hashtbl.replace t cat ((cmd,(p,m,cat,file))::l)
)
!all_cmds;
Hashtbl.fold (fun cat l acc -> (cat,l)::acc) t []
let (help_string:string -> string) =
fun cmd ->
if cmd="base" then (
("Type
help \"function\";;
to obtain more help on the following functions: \n"^
print_cmd_list2_string cmd_list)
)
else if cmd="utils" then (
print_cmd_list2_string cmd_list_utils
)
else if cmd="cat" then (
let docl = sort_cmd_by_categories () in
let cat = fst (List.split docl) in
Printf.sprintf "Available categories are: \n\t - %s " (String.concat "\n\t - " cat)
)
else if List.mem_assoc cmd !all_cmds then (
let prof,help,cat,file = List.assoc cmd !all_cmds in
Printf.sprintf "%s : %s [%s] (%s)\n%s\n" cmd prof cat file help
)
else
let docl = sort_cmd_by_categories () in
match List.assoc_opt cmd docl with
| None ->
Printf.sprintf "Unknown function '%s'. Available functions are: %s" cmd
(String.concat "," (fst (List.split !all_cmds)))
| Some cmds ->
print_cmd_list2_string (List.rev cmds)
let (help:string -> unit) = fun str ->
Printf.printf "%s\n%!" (help_string str)
let q () = print_string "bye!\n";flush stdout;exit 0
let quit () = q ()
let h = help
let a = apropos
let (man:unit -> unit) =
fun () ->
output_string stdout " rdbg is a Reactive program DeBuGger.
- web doc: http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/rdbg
- tutorials:http://www-verimag.imag.fr/DIST-TOOLS/vtt/rdbg
- online doc:
+ help cat (* List commands categories *)
+ help <a cat> (* List commands related to a given category *)
+ help <a command> (* Print the documentation of a command/function *)
+ apropos <a string> (* List functions related a string *)
+ apropos (* List all functions *)
+ h (* Shortcut for help *)
+ a (* Shortcut for apropos *)
+ l (* List rdbg commands *)
";
flush stdout
let prompt = "(rdbg) "
let get_prompt () = prompt