[m-dev.] Add an bool argument to filter

Erwan Jahier Erwan.Jahier at irisa.fr
Fri Oct 29 19:47:18 AEST 1999


Estimated hours taken: 2

This change implements the Fergus suggestion; i.e. add an argument to filter 
that returns a bool saying whether we stop collecting or not.

trace/mercury_trace_external.c:
Opium-M/source/collect.in:
Opium-M/source/collect.op:
	Add an new argument to filter that says saying whether we stop 
	collecting or not.

Opium-M/source/collect.op:
	Also improve the documentation by describing the event type.


Index: 0.4/mercury_trace_external.c
--- 0.4/mercury_trace_external.c Fri, 29 Oct 1999 09:00:28 +0200 jahier (collect/3_mercury_tr 1.3 640)
+++ 0.4(w)/mercury_trace_external.c Fri, 29 Oct 1999 11:41:39 +0200 jahier (collect/3_mercury_tr 1.3 640)
@@ -183,9 +183,10 @@
 static void	MR_trace_browse_one_external(MR_Var_Spec which_var);
 static void	MR_COLLECT_filter(Word (*filter_ptr)(Integer, Integer, Integer, 
 			Word, Word, String, String, String, Integer, Integer, 
-			Integer, String, Word, Word *), Unsigned seqno, 
+			Integer, String, Word, Word *, Char *), Unsigned seqno, 
 			Unsigned depth,	MR_Trace_Port port, 
-			const MR_Stack_Layout_Label *layout, const char *path);
+			const MR_Stack_Layout_Label *layout, const char *path,
+			bool *stop_collecting);
 
 #if 0
 This pseudocode should go in the debugger process:
@@ -462,8 +463,10 @@
 	static void	(*initialize_ptr)(Word *) = NULL;
 	static Word    	(*filter_ptr)(Integer, Integer, Integer, MR_Trace_Port,
 				MR_PredFunc, String, String, String, Integer,
-				Integer, Integer, String, Word, Word *) = NULL;
+				Integer, Integer, String, Word, Word *, 
+				Char *) = NULL;
 	static bool    	collect_linked = FALSE;
+	static bool    	stop_collecting = FALSE;
 	Integer		debugger_request_type;
 	Integer		live_var_number;
 	Word		debugger_request;
@@ -536,9 +539,21 @@
 				(Unsigned) depth, 
 				(MR_Trace_Port) port,
 				layout, 
-				path);
-			goto done;
+				path,
+				&stop_collecting);
 
+			if (stop_collecting) {
+				(*send_collect_result_ptr)(
+					(Word) MR_collecting_variable,
+					(Word) &MR_debugger_socket_out);
+				external_debugger_mode = MR_reading_request;
+				#if defined(HAVE_DLFCN_H)&&defined(HAVE_DLCLOSE)
+					dlclose((void *)handle);
+				#endif
+				break;
+			} else {
+				goto done;
+			}
 		case MR_reading_request:
 			break;
 
@@ -822,9 +837,24 @@
 						(Unsigned) depth, 
 						(MR_Trace_Port) port,
 						layout, 
-						path);
+						path,
+						&stop_collecting);
 					
-					goto done;
+					if (stop_collecting) {
+						(*send_collect_result_ptr)(
+							(Word) 
+							MR_collecting_variable,
+							(Word) 
+							&MR_debugger_socket_out);
+						external_debugger_mode = 
+							MR_reading_request;
+#if defined(HAVE_DLFCN_H)&&defined(HAVE_DLCLOSE)
+						dlclose((void *)handle);
+#endif
+						break;
+					} else {
+						goto done;
+					}
 				} else {
 					MR_send_message_to_socket(
 						"collect_not_linked");
@@ -1439,10 +1469,13 @@
 */
 static void
 MR_COLLECT_filter(Word (*filter_ptr)(Integer, Integer, Integer, Word, Word, 
-	String, String, String, Integer, Integer, Integer, String, Word, Word *), 
+	String, String, String, Integer, Integer, Integer, String, Word, Word *,
+	Char *), 
        	Unsigned seqno, Unsigned depth, MR_Trace_Port port, 
-	const MR_Stack_Layout_Label *layout, const char *path)
-{		
+	const MR_Stack_Layout_Label *layout, const char *path,
+	bool *stop_collecting)
+{
+	Char	result;		
 	MR_TRACE_CALL_MERCURY((*filter_ptr)(
 		MR_trace_event_number,
 		seqno,
@@ -1457,7 +1490,9 @@
 		layout->MR_sll_entry->MR_sle_detism,
 		(String) path,
 		MR_collecting_variable,
-		&MR_collecting_variable));
+		&MR_collecting_variable,
+		&result));
+	*stop_collecting = (result == 'y');
 }
 
 #endif /* MR_USE_EXTERNAL_DEBUGGER */
--- collect.op.save	Fri Oct 29 11:20:24 1999
+++ collect.op	Fri Oct 29 11:24:15 1999
@@ -9,7 +9,7 @@
 % There are several things to do in order to be able to execute a 
 % collect/1 command:
 % 1) create a file that will that contain the definition of collected_type, 
-%	initialize/1 and filter/3,
+%	initialize/1 and filter/4,
 % 2) generate `collect.m' from this file (generate_collect/1),
 % 3) compile collect.m (compile_collect/0),
 % 4) dynamically link it with the current execution (dyn_link_collect/0).
@@ -30,51 +30,108 @@
 	   variable that will contain the result of the monitoring\n\
 	   activity.\n\
 	(2) The predicate initialize/1 which initializes this \n\
-	   collecting variable. initialize/1 have the \n\
+	   collecting variable. initialize/1 should follow the \n\
 	   following declarations:\n\
 		:- pred initialize(collected_type).\n\
 		:- mode initialize(out) is det.\n\
-	(3) the predicate filter/3 which updates it at each execution \n\
-	   event. filter/3 should have the following declarations:\n\
-		:- pred filter(event, collected_type, collected_type).\n\
-		:- mode filter(in, acc_in, acc_out) is det.\n\
+	(3) the predicate filter/4 which updates it at each execution \n\
+	   event. filter/4 also outputs a bool that indicates whether to stop\
+	   collecting. If this bool is always set to `no', the collecting will\
+	   process until the last event is reached. filter/4 should follow the \
+	   following declarations:\n\
+		:- pred filter(event, collected_type, collected_type, bool).\n\
+		:- mode filter(in, acc_in, acc_out, out) is det.\n\
 	   where `acc_in' and `acc_out' have `in' and `out' respectively\n\
 	   as default values.\n\
 	(4) and optionally the mode definition of `acc_in' and `acc_out'\n\
 	   in one want to override their default values.\n\
 \n\
+The event type is defined as follows (for more detail about the meaning of \
+each event attributes, please refer to the Reference Manual):\n\
+\n\
+:- type event ---> \n\
+	event(\n\
+		event_number,\n\
+		call_number,\n\
+		depth_number,\n\
+		trace_port_type,\n\
+		pred_or_func,\n\
+		declarated_module_name,\n\
+		defined_module_name,	\n\
+		proc_name,\n\
+		arity,\n\
+		mode_number,\n\
+		determinism,\n\
+		goal_path_string).\n\
+\n\
+:- type event_number == int.\n\
+:- type call_number == int.\n\
+:- type depth_number == int.\n\
+:- type trace_port_type\n\
+	--->	call\n\
+	;	exit\n\
+	;	redo\n\
+	;	fail\n\
+	;	ite_cond\n\
+	;	ite_then\n\
+	;	ite_else\n\
+	;	neg_enter\n\
+	;	neg_success\n\
+	;	neg_failure\n\
+	;	disj\n\
+	;	switch\n\
+	;	nondet_pragma_first\n\
+	;	nondet_pragma_later\n\
+	;	exception.\n\
+:- type pred_or_func\n\
+	--->	predicate\n\
+	;	function.\n\
+:- type declarated_module_name == string.\n\
+:- type defined_module_name == string.\n\
+:- type proc_name == string.\n\
+:- type arity == int.\n\
+:- type mode_number == int.\n\
+:- type determinism == int. \n\
+:- type goal_path_string == string.\n\
+:- type procedure ---> proc(\n\
+	pred_or_func, \n\
+	declarated_module_name, \n\
+	proc_name, \n\
+	arity, \n\
+	mode_number).\n\
+\n\
+Here are functions that eases the access of the event attributes:\n\
+\n\
+:- func chrono(event::in) = (event_number::out) is det.\n\
+:- func call(event::in) = (call_number::out) is det.\n\
+:- func depth(event::in) = (depth_number::out) is det.\n\
+:- func port(event::in) = (trace_port_type::out) is det.\n\
+:- func proc_type(event::in) = (pred_or_func::out) is det.\n\
+:- func decl_module(event::in) = (declarated_module_name::out) is det.\n\
+:- func def_module(event::in) = (defined_module_name::out) is det.\n\
+:- func proc_name(event::in) = (proc_name::out) is det.\n\
+:- func proc_arity(event::in) = (arity::out) is det.\n\
+:- func proc_mode_number(event::in) = (mode_number::out) is det.\n\
+:- func proc(event::in) = (procedure::out) is det.\n\
+:- func determinism(event::in) = (determinism::out) is det.\n\
+:- func goal_path(event::in) = (goal_path_string::out) is det.\n\
+\n\
+\n\
 Then, this file is used to generate the Mercury module `collect.m', \
 which is compiled and dynamically linked with the current execution. \
 When a `collect' request is made from the external debugger, a variable \
 of type collected_type is first initialized (with initialize/1) and \
-then updated (with filter/3) for all the events of the remaining \
-execution. When the end of the execution is reached, the last value of \
+then updated (with filter/4) for all the events of the remaining \
+execution. When the fourth argument of filter is equal to yes, or when \
+the end of the execution is reached, the last value of \
 the collecting variable is send to Opium-M.\n\
 \n\
-collect/2 can be specified by the following pseudo Opium-M code: \n\
-`	collect_spec(File, Result) :-\n\
-		generate_collect(File),\n\
-		compile_collect,\n\
-		dyn_link_collect,\n\
-		get_event_list(EventList),\n\
-		initialize(Start),\n\
-		foldl(filter, EventList, Start, Result).\n\
-'\n\
-where: \n\
- *) generate_collect/1 generates from `File' the Mercury module \
-`collect.m'; \n\
- *) compile_collect/0 compiles `collect.m' (generating `File.so'); \n\
- *) dynamically_link_collect/0 links the corresponding object file \n\
-(`File.so') with the current program execution; \n\
- *) get_event_list/1 collects in a list all the events from the current \
-event until the end of the execution; \n\
- *) foldl/4 is the classical fold predicate operating left-to-right. \n\
- \n\
-collect/2 does the same thing as collect_spec/2 except it operates \
-on the fly without creating any list of events."
+collect/2 can be seen as fold/4 meta-predicate except that (1) the \
+initialization and the updating of the accumulator is done via Mercury \
+predicates defined in a separate file (2) it does not take a list as \
+argument but operates on the fly on a list of events."
 	).
 
-
 %------------------------------------------------------------------------------%
 opium_command(
 	name		: collect,
@@ -87,7 +144,7 @@
 	parameters	: [],
 	message		:
 "If File contains the implementation of the Mercury predicates initialize/1 \
-and filter/3, collect(File, Result) calls filter/3 with each event of the \
+and filter/4, collect(File, Result) calls filter/4 with each event of the \
 execution and an accumulator initialized by initialize/1, and returns the \
 final value in Result.\n\
 \n\
@@ -99,7 +156,7 @@
 \n\
 	initialize(0).\n\
 \n\
-	filter(Event, AccIn, AccOut) :-\n\
+	filter(Event, AccIn, AccOut, no) :-\n\
 		( port(Event) = call ->\n\
 			AccOut = AccIn + 1\n\
 		;\n\
@@ -207,7 +264,7 @@
 	message		:
 "Generates a Mercury module named `collect.m' from file File; File should \
 contain the definition of the accumulator type (collected_type), \
-initialize/1 and filter/3 predicates."
+initialize/1 and filter/4 predicates."
 	).
 
 generate_collect_Op(File) :-

--- collect.in.save	Fri Oct 29 11:30:00 1999
+++ collect.in	Fri Oct 29 11:28:48 1999
@@ -1,6 +1,7 @@
 :- module collect.
 
 :- interface.
+:- import_module char.
 
 :- type collected_type.
 
@@ -11,9 +12,9 @@
 :- pred filter(event_number, call_number, depth_number, trace_port_type,
         pred_or_func, declarated_module_name, defined_module_name, proc_name,
         arity, mode_number, determinism, goal_path_string, collected_type,
-        collected_type).
+        collected_type, char).
 
-:- mode filter(in, in, in, in, in, in, in, in, in, in, in, in, acc_in, acc_out)
+:- mode filter(in, in, in, in, in, in, in, in, in, in, in, in, acc_in, acc_out,out)
         is det.
 
 :- pred send_collect_result(collected_type, io__output_stream, io__state,
@@ -25,11 +26,11 @@
 
 :- pragma export(initialize(out), "ML_COLLECT_initialize").
 :- pragma export(filter(in, in, in, in, in, in, in, in, in, in, in, in, 
-	acc_in, acc_out), "ML_COLLECT_filter").
+	acc_in, acc_out, out), "ML_COLLECT_filter").
 :- pragma export(send_collect_result(in, in, di, uo), 
 	"ML_COLLECT_send_collect_result").
 
-:- import_module int, io.
+:- import_module bool, int, io.
 
 :- type event_number == int.
 :- type call_number == int.
@@ -153,9 +154,9 @@
 proc_mode_number(Event) = ModeNumber :-
 	Event = event(_, _, _, _, _, _, _, _, _, ModeNumber, _, _).
 
-% proc(Event) = (proc(ProcType, DeclModule, Name, Arity, ModeNum)) :-
-% 	Event = event(_, _, _, ProcType, DeclModule, _, _, Name, Arity,
-% 			ModeNum, _, _).
+proc(Event) = (proc(ProcType, DeclModule, Name, Arity, ModeNum)) :-
+	Event = event(_, _, _, _, ProcType, DeclModule, _, Name, Arity,
+			ModeNum, _, _).
 
 determinism(Event) = Determinism :-
 	Event = event(_, _, _, _, _, _, _, _, _, _, Determinism, _).
@@ -166,10 +167,17 @@
 
 filter(EventNumber, CallNumber, DepthNumber, Port, PredOrFunc, DeclModuleName,
 		DefModuleName, PredName, Arity, ModeNum, Determinism, Path,
-		AccIn, AccOut) :- 
+		AccIn, AccOut, StopChar) :- 
 	filter(event(EventNumber, CallNumber, DepthNumber, Port, PredOrFunc,
 		DeclModuleName, DefModuleName, PredName, Arity, ModeNum,
-		Determinism, Path), AccIn, AccOut).
+		Determinism, Path), AccIn, AccOut, Stop),
+	(
+		Stop = no,
+		StopChar = 'n'
+	;
+		Stop = yes,
+		StopChar = 'y'
+	).
 
 
 % This predicate is called at the end of the collect execution to sent the
@@ -183,6 +191,6 @@
 :- type collect_result --->
 	collected(collected_type).
 
-:- pred filter(event, collected_type, collected_type).
-:- mode filter(in, acc_in, acc_out) is det.
-:- pragma inline(filter/3).
+:- pred filter(event, collected_type, collected_type, bool).
+:- mode filter(in, acc_in, acc_out, out) is det.
+:- pragma inline(filter/4).

-- 
R1.


--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list