[m-dev.] for review: use readline in the browser
Mark Anthony BROWN
dougl at cs.mu.OZ.AU
Tue May 11 17:20:51 AEST 1999
Hi,
This change is motivated by the need to write test cases for the
declarative debugger, prior to enabling it by default. Test
cases do not currently work when readline is used, because of
problems with redirecting stdin. The problem is fixed (or atleast
avoided) by using the same method of input for the browser as for
the internal debugger. I never tracked down the cause of the
problems, so I don't know exactly why this change fixes them, but
it is arguably a better design to have all input going through
one place (MR_trace_getline) anyway.
Similar changes will be made to the declarative debugger when
(and if) this passes review.
This is for review by Zoltan.
Estimated hours taken: 5
Use the same method of input for the browser as for the internal
tracer. Previously, the browser did input via the Mercury library
and the internal tracer did input via readline (if available). This
did not work properly if files were redirected into stdin, which meant
that test cases could not be written for the browser. This change
also adds a test case.
browser/util.m:
Add a predicate, util__trace_getline/4, which does input via
the same method used by the internal debugger.
browser/parse.m:
Call util__trace_getline/4 instead of io__read_line/3.
browser/browse.m:
Pass the prompt to browser/parse.m as a string, rather than
printing it before calling.
trace/mercury_trace_internal.c:
trace/mercury_trace_internal.h:
Declare MR_trace_getline extern.
runtime/mercury_init.h:
runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
util/mkinit.c:
Make MR_trace_getline available to the browser via a function
pointer.
tests/debugger/Mmakefile:
Add the new test case.
tests/debugger/browser_test.m:
tests/debugger/browser_test.inp:
tests/debugger/browser_test.exp:
The new test case.
Index: browser/browse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/browse.m,v
retrieving revision 1.7
diff -u -r1.7 browse.m
--- browse.m 1999/02/23 22:37:43 1.7
+++ browse.m 1999/05/06 08:25:43
@@ -174,8 +174,8 @@
:- pred browse_main_loop(browser_state, browser_state, io__state, io__state).
:- mode browse_main_loop(in, out, di, uo) is det.
browse_main_loop(State0, State) -->
- prompt,
- parse__read_command(Command),
+ { prompt(Prompt) },
+ parse__read_command(Prompt, Command),
( { Command = quit } ->
% io__write_string("quitting...\n")
{ State = State0 }
@@ -189,9 +189,8 @@
io__write_string("-- Simple Mercury Term Browser.\n"),
io__write_string("-- Type \"help\" for help.\n\n").
-:- pred prompt(io__state::di, io__state::uo) is det.
-prompt -->
- io__write_string("browser> ").
+:- pred prompt(string::out) is det.
+prompt("browser> ").
:- pred run_command(command, browser_state, browser_state,
Index: browser/parse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/parse.m,v
retrieving revision 1.2
diff -u -r1.2 parse.m
--- parse.m 1999/03/10 20:20:09 1.2
+++ parse.m 1999/05/10 15:35:37
@@ -60,7 +60,7 @@
:- interface.
-:- import_module io, list.
+:- import_module io, list, string.
:- type command
---> ls(path)
@@ -99,8 +99,8 @@
; pretty
; verbose.
-:- pred parse__read_command(command, io__state, io__state).
-:- mode parse__read_command(out, di, uo) is det.
+:- pred parse__read_command(string, command, io__state, io__state).
+:- mode parse__read_command(in, out, di, uo) is det.
:- pred default_depth(int).
:- mode default_depth(out) is det.
@@ -108,7 +108,8 @@
%---------------------------------------------------------------------------%
:- implementation.
-:- import_module io, list, string, char, int, std_util.
+:- import_module char, int, std_util.
+:- import_module util.
:- type token
@@ -123,8 +124,8 @@
; unknown(char)
.
-parse__read_command(Comm) -->
- io__read_line(Result),
+parse__read_command(Prompt, Comm) -->
+ util__trace_getline(Prompt, Result),
( { Result = ok(Cs) } ->
{ lexer(Cs, Tokens) },
( { parse(Tokens, Comm2) } ->
Index: browser/util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/util.m,v
retrieving revision 1.1
diff -u -r1.1 util.m
--- util.m 1998/10/25 07:16:41 1.1
+++ util.m 1999/05/10 16:18:02
@@ -8,7 +8,13 @@
:- interface.
-:- import_module list.
+:- import_module list, string, char, io.
+
+ % Get user input via the same method used by the internal
+ % debugger.
+:- pred util__trace_getline(string, io__result(list(char)), io__state,
+ io__state).
+:- mode util__trace_getline(in, out, 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.
@@ -21,7 +27,47 @@
%---------------------------------------------------------------------------%
:- implementation.
-:- import_module list, int, require.
+:- import_module int, require.
+
+:- pragma promise_pure(util__trace_getline/4).
+
+util__trace_getline(Prompt, Result) -->
+ {
+ impure call_trace_getline(Prompt, Line)
+ ->
+ string__to_char_list(Line, Chars),
+ Result = ok(Chars)
+ ;
+ Result = eof
+ }.
+
+:- impure pred call_trace_getline(string, string).
+:- mode call_trace_getline(in, out) is semidet.
+
+:- pragma c_header_code("
+ #include ""mercury_wrapper.h""
+ #include ""mercury_string.h""
+ #include ""mercury_trace_internal.h""
+").
+
+:- pragma c_code(call_trace_getline(Prompt::in, Line::out),
+ [will_not_call_mercury],
+ "
+ char *line;
+ char *mercury_string;
+
+ line = MR_address_of_trace_getline((char *)Prompt);
+
+ if (line == NULL) {
+ SUCCESS_INDICATOR = FALSE;
+ } else {
+ make_aligned_string_copy(mercury_string, line);
+ free(line);
+ Line = (String) mercury_string;
+ SUCCESS_INDICATOR = TRUE;
+ }
+ "
+).
util__zip_with(Pred, XXs, YYs, Zipped) :-
( (XXs = [], YYs = []) ->
Index: runtime/mercury_init.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_init.h,v
retrieving revision 1.12
diff -u -r1.12 mercury_init.h
--- mercury_init.h 1999/04/20 11:48:14 1.12
+++ mercury_init.h 1999/05/10 15:31:08
@@ -117,6 +117,9 @@
extern void ML_io_print_to_cur_stream(Word, Word);
extern void ML_io_print_to_stream(Word, Word, Word);
+/* in trace/mercury_trace_internal.h */
+extern char *MR_trace_getline(const char *);
+
/* 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.38
diff -u -r1.38 mercury_wrapper.c
--- mercury_wrapper.c 1999/04/30 06:21:28 1.38
+++ mercury_wrapper.c 1999/05/10 16:06:00
@@ -138,6 +138,8 @@
void (*address_of_mercury_init_io)(void);
void (*address_of_init_modules)(void);
+char * (*MR_address_of_trace_getline)(const char *);
+
#ifdef MR_USE_EXTERNAL_DEBUGGER
void (*MR_address_of_trace_init_external)(void);
void (*MR_address_of_trace_final_external)(void);
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.19
diff -u -r1.19 mercury_wrapper.h
--- mercury_wrapper.h 1999/04/20 11:48:17 1.19
+++ mercury_wrapper.h 1999/05/10 15:30:22
@@ -62,6 +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.
+*/
+
+extern char * (*MR_address_of_trace_getline)(const char *);
+
+/*
** MR_trace_init_external() and MR_trace_final_external() are defined
** in trace/mercury_trace_external.c but are called in
** runtime/mercury_trace_base.c. As we can not do direct calls from
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.23
diff -u -r1.23 Mmakefile
--- Mmakefile 1999/04/16 01:12:54 1.23
+++ Mmakefile 1999/05/10 12:18:28
@@ -17,6 +17,7 @@
#-----------------------------------------------------------------------------#
DEBUGGER_PROGS= \
+ browser_test \
debugger_regs \
existential_type_classes \
implied_instance \
@@ -56,6 +57,9 @@
endif
#-----------------------------------------------------------------------------#
+
+browser_test.out: browser_test browser_test.inp
+ $(MDB) ./browser_test < browser_test.inp > browser_test.out 2>&1
debugger_regs.out: debugger_regs debugger_regs.inp
$(MDB) ./debugger_regs < debugger_regs.inp > debugger_regs.out 2>&1
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.41
diff -u -r1.41 mercury_trace_internal.c
--- mercury_trace_internal.c 1999/05/06 04:19:21 1.41
+++ mercury_trace_internal.c 1999/05/10 15:26:22
@@ -204,7 +204,6 @@
int *word_max, int *word_count);
static bool MR_trace_source(const char *filename);
static void MR_trace_source_from_open_file(FILE *fp);
-static char *MR_trace_getline(const char *prompt);
static char *MR_trace_getline_queue(void);
static void MR_insert_line_at_head(const char *line);
static void MR_insert_line_at_tail(const char *line);
@@ -2225,7 +2224,7 @@
** occurs on an empty line, return NULL.
*/
-static char *
+char *
MR_trace_getline(const char *prompt)
{
char *line;
Index: trace/mercury_trace_internal.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.h,v
retrieving revision 1.6
diff -u -r1.6 mercury_trace_internal.h
--- mercury_trace_internal.h 1999/02/20 06:08:19 1.6
+++ mercury_trace_internal.h 1999/05/10 15:26:32
@@ -55,4 +55,6 @@
extern FILE *MR_mdb_out;
extern FILE *MR_mdb_err;
+extern char *MR_trace_getline(const char *prompt);
+
#endif /* MERCURY_TRACE_INTERNAL_H */
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.49
diff -u -r1.49 mkinit.c
--- mkinit.c 1999/04/19 08:29:05 1.49
+++ mkinit.c 1999/05/10 15:31:50
@@ -152,6 +152,11 @@
" MR_io_stderr_stream = ML_io_stderr_stream;\n"
" MR_io_print_to_cur_stream = ML_io_print_to_cur_stream;\n"
" MR_io_print_to_stream = ML_io_print_to_stream;\n"
+ "#if MR_TRACE_ENABLED\n"
+ " MR_address_of_trace_getline = MR_trace_getline;\n"
+ "#else\n"
+ " MR_address_of_trace_getline = NULL;\n"
+ "#endif\n"
"#ifdef MR_USE_EXTERNAL_DEBUGGER\n"
" #if MR_TRACE_ENABLED\n"
" MR_address_of_trace_init_external = MR_trace_init_external;\n"
New module tests/debugger/browser_test.m:
:- module browser_test.
:- interface.
:- import_module io.
:- pred main(io__state::di, io__state::uo) is det.
:- implementation.
:- type big
---> big(big, int, big)
; small.
main -->
{ big_data(Data) },
io__print(Data),
io__write_string(".\n").
:- pred big_data(big::out) is det.
big_data(Data) :-
Data = big(
big(
big(
small,
1,
small
),
2,
small
),
3,
big(
big(
small,
4,
big(
small,
5,
small
)
),
6,
small
)
).
New file tests/debugger/browser_test.inp:
echo on
goto 3
print *
browse 0
print
quit
browse HeadVar__1
ls
cd /1
ls
cd /1/2
ls
cd /3
ls
cd 1/3/2
ls
cd
ls
quit
retry
continue -a
New file tests/debugger/browser_test.exp:
1: 1 1 CALL pred browser_test:main/2-0 (det)
mdb> echo on
Command echo enabled.
mdb> goto 3
3: 2 2 EXIT pred browser_test:big_data/1-0 (det)
mdb> print *
HeadVar__1 big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
mdb> browse 0
browser> print
big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
browser> quit
mdb> browse HeadVar__1
browser> ls
big
1-big
| 1-big
| | 1-small
| | 2-1
| | 3-small
| 2-2
| 3-small
2-3
3-big
1-big
| 1-small
| 2-4
| 3-big/3
2-6
3-small
browser> cd /1
browser> ls
big
1-big
| 1-small
| 2-1
| 3-small
2-2
3-small
browser> cd /1/2
browser> ls
2
browser> cd /3
browser> ls
big
1-big
| 1-small
| 2-4
| 3-big
| 1-small
| 2-5
| 3-small
2-6
3-small
browser> cd 1/3/2
browser> ls
5
browser> cd
browser> ls
big
1-big
| 1-big
| | 1-small
| | 2-1
| | 3-small
| 2-2
| 3-small
2-3
3-big
1-big
| 1-small
| 2-4
| 3-big/3
2-6
3-small
browser> quit
mdb> retry
2: 2 2 CALL pred browser_test:big_data/1-0 (det)
mdb> continue -a
3: 2 2 EXIT pred browser_test:big_data/1-0 (det)
big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big(small, 5, small)), 6, small)).
4: 1 1 EXIT pred browser_test:main/2-0 (det)
--
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