diff --git a/src/kernel_services/ast_data/alarms.ml b/src/kernel_services/ast_data/alarms.ml index 7f7451c7ae1a27ba1a73ccba3fe01ef2e5607efb..3c7cfb73c2ebce2e30cda2f42da7574861076aec 100644 --- a/src/kernel_services/ast_data/alarms.ml +++ b/src/kernel_services/ast_data/alarms.ml @@ -771,6 +771,15 @@ let fold f = by_emitter acc) +let to_seq () = + State.to_seq () |> + Seq.flat_map (fun (_,emitter) -> Usable_emitter.Hashtbl.to_seq emitter) |> + Seq.flat_map + (fun (e,h) -> + D.Hashtbl.to_seq h |> + Seq.map (fun (alarm, (annot, kf, stmt, rank)) -> + Usable_emitter.get e, kf, stmt, rank, alarm, annot)) + let find annot = try Some (Alarm_of_annot.find annot) with Not_found -> None diff --git a/src/kernel_services/ast_data/alarms.mli b/src/kernel_services/ast_data/alarms.mli index adfe341aaf4c5b959955bf27e3c78bbf0c80f308..ffaf67de138d8e4f7eeecfd2d8c943303613460f 100644 --- a/src/kernel_services/ast_data/alarms.mli +++ b/src/kernel_services/ast_data/alarms.mli @@ -105,6 +105,13 @@ val fold: point. @since Fluorine-20130401 *) +val to_seq: + unit -> + (Emitter.t * kernel_function * stmt * int * alarm * code_annotation) Seq.t +(** Returns the sequence of all alarms and the associated annotations at some + program point + @since Frama-C+dev *) + val find: code_annotation -> alarm option (** @return the alarm corresponding to the given assertion, if any. @since Fluorine-20130401 *) diff --git a/src/kernel_services/plugin_entry_points/emitter.ml b/src/kernel_services/plugin_entry_points/emitter.ml index 0349a71692e9d42ea2aefbe5fbb1453c10155f4a..bdcd37227adb7ce862c9560cedc8a83c1472e4c1 100644 --- a/src/kernel_services/plugin_entry_points/emitter.ml +++ b/src/kernel_services/plugin_entry_points/emitter.ml @@ -636,6 +636,7 @@ struct let mem key = H.mem !state key let iter f = H.iter f !state let fold f acc = H.fold f !state acc + let to_seq () = H.to_seq !state let iter_sorted ~cmp f = H.iter_sorted ~cmp f !state let fold_sorted ~cmp f acc = H.fold_sorted ~cmp f !state acc let remove key = diff --git a/src/kernel_services/plugin_entry_points/emitter.mli b/src/kernel_services/plugin_entry_points/emitter.mli index 96e4ae157d547da175a300d28f0a2def5ef33e85..402a17ba6fddac2671851a59bbfbf8af0df88fbd 100644 --- a/src/kernel_services/plugin_entry_points/emitter.mli +++ b/src/kernel_services/plugin_entry_points/emitter.mli @@ -136,6 +136,7 @@ sig val mem: H.key -> bool val iter: (H.key -> internal_tbl -> unit) -> unit val fold: (H.key -> internal_tbl -> 'a -> 'a) -> 'a -> 'a + val to_seq: unit -> (H.key * internal_tbl) Seq.t val iter_sorted: cmp: (H.key -> H.key -> int) -> (H.key -> internal_tbl -> unit) -> unit val fold_sorted: diff --git a/src/libraries/stdlib/transitioning.ml b/src/libraries/stdlib/transitioning.ml index 0ca1ea3afa5463c2237ea4363182b2dc7a2f4bcf..f11d88cb8a4a5ae5b86380cc0a7b66bb6f418b58 100644 --- a/src/libraries/stdlib/transitioning.ml +++ b/src/libraries/stdlib/transitioning.ml @@ -45,3 +45,15 @@ module List = struct let n = f x1 x2 in if n = 0 then compare f q1 q2 else n end + + +module Seq = struct + open Stdlib.Seq + + let mapi f seq = + let i = ref 0 in + map (fun x -> let y = f !i x in incr i; y) seq + + let unzip seq = + map fst seq, map snd seq +end diff --git a/src/libraries/stdlib/transitioning.mli b/src/libraries/stdlib/transitioning.mli index cb378f0cd9c0dac9102f58857be04f54eae18a2e..be40531442b3ef2af3bbd28f313dd78beea4a80e 100644 --- a/src/libraries/stdlib/transitioning.mli +++ b/src/libraries/stdlib/transitioning.mli @@ -42,3 +42,11 @@ module List: sig (** since 4.12.0 *) val compare: ('a -> 'a -> int) -> 'a list -> 'a list -> int end + +module Seq: sig + (** since 4.14.0 *) + val mapi: (int -> 'a -> 'b) -> 'a Seq.t -> 'b Seq.t + + (** since 4.14.0 *) + val unzip : ('a * 'b) Seq.t -> 'a Seq.t * 'b Seq.t +end diff --git a/src/plugins/markdown-report/sarif_gen.ml b/src/plugins/markdown-report/sarif_gen.ml index 7378f6b6b85eaaf91cb59bc239328a692d3956a3..6845c703cfde80127a09f25068071efcca492b2d 100644 --- a/src/plugins/markdown-report/sarif_gen.ml +++ b/src/plugins/markdown-report/sarif_gen.ml @@ -161,31 +161,27 @@ let opt_physical_location_of_loc loc = else [ Location.of_loc loc ] (* Cil_types *) let gen_results remarks = - let treat_alarm _e kf s ~rank:_ alarm annot (i, rules, content) = - if not (Mdr_params.PrintLibc.get ()) && kf_is_in_libc kf then - (* skip alarm in libc *) - (i, rules, content) - else - let prop = Property.ip_of_code_annot_single kf s annot in - let ruleId = Alarms.get_name alarm in - let rules = - Datatype.String.Map.add ruleId (Alarms.get_description alarm) rules - in - let label = "Alarm-" ^ string_of_int i in - let kind = kind_of_status (Property_status.Feedback.get prop) in - let level = level_of_status (Property_status.Feedback.get prop) in - let remark = get_remark remarks label in - let message = make_message alarm annot remark in - let locations = opt_physical_location_of_loc (Cil_datatype.Stmt.loc s) in - let res = - Sarif_result.create ~kind ~level ~ruleId ~message ~locations () - in - (i+1, rules, res :: content) + let keep_alarm (_,kf,_,_,_,_) = + (* skip alarm in libc *) + Mdr_params.PrintLibc.get () || not (kf_is_in_libc kf) + in + let treat_alarm i (_e,kf,s,_rank,alarm,annot) = + let prop = Property.ip_of_code_annot_single kf s annot in + let ruleId = Alarms.get_name alarm in + let label = "Alarm-" ^ string_of_int i in + let kind = kind_of_status (Property_status.Feedback.get prop) in + let level = level_of_status (Property_status.Feedback.get prop) in + let remark = get_remark remarks label in + let message = make_message alarm annot remark in + let locations = opt_physical_location_of_loc (Cil_datatype.Stmt.loc s) in + let res = Sarif_result.create ~kind ~level ~ruleId ~message ~locations () in + (ruleId, Alarms.get_description alarm), res in - let _, rules, content = - Alarms.fold treat_alarm (0, Datatype.String.Map.empty,[]) + let rules, content = + Alarms.to_seq () |> Seq.filter keep_alarm |> + Transitioning.Seq.mapi treat_alarm |> Transitioning.Seq.unzip in - rules, List.rev content + Datatype.String.Map.of_seq rules, List.of_seq content let is_alarm = function | Property.(IPCodeAnnot { ica_ca }) -> Option.is_some (Alarms.find ica_ca)