open Cil_types open Cil module Simple_metrics = Plugin.Register( struct let name = "Simple_metrics" let shortname = "simple" let help = "Computes a few simple metrics over the code" end) module Enable = Simple_metrics.False( struct let option_name = "-simple-metrics" let help = "compute and display the metrics" end) module Computed = State_builder.False_ref( struct let name = "Simple_metrics.Computed" let dependencies = [ Ast.self ] end) module Nb_fun = State_builder.Zero_ref( struct let name = "Simple_metrics.Nb_fun" let dependencies = [ Computed.self ] end) module Nb_external = State_builder.Zero_ref( struct let name = "Simple_metrics.Nb_external" let dependencies = [ Computed.self ] end) module Nb_stmts = State_builder.Zero_ref( struct let name = "Simple_metrics.Nb_stmts" let dependencies = [ Computed.self ] end) class metrics_visit: Visitor.frama_c_visitor = object inherit Visitor.frama_c_inplace method vglob_aux g = match g with | GFun _ -> Nb_fun.set(Nb_fun.get() + 1); DoChildren | GVarDecl(_,vi,_) when Cil.isFunctionType(vi.vtype) && (not (Kernel_function.is_definition (Globals.Functions.get vi))) -> Nb_external.set(Nb_external.get() + 1); SkipChildren | _ -> SkipChildren method vstmt_aux _ = Nb_stmts.set(Nb_stmts.get() + 1); DoChildren end let compute () = if not (Computed.get()) then begin let visitor = new metrics_visit in Visitor.visitFramacFileSameGlobals visitor (Ast.get()) end let display_metrics () = compute (); Simple_metrics.feedback "Defined functions: %d" (Nb_fun.get()); Simple_metrics.feedback "External functions: %d" (Nb_external.get()); Simple_metrics.feedback "Number of statements: %d" (Nb_stmts.get()) let display_metrics = Dynamic.register ~comment:"display simple metrics" ~plugin:"Simple_metrics" "display_metrics" (Datatype.func Datatype.unit Datatype.unit) ~journalize:true display_metrics let run () = if Enable.get () then display_metrics () let () = Db.Main.extend run