123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249(**************************************************************************)(* *)(* This file is part of WP plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat a l'energie atomique et aux energies *)(* 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). *)(* *)(**************************************************************************)(* -------------------------------------------------------------------------- *)(* --- Source Interaction for WP --- *)(* -------------------------------------------------------------------------- *)openCil_typesopenCil_datatypeopenPrinter_tagopenWpotypeselection=|S_none|S_funofKernel_function.t|S_propofProperty.t|S_callofcallandcall={s_caller:Kernel_function.t;s_called:Kernel_function.t;s_stmt:Stmt.t;}letselection_of_localizable=function|PStmt(kf,stmt)|PStmtStart(kf,stmt)|PLval(Somekf,Kstmtstmt,_)|PTermLval(Somekf,Kstmtstmt,_,_)->beginmatchstmtwith|{skind=Instr(Call(_,e,_,_))}->beginmatchKernel_function.get_calledewith|None->S_none|Somecalled->S_call{s_called=called;s_caller=kf;s_stmt=stmt;}end|{skind=Instr(Local_init(_,ConsInit(vi,_,_),_))}->S_call{s_called=Globals.Functions.getvi;s_caller=kf;s_stmt=stmt;}|_->S_noneend|PVDecl(Somekf,_,{vglob=true})->S_funkf|PIPip->S_propip|PVDecl_|PLval_|PExp_|PTermLval_|PGlobal_|PType_->S_noneletkind_of_property=function|Property.IPLemma_->"lemma"|Property.IPCodeAnnot_->"annotation"|Property.(IPPredicate{ip_kind=PKRequires_;ip_kinstr=Kglobal})->"precondition for callers"|_->"property"(* -------------------------------------------------------------------------- *)(* --- Popup Menu for WP --- *)(* -------------------------------------------------------------------------- *)letis_rte_generatedkf=List.for_all(fun(_,_,lookup)->lookupkf)(RteGen.Api.get_all_status())classpopup()=object(self)valmutableclick:selection->unit=(fun_->())valmutableprove:selection->unit=(fun_->())methodon_clickf=click<-fmethodon_provef=prove<-fmethodprivaterte_generatekf=letsetup=Factory.parse(Wp_parameters.Model.get())inletdriver=Driver.load_driver()inletmodel=Factory.instancesetupdriverinWpRTE.generatemodelkfmethodprivaterte_option(menu:GMenu.menuGMenu.factory)(main:Design.main_window_extension_points)titleactionkf=ignore(menu#add_itemtitle~callback:(fun()->actionkf;main#redisplay()))methodprivaterte_popupmenumainloc=matchlocwith|PVDecl(Somekf,_,{vglob=true})->ifnot(is_rte_generatedkf)thenself#rte_optionmenumain"Insert wp-rte guards"self#rte_generatekf;|_->()methodprivatewp_popup(menu:GMenu.menuGMenu.factory)=function|S_none->()|s->lettarget=matchswith|S_none->"none"|S_propip->kind_of_propertyip|S_call_->"call preconditions"|S_fun_->"function annotations"inlettitle=Printf.sprintf"Prove %s by WP"targetinignore(menu#add_itemtitle~callback:(fun()->proves))methodregister(menu:GMenu.menuGMenu.factory)(main:Design.main_window_extension_points)~(button:int)(loc:Pretty_source.localizable)=beginmatchbuttonwith|1->beginmatchselection_of_localizablelocwith|S_none->()|s->clicksend|3->beginself#wp_popupmenu(selection_of_localizableloc);self#rte_popupmenumainloc;end|_->()endend(* -------------------------------------------------------------------------- *)(* --- Source Highlighter for WP --- *)(* -------------------------------------------------------------------------- *)modulePATH=Stmt.SetmoduleDEPS=Property.Setletapply_tagnameattrbufferstartstop=lettg=Gtk_helper.make_tagbuffer~nameattrinGtk_helper.apply_tagbuffertgstartstopletapply_goal=apply_tag"wp.goal"[`BACKGROUND"lightblue"]letapply_effect=apply_tag"wp.effect"[`BACKGROUND"lightblue"]letapply_path=apply_tag"wp.path"[`BACKGROUND"yellow"]letapply_depend=apply_tag"wp.depend"[`BACKGROUND"pink"]letinstructionspath=PATH.filter(funs->matchs.skindwith|Instr_->true|_->false)pathclasshighlighter(main:Design.main_window_extension_points)=object(self)valmutablegoal=None(* orange *)valmutablesource=None(* blue *)valmutablepath=PATH.empty(* yellow *)valmutabledeps=DEPS.empty(* green *)valmutablecurrent=Nonemethodprivateclear=begingoal<-None;source<-None;path<-PATH.empty;deps<-DEPS.empty;endmethodprivatescroll()=main#rehighlight();matchgoalwith|None->()|Someip->main#scroll(PIPip)methodsets=letmoved=matchcurrent,swith|None,None->false|Somes0,Somes1->s0.po_gid<>s1.po_gid|None,Some_|Some_,None->trueinifmovedthenbegincurrent<-s;self#clear;matchswith|None->Wutil.latermain#rehighlight;|Some{Wpo.po_pid=pid;Wpo.po_formula=f}->beginsource<-f.VC_Annot.source;path<-instructionsf.VC_Annot.path;deps<-f.VC_Annot.deps;end;ifnot(WpPropId.is_checkpid||WpPropId.is_tacticpid)then(letip=WpPropId.property_of_idpidingoal<-Someip);Wutil.laterself#scroll;endmethodupdate=main#rehighlight()methodhighlight(buffer:Design.reactive_buffer)(loc:Pretty_source.localizable)~(start:int)~(stop:int)=letbuffer=buffer#bufferinbeginmatchlocwith|PStmt(_,stmt)|PStmtStart(_,stmt)->beginmatchsourcewith|Some(s,_)whenStmt.equalstmts->apply_effectbufferstartstop|_->ifPATH.memstmtpaththenapply_pathbufferstartstopend|PIPip->beginmatchgoalwith|SomegwhenProperty.equalgip->apply_goalbufferstartstop|_->ifDEPS.memipdepsthenapply_dependbufferstartstopend|PGlobal_|PVDecl_|PTermLval_|PLval_|PExp_|PType_->()endend