123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253(*********************************************************************************)(* Chamo *)(* *)(* Copyright (C) 2003-2021 Institut National de Recherche en Informatique *)(* et en Automatique. All rights reserved. *)(* *)(* This program is free software; you can redistribute it and/or modify *)(* it under the terms of the GNU Lesser General Public License version *)(* 3 as published by the Free Software Foundation. *)(* *)(* This program 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 General Public License for more details. *)(* *)(* You should have received a copy of the GNU General Public License *)(* along with this program; if not, write to the Free Software *)(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)(* 02111-1307 USA *)(* *)(* Contact: Maxence.Guesdon@inria.fr *)(* *)(*********************************************************************************)(** A window to display various output boxes with tabs. *)openStkclasstypeoutput=objectmethodname:stringmethodlabel:stringmethodset_label:string->unitmethodbox:Widget.widgetmethodon_destroy:unitend;;classoutputs?(on_destroy=fun()->())()=object(self)inheritGui_base.outputs()methodcoerce=self#notebook#coercevalmutablepages=([]:outputlist)methodoutput_by_namename=List.find(funo->o#name=name)pagesmethodprivateoutput_posname=letrecitern=function[]->raiseNot_found|h::q->ifh#name=namethennelseiter(n+1)qiniter0pagesmethodadd_output(o:output)=tryignore(self#output_by_nameo#name);failwith(Printf.sprintf"Output \"%s\" already present."o#name)withNot_found->lettab=newGui_base.outputs_note_tab()intab#wlabel#set_texto#label;let(o:output)=objectmethodname=o#namemethodlabel=o#labelmethodbox=o#boxmethodset_labels=o#set_labels;tab#wlabel#set_textsmethodon_destroy=o#on_destroyendinignore(tab#wb_close#connectWidget.Activated(fun()->letn=self#output_poso#nameinnotebook#remove_pagen;o#box#destroy;pages<-List.filter(funo2->o2#name<>o#name)pages;matchpageswith[]->toplevel#hide|_->()));ignore(notebook#pack~label:tab#hbox#coerceo#box);pages<-pages@[o]methodshowname=toplevel#show;letn=self#output_posnameinignore(notebook#set_active_pagen)initializerignore(toplevel#connectWidget.Destroy(fun()->List.iter(funo->o#on_destroy)pages;on_destroy();true));toplevel#showend;;letoutputs_window=refNone;;letoutputs()=match!outputs_windowwithNone->leto=newoutputs~on_destroy:(fun()->outputs_window:=None)()inoutputs_window:=Someo;o|Someo->o;;(*
let watch_and_insert ?(on_end=fun() -> ()) ic insert =
let gchan = GMain.Io.channel_of_descr (Unix.descr_of_in_channel ic) in
let buf_size = 512 in
let buf = Bytes.make buf_size 'x' in
let rec f_read l =
try
if List.mem `IN l then
begin
let n = GMain.Io.read gchan ~buf ~pos: 0 ~len: buf_size in
(
(
try insert (Bytes.sub_string buf 0 n)
with _ -> ()
);
(n < buf_size) || (f_read l)
)
end
else
if List.mem `HUP l then
(
on_end ();
false
)
else
true
with
e -> prerr_endline (Printexc.to_string e); true
in
GMain.Io.add_watch
~prio: 0
~cond: [ `IN ; `HUP ]
~callback: f_read gchan
;;
let run_and_read_in_buffer command insert on_end =
let com = Printf.sprintf "%s 2>&1" command in
let ic = Unix.open_process_in com in
let on_end () =
let ret =
match Unix.close_process_in ic with
Unix.WEXITED n
| Unix.WSIGNALED n
| Unix.WSTOPPED n -> n
in
on_end ret
in
ignore(watch_and_insert ~on_end ic insert)
;;
*)classtext_output?(on_destroy=fun()->())(name:string)=letscr=Bin.scrollbox()inlettl=Textlog.textlog~theme:"terminal"~pack:scr#set_child()inletmutex=Lwt_mutex.create()inobject(self)methodname=namevalmutablelabel=namemethodlabel=labelmethodset_labels=label<-smethodbox=scr#coercemethodscrollbox=scrmethodreset=ignore(tl#delete())methodinserttext=tl#rawtextmethodruncommand?(reset=false)(f_on_end:int->unit)=letcom=Lwt_process.shellcommandinletrecread_and_printic=match%lwtLwt_io.read_lineicwith|exceptionEnd_of_file->Lwt.return_unit|line->self#insertline;self#insert"\n";read_and_printicinifresetthenself#reset;let%lwt()=Lwt_mutex.lockmutexintry%lwtLwt_process.with_process_fullcom(funp->let%lwt()=Lwt.join[read_and_printp#stdout;read_and_printp#stderr]inself#insert"";match%lwtp#closewith|Unix.WEXITEDn|Unix.WSTOPPEDn|Unix.WSIGNALEDn->f_on_endn;Lwt.return_unit;Lwt_mutex.unlockmutex;Lwt.return_unit)withe->Lwt_mutex.unlockmutex;Lwt.failemethodcontents=tl#text()methodon_destroy=on_destroy()methodview=tl#as_textviewinitializer()(*Gtksv_utils.register_source_view view;
Gtksv_utils.register_source_buffer view#source_buffer;
Gtksv_utils.apply_sourceview_props view
(Gtksv_utils.read_sourceview_props ()) ;*)end;;(*
class interactive_output ?(on_destroy=fun() -> ()) ~name ~command =
let command = Printf.sprintf "%s 2>&1" command in
let (ic, oc) = Unix.open_process command in
let destroyed = ref false in
let id_watch = ref None in
let on_destroy () =
on_destroy ();
(
match !id_watch with
None -> ()
| Some id -> GMain.Io.remove id
);
if not !destroyed then
(
ignore(Unix.close_process (ic, oc)) ;
destroyed := true;
)
in
object(self)
inherit text_output ~on_destroy name
method run com ?(reset=false) f =
(
match !id_watch with
Some _ -> ()
| None ->
id_watch := Some
(
watch_and_insert
~on_end: self#view#destroy
ic self#insert
)
);
if reset then self#reset;
try output_string oc com; flush oc; f 0
with _ -> f 1
end;;
*)