[m-dev.] for review: use readline in browser/

Mark Anthony BROWN dougl at cs.mu.OZ.AU
Fri May 28 17:36:43 AEST 1999


Mark Anthony BROWN writes:
> 
> IMHO, it is a better design to avoid relying on global variables, so
> it is probably worth the extra effort to pass the streams through.
> I'll post a relative diff soon ...
> 

Actually, since I wound up undoing much of the previous diff, a
normal diff is probably shorter and easier to understand.  I have
omitted the diffs for parse.m and declarative_oracle.m --- the
changes are the same as first time round.

Cheers,
Mark.

Estimated hours taken: 6

If calling from the internal debugger, use readline input for the
interactive term browser and interactive queries.

browser/browse.m:
	Change some if-then-elses to switches, which will help
	catch errors if a new functor is added to the debugger type.

browser/parse.m:
browser/util.m:
	Return a string from util__trace_getline/4 rather than a
	list of chars, which saves converting from a string to a list
	of chars and then back again.

browser/util.m:
	Add a version of util__trace_getline that also takes I/O
	stream arguments.  Pass these arguments to MR_trace_getline.

browser/declarative_oracle.m:
	Call util__trace_getline/4 to do input via readline (if
	available).  Improve error handling.

browser/interactive_query.m:
	Call util__trace_getline to get user input, instead of
	standard library predicates.

runtime/mercury_init.h:
runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
trace/mercury_trace_internal.c:
trace/mercury_trace_internal.h:
	Add two I/O stream arguments to MR_trace_getline.


Index: browser/browse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/browse.m,v
retrieving revision 1.9
diff -u -r1.9 browse.m
--- browse.m	1999/05/21 14:38:18	1.9
+++ browse.m	1999/05/28 06:29:10
@@ -69,8 +69,9 @@
 	"ML_BROWSE_browse_external").
 
 %---------------------------------------------------------------------------%
-% If the term browser is called from the internal debugger, Input/Output are 
-% done via MR_mdb_in/MR_mdb_out. If it is called from the external debugger,
+% If the term browser is called from the internal debugger, input is
+% done via a call to the readline library (if available), using streams
+% MR_mdb_in and MR_mdb_out.  If it is called from the external debugger,
 % Input/Output are done via MR_debugger_socket_in/MR_debugger_socket_out. 
 % In the latter case we need to output terms; their type is 
 % term_browser_response.
@@ -205,6 +206,7 @@
 :- pred browse_common(debugger, T, io__input_stream, io__output_stream,
 			browser_state, browser_state, io__state, io__state).
 :- mode browse_common(in, in, in, in, in, out, di, uo) is det.
+
 browse_common(Debugger, Object, InputStream, OutputStream, State0, State) -->
 	{ type_to_univ(Object, Univ) },
 	{ set_term(Univ, State0, State1) },
@@ -219,18 +221,21 @@
 	io__state, io__state).
 :- mode browse_main_loop(in, in, out, di, uo) is det.
 browse_main_loop(Debugger, State0, State) -->
-	{ prompt(Prompt) },
-	( { Debugger = internal } ->
+	(
+		{ Debugger = internal },
+		{ prompt(Prompt) },
 		parse__read_command(Prompt, Command)
 	;
+		{ Debugger = external },
 		parse__read_command_external(Command)
 	),
 	( { Command = quit } ->
 		% write_string_debugger(Debugger, "quitting...\n")
-		( { Debugger = external } ->
+		(
+			{ Debugger = external },
 			send_term_to_socket(browser_quit)
 		;
-			{ true }
+			{ Debugger = internal }
 		),
 		{ State = State0 }
 	;
@@ -1002,30 +1007,24 @@
 
 :- pred write_string_debugger(debugger, string, io__state, io__state).
 :- mode write_string_debugger(in, in, di, uo) is det.
-write_string_debugger(Debugger, String) -->
-	( { Debugger = internal } ->
-		io__write_string(String)
-	;
-		send_term_to_socket(browser_str(String))
-	).
+write_string_debugger(internal, String) -->
+	io__write_string(String).
+write_string_debugger(external, String) -->
+	send_term_to_socket(browser_str(String)).
 
 :- pred nl_debugger(debugger, io__state, io__state).
 :- mode nl_debugger(in, di, uo) is det.
-nl_debugger(Debugger) -->
-	( { Debugger = internal } ->
-		io__nl
-	;
-		send_term_to_socket(browser_nl)
-	).
+nl_debugger(internal) -->
+	io__nl.
+nl_debugger(external) -->
+	send_term_to_socket(browser_nl).
 
 :- pred write_int_debugger(debugger, int, io__state, io__state).
 :- mode write_int_debugger(in, in, di, uo) is det.
-write_int_debugger(Debugger, Int) -->
-	( { Debugger = internal } ->
-		io__write_int(Int)
-	;
-		send_term_to_socket(browser_int(Int))
-	).
+write_int_debugger(internal, Int) -->
+	io__write_int(Int).
+write_int_debugger(external, Int) -->
+	send_term_to_socket(browser_int(Int)).
 
 
 :- pred print_format_debugger(debugger, portray_format, io__state, io__state).
Index: browser/interactive_query.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/interactive_query.m,v
retrieving revision 1.4
diff -u -r1.4 interactive_query.m
--- interactive_query.m	1999/05/28 02:22:51	1.4
+++ interactive_query.m	1999/05/28 06:30:21
@@ -33,8 +33,8 @@
 :- type options == string.
 
 :- implementation.
-:- import_module std_util, bool, string, term, varset, term_io.
-:- import_module dl, name_mangle.
+:- import_module std_util, bool, string, term, varset, term_io, parser.
+:- import_module dl, name_mangle, util.
 
 :- pragma export(query(in, in, in, in, in, di, uo), "ML_query").
 
@@ -42,17 +42,33 @@
 
 query(QueryType, Imports, Options, MDB_Stdin, MDB_Stdout) -->
 	% write_import_list(Imports),
-	print(MDB_Stdout, query_prompt(QueryType)),
-	io__flush_output(MDB_Stdout),
-	io__set_input_stream(MDB_Stdin, OldStdin),
-	term_io__read_term(Result),
-	io__set_input_stream(OldStdin, _),
+	util__trace_getline(query_prompt(QueryType), Result,
+			MDB_Stdin, MDB_Stdout),
 	( { Result = eof },
 		io__nl(MDB_Stdout)
-	; { Result = error(Msg, _Line) },
+	; { Result = error(Error) },
+		{ io__error_message(Error, Msg) },
 		io__write_string(MDB_Stdout, Msg), io__nl(MDB_Stdout),
 		query(QueryType, Imports, Options, MDB_Stdin, MDB_Stdout)
-	; { Result = term(VarSet, Term) },
+	; { Result = ok(Line) },
+		{ parser__read_term_from_string("", Line, _, ReadTerm) },
+		query_2(QueryType, Imports, Options, MDB_Stdin, MDB_Stdout,
+				ReadTerm)
+	).
+
+
+:- pred query_2(query_type::in, imports::in, options::in,
+		io__input_stream::in, io__output_stream::in,
+		read_term(generic)::in, state::di, state::uo) is det.
+
+query_2(QueryType, Imports, Options, MDB_Stdin, MDB_Stdout, ReadTerm) -->
+	( { ReadTerm = eof },
+		io__nl(MDB_Stdout)
+	; { ReadTerm = error(Msg, _Line) },
+		io__write_string(MDB_Stdout, Msg),
+		io__nl(MDB_Stdout),
+		query(QueryType, Imports, Options, MDB_Stdin, MDB_Stdout)
+	; { ReadTerm = term(VarSet, Term) },
 		% io__write_string("Read term: "),
 		% term_io__write_term(Term, VarSet),
 		% io__write_string("\n"),
Index: browser/util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/util.m,v
retrieving revision 1.2
diff -u -r1.2 util.m
--- util.m	1999/05/14 02:24:38	1.2
+++ util.m	1999/05/28 06:14:52
@@ -8,14 +8,18 @@
 
 :- interface.
 
-:- import_module list, string, char, io.
+:- import_module list, string, io.
 
 	% Get user input via the same method used by the internal
 	% debugger.
-:- pred util__trace_getline(string, io__result(list(char)), io__state,
+:- pred util__trace_getline(string, io__result(string), io__state,
 		io__state).
 :- mode util__trace_getline(in, out, di, uo) is det.
 
+:- pred util__trace_getline(string, io__result(string), io__input_stream,
+		io__output_stream, io__state, io__state).
+:- mode util__trace_getline(in, out, in, in, di, uo) is det.
+
 :- pred util__zip_with(pred(T1, T2, T3), list(T1), list(T2), list(T3)).
 :- mode util__zip_with(pred(in, in, out) is det, in, in, out) is det.
 
@@ -29,20 +33,24 @@
 
 :- import_module int, require.
 
-:- pragma promise_pure(util__trace_getline/4).
-
 util__trace_getline(Prompt, Result) -->
+	io__input_stream(MdbIn),
+	io__output_stream(MdbOut),
+	util__trace_getline(Prompt, Result, MdbIn, MdbOut).
+
+:- pragma promise_pure(util__trace_getline/6).
+
+util__trace_getline(Prompt, Result, MdbIn, MdbOut) -->
 	{
-		impure call_trace_getline(Prompt, Line)
+		impure call_trace_getline(MdbIn, MdbOut, Prompt, Line)
 	->
-		string__to_char_list(Line, Chars),
-		Result = ok(Chars)
+		Result = ok(Line)
 	;
 		Result = eof
 	}.
 
-:- impure pred call_trace_getline(string, string).
-:-        mode call_trace_getline(in, out) is semidet.
+:- impure pred call_trace_getline(input_stream, output_stream, string, string).
+:-        mode call_trace_getline(in, in, in, out) is semidet.
 
 :- pragma c_header_code("
 	#include ""mercury_wrapper.h""
@@ -51,14 +59,18 @@
 	#include ""mercury_trace_internal.h""
 ").
 
-:- pragma c_code(call_trace_getline(Prompt::in, Line::out),
+:- pragma c_code(call_trace_getline(MdbIn::in, MdbOut::in, Prompt::in,
+			Line::out),
 	[will_not_call_mercury],
 	"
 		char		*line;
 		char		*mercury_string;
+		MercuryFile	*mdb_in = (MercuryFile *) MdbIn;
+		MercuryFile	*mdb_out = (MercuryFile *) MdbOut;
 
 		if (MR_address_of_trace_getline != NULL) {
-			line = (*MR_address_of_trace_getline)((char *) Prompt);
+			line = (*MR_address_of_trace_getline)((char *) Prompt,
+					mdb_in->file, mdb_out->file);
 		} else {
 			MR_tracing_not_enabled();
 			/* not reached */
Index: runtime/mercury_init.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_init.h,v
retrieving revision 1.14
diff -u -r1.14 mercury_init.h
--- mercury_init.h	1999/05/28 05:29:07	1.14
+++ mercury_init.h	1999/05/28 05:44:47
@@ -118,7 +118,7 @@
 extern	void	ML_io_print_to_stream(Word, Word, Word);
 
 /* in trace/mercury_trace_internal.h */
-extern	char	*MR_trace_getline(const char *);
+extern	char	*MR_trace_getline(const char *, FILE *mdb_in, FILE *mdb_out);
 
 /* in trace/mercury_trace_declarative.h */
 extern	void	MR_edt_root_node(Word EDT, Word *Node);
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.40
diff -u -r1.40 mercury_wrapper.c
--- mercury_wrapper.c	1999/05/28 05:29:11	1.40
+++ mercury_wrapper.c	1999/05/28 05:44:50
@@ -138,7 +138,7 @@
 void	(*address_of_mercury_init_io)(void);
 void	(*address_of_init_modules)(void);
 
-char *	(*MR_address_of_trace_getline)(const char *);
+char *	(*MR_address_of_trace_getline)(const char *, FILE *, FILE *);
 
 #ifdef	MR_USE_EXTERNAL_DEBUGGER
 void	(*MR_address_of_trace_init_external)(void);
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.21
diff -u -r1.21 mercury_wrapper.h
--- mercury_wrapper.h	1999/05/28 05:29:12	1.21
+++ mercury_wrapper.h	1999/05/28 05:44:50
@@ -62,12 +62,14 @@
 #endif
 
 /*
-** MR_trace_getline(const char *) is defined in trace/mercury_trace_internal.c
-** but is called in browser/util.m.  As we cannot do direct calls from
-** browser/ to trace/, we do an indirect call via the following pointer.
+** MR_trace_getline(const char *, FILE *, FILE *) is defined in
+** trace/mercury_trace_internal.c but is called in browser/util.m.  As
+** we cannot do direct calls from browser/ to trace/, we do an indirect 
+** call via the following pointer.
 */
 
-extern	char *		(*MR_address_of_trace_getline)(const char *);
+extern	char *		(*MR_address_of_trace_getline)(const char *,
+				FILE *, FILE *);
 
 /*
 ** MR_trace_init_external() and MR_trace_final_external() are defined 
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.44
diff -u -r1.44 mercury_trace_internal.c
--- mercury_trace_internal.c	1999/05/27 01:01:33	1.44
+++ mercury_trace_internal.c	1999/05/28 02:49:13
@@ -233,7 +233,7 @@
 	jumpaddr = NULL;
 
 	do {
-		line = MR_trace_getline("mdb> ");
+		line = MR_trace_getline("mdb> ", MR_mdb_in, MR_mdb_out);
 		res = MR_trace_debug_cmd(line, cmd, event_info, &event_details,
 				&jumpaddr);
 	} while (res == KEEP_INTERACTING);
@@ -1356,7 +1356,8 @@
 				char	*line2;
 
 				line2 = MR_trace_getline("mdb: "
-					"are you sure you want to quit? ");
+					"are you sure you want to quit? ",
+					MR_mdb_in, MR_mdb_out);
 				if (line2 == NULL) {
 					/* This means the user input EOF. */
 					confirmed = TRUE;
@@ -1672,7 +1673,8 @@
 	int	i;
 
 	next_char_slot = 0;
-	while ((text = MR_trace_getline("cat> ")) != NULL) {
+	while ((text = MR_trace_getline("cat> ", MR_mdb_in, MR_mdb_out))
+			!= NULL) {
 		if (streq(text, "end")) {
 			free(text);
 			break;
@@ -1932,7 +1934,7 @@
 
 /*
 ** If there any lines waiting in the queue, return the first of these.
-** If not, print the prompt to MR_mdb_out, read a line from MR_mdb_in,
+** If not, print the prompt to mdb_out, read a line from mdb_in,
 ** and return it in a malloc'd buffer holding the line (without the final
 ** newline).
 ** If EOF occurs on a nonempty line, treat the EOF as a newline; if EOF
@@ -1940,7 +1942,7 @@
 */
 
 char *
-MR_trace_getline(const char *prompt)
+MR_trace_getline(const char *prompt, FILE *mdb_in, FILE *mdb_out)
 {
 	char	*line;
 
@@ -1951,13 +1953,13 @@
 
 	MR_trace_internal_interacting = TRUE;
 
-	line = MR_trace_readline(prompt, MR_mdb_in, MR_mdb_out);
+	line = MR_trace_readline(prompt, mdb_in, mdb_out);
 
 	/* if we're using readline, then readline does the echoing */
 #ifdef MR_NO_USE_READLINE
 	if (MR_echo_commands) {
-		fputs(line, MR_mdb_out);
-		putc('\n', MR_mdb_out);
+		fputs(line, mdb_out);
+		putc('\n', mdb_out);
 	}
 #endif
 
@@ -2038,7 +2040,7 @@
 	/* We try to leave one line for the prompt itself. */
 	if (MR_scroll_control && MR_scroll_next >= MR_scroll_limit - 1) {
 	try_again:
-		buf = MR_trace_getline("--more-- ");
+		buf = MR_trace_getline("--more-- ", MR_mdb_in, MR_mdb_out);
 		if (buf != NULL) {
 			for (i = 0; buf[i] != '\0' && MR_isspace(buf[i]); i++)
 				;
Index: trace/mercury_trace_internal.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.h,v
retrieving revision 1.7
diff -u -r1.7 mercury_trace_internal.h
--- mercury_trace_internal.h	1999/05/14 02:25:46	1.7
+++ mercury_trace_internal.h	1999/05/28 02:45:51
@@ -55,6 +55,7 @@
 extern FILE *MR_mdb_out;
 extern FILE *MR_mdb_err;
 
-extern	char	*MR_trace_getline(const char *prompt);
+extern	char	*MR_trace_getline(const char *prompt, FILE *mdb_in,
+				FILE *mdb_out);
 
 #endif	/* MERCURY_TRACE_INTERNAL_H */

-- 
Mark Brown  (dougl at cs.mu.oz.au)       )O+   |  For Microsoft to win,
MEngSc student,                             |  the customer must lose
Dept of Computer Science, Melbourne Uni     |          -- Eric S. Raymond
--------------------------------------------------------------------------
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