37
38:- module('$messages',
39 [ print_message/2, 40 print_message_lines/3, 41 message_to_string/2 42 ]). 43
44:- multifile
45 prolog:message//1, 46 prolog:error_message//1, 47 prolog:message_context//1, 48 prolog:deprecated//1, 49 prolog:message_location//1, 50 prolog:message_line_element/2. 51:- '$hide'((
52 prolog:message//1,
53 prolog:error_message//1,
54 prolog:message_context//1,
55 prolog:deprecated//1,
56 prolog:message_location//1,
57 prolog:message_line_element/2)). 59:- multifile
60 prolog:message//2, 61 prolog:error_message//2, 62 prolog:message_context//2, 63 prolog:message_location//2, 64 prolog:deprecated//2. 65:- '$hide'((
66 prolog:message//2,
67 prolog:error_message//2,
68 prolog:message_context//2,
69 prolog:deprecated//2,
70 prolog:message_location//2)). 71
72:- discontiguous
73 prolog_message/3. 74
75:- public
76 translate_message//1, 77 prolog:translate_message//1. 78
79:- create_prolog_flag(message_context, [thread], []). 80
102
103prolog:translate_message(Term) -->
104 translate_message(Term).
105
110
111translate_message(Term) -->
112 { nonvar(Term) },
113 ( { message_lang(Lang) },
114 prolog:message(Lang, Term)
115 ; prolog:message(Term)
116 ),
117 !.
118translate_message(Term) -->
119 { nonvar(Term) },
120 translate_message2(Term),
121 !.
122translate_message(Term) -->
123 { nonvar(Term),
124 Term = error(_, _)
125 },
126 [ 'Unknown exception: ~p'-[Term] ].
127translate_message(Term) -->
128 [ 'Unknown message: ~p'-[Term] ].
129
130translate_message2(Term) -->
131 prolog_message(Term).
132translate_message2(error(resource_error(stack), Context)) -->
133 !,
134 out_of_stack(Context).
135translate_message2(error(resource_error(tripwire(Wire, Context)), _)) -->
136 !,
137 tripwire_message(Wire, Context).
138translate_message2(error(existence_error(reset, Ball), SWI)) -->
139 swi_location(SWI),
140 tabling_existence_error(Ball, SWI).
141translate_message2(error(ISO, SWI)) -->
142 swi_location(SWI),
143 term_message(ISO),
144 swi_extra(SWI).
145translate_message2('$aborted') -->
146 [ 'Execution Aborted' ].
147translate_message2(message_lines(Lines), L, T) :- 148 make_message_lines(Lines, L, T).
149translate_message2(format(Fmt, Args)) -->
150 [ Fmt-Args ].
151
152make_message_lines([], T, T) :- !.
153make_message_lines([Last], ['~w'-[Last]|T], T) :- !.
154make_message_lines([L0|LT], ['~w'-[L0],nl|T0], T) :-
155 make_message_lines(LT, T0, T).
156
162
163:- public term_message//1. 164term_message(Term) -->
165 {var(Term)},
166 !,
167 [ 'Unknown error term: ~p'-[Term] ].
168term_message(Term) -->
169 { message_lang(Lang) },
170 prolog:error_message(Lang, Term),
171 !.
172term_message(Term) -->
173 prolog:error_message(Term),
174 !.
175term_message(Term) -->
176 iso_message(Term).
177term_message(Term) -->
178 swi_message(Term).
179term_message(Term) -->
180 [ 'Unknown error term: ~p'-[Term] ].
181
182iso_message(resource_error(Missing)) -->
183 [ 'Not enough resources: ~w'-[Missing] ].
184iso_message(type_error(evaluable, Actual)) -->
185 { callable(Actual) },
186 [ 'Arithmetic: `~p'' is not a function'-[Actual] ].
187iso_message(type_error(free_of_attvar, Actual)) -->
188 [ 'Type error: `~W'' contains attributed variables'-
189 [Actual,[portray(true), attributes(portray)]] ].
190iso_message(type_error(Expected, Actual)) -->
191 [ 'Type error: `~w'' expected, found `~p'''-[Expected, Actual] ],
192 type_error_comment(Expected, Actual).
193iso_message(domain_error(Domain, Actual)) -->
194 [ 'Domain error: '-[] ], domain(Domain),
195 [ ' expected, found `~p'''-[Actual] ].
196iso_message(instantiation_error) -->
197 [ 'Arguments are not sufficiently instantiated' ].
198iso_message(uninstantiation_error(Var)) -->
199 [ 'Uninstantiated argument expected, found ~p'-[Var] ].
200iso_message(representation_error(What)) -->
201 [ 'Cannot represent due to `~w'''-[What] ].
202iso_message(permission_error(Action, Type, Object)) -->
203 permission_error(Action, Type, Object).
204iso_message(evaluation_error(Which)) -->
205 [ 'Arithmetic: evaluation error: `~p'''-[Which] ].
206iso_message(existence_error(procedure, Proc)) -->
207 [ 'Unknown procedure: ~q'-[Proc] ],
208 unknown_proc_msg(Proc).
209iso_message(existence_error(answer_variable, Var)) -->
210 [ '$~w was not bound by a previous query'-[Var] ].
211iso_message(existence_error(matching_rule, Goal)) -->
212 [ 'No rule matches ~p'-[Goal] ].
213iso_message(existence_error(Type, Object)) -->
214 [ '~w `~p'' does not exist'-[Type, Object] ].
215iso_message(existence_error(Type, Object, In)) --> 216 [ '~w `~p'' does not exist in ~p'-[Type, Object, In] ].
217iso_message(busy(Type, Object)) -->
218 [ '~w `~p'' is busy'-[Type, Object] ].
219iso_message(syntax_error(swi_backslash_newline)) -->
220 [ 'Deprecated ... \\<newline><white>*. Use \\c' ].
221iso_message(syntax_error(Id)) -->
222 [ 'Syntax error: ' ],
223 syntax_error(Id).
224iso_message(occurs_check(Var, In)) -->
225 [ 'Cannot unify ~p with ~p: would create an infinite tree'-[Var, In] ].
226
231
232permission_error(Action, built_in_procedure, Pred) -->
233 { user_predicate_indicator(Pred, PI)
234 },
235 [ 'No permission to ~w built-in predicate `~p'''-[Action, PI] ],
236 ( {Action \== export}
237 -> [ nl,
238 'Use :- redefine_system_predicate(+Head) if redefinition is intended'
239 ]
240 ; []
241 ).
242permission_error(import_into(Dest), procedure, Pred) -->
243 [ 'No permission to import ~p into ~w'-[Pred, Dest] ].
244permission_error(Action, static_procedure, Proc) -->
245 [ 'No permission to ~w static procedure `~p'''-[Action, Proc] ],
246 defined_definition('Defined', Proc).
247permission_error(input, stream, Stream) -->
248 [ 'No permission to read from output stream `~p'''-[Stream] ].
249permission_error(output, stream, Stream) -->
250 [ 'No permission to write to input stream `~p'''-[Stream] ].
251permission_error(input, text_stream, Stream) -->
252 [ 'No permission to read bytes from TEXT stream `~p'''-[Stream] ].
253permission_error(output, text_stream, Stream) -->
254 [ 'No permission to write bytes to TEXT stream `~p'''-[Stream] ].
255permission_error(input, binary_stream, Stream) -->
256 [ 'No permission to read characters from binary stream `~p'''-[Stream] ].
257permission_error(output, binary_stream, Stream) -->
258 [ 'No permission to write characters to binary stream `~p'''-[Stream] ].
259permission_error(open, source_sink, alias(Alias)) -->
260 [ 'No permission to reuse alias "~p": already taken'-[Alias] ].
261permission_error(tnot, non_tabled_procedure, Pred) -->
262 [ 'The argument of tnot/1 is not tabled: ~p'-[Pred] ].
263permission_error(Action, Type, Object) -->
264 [ 'No permission to ~w ~w `~p'''-[Action, Type, Object] ].
265
266
267unknown_proc_msg(_:(^)/2) -->
268 !,
269 unknown_proc_msg((^)/2).
270unknown_proc_msg((^)/2) -->
271 !,
272 [nl, ' ^/2 can only appear as the 2nd argument of setof/3 and bagof/3'].
273unknown_proc_msg((:-)/2) -->
274 !,
275 [nl, ' Rules must be loaded from a file'],
276 faq('ToplevelMode').
277unknown_proc_msg((=>)/2) -->
278 !,
279 [nl, ' Rules must be loaded from a file'],
280 faq('ToplevelMode').
281unknown_proc_msg((:-)/1) -->
282 !,
283 [nl, ' Directives must be loaded from a file'],
284 faq('ToplevelMode').
285unknown_proc_msg((?-)/1) -->
286 !,
287 [nl, ' ?- is the Prolog prompt'],
288 faq('ToplevelMode').
289unknown_proc_msg(Proc) -->
290 { dwim_predicates(Proc, Dwims) },
291 ( {Dwims \== []}
292 -> [nl, ' However, there are definitions for:', nl],
293 dwim_message(Dwims)
294 ; []
295 ).
296
297dependency_error(shared(Shared), private(Private)) -->
298 [ 'Shared table for ~p may not depend on private ~p'-[Shared, Private] ].
299dependency_error(Dep, monotonic(On)) -->
300 { '$pi_head'(PI, Dep),
301 '$pi_head'(MPI, On)
302 },
303 [ 'Dependent ~p on monotonic predicate ~p is not monotonic or incremental'-
304 [PI, MPI]
305 ].
306
307faq(Page) -->
308 [nl, ' See FAQ at https://www.swi-prolog.org/FAQ/', Page, '.txt' ].
309
(_Expected, Actual) -->
311 { type_of(Actual, Type),
312 ( sub_atom(Type, 0, 1, _, First),
313 memberchk(First, [a,e,i,o,u])
314 -> Article = an
315 ; Article = a
316 )
317 },
318 [ ' (~w ~w)'-[Article, Type] ].
319
320type_of(Term, Type) :-
321 ( attvar(Term) -> Type = attvar
322 ; var(Term) -> Type = var
323 ; atom(Term) -> Type = atom
324 ; integer(Term) -> Type = integer
325 ; string(Term) -> Type = string
326 ; Term == [] -> Type = empty_list
327 ; blob(Term, BlobT) -> blob_type(BlobT, Type)
328 ; rational(Term) -> Type = rational
329 ; float(Term) -> Type = float
330 ; is_stream(Term) -> Type = stream
331 ; is_dict(Term) -> Type = dict
332 ; is_list(Term) -> Type = list
333 ; cyclic_term(Term) -> Type = cyclic
334 ; compound(Term) -> Type = compound
335 ; Type = unknown
336 ).
337
338blob_type(BlobT, Type) :-
339 atom_concat(BlobT, '_reference', Type).
340
341syntax_error(end_of_clause) -->
342 [ 'Unexpected end of clause' ].
343syntax_error(end_of_clause_expected) -->
344 [ 'End of clause expected' ].
345syntax_error(end_of_file) -->
346 [ 'Unexpected end of file' ].
347syntax_error(end_of_file_in_block_comment) -->
348 [ 'End of file in /* ... */ comment' ].
349syntax_error(end_of_file_in_quoted(Quote)) -->
350 [ 'End of file in quoted ' ],
351 quoted_type(Quote).
352syntax_error(illegal_number) -->
353 [ 'Illegal number' ].
354syntax_error(long_atom) -->
355 [ 'Atom too long (see style_check/1)' ].
356syntax_error(long_string) -->
357 [ 'String too long (see style_check/1)' ].
358syntax_error(operator_clash) -->
359 [ 'Operator priority clash' ].
360syntax_error(operator_expected) -->
361 [ 'Operator expected' ].
362syntax_error(operator_balance) -->
363 [ 'Unbalanced operator' ].
364syntax_error(quoted_punctuation) -->
365 [ 'Operand expected, unquoted comma or bar found' ].
366syntax_error(list_rest) -->
367 [ 'Unexpected comma or bar in rest of list' ].
368syntax_error(cannot_start_term) -->
369 [ 'Illegal start of term' ].
370syntax_error(punct(Punct, End)) -->
371 [ 'Unexpected `~w\' before `~w\''-[Punct, End] ].
372syntax_error(undefined_char_escape(C)) -->
373 [ 'Unknown character escape in quoted atom or string: `\\~w\''-[C] ].
374syntax_error(void_not_allowed) -->
375 [ 'Empty argument list "()"' ].
376syntax_error(Message) -->
377 [ '~w'-[Message] ].
378
379quoted_type('\'') --> [atom].
380quoted_type('\"') --> { current_prolog_flag(double_quotes, Type) }, [Type-[]].
381quoted_type('\`') --> { current_prolog_flag(back_quotes, Type) }, [Type-[]].
382
383domain(range(Low,High)) -->
384 !,
385 ['[~q..~q]'-[Low,High] ].
386domain(Domain) -->
387 ['`~w\''-[Domain] ].
388
393
394tabling_existence_error(Ball, Context) -->
395 { table_shift_ball(Ball) },
396 [ 'Tabling dependency error' ],
397 swi_extra(Context).
398
399table_shift_ball(dependency(_Head)).
400table_shift_ball(dependency(_Skeleton, _Trie, _Mono)).
401table_shift_ball(call_info(_Skeleton, _Status)).
402table_shift_ball(call_info(_GenSkeleton, _Skeleton, _Status)).
403
407
408dwim_predicates(Module:Name/_Arity, Dwims) :-
409 !,
410 findall(Dwim, dwim_predicate(Module:Name, Dwim), Dwims).
411dwim_predicates(Name/_Arity, Dwims) :-
412 findall(Dwim, dwim_predicate(user:Name, Dwim), Dwims).
413
414dwim_message([]) --> [].
415dwim_message([M:Head|T]) -->
416 { hidden_module(M),
417 !,
418 functor(Head, Name, Arity)
419 },
420 [ ' ~q'-[Name/Arity], nl ],
421 dwim_message(T).
422dwim_message([Module:Head|T]) -->
423 !,
424 { functor(Head, Name, Arity)
425 },
426 [ ' ~q'-[Module:Name/Arity], nl],
427 dwim_message(T).
428dwim_message([Head|T]) -->
429 {functor(Head, Name, Arity)},
430 [ ' ~q'-[Name/Arity], nl],
431 dwim_message(T).
432
433
434swi_message(io_error(Op, Stream)) -->
435 [ 'I/O error in ~w on stream ~p'-[Op, Stream] ].
436swi_message(thread_error(TID, false)) -->
437 [ 'Thread ~p died due to failure:'-[TID] ].
438swi_message(thread_error(TID, exception(Error))) -->
439 [ 'Thread ~p died abnormally:'-[TID], nl ],
440 translate_message(Error).
441swi_message(dependency_error(Tabled, DependsOn)) -->
442 dependency_error(Tabled, DependsOn).
443swi_message(shell(execute, Cmd)) -->
444 [ 'Could not execute `~w'''-[Cmd] ].
445swi_message(shell(signal(Sig), Cmd)) -->
446 [ 'Caught signal ~d on `~w'''-[Sig, Cmd] ].
447swi_message(format(Fmt, Args)) -->
448 [ Fmt-Args ].
449swi_message(signal(Name, Num)) -->
450 [ 'Caught signal ~d (~w)'-[Num, Name] ].
451swi_message(limit_exceeded(Limit, MaxVal)) -->
452 [ 'Exceeded ~w limit (~w)'-[Limit, MaxVal] ].
453swi_message(goal_failed(Goal)) -->
454 [ 'goal unexpectedly failed: ~p'-[Goal] ].
455swi_message(shared_object(_Action, Message)) --> 456 [ '~w'-[Message] ].
457swi_message(system_error(Error)) -->
458 [ 'error in system call: ~w'-[Error]
459 ].
460swi_message(system_error) -->
461 [ 'error in system call'
462 ].
463swi_message(failure_error(Goal)) -->
464 [ 'Goal failed: ~p'-[Goal] ].
465swi_message(timeout_error(Op, Stream)) -->
466 [ 'Timeout in ~w from ~p'-[Op, Stream] ].
467swi_message(not_implemented(Type, What)) -->
468 [ '~w `~p\' is not implemented in this version'-[Type, What] ].
469swi_message(context_error(nodirective, Goal)) -->
470 { goal_to_predicate_indicator(Goal, PI) },
471 [ 'Wrong context: ~p can only be used in a directive'-[PI] ].
472swi_message(context_error(edit, no_default_file)) -->
473 ( { current_prolog_flag(windows, true) }
474 -> [ 'Edit/0 can only be used after opening a \c
475 Prolog file by double-clicking it' ]
476 ; [ 'Edit/0 can only be used with the "-s file" commandline option'
477 ]
478 ),
479 [ nl, 'Use "?- edit(Topic)." or "?- emacs."' ].
480swi_message(context_error(function, meta_arg(S))) -->
481 [ 'Functions are not (yet) supported for meta-arguments of type ~q'-[S] ].
482swi_message(format_argument_type(Fmt, Arg)) -->
483 [ 'Illegal argument to format sequence ~~~w: ~p'-[Fmt, Arg] ].
484swi_message(format(Msg)) -->
485 [ 'Format error: ~w'-[Msg] ].
486swi_message(conditional_compilation_error(unterminated, Where)) -->
487 [ 'Unterminated conditional compilation from '-[] ],
488 cond_location(Where).
489swi_message(conditional_compilation_error(no_if, What)) -->
490 [ ':- ~w without :- if'-[What] ].
491swi_message(duplicate_key(Key)) -->
492 [ 'Duplicate key: ~p'-[Key] ].
493swi_message(initialization_error(failed, Goal, File:Line)) -->
494 !,
495 [ '~w:~w: ~p: false'-[File, Line, Goal] ].
496swi_message(initialization_error(Error, Goal, File:Line)) -->
497 [ '~w:~w: ~p '-[File, Line, Goal] ],
498 translate_message(Error).
499swi_message(determinism_error(PI, det, Found, property)) -->
500 ( { '$pi_head'(user:PI, Head),
501 predicate_property(Head, det)
502 }
503 -> [ 'Deterministic procedure ~p'-[PI] ]
504 ; [ 'Procedure ~p called from a deterministic procedure'-[PI] ]
505 ),
506 det_error(Found).
507swi_message(determinism_error(PI, det, fail, guard)) -->
508 [ 'Procedure ~p failed after $-guard'-[PI] ].
509swi_message(determinism_error(PI, det, fail, guard_in_caller)) -->
510 [ 'Procedure ~p failed after $-guard in caller'-[PI] ].
511swi_message(determinism_error(Goal, det, fail, goal)) -->
512 [ 'Goal ~p failed'-[Goal] ].
513swi_message(determinism_error(Goal, det, nondet, goal)) -->
514 [ 'Goal ~p succeeded with a choice point'-[Goal] ].
515swi_message(qlf_format_error(File, Message)) -->
516 [ '~w: Invalid QLF file: ~w'-[File, Message] ].
517swi_message(goal_expansion_error(bound, Term)) -->
518 [ 'Goal expansion bound a variable to ~p'-[Term] ].
519
520det_error(nondet) -->
521 [ ' succeeded with a choicepoint'- [] ].
522det_error(fail) -->
523 [ ' failed'- [] ].
524
525
526cond_location(File:Line) -->
527 { file_base_name(File, Base) },
528 [ '~w:~d'-[Base, Line] ].
529
534
535:- public swi_location//1. 536swi_location(X) -->
537 { var(X) },
538 !.
539swi_location(Context) -->
540 { message_lang(Lang) },
541 prolog:message_location(Lang, Context),
542 !.
543swi_location(Context) -->
544 prolog:message_location(Context),
545 !.
546swi_location(context(Caller, _Msg)) -->
547 { ground(Caller) },
548 !,
549 caller(Caller).
550swi_location(file(Path, Line, -1, _CharNo)) -->
551 !,
552 [ '~w:~d: '-[Path, Line] ].
553swi_location(file(Path, Line, LinePos, _CharNo)) -->
554 [ '~w:~d:~d: '-[Path, Line, LinePos] ].
555swi_location(stream(Stream, Line, LinePos, CharNo)) -->
556 ( { is_stream(Stream),
557 stream_property(Stream, file_name(File))
558 }
559 -> swi_location(file(File, Line, LinePos, CharNo))
560 ; [ 'Stream ~w:~d:~d '-[Stream, Line, LinePos] ]
561 ).
562swi_location(autoload(File:Line)) -->
563 [ '~w:~w: '-[File, Line] ].
564swi_location(_) -->
565 [].
566
567caller(system:'$record_clause'/3) -->
568 !,
569 [].
570caller(Module:Name/Arity) -->
571 !,
572 ( { \+ hidden_module(Module) }
573 -> [ '~q:~q/~w: '-[Module, Name, Arity] ]
574 ; [ '~q/~w: '-[Name, Arity] ]
575 ).
576caller(Name/Arity) -->
577 [ '~q/~w: '-[Name, Arity] ].
578caller(Caller) -->
579 [ '~p: '-[Caller] ].
580
581
589
(X) -->
591 { var(X) },
592 !,
593 [].
594swi_extra(Context) -->
595 { message_lang(Lang) },
596 prolog:message_context(Lang, Context),
597 !.
598swi_extra(Context) -->
599 prolog:message_context(Context).
600swi_extra(context(_, Msg)) -->
601 { nonvar(Msg),
602 Msg \== ''
603 },
604 !,
605 swi_comment(Msg).
606swi_extra(string(String, CharPos)) -->
607 { sub_string(String, 0, CharPos, _, Before),
608 sub_string(String, CharPos, _, 0, After)
609 },
610 [ nl, '~w'-[Before], nl, '** here **', nl, '~w'-[After] ].
611swi_extra(_) -->
612 [].
613
(already_from(Module)) -->
615 !,
616 [ ' (already imported from ~q)'-[Module] ].
617swi_comment(directory(_Dir)) -->
618 !,
619 [ ' (is a directory)' ].
620swi_comment(not_a_directory(_Dir)) -->
621 !,
622 [ ' (is not a directory)' ].
623swi_comment(Msg) -->
624 [ ' (~w)'-[Msg] ].
625
626
627thread_context -->
628 { thread_self(Me), Me \== main, thread_property(Me, id(Id)) },
629 !,
630 ['[Thread ~w] '-[Id]].
631thread_context -->
632 [].
633
634 637
638prolog_message(welcome) -->
639 [ 'Welcome to SWI-Prolog (' ],
640 prolog_message(threads),
641 prolog_message(address_bits),
642 ['version ' ],
643 prolog_message(version),
644 [ ')', nl ],
645 prolog_message(copyright),
646 [ nl ],
647 translate_message(user_versions),
648 [ nl ],
649 prolog_message(documentaton),
650 [ nl, nl ].
651prolog_message(user_versions) -->
652 ( { findall(Msg, prolog:version_msg(Msg), Msgs),
653 Msgs \== []
654 }
655 -> [nl],
656 user_version_messages(Msgs)
657 ; []
658 ).
659prolog_message(deprecated(Term)) -->
660 { nonvar(Term) },
661 ( { message_lang(Lang) },
662 prolog:deprecated(Lang, Term)
663 -> []
664 ; prolog:deprecated(Term)
665 -> []
666 ; deprecated(Term)
667 ).
668prolog_message(unhandled_exception(E)) -->
669 { nonvar(E) },
670 [ 'Unhandled exception: ' ],
671 ( translate_message(E)
672 -> []
673 ; [ '~p'-[E] ]
674 ).
675
677
678prolog_message(initialization_error(_, E, File:Line)) -->
679 !,
680 [ '~w:~d: '-[File, Line],
681 'Initialization goal raised exception:', nl
682 ],
683 translate_message(E).
684prolog_message(initialization_error(Goal, E, _)) -->
685 [ 'Initialization goal ~p raised exception:'-[Goal], nl ],
686 translate_message(E).
687prolog_message(initialization_failure(_Goal, File:Line)) -->
688 !,
689 [ '~w:~d: '-[File, Line],
690 'Initialization goal failed'-[]
691 ].
692prolog_message(initialization_failure(Goal, _)) -->
693 [ 'Initialization goal failed: ~p'-[Goal]
694 ].
695prolog_message(initialization_exception(E)) -->
696 [ 'Prolog initialisation failed:', nl ],
697 translate_message(E).
698prolog_message(init_goal_syntax(Error, Text)) -->
699 !,
700 [ '-g ~w: '-[Text] ],
701 translate_message(Error).
702prolog_message(init_goal_failed(failed, @(Goal,File:Line))) -->
703 !,
704 [ '~w:~w: ~p: false'-[File, Line, Goal] ].
705prolog_message(init_goal_failed(Error, @(Goal,File:Line))) -->
706 !,
707 [ '~w:~w: ~p '-[File, Line, Goal] ],
708 translate_message(Error).
709prolog_message(init_goal_failed(failed, Text)) -->
710 !,
711 [ '-g ~w: false'-[Text] ].
712prolog_message(init_goal_failed(Error, Text)) -->
713 !,
714 [ '-g ~w: '-[Text] ],
715 translate_message(Error).
716prolog_message(goal_failed(Context, Goal)) -->
717 [ 'Goal (~w) failed: ~p'-[Context, Goal] ].
718prolog_message(no_current_module(Module)) -->
719 [ '~w is not a current module (created)'-[Module] ].
720prolog_message(commandline_arg_type(Flag, Arg)) -->
721 [ 'Bad argument to commandline option -~w: ~w'-[Flag, Arg] ].
722prolog_message(missing_feature(Name)) -->
723 [ 'This version of SWI-Prolog does not support ~w'-[Name] ].
724prolog_message(singletons(_Term, List)) -->
725 [ 'Singleton variables: ~w'-[List] ].
726prolog_message(multitons(_Term, List)) -->
727 [ 'Singleton-marked variables appearing more than once: ~w'-[List] ].
728prolog_message(profile_no_cpu_time) -->
729 [ 'No CPU-time info. Check the SWI-Prolog manual for details' ].
730prolog_message(non_ascii(Text, Type)) -->
731 [ 'Unquoted ~w with non-portable characters: ~w'-[Type, Text] ].
732prolog_message(io_warning(Stream, Message)) -->
733 { stream_property(Stream, position(Position)),
734 !,
735 stream_position_data(line_count, Position, LineNo),
736 stream_position_data(line_position, Position, LinePos),
737 ( stream_property(Stream, file_name(File))
738 -> Obj = File
739 ; Obj = Stream
740 )
741 },
742 [ '~p:~d:~d: ~w'-[Obj, LineNo, LinePos, Message] ].
743prolog_message(io_warning(Stream, Message)) -->
744 [ 'stream ~p: ~w'-[Stream, Message] ].
745prolog_message(option_usage(pldoc)) -->
746 [ 'Usage: --pldoc[=port]' ].
747prolog_message(interrupt(begin)) -->
748 [ 'Action (h for help) ? ', flush ].
749prolog_message(interrupt(end)) -->
750 [ 'continue' ].
751prolog_message(interrupt(trace)) -->
752 [ 'continue (trace mode)' ].
753prolog_message(unknown_in_module_user) -->
754 [ 'Using a non-error value for unknown in the global module', nl,
755 'causes most of the development environment to stop working.', nl,
756 'Please use :- dynamic or limit usage of unknown to a module.', nl,
757 'See https://www.swi-prolog.org/howto/database.html'
758 ].
759prolog_message(untable(PI)) -->
760 [ 'Reconsult: removed tabling for ~p'-[PI] ].
761
762
763 766
767prolog_message(modify_active_procedure(Who, What)) -->
768 [ '~p: modified active procedure ~p'-[Who, What] ].
769prolog_message(load_file(failed(user:File))) -->
770 [ 'Failed to load ~p'-[File] ].
771prolog_message(load_file(failed(Module:File))) -->
772 [ 'Failed to load ~p into module ~p'-[File, Module] ].
773prolog_message(load_file(failed(File))) -->
774 [ 'Failed to load ~p'-[File] ].
775prolog_message(mixed_directive(Goal)) -->
776 [ 'Cannot pre-compile mixed load/call directive: ~p'-[Goal] ].
777prolog_message(cannot_redefine_comma) -->
778 [ 'Full stop in clause-body? Cannot redefine ,/2' ].
779prolog_message(illegal_autoload_index(Dir, Term)) -->
780 [ 'Illegal term in INDEX file of directory ~w: ~w'-[Dir, Term] ].
781prolog_message(redefined_procedure(Type, Proc)) -->
782 [ 'Redefined ~w procedure ~p'-[Type, Proc] ],
783 defined_definition('Previously defined', Proc).
784prolog_message(declare_module(Module, abolish(Predicates))) -->
785 [ 'Loading module ~w abolished: ~p'-[Module, Predicates] ].
786prolog_message(import_private(Module, Private)) -->
787 [ 'import/1: ~p is not exported (still imported into ~q)'-
788 [Private, Module]
789 ].
790prolog_message(ignored_weak_import(Into, From:PI)) -->
791 [ 'Local definition of ~p overrides weak import from ~q'-
792 [Into:PI, From]
793 ].
794prolog_message(undefined_export(Module, PI)) -->
795 [ 'Exported procedure ~q:~q is not defined'-[Module, PI] ].
796prolog_message(no_exported_op(Module, Op)) -->
797 [ 'Operator ~q:~q is not exported (still defined)'-[Module, Op] ].
798prolog_message(discontiguous((-)/2,_)) -->
799 prolog_message(minus_in_identifier).
800prolog_message(discontiguous(Proc,Current)) -->
801 [ 'Clauses of ', ansi(code, '~p', [Proc]),
802 ' are not together in the source-file', nl ],
803 current_definition(Proc, 'Earlier definition at '),
804 [ 'Current predicate: ', ansi(code, '~p', [Current]), nl,
805 'Use ', ansi(code, ':- discontiguous ~p.', [Proc]),
806 ' to suppress this message'
807 ].
808prolog_message(decl_no_effect(Goal)) -->
809 [ 'Deprecated declaration has no effect: ~p'-[Goal] ].
810prolog_message(load_file(start(Level, File))) -->
811 [ '~|~t~*+Loading '-[Level] ],
812 load_file(File),
813 [ ' ...' ].
814prolog_message(include_file(start(Level, File))) -->
815 [ '~|~t~*+include '-[Level] ],
816 load_file(File),
817 [ ' ...' ].
818prolog_message(include_file(done(Level, File))) -->
819 [ '~|~t~*+included '-[Level] ],
820 load_file(File).
821prolog_message(load_file(done(Level, File, Action, Module, Time, Clauses))) -->
822 [ '~|~t~*+'-[Level] ],
823 load_file(File),
824 [ ' ~w'-[Action] ],
825 load_module(Module),
826 [ ' ~2f sec, ~D clauses'-[Time, Clauses] ].
827prolog_message(dwim_undefined(Goal, Alternatives)) -->
828 { goal_to_predicate_indicator(Goal, Pred)
829 },
830 [ 'Unknown procedure: ~q'-[Pred], nl,
831 ' However, there are definitions for:', nl
832 ],
833 dwim_message(Alternatives).
834prolog_message(dwim_correct(Into)) -->
835 [ 'Correct to: ~q? '-[Into], flush ].
836prolog_message(error(loop_error(Spec), file_search(Used))) -->
837 [ 'File search: too many levels of indirections on: ~p'-[Spec], nl,
838 ' Used alias expansions:', nl
839 ],
840 used_search(Used).
841prolog_message(minus_in_identifier) -->
842 [ 'The "-" character should not be used to separate words in an', nl,
843 'identifier. Check the SWI-Prolog FAQ for details.'
844 ].
845prolog_message(qlf(removed_after_error(File))) -->
846 [ 'Removed incomplete QLF file ~w'-[File] ].
847prolog_message(qlf(recompile(Spec,_Pl,_Qlf,Reason))) -->
848 [ '~p: recompiling QLF file'-[Spec] ],
849 qlf_recompile_reason(Reason).
850prolog_message(qlf(can_not_recompile(Spec,QlfFile,_Reason))) -->
851 [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl,
852 '\tLoading from source'-[]
853 ].
854prolog_message(qlf(system_lib_out_of_date(Spec,QlfFile))) -->
855 [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl,
856 '\tLoading QlfFile'-[]
857 ].
858prolog_message(redefine_module(Module, OldFile, File)) -->
859 [ 'Module "~q" already loaded from ~w.'-[Module, OldFile], nl,
860 'Wipe and reload from ~w? '-[File], flush
861 ].
862prolog_message(redefine_module_reply) -->
863 [ 'Please answer y(es), n(o) or a(bort)' ].
864prolog_message(reloaded_in_module(Absolute, OldContext, LM)) -->
865 [ '~w was previously loaded in module ~w'-[Absolute, OldContext], nl,
866 '\tnow it is reloaded into module ~w'-[LM] ].
867prolog_message(expected_layout(Expected, Pos)) -->
868 [ 'Layout data: expected ~w, found: ~p'-[Expected, Pos] ].
869
870defined_definition(Message, Spec) -->
871 { strip_module(user:Spec, M, Name/Arity),
872 functor(Head, Name, Arity),
873 predicate_property(M:Head, file(File)),
874 predicate_property(M:Head, line_count(Line))
875 },
876 !,
877 [ nl, '~w at ~w:~d'-[Message, File,Line] ].
878defined_definition(_, _) --> [].
879
880used_search([]) -->
881 [].
882used_search([Alias=Expanded|T]) -->
883 [ ' file_search_path(~p, ~p)'-[Alias, Expanded], nl ],
884 used_search(T).
885
886load_file(file(Spec, _Path)) -->
887 ( {atomic(Spec)}
888 -> [ '~w'-[Spec] ]
889 ; [ '~p'-[Spec] ]
890 ).
893
894load_module(user) --> !.
895load_module(system) --> !.
896load_module(Module) -->
897 [ ' into ~w'-[Module] ].
898
899goal_to_predicate_indicator(Goal, PI) :-
900 strip_module(Goal, Module, Head),
901 callable_name_arity(Head, Name, Arity),
902 user_predicate_indicator(Module:Name/Arity, PI).
903
904callable_name_arity(Goal, Name, Arity) :-
905 compound(Goal),
906 !,
907 compound_name_arity(Goal, Name, Arity).
908callable_name_arity(Goal, Goal, 0) :-
909 atom(Goal).
910
911user_predicate_indicator(Module:PI, PI) :-
912 hidden_module(Module),
913 !.
914user_predicate_indicator(PI, PI).
915
916hidden_module(user) :- !.
917hidden_module(system) :- !.
918hidden_module(M) :-
919 sub_atom(M, 0, _, _, $).
920
921current_definition(Proc, Prefix) -->
922 { pi_uhead(Proc, Head),
923 predicate_property(Head, file(File)),
924 predicate_property(Head, line_count(Line))
925 },
926 [ '~w~w:~d'-[Prefix,File,Line], nl ].
927current_definition(_, _) --> [].
928
929pi_uhead(Module:Name/Arity, Module:Head) :-
930 !,
931 atom(Module), atom(Name), integer(Arity),
932 functor(Head, Name, Arity).
933pi_uhead(Name/Arity, user:Head) :-
934 atom(Name), integer(Arity),
935 functor(Head, Name, Arity).
936
937qlf_recompile_reason(old) -->
938 !,
939 [ ' (out of date)'-[] ].
940qlf_recompile_reason(_) -->
941 [ ' (incompatible with current Prolog version)'-[] ].
942
943prolog_message(file_search(cache(Spec, _Cond), Path)) -->
944 [ 'File search: ~p --> ~p (cache)'-[Spec, Path] ].
945prolog_message(file_search(found(Spec, Cond), Path)) -->
946 [ 'File search: ~p --> ~p OK ~p'-[Spec, Path, Cond] ].
947prolog_message(file_search(tried(Spec, Cond), Path)) -->
948 [ 'File search: ~p --> ~p NO ~p'-[Spec, Path, Cond] ].
949
950 953
954prolog_message(agc(start)) -->
955 thread_context,
956 [ 'AGC: ', flush ].
957prolog_message(agc(done(Collected, Remaining, Time))) -->
958 [ at_same_line,
959 'reclaimed ~D atoms in ~3f sec. (remaining: ~D)'-
960 [Collected, Time, Remaining]
961 ].
962prolog_message(cgc(start)) -->
963 thread_context,
964 [ 'CGC: ', flush ].
965prolog_message(cgc(done(CollectedClauses, _CollectedBytes,
966 RemainingBytes, Time))) -->
967 [ at_same_line,
968 'reclaimed ~D clauses in ~3f sec. (pending: ~D bytes)'-
969 [CollectedClauses, Time, RemainingBytes]
970 ].
971
972 975
976out_of_stack(Context) -->
977 { human_stack_size(Context.localused, Local),
978 human_stack_size(Context.globalused, Global),
979 human_stack_size(Context.trailused, Trail),
980 human_stack_size(Context.stack_limit, Limit),
981 LCO is (100*(Context.depth - Context.environments))/Context.depth
982 },
983 [ 'Stack limit (~s) exceeded'-[Limit], nl,
984 ' Stack sizes: local: ~s, global: ~s, trail: ~s'-[Local,Global,Trail], nl,
985 ' Stack depth: ~D, last-call: ~0f%, Choice points: ~D'-
986 [Context.depth, LCO, Context.choicepoints], nl
987 ],
988 overflow_reason(Context, Resolve),
989 resolve_overflow(Resolve).
990
991human_stack_size(Size, String) :-
992 Size < 100,
993 format(string(String), '~dKb', [Size]).
994human_stack_size(Size, String) :-
995 Size < 100 000,
996 Value is Size / 1024,
997 format(string(String), '~1fMb', [Value]).
998human_stack_size(Size, String) :-
999 Value is Size / (1024*1024),
1000 format(string(String), '~1fGb', [Value]).
1001
1002overflow_reason(Context, fix) -->
1003 show_non_termination(Context),
1004 !.
1005overflow_reason(Context, enlarge) -->
1006 { Stack = Context.get(stack) },
1007 !,
1008 [ ' In:'-[], nl ],
1009 stack(Stack).
1010overflow_reason(_Context, enlarge) -->
1011 [ ' Insufficient global stack'-[] ].
1012
1013show_non_termination(Context) -->
1014 ( { Stack = Context.get(cycle) }
1015 -> [ ' Probable infinite recursion (cycle):'-[], nl ]
1016 ; { Stack = Context.get(non_terminating) }
1017 -> [ ' Possible non-terminating recursion:'-[], nl ]
1018 ),
1019 stack(Stack).
1020
1021stack([]) --> [].
1022stack([frame(Depth, M:Goal, _)|T]) -->
1023 [ ' [~D] ~q:'-[Depth, M] ],
1024 stack_goal(Goal),
1025 [ nl ],
1026 stack(T).
1027
1028stack_goal(Goal) -->
1029 { compound(Goal),
1030 !,
1031 compound_name_arity(Goal, Name, Arity)
1032 },
1033 [ '~q('-[Name] ],
1034 stack_goal_args(1, Arity, Goal),
1035 [ ')'-[] ].
1036stack_goal(Goal) -->
1037 [ '~q'-[Goal] ].
1038
1039stack_goal_args(I, Arity, Goal) -->
1040 { I =< Arity,
1041 !,
1042 arg(I, Goal, A),
1043 I2 is I + 1
1044 },
1045 stack_goal_arg(A),
1046 ( { I2 =< Arity }
1047 -> [ ', '-[] ],
1048 stack_goal_args(I2, Arity, Goal)
1049 ; []
1050 ).
1051stack_goal_args(_, _, _) -->
1052 [].
1053
1054stack_goal_arg(A) -->
1055 { nonvar(A),
1056 A = [Len|T],
1057 !
1058 },
1059 ( {Len == cyclic_term}
1060 -> [ '[cyclic list]'-[] ]
1061 ; {T == []}
1062 -> [ '[length:~D]'-[Len] ]
1063 ; [ '[length:~D|~p]'-[Len, T] ]
1064 ).
1065stack_goal_arg(A) -->
1066 { nonvar(A),
1067 A = _/_,
1068 !
1069 },
1070 [ '<compound ~p>'-[A] ].
1071stack_goal_arg(A) -->
1072 [ '~p'-[A] ].
1073
1074resolve_overflow(fix) -->
1075 [].
1076resolve_overflow(enlarge) -->
1077 { current_prolog_flag(stack_limit, LimitBytes),
1078 NewLimit is LimitBytes * 2
1079 },
1080 [ nl,
1081 'Use the --stack_limit=size[KMG] command line option or'-[], nl,
1082 '?- set_prolog_flag(stack_limit, ~I). to double the limit.'-[NewLimit]
1083 ].
1084
1085
1086 1089
1090prolog_message(make(reload(Files))) -->
1091 { length(Files, N)
1092 },
1093 [ 'Make: reloading ~D files'-[N] ].
1094prolog_message(make(done(_Files))) -->
1095 [ 'Make: finished' ].
1096prolog_message(make(library_index(Dir))) -->
1097 [ 'Updating index for library ~w'-[Dir] ].
1098prolog_message(autoload(Pred, File)) -->
1099 thread_context,
1100 [ 'autoloading ~p from ~w'-[Pred, File] ].
1101prolog_message(autoload(read_index(Dir))) -->
1102 [ 'Loading autoload index for ~w'-[Dir] ].
1103prolog_message(autoload(disabled(Loaded))) -->
1104 [ 'Disabled autoloading (loaded ~D files)'-[Loaded] ].
1105prolog_message(autoload(already_defined(PI, From))) -->
1106 [ ansi(code, '~p', [PI]) ],
1107 ( { '$pi_head'(PI, Head),
1108 predicate_property(Head, built_in)
1109 }
1110 -> [' is a built-in predicate']
1111 ; [ ' is already imported from module ',
1112 ansi(code, '~p', [From])
1113 ]
1114 ).
1115
1116swi_message(autoload(Msg)) -->
1117 [ nl, ' ' ],
1118 autoload_message(Msg).
1119
1120autoload_message(not_exported(PI, Spec, _FullFile, _Exports)) -->
1121 [ ansi(code, '~w', [Spec]),
1122 ' does not export ',
1123 ansi(code, '~p', [PI])
1124 ].
1125autoload_message(no_file(Spec)) -->
1126 [ ansi(code, '~p', [Spec]), ': No such file' ].
1127
1128
1129 1132
1135
1136prolog_message(compiler_warnings(Clause, Warnings0)) -->
1137 { print_goal_options(DefOptions),
1138 ( prolog_load_context(variable_names, VarNames)
1139 -> warnings_with_named_vars(Warnings0, VarNames, Warnings),
1140 Options = [variable_names(VarNames)|DefOptions]
1141 ; Options = DefOptions,
1142 Warnings = Warnings0
1143 )
1144 },
1145 compiler_warnings(Warnings, Clause, Options).
1146
1147warnings_with_named_vars([], _, []).
1148warnings_with_named_vars([H|T0], VarNames, [H|T]) :-
1149 term_variables(H, Vars),
1150 '$member'(V1, Vars),
1151 '$member'(_=V2, VarNames),
1152 V1 == V2,
1153 !,
1154 warnings_with_named_vars(T0, VarNames, T).
1155warnings_with_named_vars([_|T0], VarNames, T) :-
1156 warnings_with_named_vars(T0, VarNames, T).
1157
1158
1159compiler_warnings([], _, _) --> [].
1160compiler_warnings([H|T], Clause, Options) -->
1161 ( compiler_warning(H, Clause, Options)
1162 -> []
1163 ; [ 'Unknown compiler warning: ~W'-[H,Options] ]
1164 ),
1165 ( {T==[]}
1166 -> []
1167 ; [nl]
1168 ),
1169 compiler_warnings(T, Clause, Options).
1170
1171compiler_warning(eq_vv(A,B), _Clause, Options) -->
1172 ( { A == B }
1173 -> [ 'Test is always true: ~W'-[A==B, Options] ]
1174 ; [ 'Test is always false: ~W'-[A==B, Options] ]
1175 ).
1176compiler_warning(eq_singleton(A,B), _Clause, Options) -->
1177 [ 'Test is always false: ~W'-[A==B, Options] ].
1178compiler_warning(neq_vv(A,B), _Clause, Options) -->
1179 ( { A \== B }
1180 -> [ 'Test is always true: ~W'-[A\==B, Options] ]
1181 ; [ 'Test is always false: ~W'-[A\==B, Options] ]
1182 ).
1183compiler_warning(neq_singleton(A,B), _Clause, Options) -->
1184 [ 'Test is always true: ~W'-[A\==B, Options] ].
1185compiler_warning(unify_singleton(A,B), _Clause, Options) -->
1186 [ 'Unified variable is not used: ~W'-[A=B, Options] ].
1187compiler_warning(always(Bool, Pred, Arg), _Clause, Options) -->
1188 { Goal =.. [Pred,Arg] },
1189 [ 'Test is always ~w: ~W'-[Bool, Goal, Options] ].
1190compiler_warning(unbalanced_var(V), _Clause, Options) -->
1191 [ 'Variable not introduced in all branches: ~W'-[V, Options] ].
1192compiler_warning(branch_singleton(V), _Clause, Options) -->
1193 [ 'Singleton variable in branch: ~W'-[V, Options] ].
1194compiler_warning(negation_singleton(V), _Clause, Options) -->
1195 [ 'Singleton variable in \\+: ~W'-[V, Options] ].
1196compiler_warning(multiton(V), _Clause, Options) -->
1197 [ 'Singleton-marked variable appears more than once: ~W'-[V, Options] ].
1198
1199print_goal_options(
1200 [ quoted(true),
1201 portray(true)
1202 ]).
1203
1204
1205 1208
1209prolog_message(version) -->
1210 { current_prolog_flag(version_git, Version) },
1211 !,
1212 [ '~w'-[Version] ].
1213prolog_message(version) -->
1214 { current_prolog_flag(version_data, swi(Major,Minor,Patch,Options))
1215 },
1216 ( { memberchk(tag(Tag), Options) }
1217 -> [ '~w.~w.~w-~w'-[Major, Minor, Patch, Tag] ]
1218 ; [ '~w.~w.~w'-[Major, Minor, Patch] ]
1219 ).
1220prolog_message(address_bits) -->
1221 { current_prolog_flag(address_bits, Bits)
1222 },
1223 !,
1224 [ '~d bits, '-[Bits] ].
1225prolog_message(threads) -->
1226 { current_prolog_flag(threads, true)
1227 },
1228 !,
1229 [ 'threaded, ' ].
1230prolog_message(threads) -->
1231 [].
1232prolog_message(copyright) -->
1233 [ 'SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.', nl,
1234 'Please run ?- license. for legal details.'
1235 ].
1236prolog_message(documentaton) -->
1237 [ 'For online help and background, visit https://www.swi-prolog.org', nl,
1238 'For built-in help, use ?- help(Topic). or ?- apropos(Word).'
1239 ].
1240prolog_message(about) -->
1241 [ 'SWI-Prolog version (' ],
1242 prolog_message(threads),
1243 prolog_message(address_bits),
1244 ['version ' ],
1245 prolog_message(version),
1246 [ ')', nl ],
1247 prolog_message(copyright).
1248prolog_message(halt) -->
1249 [ 'halt' ].
1250prolog_message(break(begin, Level)) -->
1251 [ 'Break level ~d'-[Level] ].
1252prolog_message(break(end, Level)) -->
1253 [ 'Exit break level ~d'-[Level] ].
1254prolog_message(var_query(_)) -->
1255 [ '... 1,000,000 ............ 10,000,000 years later', nl, nl,
1256 '~t~8|>> 42 << (last release gives the question)'
1257 ].
1258prolog_message(close_on_abort(Stream)) -->
1259 [ 'Abort: closed stream ~p'-[Stream] ].
1260prolog_message(cancel_halt(Reason)) -->
1261 [ 'Halt cancelled: ~p'-[Reason] ].
1262prolog_message(on_error(halt(Status))) -->
1263 { statistics(errors, Errors),
1264 statistics(warnings, Warnings)
1265 },
1266 [ 'Halting with status ~w due to ~D errors and ~D warnings'-
1267 [Status, Errors, Warnings] ].
1268
1269prolog_message(query(QueryResult)) -->
1270 query_result(QueryResult).
1271
1272query_result(no) --> 1273 [ ansi(truth(false), 'false.', []) ],
1274 extra_line.
1275query_result(yes(true, [])) --> 1276 !,
1277 [ ansi(truth(true), 'true.', []) ],
1278 extra_line.
1279query_result(yes(Delays, Residuals)) -->
1280 result([], Delays, Residuals),
1281 extra_line.
1282query_result(done) --> 1283 extra_line.
1284query_result(yes(Bindings, Delays, Residuals)) -->
1285 result(Bindings, Delays, Residuals),
1286 prompt(yes, Bindings, Delays, Residuals).
1287query_result(more(Bindings, Delays, Residuals)) -->
1288 result(Bindings, Delays, Residuals),
1289 prompt(more, Bindings, Delays, Residuals).
1290query_result(help) -->
1291 [ nl, 'Actions:'-[], nl, nl,
1292 '; (n, r, space, TAB): redo t: trace & redo'-[], nl,
1293 'b: break c (a, RET): exit'-[], nl,
1294 'w: write p print'-[], nl,
1295 'h (?): help'-[],
1296 nl, nl
1297 ].
1298query_result(action) -->
1299 [ 'Action? '-[], flush ].
1300query_result(confirm) -->
1301 [ 'Please answer \'y\' or \'n\'? '-[], flush ].
1302query_result(eof) -->
1303 [ nl ].
1304query_result(toplevel_open_line) -->
1305 [].
1306
1307prompt(Answer, [], true, []-[]) -->
1308 !,
1309 prompt(Answer, empty).
1310prompt(Answer, _, _, _) -->
1311 !,
1312 prompt(Answer, non_empty).
1313
1314prompt(yes, empty) -->
1315 !,
1316 [ ansi(truth(true), 'true.', []) ],
1317 extra_line.
1318prompt(yes, _) -->
1319 !,
1320 [ full_stop ],
1321 extra_line.
1322prompt(more, empty) -->
1323 !,
1324 [ ansi(truth(true), 'true ', []), flush ].
1325prompt(more, _) -->
1326 !,
1327 [ ' '-[], flush ].
1328
1329result(Bindings, Delays, Residuals) -->
1330 { current_prolog_flag(answer_write_options, Options0),
1331 Options = [partial(true)|Options0],
1332 GOptions = [priority(999)|Options0]
1333 },
1334 wfs_residual_program(Delays, GOptions),
1335 bindings(Bindings, [priority(699)|Options]),
1336 ( {Residuals == []-[]}
1337 -> bind_delays_sep(Bindings, Delays),
1338 delays(Delays, GOptions)
1339 ; bind_res_sep(Bindings, Residuals),
1340 residuals(Residuals, GOptions),
1341 ( {Delays == true}
1342 -> []
1343 ; [','-[], nl],
1344 delays(Delays, GOptions)
1345 )
1346 ).
1347
1348bindings([], _) -->
1349 [].
1350bindings([binding(Names,Skel,Subst)|T], Options) -->
1351 { '$last'(Names, Name) },
1352 var_names(Names), value(Name, Skel, Subst, Options),
1353 ( { T \== [] }
1354 -> [ ','-[], nl ],
1355 bindings(T, Options)
1356 ; []
1357 ).
1358
1359var_names([Name]) -->
1360 !,
1361 [ '~w = '-[Name] ].
1362var_names([Name1,Name2|T]) -->
1363 !,
1364 [ '~w = ~w, '-[Name1, Name2] ],
1365 var_names([Name2|T]).
1366
1367
1368value(Name, Skel, Subst, Options) -->
1369 ( { var(Skel), Subst = [Skel=S] }
1370 -> { Skel = '$VAR'(Name) },
1371 [ '~W'-[S, Options] ]
1372 ; [ '~W'-[Skel, Options] ],
1373 substitution(Subst, Options)
1374 ).
1375
1376substitution([], _) --> !.
1377substitution([N=V|T], Options) -->
1378 [ ', ', ansi(comment, '% where', []), nl,
1379 ' ~w = ~W'-[N,V,Options] ],
1380 substitutions(T, Options).
1381
1382substitutions([], _) --> [].
1383substitutions([N=V|T], Options) -->
1384 [ ','-[], nl, ' ~w = ~W'-[N,V,Options] ],
1385 substitutions(T, Options).
1386
1387
1388residuals(Normal-Hidden, Options) -->
1389 residuals1(Normal, Options),
1390 bind_res_sep(Normal, Hidden),
1391 ( {Hidden == []}
1392 -> []
1393 ; [ansi(comment, '% with pending residual goals', []), nl]
1394 ),
1395 residuals1(Hidden, Options).
1396
1397residuals1([], _) -->
1398 [].
1399residuals1([G|Gs], Options) -->
1400 ( { Gs \== [] }
1401 -> [ '~W,'-[G, Options], nl ],
1402 residuals1(Gs, Options)
1403 ; [ '~W'-[G, Options] ]
1404 ).
1405
1406wfs_residual_program(true, _Options) -->
1407 !.
1408wfs_residual_program(Goal, _Options) -->
1409 { current_prolog_flag(toplevel_list_wfs_residual_program, true),
1410 '$current_typein_module'(TypeIn),
1411 ( current_predicate(delays_residual_program/2)
1412 -> true
1413 ; use_module(library(wfs), [delays_residual_program/2])
1414 ),
1415 delays_residual_program(TypeIn:Goal, TypeIn:Program),
1416 Program \== []
1417 },
1418 !,
1419 [ ansi(comment, '% WFS residual program', []), nl ],
1420 [ ansi(wfs(residual_program), '~@', ['$messages':list_clauses(Program)]) ].
1421wfs_residual_program(_, _) --> [].
1422
1423delays(true, _Options) -->
1424 !.
1425delays(Goal, Options) -->
1426 { current_prolog_flag(toplevel_list_wfs_residual_program, true)
1427 },
1428 !,
1429 [ ansi(truth(undefined), '~W', [Goal, Options]) ].
1430delays(_, _Options) -->
1431 [ ansi(truth(undefined), undefined, []) ].
1432
1433:- public list_clauses/1. 1434
1435list_clauses([]).
1436list_clauses([H|T]) :-
1437 ( system_undefined(H)
1438 -> true
1439 ; portray_clause(user_output, H, [indent(4)])
1440 ),
1441 list_clauses(T).
1442
1443system_undefined((undefined :- tnot(undefined))).
1444system_undefined((answer_count_restraint :- tnot(answer_count_restraint))).
1445system_undefined((radial_restraint :- tnot(radial_restraint))).
1446
1447bind_res_sep(_, []) --> !.
1448bind_res_sep(_, []-[]) --> !.
1449bind_res_sep([], _) --> !.
1450bind_res_sep(_, _) --> [','-[], nl].
1451
1452bind_delays_sep([], _) --> !.
1453bind_delays_sep(_, true) --> !.
1454bind_delays_sep(_, _) --> [','-[], nl].
1455
-->
1457 { current_prolog_flag(toplevel_extra_white_line, true) },
1458 !,
1459 ['~N'-[]].
1460extra_line -->
1461 [].
1462
1463prolog_message(if_tty(Message)) -->
1464 ( {current_prolog_flag(tty_control, true)}
1465 -> [ at_same_line | Message ]
1466 ; []
1467 ).
1468prolog_message(halt(Reason)) -->
1469 [ '~w: halt'-[Reason] ].
1470prolog_message(no_action(Char)) -->
1471 [ 'Unknown action: ~c (h for help)'-[Char], nl ].
1472
1473prolog_message(history(help(Show, Help))) -->
1474 [ 'History Commands:', nl,
1475 ' !!. Repeat last query', nl,
1476 ' !nr. Repeat query numbered <nr>', nl,
1477 ' !str. Repeat last query starting with <str>', nl,
1478 ' !?str. Repeat last query holding <str>', nl,
1479 ' ^old^new. Substitute <old> into <new> of last query', nl,
1480 ' !nr^old^new. Substitute in query numbered <nr>', nl,
1481 ' !str^old^new. Substitute in query starting with <str>', nl,
1482 ' !?str^old^new. Substitute in query holding <str>', nl,
1483 ' ~w.~21|Show history list'-[Show], nl,
1484 ' ~w.~21|Show this list'-[Help], nl, nl
1485 ].
1486prolog_message(history(no_event)) -->
1487 [ '! No such event' ].
1488prolog_message(history(bad_substitution)) -->
1489 [ '! Bad substitution' ].
1490prolog_message(history(expanded(Event))) -->
1491 [ '~w.'-[Event] ].
1492prolog_message(history(history(Events))) -->
1493 history_events(Events).
1494
1495history_events([]) -->
1496 [].
1497history_events([Nr/Event|T]) -->
1498 [ '~t~w ~8|~W~W'-[ Nr,
1499 Event, [partial(true)],
1500 '.', [partial(true)]
1501 ],
1502 nl
1503 ],
1504 history_events(T).
1505
1506
1511
1512user_version_messages([]) --> [].
1513user_version_messages([H|T]) -->
1514 user_version_message(H),
1515 user_version_messages(T).
1516
1518
1519user_version_message(Term) -->
1520 translate_message(Term), !, [nl].
1521user_version_message(Atom) -->
1522 [ '~w'-[Atom], nl ].
1523
1524
1525 1528
1529prolog_message(spy(Head)) -->
1530 { goal_to_predicate_indicator(Head, Pred)
1531 },
1532 [ 'Spy point on ~p'-[Pred] ].
1533prolog_message(nospy(Head)) -->
1534 { goal_to_predicate_indicator(Head, Pred)
1535 },
1536 [ 'Spy point removed from ~p'-[Pred] ].
1537prolog_message(trace_mode(OnOff)) -->
1538 [ 'Trace mode switched to ~w'-[OnOff] ].
1539prolog_message(debug_mode(OnOff)) -->
1540 [ 'Debug mode switched to ~w'-[OnOff] ].
1541prolog_message(debugging(OnOff)) -->
1542 [ 'Debug mode is ~w'-[OnOff] ].
1543prolog_message(spying([])) -->
1544 !,
1545 [ 'No spy points' ].
1546prolog_message(spying(Heads)) -->
1547 [ 'Spy points (see spy/1) on:', nl ],
1548 predicate_list(Heads).
1549prolog_message(trace(Head, [])) -->
1550 !,
1551 { goal_to_predicate_indicator(Head, Pred)
1552 },
1553 [ ' ~p: Not tracing'-[Pred], nl].
1554prolog_message(trace(Head, Ports)) -->
1555 { goal_to_predicate_indicator(Head, Pred)
1556 },
1557 [ ' ~p: ~w'-[Pred, Ports], nl].
1558prolog_message(tracing([])) -->
1559 !,
1560 [ 'No traced predicates (see trace/1)' ].
1561prolog_message(tracing(Heads)) -->
1562 [ 'Trace points (see trace/1) on:', nl ],
1563 tracing_list(Heads).
1564
1565predicate_list([]) --> 1566 [].
1567predicate_list([H|T]) -->
1568 { goal_to_predicate_indicator(H, Pred)
1569 },
1570 [ ' ~p'-[Pred], nl],
1571 predicate_list(T).
1572
1573tracing_list([]) -->
1574 [].
1575tracing_list([trace(Head, Ports)|T]) -->
1576 translate_message(trace(Head, Ports)),
1577 tracing_list(T).
1578
1579prolog_message(frame(Frame, backtrace, _PC)) -->
1580 !,
1581 { prolog_frame_attribute(Frame, level, Level)
1582 },
1583 [ ansi(frame(level), '~t[~D] ~10|', [Level]) ],
1584 frame_context(Frame),
1585 frame_goal(Frame).
1586prolog_message(frame(Frame, choice, PC)) -->
1587 !,
1588 prolog_message(frame(Frame, backtrace, PC)).
1589prolog_message(frame(_, cut_call, _)) --> !, [].
1590prolog_message(frame(Goal, trace(Port))) -->
1591 !,
1592 thread_context,
1593 [ ' T ' ],
1594 port(Port),
1595 goal(Goal).
1596prolog_message(frame(Goal, trace(Port, Id))) -->
1597 !,
1598 thread_context,
1599 [ ' T ' ],
1600 port(Port, Id),
1601 goal(Goal).
1602prolog_message(frame(Frame, Port, _PC)) -->
1603 frame_flags(Frame),
1604 port(Port),
1605 frame_level(Frame),
1606 frame_context(Frame),
1607 frame_depth_limit(Port, Frame),
1608 frame_goal(Frame),
1609 [ flush ].
1610
1611frame_goal(Frame) -->
1612 { prolog_frame_attribute(Frame, goal, Goal)
1613 },
1614 goal(Goal).
1615
1616goal(Goal0) -->
1617 { clean_goal(Goal0, Goal),
1618 current_prolog_flag(debugger_write_options, Options)
1619 },
1620 [ '~W'-[Goal, Options] ].
1621
1622frame_level(Frame) -->
1623 { prolog_frame_attribute(Frame, level, Level)
1624 },
1625 [ '(~D) '-[Level] ].
1626
1627frame_context(Frame) -->
1628 ( { current_prolog_flag(debugger_show_context, true),
1629 prolog_frame_attribute(Frame, context_module, Context)
1630 }
1631 -> [ '[~w] '-[Context] ]
1632 ; []
1633 ).
1634
1635frame_depth_limit(fail, Frame) -->
1636 { prolog_frame_attribute(Frame, depth_limit_exceeded, true)
1637 },
1638 !,
1639 [ '[depth-limit exceeded] ' ].
1640frame_depth_limit(_, _) -->
1641 [].
1642
1643frame_flags(Frame) -->
1644 { prolog_frame_attribute(Frame, goal, Goal),
1645 ( predicate_property(Goal, transparent)
1646 -> T = '^'
1647 ; T = ' '
1648 ),
1649 ( predicate_property(Goal, spying)
1650 -> S = '*'
1651 ; S = ' '
1652 )
1653 },
1654 [ '~w~w '-[T, S] ].
1655
1657port(Port, _Id-Level) -->
1658 [ '[~d] '-Level ],
1659 port(Port).
1660
1661port(Port) -->
1662 { port_name(Port, Name)
1663 },
1664 !,
1665 [ ansi(port(Port), '~w: ', [Name]) ].
1666
1667port_name(call, 'Call').
1668port_name(exit, 'Exit').
1669port_name(fail, 'Fail').
1670port_name(redo, 'Redo').
1671port_name(unify, 'Unify').
1672port_name(exception, 'Exception').
1673
1674clean_goal(M:Goal, Goal) :-
1675 hidden_module(M),
1676 !.
1677clean_goal(M:Goal, Goal) :-
1678 predicate_property(M:Goal, built_in),
1679 !.
1680clean_goal(Goal, Goal).
1681
1682
1683 1686
1687prolog_message(compatibility(renamed(Old, New))) -->
1688 [ 'The predicate ~p has been renamed to ~p.'-[Old, New], nl,
1689 'Please update your sources for compatibility with future versions.'
1690 ].
1691
1692
1693 1696
1697prolog_message(abnormal_thread_completion(Goal, exception(Ex))) -->
1698 !,
1699 [ 'Thread running "~p" died on exception: '-[Goal] ],
1700 translate_message(Ex).
1701prolog_message(abnormal_thread_completion(Goal, fail)) -->
1702 [ 'Thread running "~p" died due to failure'-[Goal] ].
1703prolog_message(threads_not_died(Running)) -->
1704 [ 'The following threads wouldn\'t die: ~p'-[Running] ].
1705
1706
1707 1710
1711prolog_message(pack(attached(Pack, BaseDir))) -->
1712 [ 'Attached package ~w at ~q'-[Pack, BaseDir] ].
1713prolog_message(pack(duplicate(Entry, OldDir, Dir))) -->
1714 [ 'Package ~w already attached at ~q.'-[Entry,OldDir], nl,
1715 '\tIgnoring version from ~q'- [Dir]
1716 ].
1717prolog_message(pack(no_arch(Entry, Arch))) -->
1718 [ 'Package ~w: no binary for architecture ~w'-[Entry, Arch] ].
1719
1720 1723
1724prolog_message(null_byte_in_path(Component)) -->
1725 [ '0-byte in PATH component: ~p (skipped directory)'-[Component] ].
1726prolog_message(invalid_tmp_dir(Dir, Reason)) -->
1727 [ 'Cannot use ~p as temporary file directory: ~w'-[Dir, Reason] ].
1728prolog_message(ambiguous_stream_pair(Pair)) -->
1729 [ 'Ambiguous operation on stream pair ~p'-[Pair] ].
1730prolog_message(backcomp(init_file_moved(FoundFile))) -->
1731 { absolute_file_name(app_config('init.pl'), InitFile,
1732 [ file_errors(fail)
1733 ])
1734 },
1735 [ 'The location of the config file has moved'-[], nl,
1736 ' from "~w"'-[FoundFile], nl,
1737 ' to "~w"'-[InitFile], nl,
1738 ' See https://www.swi-prolog.org/modified/config-files.html'-[]
1739 ].
1740
1741 1744
1745deprecated(set_prolog_stack(_Stack,limit)) -->
1746 [ 'set_prolog_stack/2: limit(Size) sets the combined limit.'-[], nl,
1747 'See https://www.swi-prolog.org/changes/stack-limit.html'
1748 ].
1749
1750 1753
1754tripwire_message(Wire, Context) -->
1755 [ 'Trapped tripwire ~w for '-[Wire] ],
1756 tripwire_context(Wire, Context).
1757
1758tripwire_context(_, ATrie) -->
1759 { '$is_answer_trie'(ATrie, _),
1760 !,
1761 '$tabling':atrie_goal(ATrie, QGoal),
1762 user_predicate_indicator(QGoal, Goal)
1763 },
1764 [ '~p'-[Goal] ].
1765tripwire_context(_, Ctx) -->
1766 [ '~p'-[Ctx] ].
1767
1768
1769 1772
1773:- create_prolog_flag(message_language, default, []). 1774
1779
1780message_lang(Lang) :-
1781 current_message_lang(Lang0),
1782 ( Lang0 == en
1783 -> Lang = en
1784 ; sub_atom(Lang0, 0, _, _, en_)
1785 -> longest_id(Lang0, Lang)
1786 ; ( longest_id(Lang0, Lang)
1787 ; Lang = en
1788 )
1789 ).
1790
1791longest_id(Lang, Id) :-
1792 split_string(Lang, "_-", "", [H|Components]),
1793 longest_prefix(Components, Taken),
1794 atomic_list_concat([H|Taken], '_', Id).
1795
1796longest_prefix([H|T0], [H|T]) :-
1797 longest_prefix(T0, T).
1798longest_prefix(_, []).
1799
1803
1804current_message_lang(Lang) :-
1805 ( current_prolog_flag(message_language, Lang0),
1806 Lang0 \== default
1807 -> Lang = Lang0
1808 ; os_user_lang(Lang0)
1809 -> clean_encoding(Lang0, Lang1),
1810 set_prolog_flag(message_language, Lang1),
1811 Lang = Lang1
1812 ; Lang = en
1813 ).
1814
1815os_user_lang(Lang) :-
1816 current_prolog_flag(windows, true),
1817 win_get_user_preferred_ui_languages(name, [Lang|_]).
1818os_user_lang(Lang) :-
1819 catch(setlocale(messages, _, ''), _, fail),
1820 setlocale(messages, Lang, Lang).
1821os_user_lang(Lang) :-
1822 getenv('LANG', Lang).
1823
1824
1825clean_encoding(Lang0, Lang) :-
1826 ( sub_atom(Lang0, A, _, _, '.')
1827 -> sub_atom(Lang0, 0, A, _, Lang)
1828 ; Lang = Lang0
1829 ).
1830
1831
1832 1835
1836:- public default_theme/2. 1837
1838default_theme(var, [fg(red)]).
1839default_theme(code, [fg(blue)]).
1840default_theme(comment, [fg(green)]).
1841default_theme(warning, [fg(red)]).
1842default_theme(error, [bold, fg(red)]).
1843default_theme(truth(false), [bold, fg(red)]).
1844default_theme(truth(true), [bold]).
1845default_theme(truth(undefined), [bold, fg(cyan)]).
1846default_theme(wfs(residual_program), [fg(cyan)]).
1847default_theme(frame(level), [bold]).
1848default_theme(port(call), [bold, fg(green)]).
1849default_theme(port(exit), [bold, fg(green)]).
1850default_theme(port(fail), [bold, fg(red)]).
1851default_theme(port(redo), [bold, fg(yellow)]).
1852default_theme(port(unify), [bold, fg(blue)]).
1853default_theme(port(exception), [bold, fg(magenta)]).
1854default_theme(message(informational), [fg(green)]).
1855default_theme(message(information), [fg(green)]).
1856default_theme(message(debug(_)), [fg(blue)]).
1857default_theme(message(Level), Attrs) :-
1858 nonvar(Level),
1859 default_theme(Level, Attrs).
1860
1861
1862 1865
1866:- multifile
1867 user:message_hook/3,
1868 prolog:message_prefix_hook/2. 1869:- dynamic
1870 user:message_hook/3,
1871 prolog:message_prefix_hook/2. 1872:- thread_local
1873 user:thread_message_hook/3. 1874:- '$hide'((push_msg/1,pop_msg/0)). 1875
1880
1881print_message(Level, Term) :-
1882 setup_call_cleanup(
1883 push_msg(Term),
1884 print_message_guarded(Level, Term),
1885 pop_msg),
1886 !.
1887print_message(Level, Term) :-
1888 ( Level \== silent
1889 -> format(user_error, 'Recursive ~w message: ~q~n', [Level, Term])
1890 ; true
1891 ).
1892
1893push_msg(Term) :-
1894 nb_current('$inprint_message', Messages),
1895 !,
1896 \+ ( '$member'(Msg, Messages),
1897 Msg =@= Term
1898 ),
1899 b_setval('$inprint_message', [Term|Messages]).
1900push_msg(Term) :-
1901 b_setval('$inprint_message', [Term]).
1902
1903pop_msg :-
1904 ( nb_current('$inprint_message', [_|Messages]),
1905 Messages \== []
1906 -> b_setval('$inprint_message', Messages)
1907 ; nb_delete('$inprint_message'), 1908 b_setval('$inprint_message', [])
1909 ).
1910
1911print_message_guarded(Level, Term) :-
1912 ( must_print(Level, Term)
1913 -> ( translate_message(Term, Lines, [])
1914 -> ( nonvar(Term),
1915 ( notrace(user:thread_message_hook(Term, Level, Lines))
1916 -> true
1917 ; notrace(user:message_hook(Term, Level, Lines))
1918 )
1919 -> true
1920 ; '$inc_message_count'(Level),
1921 print_system_message(Term, Level, Lines),
1922 maybe_halt_on_error(Level)
1923 )
1924 )
1925 ; true
1926 ).
1927
1928maybe_halt_on_error(error) :-
1929 current_prolog_flag(on_error, halt),
1930 !,
1931 halt(1).
1932maybe_halt_on_error(warning) :-
1933 current_prolog_flag(on_warning, halt),
1934 !,
1935 halt(1).
1936maybe_halt_on_error(_).
1937
1938
1945
1946print_system_message(_, silent, _) :- !.
1947print_system_message(_, informational, _) :-
1948 current_prolog_flag(verbose, silent),
1949 !.
1950print_system_message(_, banner, _) :-
1951 current_prolog_flag(verbose, silent),
1952 !.
1953print_system_message(_, _, []) :- !.
1954print_system_message(Term, Kind, Lines) :-
1955 catch(flush_output(user_output), _, true), 1956 source_location(File, Line),
1957 Term \= error(syntax_error(_), _),
1958 msg_property(Kind, location_prefix(File:Line, LocPrefix, LinePrefix)),
1959 !,
1960 insert_prefix(Lines, LinePrefix, Ctx, PrefixLines),
1961 '$append'([ begin(Kind, Ctx),
1962 LocPrefix,
1963 nl
1964 | PrefixLines
1965 ],
1966 [ end(Ctx)
1967 ],
1968 AllLines),
1969 msg_property(Kind, stream(Stream)),
1970 ignore(stream_property(Stream, position(Pos))),
1971 print_message_lines(Stream, AllLines),
1972 ( \+ stream_property(Stream, position(Pos)),
1973 msg_property(Kind, wait(Wait)),
1974 Wait > 0
1975 -> sleep(Wait)
1976 ; true
1977 ).
1978print_system_message(_, Kind, Lines) :-
1979 msg_property(Kind, stream(Stream)),
1980 print_message_lines(Stream, kind(Kind), Lines).
1981
1982:- multifile
1983 user:message_property/2. 1984
1985msg_property(Kind, Property) :-
1986 notrace(user:message_property(Kind, Property)),
1987 !.
1988msg_property(Kind, prefix(Prefix)) :-
1989 msg_prefix(Kind, Prefix),
1990 !.
1991msg_property(_, prefix('~N')) :- !.
1992msg_property(query, stream(user_output)) :- !.
1993msg_property(_, stream(user_error)) :- !.
1994msg_property(error, tag('ERROR')).
1995msg_property(warning, tag('Warning')).
1996msg_property(Level,
1997 location_prefix(File:Line,
1998 Prefix1-[File,Line],
1999 PrefixC)) :-
2000 include_msg_location(Level),
2001 msg_property(Level, tag(Tag)),
2002 atomics_to_string(['~N', Tag, ': ~w:~d:'], Prefix1),
2003 atomics_to_string(['~N', Tag, ': ' ], PrefixC).
2004msg_property(error, wait(0.1)) :- !.
2005
2006include_msg_location(warning).
2007include_msg_location(error).
2008
2009msg_prefix(debug(_), Prefix) :-
2010 msg_context('~N% ', Prefix).
2011msg_prefix(Level, Prefix) :-
2012 msg_property(Level, tag(Tag)),
2013 atomics_to_string(['~N', Tag, ': '], Prefix0),
2014 msg_context(Prefix0, Prefix).
2015msg_prefix(informational, '~N% ').
2016msg_prefix(information, '~N% ').
2017
2029
2030msg_context(Prefix0, Prefix) :-
2031 current_prolog_flag(message_context, Context),
2032 is_list(Context),
2033 !,
2034 add_message_context(Context, Prefix0, Prefix).
2035msg_context(Prefix, Prefix).
2036
2037add_message_context([], Prefix, Prefix).
2038add_message_context([H|T], Prefix0, Prefix) :-
2039 ( add_message_context1(H, Prefix0, Prefix1)
2040 -> true
2041 ; Prefix1 = Prefix0
2042 ),
2043 add_message_context(T, Prefix1, Prefix).
2044
2045add_message_context1(Context, Prefix0, Prefix) :-
2046 prolog:message_prefix_hook(Context, Extra),
2047 atomics_to_string([Prefix0, Extra, ' '], Prefix).
2048add_message_context1(time, Prefix0, Prefix) :-
2049 get_time(Now),
2050 format_time(string(S), '%T.%3f ', Now),
2051 string_concat(Prefix0, S, Prefix).
2052add_message_context1(time(Format), Prefix0, Prefix) :-
2053 get_time(Now),
2054 format_time(string(S), Format, Now),
2055 atomics_to_string([Prefix0, S, ' '], Prefix).
2056add_message_context1(thread, Prefix0, Prefix) :-
2057 thread_self(Id0),
2058 Id0 \== main,
2059 !,
2060 ( atom(Id0)
2061 -> Id = Id0
2062 ; thread_property(Id0, id(Id))
2063 ),
2064 format(string(Prefix), '~w[Thread ~w] ', [Prefix0, Id]).
2065
2070
2071print_message_lines(Stream, kind(Kind), Lines) :-
2072 !,
2073 msg_property(Kind, prefix(Prefix)),
2074 insert_prefix(Lines, Prefix, Ctx, PrefixLines),
2075 '$append'([ begin(Kind, Ctx)
2076 | PrefixLines
2077 ],
2078 [ end(Ctx)
2079 ],
2080 AllLines),
2081 print_message_lines(Stream, AllLines).
2082print_message_lines(Stream, Prefix, Lines) :-
2083 insert_prefix(Lines, Prefix, _, PrefixLines),
2084 print_message_lines(Stream, PrefixLines).
2085
2087
2088insert_prefix([at_same_line|Lines0], Prefix, Ctx, Lines) :-
2089 !,
2090 prefix_nl(Lines0, Prefix, Ctx, Lines).
2091insert_prefix(Lines0, Prefix, Ctx, [prefix(Prefix)|Lines]) :-
2092 prefix_nl(Lines0, Prefix, Ctx, Lines).
2093
2094prefix_nl([], _, _, [nl]).
2095prefix_nl([nl], _, _, [nl]) :- !.
2096prefix_nl([flush], _, _, [flush]) :- !.
2097prefix_nl([nl|T0], Prefix, Ctx, [nl, prefix(Prefix)|T]) :-
2098 !,
2099 prefix_nl(T0, Prefix, Ctx, T).
2100prefix_nl([ansi(Attrs,Fmt,Args)|T0], Prefix, Ctx,
2101 [ansi(Attrs,Fmt,Args,Ctx)|T]) :-
2102 !,
2103 prefix_nl(T0, Prefix, Ctx, T).
2104prefix_nl([H|T0], Prefix, Ctx, [H|T]) :-
2105 prefix_nl(T0, Prefix, Ctx, T).
2106
2108
2109print_message_lines(Stream, Lines) :-
2110 with_output_to(
2111 Stream,
2112 notrace(print_message_lines_guarded(current_output, Lines))).
2113
2114print_message_lines_guarded(_, []) :- !.
2115print_message_lines_guarded(S, [H|T]) :-
2116 line_element(S, H),
2117 print_message_lines_guarded(S, T).
2118
2119line_element(S, E) :-
2120 prolog:message_line_element(S, E),
2121 !.
2122line_element(S, full_stop) :-
2123 !,
2124 '$put_token'(S, '.'). 2125line_element(S, nl) :-
2126 !,
2127 nl(S).
2128line_element(S, prefix(Fmt-Args)) :-
2129 !,
2130 safe_format(S, Fmt, Args).
2131line_element(S, prefix(Fmt)) :-
2132 !,
2133 safe_format(S, Fmt, []).
2134line_element(S, flush) :-
2135 !,
2136 flush_output(S).
2137line_element(S, Fmt-Args) :-
2138 !,
2139 safe_format(S, Fmt, Args).
2140line_element(S, ansi(_, Fmt, Args)) :-
2141 !,
2142 safe_format(S, Fmt, Args).
2143line_element(S, ansi(_, Fmt, Args, _Ctx)) :-
2144 !,
2145 safe_format(S, Fmt, Args).
2146line_element(_, begin(_Level, _Ctx)) :- !.
2147line_element(_, end(_Ctx)) :- !.
2148line_element(S, Fmt) :-
2149 safe_format(S, Fmt, []).
2150
2152
2153safe_format(S, Fmt, Args) :-
2154 E = error(_,_),
2155 catch(format(S,Fmt,Args), E,
2156 format_failed(S,Fmt,Args,E)).
2157
2158format_failed(S, _Fmt, _Args, E) :-
2159 E = error(io_error(_,S),_),
2160 !,
2161 throw(E).
2162format_failed(S, Fmt, Args, error(E,_)) :-
2163 format(S, '~N [[ EXCEPTION while printing message ~q~n\c
2164 ~7|with arguments ~W:~n\c
2165 ~7|raised: ~W~n~4|]]~n',
2166 [ Fmt,
2167 Args, [quoted(true), max_depth(10)],
2168 E, [quoted(true), max_depth(10)]
2169 ]).
2170
2174
2175message_to_string(Term, Str) :-
2176 translate_message(Term, Actions, []),
2177 !,
2178 actions_to_format(Actions, Fmt, Args),
2179 format(string(Str), Fmt, Args).
2180
2181actions_to_format([], '', []) :- !.
2182actions_to_format([nl], '', []) :- !.
2183actions_to_format([Term, nl], Fmt, Args) :-
2184 !,
2185 actions_to_format([Term], Fmt, Args).
2186actions_to_format([nl|T], Fmt, Args) :-
2187 !,
2188 actions_to_format(T, Fmt0, Args),
2189 atom_concat('~n', Fmt0, Fmt).
2190actions_to_format([ansi(_Attrs, Fmt0, Args0)|Tail], Fmt, Args) :-
2191 !,
2192 actions_to_format(Tail, Fmt1, Args1),
2193 atom_concat(Fmt0, Fmt1, Fmt),
2194 append_args(Args0, Args1, Args).
2195actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :-
2196 !,
2197 actions_to_format(Tail, Fmt1, Args1),
2198 atom_concat(Fmt0, Fmt1, Fmt),
2199 append_args(Args0, Args1, Args).
2200actions_to_format([Skip|T], Fmt, Args) :-
2201 action_skip(Skip),
2202 !,
2203 actions_to_format(T, Fmt, Args).
2204actions_to_format([Term|Tail], Fmt, Args) :-
2205 atomic(Term),
2206 !,
2207 actions_to_format(Tail, Fmt1, Args),
2208 atom_concat(Term, Fmt1, Fmt).
2209actions_to_format([Term|Tail], Fmt, Args) :-
2210 actions_to_format(Tail, Fmt1, Args1),
2211 atom_concat('~w', Fmt1, Fmt),
2212 append_args([Term], Args1, Args).
2213
2214action_skip(at_same_line).
2215action_skip(flush).
2216action_skip(begin(_Level, _Ctx)).
2217action_skip(end(_Ctx)).
2218
2219append_args(M:Args0, Args1, M:Args) :-
2220 !,
2221 strip_module(Args1, _, A1),
2222 '$append'(Args0, A1, Args).
2223append_args(Args0, Args1, Args) :-
2224 strip_module(Args1, _, A1),
2225 '$append'(Args0, A1, Args).
2226
2227
2228 2231
2232:- dynamic
2233 printed/2. 2234
2238
2239print_once(compatibility(_), _).
2240print_once(null_byte_in_path(_), _).
2241print_once(deprecated(_), _).
2242
2246
2247must_print(Level, Message) :-
2248 nonvar(Message),
2249 print_once(Message, Level),
2250 !,
2251 \+ printed(Message, Level),
2252 assert(printed(Message, Level)).
2253must_print(_, _)