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

Fergus Henderson fjh at cs.mu.OZ.AU
Fri May 28 17:54:38 AEST 1999


That looks great -- thanks, Mark.

On 28-May-1999, Mark Anthony BROWN <dougl at cs.mu.OZ.AU> wrote:
> 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
> --------------------------------------------------------------------------
> 

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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