Skip to content

Commit c23d804

Browse files
committed
Add yamlWitnessConvert utility
1 parent 49d5de5 commit c23d804

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

tests/util/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(executables
2-
(names yamlWitnessStrip yamlWitnessStripDiff multilibConfigure)
2+
(names yamlWitnessStrip yamlWitnessStripDiff yamlWitnessConvert multilibConfigure)
33
(libraries
44
batteries.unthreaded
55
goblint-cil

tests/util/yamlWitnessConvert.ml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
(** Tool for converting YAML witness 0.1 ([location_invariant] and [loop_invariant] entries) to YAML witness 2.0 ([invariant_set] entry). *)
2+
3+
open Goblint_lib
4+
open YamlWitnessType
5+
6+
let invariant2invariant_set_invariant ~location (invariant: Invariant.t): InvariantSet.LoopInvariant.t =
7+
assert (invariant.type_ = "assertion");
8+
assert (invariant.format = "C");
9+
{
10+
location;
11+
value = invariant.string;
12+
format = "c_expression"
13+
}
14+
15+
let strip_location (location: Location.t): Location.t =
16+
{location with file_hash = None}
17+
18+
let main () =
19+
let yaml_str = Batteries.input_all stdin in
20+
let yaml = Yaml.of_string_exn yaml_str in
21+
let yaml_entries = yaml |> GobYaml.list |> BatResult.get_ok in
22+
23+
let metadata': Metadata.t option ref = ref None in
24+
let invariants = List.map (fun yaml_entry ->
25+
let entry = Entry.of_yaml yaml_entry |> Result.get_ok in
26+
begin match !metadata' with
27+
| None ->
28+
metadata' := Some {entry.metadata with format_version = "2.0"}
29+
| Some metadata ->
30+
(* all existing metadata should be the same *)
31+
(* they (should) have different UUIDs, so change UUID to match to compare the rest *)
32+
assert (Metadata.equal metadata {entry.metadata with uuid = metadata.uuid})
33+
end;
34+
match entry.entry_type with
35+
| LocationInvariant {location; location_invariant} ->
36+
let location = strip_location location in
37+
let invariant = invariant2invariant_set_invariant ~location location_invariant in
38+
{InvariantSet.Invariant.invariant_type = LocationInvariant invariant}
39+
| LoopInvariant {location; loop_invariant} ->
40+
let location = strip_location location in
41+
let invariant = invariant2invariant_set_invariant ~location loop_invariant in
42+
{InvariantSet.Invariant.invariant_type = LoopInvariant invariant}
43+
| _ -> failwith "unsupported entry type"
44+
) yaml_entries
45+
in
46+
47+
let invariant_set: InvariantSet.t = {content = invariants} in
48+
let entry': Entry.t = {
49+
metadata = Option.get !metadata';
50+
entry_type = InvariantSet invariant_set
51+
}
52+
in
53+
54+
let yaml' = `A [Entry.to_yaml entry'] in
55+
(* to_file/to_string uses a fixed-size buffer... *)
56+
let yaml_str' = match GobYaml.to_string' yaml' with
57+
| Ok text -> text
58+
| Error (`Msg m) -> failwith ("Yaml.to_string: " ^ m)
59+
in
60+
Batteries.output_string Batteries.stdout yaml_str'
61+
62+
let () = main ()

0 commit comments

Comments
 (0)