123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)openPrinter_tagopenGtk_helperopenCil_typesopenCil_datatype(* Update the 'Occurrence' column of the gui filetree. *)letupdate_column=ref(fun_->())(* Are results shown? *)moduleEnabled=State_builder.Ref(Datatype.Bool)(structletname="Occurrence_gui.State"letdependencies=[Register.self]letdefault()=falseend)moduleShowRead=State_builder.Ref(Datatype.Bool)(structletname="Occurrence_gui.ShowRead"letdependencies=[]letdefault()=trueend)moduleShowWrite=State_builder.Ref(Datatype.Bool)(structletname="Occurrence_gui.ShowWrite"letdependencies=[]letdefault()=trueend)letconsider_access()=matchShowRead.get(),ShowWrite.get()with|false,false->(fun_->false)|true,true->(fun_->true)|true,false->(funak->ak=Register.Read||ak=Register.Both)|false,true->(funak->ak=Register.Write||ak=Register.Both)letfilter_accessesl=matchShowRead.get(),ShowWrite.get()with|false,false->[]|true,true->l|true,false|false,true->letf=consider_access()inList.filter(funaccess->f(Register.classify_accessesaccess))llet_ignore=Dynamic.register~plugin:"Occurrence""Enabled.set"(Datatype.funcDatatype.boolDatatype.unit)Enabled.setlet_ignore=Dynamic.register~plugin:"Occurrence""Enabled.get"(Datatype.funcDatatype.unitDatatype.bool)Enabled.getletfind_occurrence(main_ui:Design.main_window_extension_points)vi()=tryignore(Register.getvi);Enabled.settrue;!update_column`Contents;main_ui#rehighlight()with|Globals.No_such_entry_point_->GToolbox.message_box~title:"Error""Error: Occurrence requires a main function"letapply_on_viflocalizable=matchlocalizablewith|PVDecl(_,_,vi)|PLval(_,_,(Varvi,NoOffset))|PTermLval(_,_,_,(TVar{lv_origin=Somevi},TNoOffset))->ifnot(Cil.isFunctionTypevi.vtype)thenfvi|_->()letoccurrence_highlighterbufferloc~start~stop=ifEnabled.get()thenmatchRegister.get_last_result()with|None->(* occurrence not computed *)()|Some(result,vi)->letresult=filter_accessesresultinletbuffer=buffer#bufferinlethighlight()=lettag=make_tagbuffer~name:"occurrence"[`BACKGROUND"yellow"]inapply_tagbuffertagstartstopinmatchlocwith|PLval(_,ki,lval)->letsame_lval(_kf,k,l)=Kinstr.equalkki&&Lval.equalllvalinifList.existssame_lvalresultthenhighlight()|PTermLval(_,ki,_,term_lval)->letsame_tlval(_kf,k,l)=Logic_utils.is_same_tlval(Logic_utils.lval_to_term_lvall)term_lval&&Kinstr.equalkkiinifList.existssame_tlvalresultthenhighlight()|PVDecl(_,_,vi')whenVarinfo.equalvivi'->highlight()|PExp_|PVDecl_|PStmt_|PStmtStart_|PGlobal_|PIP_|PType_->()moduleFollowFocus=State_builder.Ref(Datatype.Bool)(structletname="Occurrence_gui.FollowFocus"letdependencies=[]letdefault()=falseend)letoccurrence_panelmain_ui=letw=GPack.vbox()in(* Selected Var display *)letselected_var_box=GPack.hbox~packing:w#pack()inignore(GMisc.label~xalign:0.0~text:"Current var: "~packing:(selected_var_box#pack~expand:false)());lete=GMisc.label~xalign:0.0~selectable:true~packing:(selected_var_box#pack~expand:true~fill:true)()ine#set_use_markuptrue;old_gtk_compate#set_single_line_modetrue;(* check_button enabled *)letrefresh_enabled_button=on_boolw"Enable"Enabled.get(funv->Enabled.setv;!update_column`Visibility;main_ui#rehighlight())in(* check_button followFocus *)letrefresh_followFocus=on_boolw"Follow focus"FollowFocus.getFollowFocus.setinleth_read_write=GPack.hbox~packing:w#pack()inletrefresh_rw_auxfv=fv;main_ui#file_tree#reset();main_ui#rehighlight()inletrefresh_read=Gtk_helper.on_bool~tooltip:"Show only occurrences where the zone is read"h_read_write"Read"ShowRead.get(refresh_rw_auxShowRead.set)inletrefresh_write=Gtk_helper.on_bool~tooltip:"Show only occurrences where the zone is written"h_read_write"Write"ShowWrite.get(refresh_rw_auxShowWrite.set)inletrefresh=letold_vi=ref(-2)in(fun()->refresh_read();refresh_write();refresh_followFocus();refresh_enabled_button();letnew_result=Register.get_last_result()in(matchnew_resultwith|Nonewhen!old_vi<>-1->old_vi:=-1;e#set_label"<i>None</i>"|Some(_,vi)whenvi.vid<>!old_vi->old_vi:=vi.vid;e#set_labelvi.vname|_->()))in"Occurrence",w#coerce,Somerefreshletoccurrence_selector(popup_factory:GMenu.menuGMenu.factory)main_ui~buttonlocalizable=apply_on_vi(funvi->ifbutton=3||FollowFocus.get()thenbeginletcallback=find_occurrencemain_uiviinignore(popup_factory#add_item"_Occurrence"~callback);ifFollowFocus.get()thenignore(Glib.Idle.add(fun()->callback();false))end)localizableletfile_tree_decorate(file_tree:Filetree.t)=update_column:=file_tree#append_pixbuf_column~title:"Occurrence"(funglobs->matchRegister.get_last_result()with|None->(* occurrence not computed *)[`STOCK_ID""]|Some(result,_)->letin_globals(kf,ki,_asaccess)=(letak=Register.classify_accessesaccessinconsider_access()ak)&&matchkiwith|Kglobal->false|Kstmt_->letkf=Option.getkfinletv0=Kernel_function.get_vikfinList.exists(funglob->matchglobwith|GFun({svar=v1},_)->Varinfo.equalv1v0|_->false)globsinifList.existsin_globalsresultthen[`STOCK_ID"gtk-apply"]else[`STOCK_ID""])(fun()->Enabled.get());!update_column`Visibilityletmainmain_ui=main_ui#register_source_selectoroccurrence_selector;main_ui#register_source_highlighteroccurrence_highlighter;main_ui#register_paneloccurrence_panel;file_tree_decoratemain_ui#file_tree;;;let()=Design.register_extensionmain(*
Local Variables:
compile-command: "make -C ../../.."
End:
*)