Node:Message Processing, Next:Message Handling Predicates, Previous:Messages and Queries, Up:Messages and Queries
Every message issued by the Prolog system is displayed using a single predicate:
print_message(
+Severity,
+Message)
Message is a term that encodes the message to be printed. The
format of message terms is subject to change, but can be inspected in
the file library('SU_messages')
of the SICStus Prolog distribution.
The atom Severity specifies the type (or importance) of the message. The following table lists the severities known to the SICStus Prolog system, together with the line prefixes used in displaying messages of the given severity:
error | '! ' | for error messages
|
warning | '* ' | for warning messages
|
informational | '% ' | for informational messages
|
help | '' | for help messages
|
query | '' | for query texts (see Query Processing)
|
silent | '' | a special kind of message
which normally does not produce any outpu, but can be intercepted by
hooks
|
print_message/2
is a built-in predicate, so that users can
invoke it to have their own messages processed in the same way as the
system messages.
The processing and printing of the messages is highly customizable. For example, this allows the user to change the language of the messages, or to make them appear in dialog windows rather than on the terminal.
Messages are processed in two major phases. The user can influence the behavior of each phase using appropriate hooks, described later.
The first phase is called the message generation phase: it determines the text of the message from the input (the abstract message term). No printing is done here. In this phase the user can change the phrasing or the language of the messages.
The result of the first phase is created in the form of a
format-command list. This is a list whose elements are
format-commands, or the atom nl
denoting the end of a line. A
format-command describes a piece of text not extending over a line
boundary and it can be one of the following:
FormatString-
Args
format(
FormatString,
Args)
format(FormatString, Args).
write_term(
Term,
Options)
write_term(Term, Options).
write_term(
Term)
write_term(
Term,
Options)
where
Options is the actual value of the prolog flag
toplevel_print_options
.
As an example, let us see what happens in case of the toplevel call
_ =:= 3
. An instantiation error is raised by the Prolog system,
which is caught, and the abstract message term
instantiation_error(_=:=3,1)
is generated (assuming
sicstus
execution mode)--the first argument is
the goal, and the second argument is the position of the uninstantiated
variable within the goal. In the first phase of message processing this
is converted to the following format-command list:
['Instantiation error'-[],' in argument ~d of ~q'-[1,=:= /2],nl, 'goal: '-[],write_term(_=:=3),nl]
A minor transformation, so-called line splitting is performed on the
message text before it is handed over to the second phase. The
format-command list is broken up along the nl
atoms into a list
of lines, where each line is a list of format-commands. We will use the
term format-command lines to refer to the result of this
transformation.
In the example above, the result of this conversion is the following:
[['Instantiation error'-[],' in argument ~d of ~q'-[1,=:= /2]], ['goal: '-[],write_term(_=:=3)]]The above format-command lines term is the input of the second phase of message processing.
The second phase is called the message printing phase, this is where the message is actually displayed. The severity of the message is used here to prefix each line of the message with some characters indicating the type of the message, as listed above.
The user can change the exact method of printing (e.g. redirection of messages to a stream, a window, or using different prefixes, etc.) through appropriate hooks.
In our example the following lines are printed by the second phase of processing:
! Instantiation error in argument 1 of =:= /2 ! goal: _=:=3
The user can override the default message processing mechanism in the following two ways:
portray_message/2
, which is the first thing called by message
processing. If this hook exists and succeeds, then it overrides all
other processing--nothing further is done by print_message/2
.
The default message generation predicates are located in the
library('SU_messages')
file, in the 'SU_messages'
module,
together with other message and query related predicates. This is
advantageous when these predicates have to be changed as a whole (for
example when translating all messages to another language), because this
can be done simply by replacing the file library('SU_messages')
by a new one.
In the message generation phase three alternative methods are tried:
generate_message_hook/3
is executed, if
it succeeds, it is assumed to deliver the output of this phase.
'SU_messages':generate_message/3
predicate.
The hook predicate generate_message_hook/3
can be used to
override the default behavior, or to handle new messages defined by the
programmer, which do not fit the default message generation schemes.
The latter can also be achieved by adding new clauses to the extendible
'SU_messages':generate_message/3
predicate.
If both the hook and the default method refuses to handle the message, then the following simple format-command list is generated from the abstract message term Message:
['~q'-[Message],nl]This will result in displaying the abstract message term itself, as if printed by
writeq/1
.
For messages of the severity silent
the message generation phase
is skipped, and the []
format-command list is returned as the
output.
By default this phase is handled by the built-in predicate
print_message_lines/3
. Each line of the message is prefixed with a
string depending on the severity, and is printed to user_error
.
The query
severity is special--no newline is printed after the
last line of the message.
This behavior can be overridden by defining the hook predicate
message_hook/3
, which is called with the severity of the message,
the abstract message term and its translation to format-command lines.
It can be used to make smaller changes, for example by calling
print_message_lines/3
with a stream argument other than
user_error
, or to implement a totally different display
method such as using dialog windows for messages.
For messages of the severity silent
the message printing phase
consists of calling the hook predicate message_hook/3
only. Even
if the hook fails, no printing is done.