/* File: flrdebugger.P -- Flora debugger
**
** Author(s): Michael Kifer
** Contact: flora-users@lists.sourceforge.net
**
** Copyright (C) The Research Foundation of SUNY, 2001
**
** FLORA-2 is free software; you can redistribute it and/or modify it under the
** terms of the GNU Library General Public License as published by the Free
** Software Foundation; either version 2 of the License, or (at your option)
** any later version.
**
** FLORA-2 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 Library General Public License for
** more details.
**
** You should have received a copy of the GNU Library General Public License
** along with FLORA-2; if not, write to the Free Software Foundation,
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** $Id: flrdebugger.P,v 1.22 2003/06/18 07:01:33 kifer Exp $
**
*/
:- compiler_options([xpp_on]).
#include "standard.h"
#include "flrheader.flh"
#include "flora_terms.flh"
:- import file_close/1, ioport2iostream/2 from file_io.
:- import debug_display_call_hook/1, flora_switch/1 from usermod.
:- import flora_configuration/2 from flrregistry.
:- import process_control/2 from shell.
:- import xpp_process_file/3 from parse.
:- import flora_decode_predicate/6,
flora_module_name/3,
flora_module_predicate_symbol/3
from flrwrapper.
:- import flora_set_xpp_options_for_read/1,
flora_set_xpp_options_for_read/0,
flora_clear_xpp_options/0 from flrutils.
:- import flora_message_line/1, flora_message_line/2 from flrprint.
:- import flLoadedModule/1 from flora2.
:- import flora_concat_atoms/2,
flora_slash/1,
flora_set_counter/2
from flrporting.
:- import flora_write_goal/2 from flrdecode.
:- import flora_handle_trace/0,
flora_handle_notrace/0
from usermod.
%% This is a trick: the debugger wants the hook to be in usermod,
%% but we want to work in a module
:- import flora_write_debugger_hook/1 from usermod.
:- dynamic debug_display_call_hook/1.
:- dynamic flora_switch/1.
:- dynamic flora_write_debugger_hook/1.
:- dynamic
hide_this_hide/2,
show_this_hide/2,
hide_this_show/2,
trace_this_noprint/2,
trace_this_print/2,
flora_hide_this_hide/1,
flora_hide_this_show/1,
flora_show_this_hide/1,
flora_trace_this_noprint/1,
flora_trace_this_print/1.
:- import
hide_this_hide/2,
show_this_hide/2,
hide_this_show/2,
trace_this_noprint/2,
trace_this_print/2,
flora_hide_this_hide/1,
flora_hide_this_show/1,
flora_show_this_hide/1,
flora_trace_this_noprint/1,
flora_trace_this_print/1
from usermod.
:- export flora_read_debugger_data/1,
flora_load_dyndata_for_user_modules/1,
FLORA_SYMBOL('debugger_loaded'),
flora_trace/0,
flora_notrace/0.
%% Assert the debugger hook
?- assert(debug_display_call_hook(flora_write_debugger_hook)).
?- assert((
flora_write_debugger_hook(X) :-
(\+flora_switch(low_level_trace) -> flora_write_debug_call(X)
; flora_write_dbg_item(X)
)
)).
%% Get the debugging output stream
:- dynamic flora_dbg_stream/1.
?- (flora_dbg_stream(Stream) -> close(Stream), retractall(flora_dbg_stream(_))
; ioport2iostream(STDDBG,Stream), assert(flora_dbg_stream(Stream))
).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% flora_write_goal %%%%%%%%%%%%%%%%%%%%%%%%%%%
flora_write_debug_call(Call) :-
flora_dbg_stream(Stream), flora_write_goal(Stream,Call).
flora_write_dbg_item(Item) :- flora_dbg_stream(Stream), write(Stream,Item).
/*********************************************************************/
flora_trace :-
assert(flora_switch(trace)),
flora_handle_trace.
flora_notrace :-
retractall(flora_switch(trace)),
flora_handle_notrace.
/*********************************************************************/
flora_debug_dyndata_file(Filename) :-
flora_configuration(installdir,FlrSysLib),
flora_slash(S),
flora_concat_atoms([FlrSysLib,S,debugger,S,'dynamic_data.dat'],Filename).
flora_debug_statdata_file(Filename) :-
flora_configuration(installdir,FlrSysLib),
flora_slash(S),
flora_concat_atoms([FlrSysLib,S,debugger,S,'static_data.dat'],Filename).
%% If WS is a var -- loading static data
%% Otherwise, loading dynamic data for the specified module
flora_read_debugger_data(WS,_Datafile) :-
%% Check if already loaded
(var(WS)
-> current_predicate(FLORA_SYMBOL('debugger_static_data_loaded')/0)
; flora_module_predicate_symbol(debugger_data_loaded, WS, WSSym),
current_predicate(WSSym/0)
),
!.
flora_read_debugger_data(WS,Datafile) :-
(var(WS)
-> flora_set_xpp_options_for_read
; flora_set_xpp_options_for_read(WS)
),
xpp_process_file(Datafile, CPP_process, IOportFromCPP),
repeat,
file_read(IOportFromCPP,T),
(T = end_of_file -> true
; assert(T), fail
),
process_control(CPP_process, wait(ExitStatus)),
(ExitStatus==0, !
; abort(('[Debugger] Error while preprocessing ', Datafile))
),
flora_clear_xpp_options,
file_close(IOportFromCPP),
flora_set_counter(xpp_on,0),
(var(WS)
-> flora_message_line('Static debugger data loaded')
; flora_message_line('Dynamic debugger data loaded for module ~w', WS)
),
!.
%% Read dynamic data for preloaded user modules
flora_load_dyndata_for_user_modules([]).
flora_load_dyndata_for_user_modules([M|List]) :-
flora_debug_dyndata_file(DataFile),
flora_read_debugger_data(M,DataFile),
flora_load_dyndata_for_user_modules(List).
flora_load_statdata :-
flora_debug_statdata_file(DataFile),
flora_read_debugger_data(_M,DataFile).
%% The bridge is disabled during low level tracing
flora_build_bridge_to_xsb_debugger :-
assert((hide_this_hide(X,Y) :-
\+flora_switch(low_level_trace),flora_hide_this_hide(X/Y))),
assert((hide_this_show(X,Y) :-
\+flora_switch(low_level_trace),flora_hide_this_show(X/Y))),
assert((show_this_hide(X,Y) :-
\+flora_switch(low_level_trace),flora_show_this_hide(X/Y))),
assert((trace_this_noprint(X,Y) :-
\+flora_switch(low_level_trace),flora_trace_this_noprint(X/Y))),
assert((trace_this_print(X,Y) :-
\+flora_switch(low_level_trace),flora_trace_this_print(X/Y))),
%% Rule for handling system modules.
%% This prevents tracing inside flora system modules.
%% We might add a switch that would enable this optionally.
%% Not clear if this is useful.
assert((show_this_hide(X,Y) :-
\+flora_switch(low_level_trace),
functor(PX,X,Y),
flora_decode_predicate(PX,_,WS,_,_,_),
flora_module_name(WS,systemmodule,_)
)),
%% Rules for prefixes of predicates that need
%% to be handled by the debugger
assert((hide_this_hide(X,Y) :-
\+flora_switch(low_level_trace),
(flora_hide_this_hide(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), !
; flora_hide_this_hide(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), !
)
)),
assert((hide_this_show(X,Y) :-
\+flora_switch(low_level_trace),
( flora_hide_this_show(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), !
; flora_hide_this_show(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), !
)
)),
assert((show_this_hide(X,Y) :-
\+flora_switch(low_level_trace),
( flora_show_this_hide(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), !
; flora_show_this_hide(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), !
)
)),
assert((trace_this_noprint(X,Y) :-
\+flora_switch(low_level_trace),
( flora_trace_this_noprint(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), !
; flora_trace_this_noprint(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), !
)
)),
assert((trace_this_print(X,Y) :-
\+flora_switch(low_level_trace),
( flora_trace_this_print(pref(X1/Y)), atom(X),atom(X1), str_sub(X1,X,0), !
; flora_trace_this_print(match(X1/Y)), atom(X),atom(X1), str_sub(X1,X), !
)
)).
?- findall(X,flLoadedModule(X),L),
flora_load_statdata,
flora_load_dyndata_for_user_modules(L).
?- flora_build_bridge_to_xsb_debugger.
FLORA_SYMBOL('debugger_loaded').
syntax highlighted by Code2HTML, v. 0.9.1