Search code examples
ioprologswi-prologprolog-toplevel

In SWI-Prolog, when calling copy_stream_data, how can I avoid the '|: ' prompt?


I have implemented a cat program in SWI-Prolog by using copy_stream_data.

File args.pl:

:- module(args, [withFilesOrUserInput/2]).

withFilesOrUserInput(StreamFunction, []) :-
    call(StreamFunction, user_input).

withFilesOrUserInput(StreamFunction, [Filename]) :-
    withFile(StreamFunction, Filename).

withFilesOrUserInput(StreamFunction, [Head|Tail]) :-
    withFile(StreamFunction, Head),
    withFilesOrUserInput(StreamFunction, Tail).

withFile(StreamFunction, Filename) :-
    open(Filename, read, StreamIn),
    call(StreamFunction, StreamIn),
    close(StreamIn).

File cat.pl:

:- use_module(args).

main(Argv) :-
    withFilesOrUserInput(catStream, Argv).

catStream(Stream) :-
    copy_stream_data(Stream, user_output),
    flush_output(user_output).

When I use the program to cat from stdin to stdout, it prints a prompt |: where it expects input from stdin. How can I avoid that prompt?


Solution

  • The |: prompt only appears when stdout is a terminal. It does not appear when stdout is a file. So, it won't cause garbage in the output when your output is redirected to a file. But still, it's not nice.

    In order to avoid the prompt, clear it using the built-in predicate prompt, like this: prompt(_, ''), which you could insert into your main(Argv) predicate:

    main(Argv) :-
        prompt(_, ''),
        withFilesOrUserInput(catStream, Argv).
    

    You could also put a clause with the prompt(_, '') predicate at program start, by inserting the following at the top of the code:

     :- prompt(_, '').
    

    You could even do that in the module, after the :- module() clause.