:- multifile 'QU_messages':generate_message/3.
generate_message(
+MessageTerm,
-S0,
-S)
For a given MessageTerm, generates a list composed of
Control-Arg pairs and the atom nl
. This can be translated into a
nested list of Control-Arg pairs, which can be used as input to
print_message_lines/3
.
Clauses for generate_message/3
underly all messages from Prolog. They may
be examined and altered. They are found in messages(language('QU_messages'))
,
which by default is qplib('embed/english/QU_messages.pl')
.
The purpose of this predicate is to allow you to totally redefine the content of Prolog's messages. In particular, it is possible to translate all the messages from English into some other language.
This predicate should not be modified if all you want to do is modify or
add a few messages: user:generate_message_hook/3
is provided for that purpose.
The Prolog system uses the built-in predicate print_message/2
to print
all its messages. When print_message/2
is called, it calls
user:generate_message_hook(Message,L,[])
to generate the message. If that fails,
'QU_messages':generate_message(Message,L,[])
is called instead.
If generate_message/3
succeeds, L is assumed to have been bound to a list whose
elements are either Control-Args pairs or the atom nl
. Each Control-Arg
pair should be such that the call
format(user_error, Control, Args)
is valid.
The atom nl
is used for breaking the message into lines.
Using the format specification ~n
(new-line) is discouraged, since the
routine that actually prints the message (see user:message_hook/3
and
print_message_lines/3
) may need to have control over newlines.
'QU_messages':generate_message/3
is not included by default in runtime systems,
since end-users of application programs should probably not be seeing any
messages from the Prolog system. If a runtime system does require the
messages facility its source code should include a goal such as:
:- ensure_loaded(library( language('QU_messages'))).
If there is a call to print_message/2
when 'QU_messages':generate_message/3
is undefined, or if generate_message/3
fails
for some reason, the message term itself is printed. Here is an example of what
happens when generate_message/3
fails.
| ?- print_message(error,unexpected_error(37)). ! unexpected_error(37)
generate_message/3
failed because the message term was not recognized. In
the following example print_message/2
is being called by the default
exception handler.
| ?- write(A,B). ! Instantiation error in argument 1 of write/2 ! goal: write(_2107,_2108) | ?- abolish('QU_messages':generate_message/3). ... | ?- write(A,B). ! instantiation_error(write(_2187,_2188),1)
Note that a call to 'QU_messages':generate_message/3
simply fails if the predicate
is undefined; an existence_error
is never signalled.
The following example shows how
the output of generate_message/3
is translated and passed
to print_message_lines/3
.
gen_message_and_print_lines(Msg, Stream, Prefix) :- generate_message(Msg, L, []), lines(L, Lines, []), print_message_lines(Stream, Prefix, Lines) lines([]) --> []. lines([H|T]) --> line(H), [nl], lines(T). line([]) --> []. line([Control-Args|T]) --> [Control-Args], line(T).
When print_message/2
calls 'QU_messages':generate_message/3
it handles any exceptions that arise by printing out an error message. It then
writes out the original message.
print_message/2
,
message_hook/3
,
format/[2,3]
,
print_message_lines/3
,
user:generate_message_hook/3
,
QU_messages':query_abbreviation/2
ref-msg