1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: jan@swi-prolog.org 5 WWW: https://www.swi-prolog.org 6 Copyright (c) 1997-2026, University of Amsterdam 7 VU University Amsterdam 8 CWI, Amsterdam 9 SWI-Prolog Solutions b.v. 10 All rights reserved. 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions 14 are met: 15 16 1. Redistributions of source code must retain the above copyright 17 notice, this list of conditions and the following disclaimer. 18 19 2. Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in 21 the documentation and/or other materials provided with the 22 distribution. 23 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 POSSIBILITY OF SUCH DAMAGE. 36*/ 37 38:- module('$messages', 39 [ print_message/2, % +Kind, +Term 40 print_message_lines/3, % +Stream, +Prefix, +Lines 41 message_to_string/2 % +Term, -String 42 ]). 43 44:- multifile 45 prolog:message//1, % entire message 46 prolog:error_message//1, % 1-st argument of error term 47 prolog:message_context//1, % Context of error messages 48 prolog:deprecated//1, % Deprecated features 49 prolog:message_location//1, % (File) location of error messages 50 prolog:message_line_element/2, % Extend printing 51 prolog:message_action/2. % Side effects (broadcast) 52:- dynamic 53 prolog:message_action/2. % Allow overruling 54:- '$hide'(( 55 prolog:message//1, 56 prolog:error_message//1, 57 prolog:message_context//1, 58 prolog:deprecated//1, 59 prolog:message_location//1, 60 prolog:message_line_element/2)). 61% Lang, Term versions 62:- multifile 63 prolog:message//2, % entire message 64 prolog:error_message//2, % 1-st argument of error term 65 prolog:message_context//2, % Context of error messages 66 prolog:message_location//2, % (File) location of error messages 67 prolog:deprecated//2. % Deprecated features 68:- '$hide'(( 69 prolog:message//2, 70 prolog:error_message//2, 71 prolog:message_context//2, 72 prolog:deprecated//2, 73 prolog:message_location//2)). 74 75:- discontiguous 76 prolog_message/3. 77 78:- public 79 translate_message//1, % +Message (deprecated) 80 prolog:translate_message//1. % +Message 81 82:- create_prolog_flag(message_context, [thread], []). 83:- create_prolog_flag(debugger_goal_links, auto, 84 [ type(oneof([false,true,auto])), 85 keep(true) 86 ]).
format(Fmt, Args)format(Fmt)ansi(Class, Fmt, Args), the latter
combining a hyperlink with a style class.
The elements begin(Class, Ctx) and end(Ctx) that decorate the
message as a whole are added by print_message_lines/3.
Use predicate_reference//1,2 to refer to a predicate rather than formatting the predicate indicator by hand.
126prologtranslate_message(Term) -->
127 translate_message(Term).134translate_message(Term) --> 135 { nonvar(Term) }, 136 ( { message_lang(Lang) }, 137 prolog:message(Lang, Term) 138 ; prolog:message(Term) 139 ), 140 !. 141translate_message(Term) --> 142 { nonvar(Term) }, 143 translate_message2(Term), 144 !. 145translate_message(Term) --> 146 { nonvar(Term), 147 Term = error(_, _) 148 }, 149 [ 'Unknown exception: ~p'-[Term] ]. 150translate_message(Term) --> 151 [ 'Unknown message: ~p'-[Term] ]. 152 153translate_message2(Term) --> 154 prolog_message(Term). 155translate_message2(error(resource_error(stack), Context)) --> 156 !, 157 out_of_stack(Context). 158translate_message2(error(resource_error(tripwire(Wire, Context)), _)) --> 159 !, 160 tripwire_message(Wire, Context). 161translate_message2(error(existence_error(reset, Ball), SWI)) --> 162 swi_location(SWI), 163 tabling_existence_error(Ball, SWI). 164translate_message2(error(ISO, SWI)) --> 165 swi_location(SWI), 166 term_message(ISO), 167 swi_extra(SWI). 168translate_message2(unwind(Term)) --> 169 unwind_message(Term). 170translate_message2(message_lines(Lines), L, T) :- % deal with old C-warning() 171 make_message_lines(Lines, L, T). 172translate_message2(format(Fmt, Args)) --> 173 [ Fmt-Args ]. 174 175make_message_lines([], T, T) :- !. 176make_message_lines([Last], ['~w'-[Last]|T], T) :- !. 177make_message_lines([L0|LT], ['~w'-[L0],nl|T0], T) :- 178 make_message_lines(LT, T0, T).
error(Format, ImplDefined)
exception terms. The ImplDefined argument is handled by
swi_location//2.186:- public term_message//1. 187term_message(Term) --> 188 {var(Term)}, 189 !, 190 [ 'Unknown error term: ~p'-[Term] ]. 191term_message(Term) --> 192 { message_lang(Lang) }, 193 prolog:error_message(Lang, Term), 194 !. 195term_message(Term) --> 196 prolog:error_message(Term), 197 !. 198term_message(Term) --> 199 iso_message(Term). 200term_message(Term) --> 201 swi_message(Term). 202term_message(Term) --> 203 [ 'Unknown error term: ~p'-[Term] ]. 204 205iso_message(resource_error(c_stack)) --> 206 out_of_c_stack. 207iso_message(resource_error(Missing)) --> 208 [ 'Not enough resources: ~w'-[Missing] ]. 209iso_message(type_error(Var, Actual)) --> 210 { var(Var) }, 211 [ 'Type error: unbound (var) type expected, found `~p'''-[Actual] ]. 212iso_message(type_error(evaluable, Actual)) --> 213 { callable(Actual) }, 214 [ 'Arithmetic: `~p'' is not a function'-[Actual] ]. 215iso_message(type_error(free_of_attvar, Actual)) --> 216 [ 'Type error: `~W'' contains attributed variables'- 217 [Actual,[portray(true), attributes(portray)]] ]. 218iso_message(type_error(Expected, Actual)) --> 219 [ 'Type error: `~w'' expected, found `~p'''-[Expected, Actual] ], 220 type_error_comment(Expected, Actual). 221iso_message(domain_error(Domain, Actual)) --> 222 [ 'Domain error: '-[] ], domain(Domain), 223 [ ' expected, found `~p'''-[Actual] ]. 224iso_message(instantiation_error) --> 225 [ 'Arguments are not sufficiently instantiated' ]. 226iso_message(uninstantiation_error(Var)) --> 227 [ 'Uninstantiated argument expected, found ~p'-[Var] ]. 228iso_message(representation_error(What)) --> 229 [ 'Cannot represent due to `~w'''-[What] ]. 230iso_message(permission_error(Action, Type, Object)) --> 231 permission_error(Action, Type, Object). 232iso_message(evaluation_error(Which)) --> 233 [ 'Arithmetic: evaluation error: `~p'''-[Which] ]. 234iso_message(existence_error(procedure, Proc)) --> 235 [ 'Unknown procedure: ' ], 236 predicate_reference(Proc), 237 unknown_proc_msg(Proc). 238iso_message(existence_error(answer_variable, Var)) --> 239 [ '$~w was not bound by a previous query'-[Var] ]. 240iso_message(existence_error(matching_rule, Goal)) --> 241 [ 'No rule matches ~p'-[Goal] ]. 242iso_message(existence_error(Type, Object)) --> 243 [ '~w `~p'' does not exist'-[Type, Object] ]. 244iso_message(existence_error(export, PI, module(M))) --> % not ISO 245 [ 'Module ', ansi(code, '~q', [M]), ' does not export ' ], 246 predicate_reference(M:PI, [module(hide)]). 247iso_message(existence_error(Type, Object, In)) --> % not ISO 248 [ '~w `~p'' does not exist in ~p'-[Type, Object, In] ]. 249iso_message(busy(Type, Object)) --> 250 [ '~w `~p'' is busy'-[Type, Object] ]. 251iso_message(syntax_error(swi_backslash_newline)) --> 252 [ 'Deprecated: ... \\<newline><white>*. Use \\c' ]. 253iso_message(syntax_error(warning_var_tag)) --> 254 [ 'Deprecated: dict with unbound tag (_{...}). Mapped to #{...}.' ]. 255iso_message(syntax_error(var_tag)) --> 256 [ 'Syntax error: dict syntax with unbound tag (_{...}).' ]. 257iso_message(syntax_error(Id)) --> 258 [ 'Syntax error: ' ], 259 syntax_error(Id). 260iso_message(occurs_check(Var, In)) --> 261 [ 'Cannot unify ~p with ~p: would create an infinite tree'-[Var, In] ].
268permission_error(Action, built_in_procedure, Pred) --> 269 [ 'No permission to ~w built-in predicate '-[Action] ], 270 predicate_reference(Pred), 271 ( {Action \== export} 272 -> [ nl, 273 'Use :- redefine_system_predicate(+Head) if redefinition is intended' 274 ] 275 ; [] 276 ). 277permission_error(import_into(Dest), procedure, Pred) --> 278 [ 'No permission to import ' ], 279 predicate_reference(Pred), 280 [ ' into ~w'-[Dest] ]. 281permission_error(Action, static_procedure, Proc) --> 282 [ 'No permission to ~w static procedure '-[Action] ], 283 predicate_reference(Proc), 284 predicate_definition(Proc, 'Defined'). 285permission_error(input, stream, Stream) --> 286 [ 'No permission to read from output stream `~p'''-[Stream] ]. 287permission_error(output, stream, Stream) --> 288 [ 'No permission to write to input stream `~p'''-[Stream] ]. 289permission_error(input, text_stream, Stream) --> 290 [ 'No permission to read bytes from TEXT stream `~p'''-[Stream] ]. 291permission_error(output, text_stream, Stream) --> 292 [ 'No permission to write bytes to TEXT stream `~p'''-[Stream] ]. 293permission_error(input, binary_stream, Stream) --> 294 [ 'No permission to read characters from binary stream `~p'''-[Stream] ]. 295permission_error(output, binary_stream, Stream) --> 296 [ 'No permission to write characters to binary stream `~p'''-[Stream] ]. 297permission_error(open, source_sink, alias(Alias)) --> 298 [ 'No permission to reuse alias "~p": already taken'-[Alias] ]. 299permission_error(tnot, non_tabled_procedure, Pred) --> 300 [ 'The argument of ' ], predicate_reference(tnot/1), 301 [ ' is not tabled: ' ], predicate_reference(Pred). 302permission_error(assert, procedure, Pred) --> 303 { predicate_head(Pred, Head), 304 predicate_property(Head, ssu) 305 }, 306 predicate_reference(Pred), 307 [ ': an SSU (Head => Body) predicate cannot have normal Prolog clauses' ]. 308permission_error(Action, Type, Object) --> 309 [ 'No permission to ~w ~w `~p'''-[Action, Type, Object] ]. 310 311 312unknown_proc_msg(_:(^)/2) --> 313 !, 314 unknown_proc_msg((^)/2). 315unknown_proc_msg((^)/2) --> 316 !, 317 [nl, ' ^/2 can only appear as the 2nd argument of setof/3 and bagof/3']. 318unknown_proc_msg((:-)/2) --> 319 !, 320 [nl, ' Rules must be loaded from a file'], 321 faq('ToplevelMode'). 322unknown_proc_msg((=>)/2) --> 323 !, 324 [nl, ' Rules must be loaded from a file'], 325 faq('ToplevelMode'). 326unknown_proc_msg((:-)/1) --> 327 !, 328 [nl, ' Directives must be loaded from a file'], 329 faq('ToplevelMode'). 330unknown_proc_msg((?-)/1) --> 331 !, 332 [nl, ' ?- is the Prolog prompt'], 333 faq('ToplevelMode'). 334unknown_proc_msg(Proc) --> 335 { dwim_predicates(Proc, Dwims) }, 336 ( {Dwims \== []} 337 -> [nl, ' However, there are definitions for:', nl], 338 dwim_alternatives(Dwims) 339 ; [] 340 ). 341 342dependency_error(shared(Shared), private(Private)) --> 343 [ 'Shared table for ' ], predicate_reference(Shared), 344 [ ' may not depend on private ' ], predicate_reference(Private). 345dependency_error(Dep, monotonic(On)) --> 346 [ 'Dependent ' ], predicate_reference(Dep), 347 [ ' on monotonic predicate ' ], predicate_reference(On), 348 [ ' is not monotonic or incremental' ]. 349 350faq(Page) --> 351 [nl, ' See FAQ at https://www.swi-prolog.org/FAQ/', Page, '.html' ]. 352 353type_error_comment(_Expected, Actual) --> 354 { type_of(Actual, Type), 355 ( sub_atom(Type, 0, 1, _, First), 356 memberchk(First, [a,e,i,o,u]) 357 -> Article = an 358 ; Article = a 359 ) 360 }, 361 [ ' (~w ~w)'-[Article, Type] ]. 362 363type_of(Term, Type) :- 364 ( attvar(Term) -> Type = attvar 365 ; var(Term) -> Type = var 366 ; atom(Term) -> Type = atom 367 ; integer(Term) -> Type = integer 368 ; string(Term) -> Type = string 369 ; Term == [] -> Type = empty_list 370 ; blob(Term, BlobT) -> blob_type(BlobT, Type) 371 ; rational(Term) -> Type = rational 372 ; float(Term) -> Type = float 373 ; is_stream(Term) -> Type = stream 374 ; is_dict(Term) -> Type = dict 375 ; is_list(Term) -> Type = list 376 ; Term = [_|_] -> list_like(Term, Type) 377 ; cyclic_term(Term) -> Type = cyclic 378 ; compound(Term) -> Type = compound 379 ; Type = unknown 380 ). 381 382list_like(Term, Type) :- 383 '$skip_list'(_, Term, Tail), 384 ( var(Tail) 385 -> Type = partial_list 386 ; Type = invalid_list % TBD: Better name? 387 ). 388 389blob_type(BlobT, Type) :- 390 atom_concat(BlobT, '_reference', Type). 391 392syntax_error(end_of_clause) --> 393 [ 'Unexpected end of clause' ]. 394syntax_error(end_of_clause_expected) --> 395 [ 'End of clause expected' ]. 396syntax_error(end_of_file) --> 397 [ 'Unexpected end of file' ]. 398syntax_error(end_of_file_in_block_comment) --> 399 [ 'End of file in /* ... */ comment' ]. 400syntax_error(end_of_file_in_quoted(Quote)) --> 401 [ 'End of file in quoted ' ], 402 quoted_type(Quote). 403syntax_error(illegal_number) --> 404 [ 'Illegal number' ]. 405syntax_error(long_atom) --> 406 [ 'Atom too long (see style_check/1)' ]. 407syntax_error(long_string) --> 408 [ 'String too long (see style_check/1)' ]. 409syntax_error(operator_clash) --> 410 [ 'Operator priority clash' ]. 411syntax_error(operator_expected) --> 412 [ 'Operator expected' ]. 413syntax_error(operator_balance) --> 414 [ 'Unbalanced operator' ]. 415syntax_error(quoted_punctuation) --> 416 [ 'Operand expected, unquoted comma or bar found' ]. 417syntax_error(list_rest) --> 418 [ 'Unexpected comma or bar in rest of list' ]. 419syntax_error(cannot_start_term) --> 420 [ 'Illegal start of term' ]. 421syntax_error(punct(Punct, End)) --> 422 [ 'Unexpected `~w\' before `~w\''-[Punct, End] ]. 423syntax_error(undefined_char_escape(C)) --> 424 [ 'Unknown character escape in quoted atom or string: `\\~w\''-[C] ]. 425syntax_error(void_not_allowed) --> 426 [ 'Empty argument list "()"' ]. 427syntax_error(Term) --> 428 { compound(Term), 429 compound_name_arguments(Term, Syntax, [Text]) 430 }, !, 431 [ '~w expected, found '-[Syntax], ansi(code, '"~w"', [Text]) ]. 432syntax_error(Message) --> 433 [ '~w'-[Message] ]. 434 435quoted_type('\'') --> [atom]. 436quoted_type('\"') --> { current_prolog_flag(double_quotes, Type) }, [Type-[]]. 437quoted_type('\`') --> { current_prolog_flag(back_quotes, Type) }, [Type-[]]. 438 439domain(range(Low,High)) --> 440 !, 441 ['[~q..~q]'-[Low,High] ]. 442domain(Domain) --> 443 ['`~w\''-[Domain] ].
450tabling_existence_error(Ball, Context) --> 451 { table_shift_ball(Ball) }, 452 [ 'Tabling dependency error' ], 453 swi_extra(Context). 454 455table_shift_ball(dependency(_Head)). 456table_shift_ball(dependency(_Skeleton, _Trie, _Mono)). 457table_shift_ball(call_info(_Skeleton, _Status)). 458table_shift_ball(call_info(_GenSkeleton, _Skeleton, _Status)).
464dwim_predicates(Module:Name/_Arity, Dwims) :- 465 !, 466 findall(Dwim, dwim_predicate(Module:Name, Dwim), Dwims). 467dwim_predicates(Name/_Arity, Dwims) :- 468 findall(Dwim, dwim_predicate(user:Name, Dwim), Dwims). 469 470dwim_alternatives([]) --> []. 471dwim_alternatives([H|T]) --> 472 [ ' ' ], 473 predicate_reference(H, [tag(true)]), 474 [ nl ], 475 dwim_alternatives(T). 476 477swi_message(io_error(Op, Stream)) --> 478 [ 'I/O error in ~w on stream ~p'-[Op, Stream] ]. 479swi_message(thread_error(TID, false)) --> 480 [ 'Thread ~p died due to failure:'-[TID] ]. 481swi_message(thread_error(TID, exception(Error))) --> 482 [ 'Thread ~p died abnormally:'-[TID], nl ], 483 translate_message(Error). 484swi_message(dependency_error(Tabled, DependsOn)) --> 485 dependency_error(Tabled, DependsOn). 486swi_message(shell(execute, Cmd)) --> 487 [ 'Could not execute `~w'''-[Cmd] ]. 488swi_message(shell(signal(Sig), Cmd)) --> 489 [ 'Caught signal ~d on `~w'''-[Sig, Cmd] ]. 490swi_message(format(Fmt, Args)) --> 491 [ Fmt-Args ]. 492swi_message(signal(Name, Num)) --> 493 [ 'Caught signal ~d (~w)'-[Num, Name] ]. 494swi_message(limit_exceeded(Limit, MaxVal)) --> 495 [ 'Exceeded ~w limit (~w)'-[Limit, MaxVal] ]. 496swi_message(goal_failed(Goal)) --> 497 [ 'goal unexpectedly failed: ~p'-[Goal] ]. 498swi_message(shared_object(_Action, Message)) --> % Message = dlerror() 499 [ '~w'-[Message] ]. 500swi_message(system_error(Error)) --> 501 [ 'error in system call: ~w'-[Error] 502 ]. 503swi_message(system_error) --> 504 [ 'error in system call' 505 ]. 506swi_message(failure_error(Goal)) --> 507 [ 'Goal failed: ~p'-[Goal] ]. 508swi_message(timeout_error(Op, Stream)) --> 509 [ 'Timeout in ~w from ~p'-[Op, Stream] ]. 510swi_message(not_implemented(Type, What)) --> 511 [ '~w `~p\' is not implemented in this version'-[Type, What] ]. 512swi_message(context_error(nodirective, Goal)) --> 513 [ 'Wrong context: ' ], predicate_reference(Goal), 514 [ ' can only be used in a directive' ]. 515swi_message(context_error(edit, no_default_file)) --> 516 ( { current_prolog_flag(windows, true) } 517 -> [ 'Edit/0 can only be used after opening a \c 518 Prolog file by double-clicking it' ] 519 ; [ 'Edit/0 can only be used with the "-s file" commandline option' 520 ] 521 ), 522 [ nl, 'Use "?- edit(Topic)." or "?- emacs."' ]. 523swi_message(context_error(function, meta_arg(S))) --> 524 [ 'Functions are not (yet) supported for meta-arguments of type ~q'-[S] ]. 525swi_message(format_argument_type(Fmt, Arg)) --> 526 [ 'Illegal argument to format sequence ~~~w: ~p'-[Fmt, Arg] ]. 527swi_message(format(Msg)) --> 528 [ 'Format error: ~w'-[Msg] ]. 529swi_message(conditional_compilation_error(unterminated, File:Line)) --> 530 [ 'Unterminated conditional compilation from '-[], url(File:Line) ]. 531swi_message(conditional_compilation_error(no_if, What)) --> 532 [ ':- ~w without :- if'-[What] ]. 533swi_message(duplicate_key(Key)) --> 534 [ 'Duplicate key: ~p'-[Key] ]. 535swi_message(determinism_error(PI, det, Found, property)) --> 536 ( { predicate_head(PI, Head), 537 predicate_property(Head, det) 538 } 539 -> [ 'Deterministic procedure ' ], predicate_reference(PI) 540 ; [ 'Procedure ' ], predicate_reference(PI), 541 [ ' called from a deterministic procedure' ] 542 ), 543 det_error(Found). 544swi_message(determinism_error(PI, det, fail, guard)) --> 545 [ 'Procedure ' ], predicate_reference(PI), 546 [ ' failed after $-guard' ]. 547swi_message(determinism_error(PI, det, fail, guard_in_caller)) --> 548 [ 'Procedure ' ], predicate_reference(PI), 549 [ ' failed after $-guard in caller' ]. 550swi_message(determinism_error(Goal, det, fail, goal)) --> 551 [ 'Goal ~p failed'-[Goal] ]. 552swi_message(determinism_error(Goal, det, nondet, goal)) --> 553 [ 'Goal ~p succeeded with a choice point'-[Goal] ]. 554swi_message(qlf_format_error(File, Message)) --> 555 [ '~w: Invalid QLF file: ~w'-[File, Message] ]. 556swi_message(goal_expansion_error(bound, Term)) --> 557 [ 'Goal expansion bound a variable to ~p'-[Term] ]. 558 559det_error(nondet) --> 560 [ ' succeeded with a choicepoint'- [] ]. 561det_error(fail) --> 562 [ ' failed'- [] ].
error(Formal, ImplDefined) from the
ImplDefined term.570:- public swi_location//1. 571swi_location(X) --> 572 { var(X) }, 573 !. 574swi_location(Context) --> 575 { message_lang(Lang) }, 576 prolog:message_location(Lang, Context), 577 !. 578swi_location(Context) --> 579 prolog:message_location(Context), 580 !. 581swi_location(context(Caller, _Msg)) --> 582 { ground(Caller) }, 583 !, 584 caller(Caller). 585swi_location(file(Path, Line, -1, _CharNo)) --> 586 !, 587 [ url(Path:Line), ': ' ]. 588swi_location(file(Path, Line, LinePos, _CharNo)) --> 589 { Column is LinePos+1 }, % line_position is 0-based 590 [ url(Path:Line:Column), ': ' ]. 591swi_location(stream(Stream, Line, LinePos, CharNo)) --> 592 ( { is_stream(Stream), 593 stream_property(Stream, file_name(File)) 594 } 595 -> swi_location(file(File, Line, LinePos, CharNo)) 596 ; { Column is LinePos+1 }, 597 [ 'Stream ~w:~d:~d '-[Stream, Line, Column] ] 598 ). 599swi_location(autoload(File:Line)) --> 600 [ url(File:Line), ': ' ]. 601swi_location(_) --> 602 []. 603 604caller(system:'$record_clause'/3) --> 605 !, 606 []. 607caller(Caller) --> 608 { predicate_indicator(Caller, _) }, 609 !, 610 predicate_reference(Caller, [link(false)]), 611 [ ': ' ]. 612caller(Caller) --> 613 [ '~p: '-[Caller] ].
error(Formal,
ImplDefined) that is printed after the core of the message.
624swi_extra(X) --> 625 { var(X) }, 626 !, 627 []. 628swi_extra(Context) --> 629 { message_lang(Lang) }, 630 prolog:message_context(Lang, Context), 631 !. 632swi_extra(Context) --> 633 prolog:message_context(Context). 634swi_extra(context(_, Msg)) --> 635 { nonvar(Msg), 636 Msg \== '' 637 }, 638 !, 639 swi_comment(Msg). 640swi_extra(string(String, CharPos)) --> 641 { sub_string(String, 0, CharPos, _, Before), 642 sub_string(String, CharPos, _, 0, After) 643 }, 644 [ nl, '~w'-[Before], nl, '** here **', nl, '~w'-[After] ]. 645swi_extra(_) --> 646 []. 647 648swi_comment(already_from(Module)) --> 649 !, 650 [ ' (already imported from ~q)'-[Module] ]. 651swi_comment(directory(_Dir)) --> 652 !, 653 [ ' (is a directory)' ]. 654swi_comment(not_a_directory(_Dir)) --> 655 !, 656 [ ' (is not a directory)' ]. 657swi_comment(Msg) --> 658 [ ' (~w)'-[Msg] ]. 659 660 661thread_context --> 662 { \+ current_prolog_flag(toplevel_thread, true), 663 thread_self(Id) 664 }, 665 !, 666 ['[Thread ~w] '-[Id]]. 667thread_context --> 668 []. 669 670 /******************************* 671 * UNWIND MESSAGES * 672 *******************************/ 673 674unwind_message(Var) --> 675 { var(Var) }, !, 676 [ 'Unknown unwind message: ~p'-[Var] ]. 677unwind_message(abort) --> 678 [ 'Execution Aborted' ]. 679unwind_message(halt(_)) --> 680 []. 681unwind_message(thread_exit(Term)) --> 682 [ 'Invalid thread_exit/1. Payload: ~p'-[Term] ]. 683unwind_message(Term) --> 684 [ 'Unknown "unwind" exception: ~p'-[Term] ]. 685 686 687 /******************************* 688 * NORMAL MESSAGES * 689 *******************************/ 690 691:- dynamic prolog:version_msg/1. 692:- multifile prolog:version_msg/1. 693 694prolog_message(welcome) --> 695 [ 'Welcome to SWI-Prolog (' ], 696 prolog_message(threads), 697 prolog_message(address_bits), 698 ['version ' ], 699 prolog_message(version), 700 [ ')', nl ], 701 prolog_message(copyright), 702 [ nl ], 703 translate_message(user_versions), 704 [ nl ], 705 prolog_message(documentaton), 706 [ nl, nl ]. 707prolog_message(user_versions) --> 708 ( { findall(Msg, prolog:version_msg(Msg), Msgs), 709 Msgs \== [] 710 } 711 -> [nl], 712 user_version_messages(Msgs) 713 ; [] 714 ). 715prolog_message(deprecated(Term)) --> 716 { nonvar(Term) }, 717 ( { message_lang(Lang) }, 718 prolog:deprecated(Lang, Term) 719 -> [] 720 ; prolog:deprecated(Term) 721 -> [] 722 ; deprecated(Term) 723 ). 724prolog_message(unhandled_exception(E)) --> 725 { nonvar(E) }, 726 [ 'Unhandled exception: ' ], 727 ( translate_message(E) 728 -> [] 729 ; [ '~p'-[E] ] 730 ).
734prolog_message(initialization_error(_, E, File:Line)) --> 735 !, 736 [ url(File:Line), 737 ': Initialization goal raised exception:', nl 738 ], 739 translate_message(E). 740prolog_message(initialization_error(Goal, E, _)) --> 741 [ 'Initialization goal ~p raised exception:'-[Goal], nl ], 742 translate_message(E). 743prolog_message(initialization_failure(_Goal, File:Line)) --> 744 !, 745 [ url(File:Line), 746 ': Initialization goal failed'-[] 747 ]. 748prolog_message(initialization_failure(Goal, _)) --> 749 [ 'Initialization goal failed: ~p'-[Goal] 750 ]. 751prolog_message(initialization_exception(E)) --> 752 [ 'Prolog initialisation failed:', nl ], 753 translate_message(E). 754prolog_message(initialization(halt(Status), Goal, File:Line)) --> 755 [ url(File:Line), ': '], goal(Goal), [nl, 756 ' Initialization goal called ', ansi(code, '~p', [halt(Status)]), 757 '.', nl, 758 ' The program entry point should be called using ', 759 ansi(code, 'initialization/2', []), '.', nl, 760 ' Consider using ', ansi(code, 'library(main)', []), '.' 761 ]. 762prolog_message(init_goal_syntax(Error, Text)) --> 763 !, 764 [ '-g ~w: '-[Text] ], 765 translate_message(Error). 766prolog_message(init_goal_failed(failed, @(Goal,File:Line))) --> 767 !, 768 [ url(File:Line), ': ~p: false'-[Goal] ]. 769prolog_message(init_goal_failed(Error, @(Goal,File:Line))) --> 770 !, 771 [ url(File:Line), ': ~p '-[Goal] ], 772 translate_message(Error). 773prolog_message(init_goal_failed(failed, Text)) --> 774 !, 775 [ '-g ~w: false'-[Text] ]. 776prolog_message(init_goal_failed(Error, Text)) --> 777 !, 778 [ '-g ~w: '-[Text] ], 779 translate_message(Error). 780prolog_message(goal_failed(Context, Goal)) --> 781 [ 'Goal (~w) failed: ~p'-[Context, Goal] ]. 782prolog_message(no_current_module(Module)) --> 783 [ '~w is not a current module (created)'-[Module] ]. 784prolog_message(commandline_arg_type(Flag, Arg)) --> 785 [ 'Bad argument to commandline option -~w: ~w'-[Flag, Arg] ]. 786prolog_message(missing_feature(Name)) --> 787 [ 'This version of SWI-Prolog does not support ~w'-[Name] ]. 788prolog_message(singletons(_Term, List)) --> 789 [ 'Singleton variables: ~w'-[List] ]. 790prolog_message(multitons(_Term, List)) --> 791 [ 'Singleton-marked variables appearing more than once: ~w'-[List] ]. 792prolog_message(profile_no_cpu_time) --> 793 [ 'No CPU-time info. Check the SWI-Prolog manual for details' ]. 794prolog_message(non_ascii(Text, Type)) --> 795 [ 'Unquoted ~w with non-portable characters: ~w'-[Type, Text] ]. 796prolog_message(io_warning(Stream, Message)) --> 797 { stream_property(Stream, position(Position)), 798 !, 799 stream_position_data(line_count, Position, LineNo), 800 stream_position_data(line_position, Position, LinePos), 801 Column is LinePos+1 % line_position is 0-based 802 }, 803 ( { stream_property(Stream, file_name(File)) } 804 -> [ url(File:LineNo:Column) ] 805 ; [ '~p:~d:~d'-[Stream, LineNo, Column] ] 806 ), 807 [ ': ~w'-[Message] ]. 808prolog_message(io_warning(Stream, Message)) --> 809 [ 'stream ~p: ~w'-[Stream, Message] ]. 810prolog_message(option_usage(pldoc)) --> 811 [ 'Usage: --pldoc[=port]' ]. 812prolog_message(interrupt(begin)) --> 813 [ 'Action (h for help) ? ', flush ]. 814prolog_message(interrupt(end)) --> 815 [ 'continue' ]. 816prolog_message(interrupt(trace)) --> 817 [ 'continue (trace mode)' ]. 818prolog_message(unknown_in_module_user) --> 819 [ 'Using a non-error value for unknown in the global module', nl, 820 'causes most of the development environment to stop working.', nl, 821 'Please use :- dynamic or limit usage of unknown to a module.', nl, 822 'See https://www.swi-prolog.org/howto/database.html' 823 ]. 824prolog_message(untable(PI)) --> 825 [ 'Reconsult: removed tabling for ' ], predicate_reference(PI). 826prolog_message(unknown_option(Set, Opt)) --> 827 [ 'Unknown ~w option: ~p'-[Set, Opt] ]. 828 829 830 /******************************* 831 * LOADING FILES * 832 *******************************/ 833 834prolog_message(modify_active_procedure(Who, What)) --> 835 predicate_reference(Who), 836 [ ': modified active procedure ' ], 837 predicate_reference(What). 838prolog_message(load_file(failed(user:File))) --> 839 [ 'Failed to load ~p'-[File] ]. 840prolog_message(load_file(failed(Module:File))) --> 841 [ 'Failed to load ~p into module ~p'-[File, Module] ]. 842prolog_message(load_file(failed(File))) --> 843 [ 'Failed to load ~p'-[File] ]. 844prolog_message(mixed_directive(Goal)) --> 845 [ 'Cannot pre-compile mixed load/call directive: ~p'-[Goal] ]. 846prolog_message(cannot_redefine_comma) --> 847 [ 'Full stop in clause-body? Cannot redefine ,/2' ]. 848prolog_message(illegal_autoload_index(Dir, Term)) --> 849 [ 'Illegal term in INDEX file of directory ~w: ~w'-[Dir, Term] ]. 850prolog_message(redefined_procedure(Type, Proc)) --> 851 [ 'Redefined ~w procedure '-[Type] ], 852 predicate_reference(Proc), 853 predicate_definition(Proc, 'Previously defined'). 854prolog_message(declare_module(Module, abolish(Predicates))) --> 855 [ 'Loading module ~w abolished:'-[Module], nl ], 856 predicate_list(Predicates). 857prolog_message(import_private(Module, Private)) --> 858 [ 'import/1: ' ], predicate_reference(Private), 859 [ ' is not exported (still imported into ~q)'-[Module] ]. 860prolog_message(ignored_weak_import(Into, From:PI)) --> 861 [ 'Local definition of ' ], 862 predicate_reference(Into:PI, [module(show)]), 863 [ ' overrides weak import from ~q'-[From] ]. 864prolog_message(undefined_export(Module, PI)) --> 865 [ 'Exported procedure ' ], 866 predicate_reference(Module:PI, [module(show)]), 867 [ ' is not defined' ]. 868prolog_message(no_exported_op(Module, Op)) --> 869 [ 'Operator ~q:~q is not exported (still defined)'-[Module, Op] ]. 870prolog_message(discontiguous((-)/2,_)) --> 871 prolog_message(minus_in_identifier). 872prolog_message(discontiguous(Proc,Current)) --> 873 [ 'Clauses of ' ], predicate_reference(Proc), 874 [ ' are not together in the source-file' ], 875 predicate_definition(Proc, 'Earlier definition'), 876 [ nl, 'Current predicate: ' ], predicate_reference(Current), 877 [ nl, 'Use ', ansi(code, ':- discontiguous ~p.', [Proc]), 878 ' to suppress this message' 879 ]. 880prolog_message(decl_no_effect(Goal)) --> 881 [ 'Deprecated declaration has no effect: ~p'-[Goal] ]. 882prolog_message(load_file(start(Level, File))) --> 883 [ '~|~t~*+Loading '-[Level] ], 884 load_file(File), 885 [ ' ...' ]. 886prolog_message(include_file(start(Level, File))) --> 887 [ '~|~t~*+include '-[Level] ], 888 load_file(File), 889 [ ' ...' ]. 890prolog_message(include_file(done(Level, File))) --> 891 [ '~|~t~*+included '-[Level] ], 892 load_file(File). 893prolog_message(load_file(done(Level, File, Action, Module, Time, Clauses))) --> 894 [ '~|~t~*+'-[Level] ], 895 load_file(File), 896 [ ' ~w'-[Action] ], 897 load_module(Module), 898 [ ' ~2f sec, ~D clauses'-[Time, Clauses] ]. 899prolog_message(dwim_undefined(Goal, Alternatives)) --> 900 [ 'Unknown procedure: ' ], 901 predicate_reference(Goal), 902 [ nl, ' However, there are definitions for:', nl ], 903 dwim_alternatives(Alternatives). 904prolog_message(dwim_correct(Into)) --> 905 [ ansi(warning, 'Correct to: ', []), ansi(code, '~q', [Into]), 906 ansi(warning, '? ', []), flush 907 ]. 908prolog_message(error(loop_error(Spec), file_search(Used))) --> 909 [ 'File search: too many levels of indirections on: ~p'-[Spec], nl, 910 ' Used alias expansions:', nl 911 ], 912 used_search(Used). 913prolog_message(minus_in_identifier) --> 914 [ 'The "-" character should not be used to separate words in an', nl, 915 'identifier. Check the SWI-Prolog FAQ for details.' 916 ]. 917prolog_message(qlf(removed_after_error(File))) --> 918 [ 'Removed incomplete QLF file ~w'-[File] ]. 919prolog_message(qlf(recompile(Spec,_Pl,_Qlf,Reason))) --> 920 [ '~p: recompiling QLF file'-[Spec] ], 921 qlf_recompile_reason(Reason). 922prolog_message(qlf(can_not_recompile(Spec,QlfFile,_Reason))) --> 923 [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl, 924 '\tLoading from source'-[] 925 ]. 926prolog_message(qlf(system_lib_out_of_date(Spec,QlfFile))) --> 927 [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl, 928 '\tLoading QlfFile'-[] 929 ]. 930prolog_message(redefine_module(Module, OldFile, File)) --> 931 [ 'Module "~q" already loaded from ~w.'-[Module, OldFile], nl, 932 'Wipe and reload from ~w? '-[File], flush 933 ]. 934prolog_message(redefine_module_reply) --> 935 [ 'Please answer y(es), n(o) or a(bort)' ]. 936prolog_message(reloaded_in_module(Absolute, OldContext, LM)) --> 937 [ '~w was previously loaded in module ~w'-[Absolute, OldContext], nl, 938 '\tnow it is reloaded into module ~w'-[LM] ]. 939prolog_message(expected_layout(Expected, Pos)) --> 940 [ 'Layout data: expected ~w, found: ~p'-[Expected, Pos] ]. 941 942used_search([]) --> 943 []. 944used_search([Alias=Expanded|T]) --> 945 [ ' file_search_path(~p, ~p)'-[Alias, Expanded], nl ], 946 used_search(T). 947 948load_file(file(Spec, _Path)) --> 949 ( {atomic(Spec)} 950 -> [ '~w'-[Spec] ] 951 ; [ '~p'-[Spec] ] 952 ). 953%load_file(file(_, Path)) --> 954% [ '~w'-[Path] ]. 955 956load_module(user) --> !. 957load_module(system) --> !. 958load_module(Module) --> 959 [ ' into ~w'-[Module] ].
967user_predicate_indicator(Module:PI, PI) :- 968 hidden_module(Module), 969 !. 970user_predicate_indicator(PI, PI). 971 (user) :- !. 973hidden_module(system) :- !. 974hidden_module(M) :- 975 sub_atom(M, 0, _, _, $). 976 977qlf_recompile_reason(old) --> 978 !, 979 [ ' (out of date)'-[] ]. 980qlf_recompile_reason(_) --> 981 [ ' (incompatible with current Prolog version)'-[] ]. 982 983prolog_message(file_search(cache(Spec, _Cond), Path)) --> 984 [ 'File search: ~p --> ~p (cache)'-[Spec, Path] ]. 985prolog_message(file_search(found(Spec, Cond), Path)) --> 986 [ 'File search: ~p --> ~p OK ~p'-[Spec, Path, Cond] ]. 987prolog_message(file_search(tried(Spec, Cond), Path)) --> 988 [ 'File search: ~p --> ~p NO ~p'-[Spec, Path, Cond] ]. 989 990 /******************************* 991 * GC * 992 *******************************/ 993 994prolog_message(agc(start)) --> 995 thread_context, 996 [ 'AGC: ', flush ]. 997prolog_message(agc(done(Collected, Remaining, Time))) --> 998 [ at_same_line, 999 'reclaimed ~D atoms in ~3f sec. (remaining: ~D)'- 1000 [Collected, Time, Remaining] 1001 ]. 1002prolog_message(cgc(start)) --> 1003 thread_context, 1004 [ 'CGC: ', flush ]. 1005prolog_message(cgc(done(CollectedClauses, _CollectedBytes, 1006 RemainingBytes, Time))) --> 1007 [ at_same_line, 1008 'reclaimed ~D clauses in ~3f sec. (pending: ~D bytes)'- 1009 [CollectedClauses, Time, RemainingBytes] 1010 ]. 1011 1012 /******************************* 1013 * STACK OVERFLOW * 1014 *******************************/ 1015 1016out_of_stack(Context) --> 1017 { human_stack_size(Context.localused, Local), 1018 human_stack_size(Context.globalused, Global), 1019 human_stack_size(Context.trailused, Trail), 1020 human_stack_size(Context.stack_limit, Limit), 1021 LCO is (100*(Context.depth - Context.environments))/Context.depth 1022 }, 1023 [ 'Stack limit (~s) exceeded'-[Limit], nl, 1024 ' Stack sizes: local: ~s, global: ~s, trail: ~s'-[Local,Global,Trail], nl, 1025 ' Stack depth: ~D, last-call: ~0f%, Choice points: ~D'- 1026 [Context.depth, LCO, Context.choicepoints], nl 1027 ], 1028 overflow_reason(Context, Resolve), 1029 resolve_overflow(Resolve). 1030 1031human_stack_size(Size, String) :- 1032 Size < 100, 1033 format(string(String), '~dKb', [Size]). 1034human_stack_size(Size, String) :- 1035 Size < 100 000, 1036 Value is Size / 1024, 1037 format(string(String), '~1fMb', [Value]). 1038human_stack_size(Size, String) :- 1039 Value is Size / (1024*1024), 1040 format(string(String), '~1fGb', [Value]). 1041 1042overflow_reason(Context, fix) --> 1043 show_non_termination(Context), 1044 !. 1045overflow_reason(Context, enlarge) --> 1046 { Stack = Context.get(stack) }, 1047 !, 1048 [ ' In:'-[], nl ], 1049 stack(Stack). 1050overflow_reason(_Context, enlarge) --> 1051 [ ' Insufficient global stack'-[] ]. 1052 1053show_non_termination(Context) --> 1054 ( { Stack = Context.get(cycle) } 1055 -> [ ' Probable infinite recursion (cycle):'-[], nl ] 1056 ; { Stack = Context.get(non_terminating) } 1057 -> [ ' Possible non-terminating recursion:'-[], nl ] 1058 ), 1059 stack(Stack). 1060 1061stack([]) --> []. 1062stack([frame(Depth, M:Goal, _)|T]) --> 1063 [ ' [~D] ~q:'-[Depth, M] ], 1064 stack_goal(Goal), 1065 [ nl ], 1066 stack(T). 1067 1068stack_goal(Goal) --> 1069 { compound(Goal), 1070 !, 1071 compound_name_arity(Goal, Name, Arity) 1072 }, 1073 [ '~q('-[Name] ], 1074 stack_goal_args(1, Arity, Goal), 1075 [ ')'-[] ]. 1076stack_goal(Goal) --> 1077 [ '~q'-[Goal] ]. 1078 1079stack_goal_args(I, Arity, Goal) --> 1080 { I =< Arity, 1081 !, 1082 arg(I, Goal, A), 1083 I2 is I + 1 1084 }, 1085 stack_goal_arg(A), 1086 ( { I2 =< Arity } 1087 -> [ ', '-[] ], 1088 stack_goal_args(I2, Arity, Goal) 1089 ; [] 1090 ). 1091stack_goal_args(_, _, _) --> 1092 []. 1093 1094stack_goal_arg(A) --> 1095 { nonvar(A), 1096 A = [Len|T], 1097 ! 1098 }, 1099 ( {Len == cyclic_term} 1100 -> [ '[cyclic list]'-[] ] 1101 ; {T == []} 1102 -> [ '[length:~D]'-[Len] ] 1103 ; [ '[length:~D|~p]'-[Len, T] ] 1104 ). 1105stack_goal_arg(A) --> 1106 { nonvar(A), 1107 A = _/_, 1108 ! 1109 }, 1110 [ '<compound ~p>'-[A] ]. 1111stack_goal_arg(A) --> 1112 [ '~p'-[A] ]. 1113 1114resolve_overflow(fix) --> 1115 []. 1116resolve_overflow(enlarge) --> 1117 { current_prolog_flag(stack_limit, LimitBytes), 1118 NewLimit is LimitBytes * 2 1119 }, 1120 [ nl, 1121 'Use the --stack_limit=size[KMG] command line option or'-[], nl, 1122 '?- set_prolog_flag(stack_limit, ~I). to double the limit.'-[NewLimit] 1123 ].
1130out_of_c_stack --> 1131 { statistics(c_stack, Limit), Limit > 0 }, 1132 !, 1133 [ 'C-stack limit (~D bytes) exceeded.'-[Limit], nl ], 1134 resolve_c_stack_overflow(Limit). 1135out_of_c_stack --> 1136 { statistics(c_stack, Limit), Limit > 0 }, 1137 [ 'C-stack limit exceeded.'-[Limit], nl ], 1138 resolve_c_stack_overflow(Limit). 1139 1140resolve_c_stack_overflow(_Limit) --> 1141 { thread_self(main) }, 1142 [ 'Use the shell command ' ], code('~w', 'ulimit -s size'), 1143 [ ' to enlarge the limit.' ]. 1144resolve_c_stack_overflow(_Limit) --> 1145 [ 'Use the ' ], code('~w', 'c_stack(KBytes)'), 1146 [ ' option of '], code(thread_create/3), [' to enlarge the limit.' ]. 1147 1148 1149 /******************************* 1150 * MAKE/AUTOLOAD * 1151 *******************************/ 1152 1153prolog_message(make(reload(Files))) --> 1154 { length(Files, N) 1155 }, 1156 [ 'Make: reloading ~D files'-[N] ]. 1157prolog_message(make(done(_Files))) --> 1158 [ 'Make: finished' ]. 1159prolog_message(make(library_index(Dir))) --> 1160 [ 'Updating index for library ~w'-[Dir] ]. 1161prolog_message(autoload(Pred, File)) --> 1162 thread_context, 1163 [ 'autoloading ' ], predicate_reference(Pred, [link(false)]), 1164 [ ' from ~w'-[File] ]. 1165prolog_message(autoload(read_index(Dir))) --> 1166 [ 'Loading autoload index for ~w'-[Dir] ]. 1167prolog_message(autoload(disabled(Loaded))) --> 1168 [ 'Disabled autoloading (loaded ~D files)'-[Loaded] ]. 1169prolog_message(autoload(already_defined(PI, From))) --> 1170 predicate_reference(PI), 1171 ( { predicate_head(PI, Head), 1172 predicate_property(Head, built_in) 1173 } 1174 -> [' is a built-in predicate'] 1175 ; [ ' is already imported from module ' ], 1176 code(From) 1177 ). 1178 1179swi_message(autoload(Msg)) --> 1180 [ nl, ' ' ], 1181 autoload_message(Msg). 1182 1183autoload_message(not_exported(PI, Spec, _FullFile, _Exports)) --> 1184 [ ansi(code, '~w', [Spec]), 1185 ' does not export ' 1186 ], 1187 predicate_reference(PI, [link(false)]). 1188autoload_message(no_file(Spec)) --> 1189 [ ansi(code, '~p', [Spec]), ': No such file' ]. 1190 1191 1192 /******************************* 1193 * COMPILER WARNINGS * 1194 *******************************/ 1195 1196% print warnings about dubious code raised by the compiler. 1197% TBD: pass in PC to produce exact error locations. 1198 1199prolog_message(compiler_warnings(Clause, Warnings0)) --> 1200 { print_goal_options(DefOptions), 1201 ( prolog_load_context(variable_names, VarNames) 1202 -> warnings_with_named_vars(Warnings0, VarNames, Warnings), 1203 Options = [variable_names(VarNames)|DefOptions] 1204 ; Options = DefOptions, 1205 Warnings = Warnings0 1206 ) 1207 }, 1208 compiler_warnings(Warnings, Clause, Options). 1209 1210warnings_with_named_vars([], _, []). 1211warnings_with_named_vars([H|T0], VarNames, [H|T]) :- 1212 term_variables(H, Vars), 1213 '$member'(V1, Vars), 1214 '$member'(_=V2, VarNames), 1215 V1 == V2, 1216 !, 1217 warnings_with_named_vars(T0, VarNames, T). 1218warnings_with_named_vars([_|T0], VarNames, T) :- 1219 warnings_with_named_vars(T0, VarNames, T). 1220 1221 1222compiler_warnings([], _, _) --> []. 1223compiler_warnings([H|T], Clause, Options) --> 1224 ( compiler_warning(H, Clause, Options) 1225 -> [] 1226 ; [ 'Unknown compiler warning: ~W'-[H,Options] ] 1227 ), 1228 ( {T==[]} 1229 -> [] 1230 ; [nl] 1231 ), 1232 compiler_warnings(T, Clause, Options). 1233 1234compiler_warning(eq_vv(A,B), _Clause, Options) --> 1235 ( { A == B } 1236 -> [ 'Test is always true: ~W'-[A==B, Options] ] 1237 ; [ 'Test is always false: ~W'-[A==B, Options] ] 1238 ). 1239compiler_warning(eq_singleton(A,B), _Clause, Options) --> 1240 [ 'Test is always false: ~W'-[A==B, Options] ]. 1241compiler_warning(neq_vv(A,B), _Clause, Options) --> 1242 ( { A \== B } 1243 -> [ 'Test is always true: ~W'-[A\==B, Options] ] 1244 ; [ 'Test is always false: ~W'-[A\==B, Options] ] 1245 ). 1246compiler_warning(neq_singleton(A,B), _Clause, Options) --> 1247 [ 'Test is always true: ~W'-[A\==B, Options] ]. 1248compiler_warning(unify_singleton(A,B), _Clause, Options) --> 1249 [ 'Unified variable is not used: ~W'-[A=B, Options] ]. 1250compiler_warning(always(Bool, Pred, Arg), _Clause, Options) --> 1251 { Goal =.. [Pred,Arg] }, 1252 [ 'Test is always ~w: ~W'-[Bool, Goal, Options] ]. 1253compiler_warning(unbalanced_var(V), _Clause, Options) --> 1254 [ 'Variable not introduced in all branches: ~W'-[V, Options] ]. 1255compiler_warning(branch_singleton(V), _Clause, Options) --> 1256 [ 'Singleton variable in branch: ~W'-[V, Options] ]. 1257compiler_warning(negation_singleton(V), _Clause, Options) --> 1258 [ 'Singleton variable in \\+: ~W'-[V, Options] ]. 1259compiler_warning(multiton(V), _Clause, Options) --> 1260 [ 'Singleton-marked variable appears more than once: ~W'-[V, Options] ]. 1261 1262print_goal_options( 1263 [ quoted(true), 1264 portray(true) 1265 ]). 1266 1267 1268 /******************************* 1269 * TOPLEVEL MESSAGES * 1270 *******************************/ 1271 1272prolog_message(version) --> 1273 { current_prolog_flag(version_git, Version) }, 1274 !, 1275 [ '~w'-[Version] ]. 1276prolog_message(version) --> 1277 { current_prolog_flag(version_data, swi(Major,Minor,Patch,Options)) 1278 }, 1279 ( { '$option'(tag(Tag), Options) } 1280 -> [ '~w.~w.~w-~w'-[Major, Minor, Patch, Tag] ] 1281 ; [ '~w.~w.~w'-[Major, Minor, Patch] ] 1282 ). 1283prolog_message(address_bits) --> 1284 { current_prolog_flag(address_bits, Bits) 1285 }, 1286 !, 1287 [ '~d bits, '-[Bits] ]. 1288prolog_message(threads) --> 1289 { current_prolog_flag(threads, true) 1290 }, 1291 !, 1292 [ 'threaded, ' ]. 1293prolog_message(threads) --> 1294 []. 1295prolog_message(copyright) --> 1296 [ 'SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.', nl, 1297 'Please run ', ansi(code, '?- license.', []), ' for legal details.' 1298 ]. 1299prolog_message(documentaton) --> 1300 [ 'For online help and background, visit ', url('https://www.swi-prolog.org') ], 1301 ( { exists_source(library(help)) } 1302 -> [ nl, 1303 'For built-in help, use ', ansi(code, '?- help(Topic).', []), 1304 ' or ', ansi(code, '?- apropos(Word).', []) 1305 ] 1306 ; [] 1307 ). 1308prolog_message(about) --> 1309 [ 'SWI-Prolog version (' ], 1310 prolog_message(threads), 1311 prolog_message(address_bits), 1312 ['version ' ], 1313 prolog_message(version), 1314 [ ')', nl ], 1315 prolog_message(copyright). 1316prolog_message(halt) --> 1317 [ 'halt' ]. 1318prolog_message(break(begin, Level)) --> 1319 [ 'Break level ~d'-[Level] ]. 1320prolog_message(break(end, Level)) --> 1321 [ 'Exit break level ~d'-[Level] ]. 1322prolog_message(var_query(_)) --> 1323 [ '... 1,000,000 ............ 10,000,000 years later', nl, nl, 1324 '~t~8|>> 42 << (last release gives the question)' 1325 ]. 1326prolog_message(close_on_abort(Stream)) --> 1327 [ 'Abort: closed stream ~p'-[Stream] ]. 1328prolog_message(cancel_halt(Reason)) --> 1329 [ 'Halt cancelled: ~p'-[Reason] ]. 1330prolog_message(on_error(halt(Status))) --> 1331 { statistics(errors, Errors), 1332 statistics(warnings, Warnings) 1333 }, 1334 [ 'Halting with status ~w due to ~D errors and ~D warnings'- 1335 [Status, Errors, Warnings] ]. 1336 1337prolog_message(query(QueryResult)) --> 1338 query_result(QueryResult). 1339 1340query_result(no) --> % failure 1341 [ ansi(truth(false), 'false.', []) ], 1342 extra_line. 1343query_result(yes(true, [])) --> % prompt_alternatives_on: groundness 1344 !, 1345 [ ansi(truth(true), 'true.', []) ], 1346 extra_line. 1347query_result(yes(Delays, Residuals)) --> 1348 result([], Delays, Residuals), 1349 extra_line. 1350query_result(done) --> % user typed <CR> 1351 extra_line. 1352query_result(yes(Bindings, Delays, Residuals)) --> 1353 result(Bindings, Delays, Residuals), 1354 prompt(yes, Bindings, Delays, Residuals). 1355query_result(more(Bindings, Delays, Residuals)) --> 1356 result(Bindings, Delays, Residuals), 1357 prompt(more, Bindings, Delays, Residuals). 1358:- if(current_prolog_flag(emscripten, true)). 1359query_result(help) --> 1360 [ ansi(bold, ' Possible actions:', []), nl, 1361 ' ; (n,r,space): redo | t: trace&redo'-[], nl, 1362 ' *: show choicepoint | . (c,a): stop'-[], nl, 1363 ' w: write | p: print'-[], nl, 1364 ' +: max_depth*5 | -: max_depth//5'-[], nl, 1365 ' h (?): help'-[], 1366 nl, nl 1367 ]. 1368:- else. 1369query_result(help) --> 1370 [ ansi(bold, ' Possible actions:', []), nl, 1371 ' ; (n,r,space,TAB): redo | t: trace&redo'-[], nl, 1372 ' *: show choicepoint | . (c,a,RET): stop'-[], nl, 1373 ' w: write | p: print'-[], nl, 1374 ' +: max_depth*5 | -: max_depth//5'-[], nl, 1375 ' b: break | h (?): help'-[], 1376 nl, nl 1377 ]. 1378:- endif. 1379query_result(action) --> 1380 [ 'Action? '-[], flush ]. 1381query_result(confirm) --> 1382 [ 'Please answer \'y\' or \'n\'? '-[], flush ]. 1383query_result(eof) --> 1384 [ nl ]. 1385query_result(toplevel_open_line) --> 1386 []. 1387 1388prompt(Answer, [], true, []-[]) --> 1389 !, 1390 prompt(Answer, empty). 1391prompt(Answer, _, _, _) --> 1392 !, 1393 prompt(Answer, non_empty). 1394 1395prompt(yes, empty) --> 1396 !, 1397 [ ansi(truth(true), 'true.', []) ], 1398 extra_line. 1399prompt(yes, _) --> 1400 !, 1401 [ full_stop ], 1402 extra_line. 1403prompt(more, empty) --> 1404 !, 1405 [ ansi(truth(true), 'true ', []), flush ]. 1406prompt(more, _) --> 1407 !, 1408 [ ' '-[], flush ]. 1409 1410result(Bindings, Delays, Residuals) --> 1411 { current_prolog_flag(answer_write_options, Options0), 1412 Options = [partial(true)|Options0], 1413 GOptions = [priority(999)|Options0] 1414 }, 1415 wfs_residual_program(Delays, GOptions), 1416 bindings(Bindings, [priority(699)|Options]), 1417 ( {Residuals == []-[]} 1418 -> bind_delays_sep(Bindings, Delays), 1419 delays(Delays, GOptions) 1420 ; bind_res_sep(Bindings, Residuals), 1421 residuals(Residuals, GOptions), 1422 ( {Delays == true} 1423 -> [] 1424 ; [','-[], nl], 1425 delays(Delays, GOptions) 1426 ) 1427 ). 1428 1429bindings([], _) --> 1430 []. 1431bindings([binding(Names,Skel,Subst)|T], Options) --> 1432 { '$last'(Names, Name) }, 1433 var_names(Names), value(Name, Skel, Subst, Options), 1434 ( { T \== [] } 1435 -> [ ','-[], nl ], 1436 bindings(T, Options) 1437 ; [] 1438 ). 1439 1440var_names([Name]) --> 1441 !, 1442 [ ansi(binding(name), '~w', [Name]), ' = '-[] ]. 1443var_names([Name1,Name2|T]) --> 1444 !, 1445 [ ansi(binding(name), '~w', [Name1]), ' = '-[], 1446 ansi(binding(name), '~w', [Name2]), ', '-[] 1447 ], 1448 var_names([Name2|T]). 1449 1450 1451value(Name, Skel, Subst, Options) --> 1452 ( { var(Skel), Subst = [Skel=S] } 1453 -> { Skel = '$VAR'(Name) }, 1454 [ '~W'-[S, Options] ] 1455 ; [ '~W'-[Skel, Options] ], 1456 substitution(Subst, Options) 1457 ). 1458 1459substitution([], _) --> !. 1460substitution([N=V|T], Options) --> 1461 [ ', ', ansi(comment, '% where', []), nl, 1462 ' ~w = ~W'-[N,V,Options] ], 1463 substitutions(T, Options). 1464 1465substitutions([], _) --> []. 1466substitutions([N=V|T], Options) --> 1467 [ ','-[], nl, ' ~w = ~W'-[N,V,Options] ], 1468 substitutions(T, Options). 1469 1470 1471residuals(Normal-Hidden, Options) --> 1472 residuals1(Normal, Options), 1473 bind_res_sep(Normal, Hidden), 1474 ( {Hidden == []} 1475 -> [] 1476 ; [ansi(comment, '% with pending residual goals', []), nl] 1477 ), 1478 residuals1(Hidden, Options). 1479 1480residuals1([], _) --> 1481 []. 1482residuals1([G|Gs], Options) --> 1483 ( { Gs \== [] } 1484 -> [ '~W,'-[G, Options], nl ], 1485 residuals1(Gs, Options) 1486 ; [ '~W'-[G, Options] ] 1487 ). 1488 1489wfs_residual_program(true, _Options) --> 1490 !. 1491wfs_residual_program(Goal, _Options) --> 1492 { current_prolog_flag(toplevel_list_wfs_residual_program, true), 1493 '$current_typein_module'(TypeIn), 1494 ( current_predicate(delays_residual_program/2) 1495 -> true 1496 ; use_module(library(wfs), [delays_residual_program/2]) 1497 ), 1498 delays_residual_program(TypeIn:Goal, TypeIn:Program), 1499 Program \== [] 1500 }, 1501 !, 1502 [ ansi(comment, '% WFS residual program', []), nl ], 1503 [ ansi(wfs(residual_program), '~@', ['$messages':list_clauses(Program)]) ]. 1504wfs_residual_program(_, _) --> []. 1505 1506delays(true, _Options) --> 1507 !. 1508delays(Goal, Options) --> 1509 { current_prolog_flag(toplevel_list_wfs_residual_program, true) 1510 }, 1511 !, 1512 [ ansi(truth(undefined), '~W', [Goal, Options]) ]. 1513delays(_, _Options) --> 1514 [ ansi(truth(undefined), undefined, []) ]. 1515 1516:- public list_clauses/1. 1517 1518list_clauses([]). 1519list_clauses([H|T]) :- 1520 ( system_undefined(H) 1521 -> true 1522 ; portray_clause(user_output, H, [indent(4)]) 1523 ), 1524 list_clauses(T). 1525 1526system_undefined((undefined :- tnot(undefined))). 1527system_undefined((answer_count_restraint :- tnot(answer_count_restraint))). 1528system_undefined((radial_restraint :- tnot(radial_restraint))). 1529 1530bind_res_sep(_, []) --> !. 1531bind_res_sep(_, []-[]) --> !. 1532bind_res_sep([], _) --> !. 1533bind_res_sep(_, _) --> [','-[], nl]. 1534 1535bind_delays_sep([], _) --> !. 1536bind_delays_sep(_, true) --> !. 1537bind_delays_sep(_, _) --> [','-[], nl].
toplevel_extra_white_line is true, add an
empty line. The ~N cannot be replaced by nl because the answer
is not always left at a non-empty line. The eol element paints
the remainder of the line if the message has a background colour,
which ~N cannot do as it is written using format/3.
Note that eol ends the last line of the answer. The empty
line that separates the answer from the next query is not part of
the answer and keeps the default background.
1551extra_line --> 1552 { current_prolog_flag(toplevel_extra_white_line, true) }, 1553 !, 1554 [eol, '~N'-[]]. 1555extra_line --> 1556 [eol]. 1557 1558prolog_message(if_tty(Message)) --> 1559 ( {current_prolog_flag(tty_control, true)} 1560 -> [ at_same_line ], list(Message) 1561 ; [] 1562 ). 1563prolog_message(halt(Reason)) --> 1564 [ '~w: halt'-[Reason] ]. 1565prolog_message(no_action(Char)) --> 1566 [ 'Unknown action: ~c (h for help)'-[Char], nl ]. 1567 1568prolog_message(history(help(Show, Help))) --> 1569 [ 'History Commands:', nl, 1570 ' !!. Repeat last query', nl, 1571 ' !nr. Repeat query numbered <nr>', nl, 1572 ' !str. Repeat last query starting with <str>', nl, 1573 ' !?str. Repeat last query holding <str>', nl, 1574 ' ^old^new. Substitute <old> into <new> of last query', nl, 1575 ' !nr^old^new. Substitute in query numbered <nr>', nl, 1576 ' !str^old^new. Substitute in query starting with <str>', nl, 1577 ' !?str^old^new. Substitute in query holding <str>', nl, 1578 ' ~w.~21|Show history list'-[Show], nl, 1579 ' ~w.~21|Show this list'-[Help], nl, nl 1580 ]. 1581prolog_message(history(no_event)) --> 1582 [ '! No such event' ]. 1583prolog_message(history(bad_substitution)) --> 1584 [ '! Bad substitution' ]. 1585prolog_message(history(expanded(Event))) --> 1586 [ '~w.'-[Event] ]. 1587prolog_message(history(history(Events))) --> 1588 history_events(Events). 1589prolog_message(history(no_history)) --> 1590 [ '! event history not supported in this version' ]. 1591 1592history_events([]) --> 1593 []. 1594history_events([Nr-Event|T]) --> 1595 [ ansi(comment, '%', []), 1596 ansi(bold, '~t~w ~6|', [Nr]), 1597 ansi(code, '~s', [Event]), 1598 nl 1599 ], 1600 history_events(T).
welcome message to print information registered
using version/1.1608user_version_messages([]) --> []. 1609user_version_messages([H|T]) --> 1610 user_version_message(H), 1611 user_version_messages(T).
1615user_version_message(Term) --> 1616 translate_message(Term), !, [nl]. 1617user_version_message(Atom) --> 1618 [ '~w'-[Atom], nl ]. 1619 1620 1621 /******************************* 1622 * DEBUGGER MESSAGES * 1623 *******************************/ 1624 1625prolog_message(spy(Head)) --> 1626 [ 'New spy point on ' ], 1627 predicate_reference(Head). 1628prolog_message(already_spying(Head)) --> 1629 [ 'Already spying ' ], 1630 predicate_reference(Head). 1631prolog_message(nospy(Head)) --> 1632 [ 'Removed spy point from ' ], 1633 predicate_reference(Head). 1634prolog_message(trace_mode(OnOff)) --> 1635 [ 'Trace mode switched to ~w'-[OnOff] ]. 1636prolog_message(debug_mode(OnOff)) --> 1637 [ 'Debug mode switched to ~w'-[OnOff] ]. 1638prolog_message(debugging(OnOff, Threads)) --> 1639 [ 'Debug mode is ~w'-[OnOff] ], 1640 debugging_threads(Threads). 1641prolog_message(spying([])) --> 1642 !, 1643 [ 'No spy points' ]. 1644prolog_message(spying(Heads)) --> 1645 [ 'Spy points (see spy/1) on:', nl ], 1646 predicate_list(Heads). 1647prolog_message(trace(Head, [])) --> 1648 !, 1649 [ ' ' ], predicate_reference(Head, [tag(true)]), 1650 [ ' Not tracing'-[], nl]. 1651prolog_message(trace(Head, Ports)) --> 1652 { '$member'(Port, Ports), compound(Port), 1653 !, 1654 numbervars(Head+Ports, 0, _, [singletons(true)]) 1655 }, 1656 [ ' ~p: ~p'-[Head,Ports] ]. 1657prolog_message(trace(Head, Ports)) --> 1658 [ ' ' ], predicate_reference(Head, [tag(true)]), 1659 [ ': ~w'-[Ports], nl]. 1660prolog_message(tracing([])) --> 1661 !, 1662 [ 'No traced predicates (see trace/1,2)' ]. 1663prolog_message(tracing(Heads)) --> 1664 [ 'Trace points (see trace/1,2) on:', nl ], 1665 tracing_list(Heads).
1672predicate_list([]) --> 1673 []. 1674predicate_list([H|T]) --> 1675 [ ' ' ], predicate_reference(H, [tag(true)]), [nl], 1676 predicate_list(T). 1677 1678tracing_list([]) --> 1679 []. 1680tracing_list([trace(Head, Ports)|T]) --> 1681 translate_message(trace(Head, Ports)), 1682 tracing_list(T). 1683 1684debugging_threads([]) --> 1685 []. 1686debugging_threads(ThreadsByClass) --> 1687 [ nl, 'Threads in the following classes run in debug mode:', nl], 1688 list_threads_by_class(ThreadsByClass). 1689 1690list_threads_by_class([]) --> 1691 []. 1692list_threads_by_class([H|T]) --> 1693 list_thread_class(H), 1694 list_threads_by_class(T). 1695 1696list_thread_class(Class-Threads) --> 1697 { length(Threads, Count) }, 1698 [ ' Class ', ansi(code, '~p', [Class]), ': ~D threads'-[Count] ]. 1699 1700% frame(+Frame, +Choice, +Port, +PC) - Print for the debugger. 1701prolog_message(frame(Frame, _Choice, backtrace, _PC)) --> 1702 !, 1703 { prolog_frame_attribute(Frame, level, Level) 1704 }, 1705 [ ansi(frame(level), '~t[~D] ~10|', [Level]) ], 1706 frame_context(Frame), 1707 frame_goal(Frame, backtrace). 1708prolog_message(frame(Frame, Choice, choice, PC)) --> 1709 !, 1710 prolog_message(frame(Frame, Choice, backtrace, PC)). 1711prolog_message(frame(_, _Choice, cut_call(_PC), _)) --> !. 1712prolog_message(frame(Frame, _Choice, Port, _PC)) --> 1713 frame_flags(Frame), 1714 port(Port), 1715 frame_level(Frame), 1716 frame_context(Frame), 1717 frame_depth_limit(Port, Frame), 1718 frame_goal(Frame, Port), 1719 [ flush ]. 1720 1721% frame(:Goal, +Trace) - Print for trace/2 1722prolog_message(frame(Goal, trace(Port))) --> 1723 !, 1724 thread_context, 1725 [ ' T ' ], 1726 port(Port), 1727 predicate_goal(Goal, Port). 1728prolog_message(frame(Goal, trace(Port, Id))) --> 1729 !, 1730 thread_context, 1731 [ ' T ' ], 1732 port(Port, Id), 1733 predicate_goal(Goal, Port).
goal(Port, Parity), which allows
themes to decorate the goal depending on the port, on the parity of
the step count (striping, which separates the steps of a trace
visually) or both. See also '$answer_class'/1, which does the same
for the answers of the interactive toplevel.1744goal_style(Port0, goal(Port, Parity)) :- 1745 functor(Port0, Port, _), 1746 trace_parity(Parity). 1747 1748trace_parity(Parity) :- 1749 ( nb_current('$trace_step', C0) 1750 -> true 1751 ; C0 = 0 1752 ), 1753 C is C0+1, 1754 nb_setval('$trace_step', C), 1755 ( C mod 2 =:= 0 1756 -> Parity = even 1757 ; Parity = odd 1758 ). 1759 1760frame_goal(Frame, Port) --> 1761 { prolog_frame_attribute(Frame, goal, Goal), 1762 goal_style(Port, Style) 1763 }, 1764 ( { frame_location(Frame, Location) } 1765 -> goal(Goal, Style, Location) 1766 ; goal(Goal, Style) 1767 ).
1774predicate_goal(Goal, Port) --> 1775 { goal_style(Port, Style) 1776 }, 1777 ( { goal_links, 1778 predicate_location(Goal, Location) 1779 } 1780 -> goal(Goal, Style, Location) 1781 ; goal(Goal, Style) 1782 ). 1783 1784goal(Goal0, Style) --> 1785 { goal_format(Goal0, Goal, Options) 1786 }, 1787 [ ansi(Style, '~W', [Goal, Options]) ]. 1788 1789goal(Goal0, Style, Location) --> 1790 { goal_format(Goal0, Goal, Options) 1791 }, 1792 [ url(Location, ansi(Style, '~W', [Goal, Options])) ]. 1793 1794goal_format(Goal0, Goal, Options) :- 1795 clean_goal(Goal0, Goal), 1796 current_prolog_flag(debugger_write_options, Options).
File:Line for the call site of Frame, i.e., the place
in the clause of the parent frame from which Frame was called. This
is the position the user is at while tracing. If we cannot find it,
fall back to the clause that runs in Frame and finally to the file
that defines the predicate.
Resolving the call site uses library(prolog_stack), which has to run the decompiler and read the source file. This is affordable for an interactive tracer, but we only do it if the location can actually be used, i.e., if hyperlinks are rendered. See goal_links/0.
1811frame_location(Frame, Location) :- 1812 goal_links, 1813 catch(frame_location_(Frame, Location), _, fail). 1814 1815frame_location_(Frame, File:Line) :- 1816 prolog_frame_attribute(Frame, pc, PC), 1817 prolog_frame_attribute(Frame, parent, Parent), 1818 prolog_frame_attribute(Parent, clause, Clause), 1819 prolog_stack_frame_property(frame(_,clause(Clause,PC),_), 1820 location(File:Line)), 1821 !. 1822frame_location_(Frame, File:Line) :- 1823 prolog_frame_attribute(Frame, clause, Clause), 1824 clause_property(Clause, file(File)), 1825 clause_property(Clause, line_count(Line)), 1826 !. 1827frame_location_(Frame, Location) :- 1828 prolog_frame_attribute(Frame, goal, Goal), 1829 predicate_location(Goal, Location).
debugger_goal_links, which
is one of true, false or auto. Using auto (default) we create
the links if the console can render them.1838goal_links :- 1839 current_prolog_flag(debugger_goal_links, Links), 1840 goal_links(Links). 1841 1842goal_links(true). % note: no clause for `false` 1843goal_links(auto) :- 1844 ( current_prolog_flag(hyperlink_term, true) 1845 -> true 1846 ; predicate_property(ansi_term:hyperlink(_,_), number_of_clauses(N)), 1847 N > 0 1848 ). 1849 1850frame_level(Frame) --> 1851 { prolog_frame_attribute(Frame, level, Level) 1852 }, 1853 [ '(~D) '-[Level] ]. 1854 1855frame_context(Frame) --> 1856 ( { current_prolog_flag(debugger_show_context, true), 1857 prolog_frame_attribute(Frame, context_module, Context) 1858 } 1859 -> [ '[~w] '-[Context] ] 1860 ; [] 1861 ). 1862 1863frame_depth_limit(fail, Frame) --> 1864 { prolog_frame_attribute(Frame, depth_limit_exceeded, true) 1865 }, 1866 !, 1867 [ '[depth-limit exceeded] ' ]. 1868frame_depth_limit(_, _) --> 1869 []. 1870 1871frame_flags(Frame) --> 1872 { prolog_frame_attribute(Frame, goal, Goal), 1873 ( predicate_property(Goal, transparent) 1874 -> T = '^' 1875 ; T = ' ' 1876 ), 1877 ( predicate_property(Goal, spying) 1878 -> S = '*' 1879 ; S = ' ' 1880 ) 1881 }, 1882 [ '~w~w '-[T, S] ]. 1883 1884% trace/1 context handling 1885port(Port, Dict) --> 1886 { _{level:Level, start:Time} :< Dict 1887 }, 1888 ( { Port \== call, 1889 get_time(Now), 1890 Passed is (Now - Time)*1000.0 1891 } 1892 -> [ '[~d +~1fms] '-[Level, Passed] ] 1893 ; [ '[~d] '-[Level] ] 1894 ), 1895 port(Port). 1896port(Port, _Id-Level) --> 1897 [ '[~d] '-[Level] ], 1898 port(Port). 1899 1900port(PortTerm) --> 1901 { functor(PortTerm, Port, _), 1902 port_name(Port, Name) 1903 }, 1904 !, 1905 [ ansi(port(Port), '~w: ', [Name]) ]. 1906 1907port_name(call, 'Call'). 1908port_name(exit, 'Exit'). 1909port_name(fail, 'Fail'). 1910port_name(redo, 'Redo'). 1911port_name(unify, 'Unify'). 1912port_name(exception, 'Exception'). 1913 1914clean_goal(M:Goal, Goal) :- 1915 hidden_module(M), 1916 !. 1917clean_goal(M:Goal, Goal) :- 1918 predicate_property(M:Goal, built_in), 1919 !. 1920clean_goal(Goal, Goal). 1921 1922 1923 /******************************* 1924 * COMPATIBILITY * 1925 *******************************/ 1926 1927prolog_message(compatibility(renamed(Old, New))) --> 1928 [ 'The predicate ' ], predicate_reference(Old, [link(false)]), 1929 [ ' has been renamed to ' ], predicate_reference(New), 1930 [ '.', nl, 1931 'Please update your sources for compatibility with future versions.' 1932 ]. 1933 1934 1935 /******************************* 1936 * THREADS * 1937 *******************************/ 1938 1939prolog_message(abnormal_thread_completion(Goal, exception(Ex))) --> 1940 !, 1941 [ 'Thread running "~p" died on exception: '-[Goal] ], 1942 translate_message(Ex). 1943prolog_message(abnormal_thread_completion(Goal, fail)) --> 1944 [ 'Thread running "~p" died due to failure'-[Goal] ]. 1945prolog_message(threads_not_died(Running)) --> 1946 [ 'The following threads wouldn\'t die: ~p'-[Running] ]. 1947 1948 1949 /******************************* 1950 * PACKS * 1951 *******************************/ 1952 1953prolog_message(pack(attached(Pack, BaseDir))) --> 1954 [ 'Attached package ~w at ~q'-[Pack, BaseDir] ]. 1955prolog_message(pack(duplicate(Entry, OldDir, Dir))) --> 1956 [ 'Package ~w already attached at ~q.'-[Entry,OldDir], nl, 1957 '\tIgnoring version from ~q'- [Dir] 1958 ]. 1959prolog_message(pack(no_arch(Entry, Arch))) --> 1960 [ 'Package ~w: no binary for architecture ~w'-[Entry, Arch] ]. 1961 1962 /******************************* 1963 * MISC * 1964 *******************************/ 1965 1966prolog_message(null_byte_in_path(Component)) --> 1967 [ '0-byte in PATH component: ~p (skipped directory)'-[Component] ]. 1968prolog_message(invalid_tmp_dir(Dir, Reason)) --> 1969 [ 'Cannot use ~p as temporary file directory: ~w'-[Dir, Reason] ]. 1970prolog_message(ambiguous_stream_pair(Pair)) --> 1971 [ 'Ambiguous operation on stream pair ~p'-[Pair] ]. 1972prolog_message(backcomp(init_file_moved(FoundFile))) --> 1973 { absolute_file_name(app_config('init.pl'), InitFile, 1974 [ file_errors(fail) 1975 ]) 1976 }, 1977 [ 'The location of the config file has moved'-[], nl, 1978 ' from "~w"'-[FoundFile], nl, 1979 ' to "~w"'-[InitFile], nl, 1980 ' See https://www.swi-prolog.org/modified/config-files.html'-[] 1981 ]. 1982prolog_message(not_accessed_flags(List)) --> 1983 [ 'The following Prolog flags have been set but not used:', nl ], 1984 flags(List). 1985prolog_message(prolog_flag_invalid_preset(Flag, Preset, _Type, New)) --> 1986 [ 'Prolog flag ', ansi(code, '~q', Flag), ' has been (re-)created with a type that is \c 1987 incompatible with its value.', nl, 1988 'Value updated from ', ansi(code, '~p', [Preset]), ' to default (', 1989 ansi(code, '~p', [New]), ')' 1990 ]. 1991 1992 1993flags([H|T]) --> 1994 [' ', ansi(code, '~q', [H])], 1995 ( {T == []} 1996 -> [] 1997 ; [nl], 1998 flags(T) 1999 ). 2000 2001 2002 /******************************* 2003 * DEPRECATED * 2004 *******************************/ 2005 2006deprecated(set_prolog_stack(_Stack,limit)) --> 2007 [ 'set_prolog_stack/2: limit(Size) sets the combined limit.'-[], nl, 2008 'See https://www.swi-prolog.org/changes/stack-limit.html' 2009 ]. 2010deprecated(autoload(TargetModule, File, _M:PI, expansion)) --> 2011 !, 2012 [ 'Auto-loading ' ], predicate_reference(PI, [link(false)]), 2013 [ ' from ' ], 2014 load_file(File), [ ' into ' ], 2015 target_module(TargetModule), 2016 [ ' is deprecated due to term- or goal-expansion' ]. 2017deprecated(source_search_working_directory(File, _FullFile)) --> 2018 [ 'Found file ', ansi(code, '~w', [File]), 2019 ' relative to the current working directory.', nl, 2020 'This behaviour is deprecated but still supported by', nl, 2021 'the Prolog flag ', 2022 ansi(code, source_search_working_directory, []), '.', nl 2023 ]. 2024deprecated(moved_library(Old, New)) --> 2025 [ 'Library was moved: ~q --> ~q'-[Old, New] ]. 2026 2027load_file(File) --> 2028 { file_base_name(File, Base), 2029 absolute_file_name(library(Base), File, [access(read), file_errors(fail)]), 2030 file_name_extension(Clean, pl, Base) 2031 }, 2032 !, 2033 [ ansi(code, '~p', [library(Clean)]) ]. 2034load_file(File) --> 2035 [ url(File) ]. 2036 2037target_module(Module) --> 2038 { module_property(Module, file(File)) }, 2039 !, 2040 load_file(File). 2041target_module(Module) --> 2042 [ 'module ', ansi(code, '~p', [Module]) ]. 2043 2044 2045 2046 /******************************* 2047 * TRIPWIRES * 2048 *******************************/ 2049 2050tripwire_message(max_integer_size, Bytes) --> 2051 !, 2052 [ 'Trapped tripwire max_integer_size: big integers and \c 2053 rationals are limited to ~D bytes'-[Bytes] ]. 2054tripwire_message(Wire, Context) --> 2055 [ 'Trapped tripwire ~w for '-[Wire] ], 2056 tripwire_context(Wire, Context). 2057 2058tripwire_context(_, ATrie) --> 2059 { '$is_answer_trie'(ATrie, _), 2060 !, 2061 '$tabling':atrie_goal(ATrie, QGoal), 2062 clean_goal(QGoal, Goal) % a goal, not a predicate indicator 2063 }, 2064 [ '~p'-[Goal] ]. 2065tripwire_context(_, Ctx) --> 2066 [ '~p'-[Ctx] ]. 2067 2068 2069 /******************************* 2070 * INTERNATIONALIZATION * 2071 *******************************/ 2072 2073:- create_prolog_flag(message_language, default, []).
nl_BE) and ends with en.2080message_lang(Lang) :- 2081 current_message_lang(Lang0), 2082 ( Lang0 == en 2083 -> Lang = en 2084 ; sub_atom(Lang0, 0, _, _, en_) 2085 -> longest_id(Lang0, Lang) 2086 ; ( longest_id(Lang0, Lang) 2087 ; Lang = en 2088 ) 2089 ). 2090 2091longest_id(Lang, Id) :- 2092 split_string(Lang, "_-", "", [H|Components]), 2093 longest_prefix(Components, Taken), 2094 atomic_list_concat([H|Taken], '_', Id). 2095 2096longest_prefix([H|T0], [H|T]) :- 2097 longest_prefix(T0, T). 2098longest_prefix(_, []).
2104current_message_lang(Lang) :- 2105 ( current_prolog_flag(message_language, Lang0), 2106 Lang0 \== default 2107 -> Lang = Lang0 2108 ; os_user_lang(Lang0) 2109 -> clean_encoding(Lang0, Lang1), 2110 set_prolog_flag(message_language, Lang1), 2111 Lang = Lang1 2112 ; Lang = en 2113 ). 2114 2115os_user_lang(Lang) :- 2116 current_prolog_flag(windows, true), 2117 win_get_user_preferred_ui_languages(name, [Lang|_]). 2118os_user_lang(Lang) :- 2119 catch(setlocale(messages, _, ''), _, fail), 2120 setlocale(messages, Lang, Lang). 2121os_user_lang(Lang) :- 2122 getenv('LANG', Lang). 2123 2124 2125clean_encoding(Lang0, Lang) :- 2126 ( sub_atom(Lang0, A, _, _, '.') 2127 -> sub_atom(Lang0, 0, A, _, Lang) 2128 ; Lang = Lang0 2129 ). 2130 2131 /******************************* 2132 * PRIMITIVES * 2133 *******************************/ 2134 2135code(Term) --> 2136 code('~p', Term). 2137 2138code(Format, Term) --> 2139 [ ansi(code, Format, [Term]) ]. 2140 2141list([]) --> []. 2142list([H|T]) --> [H], list(T). 2143 2144 2145 /******************************* 2146 * PREDICATE REFERENCES * 2147 *******************************/
Module:Name/Arity
or, for a non-terminal, Module:Name//Arity for Spec. Spec is one
of
The module is kept here. Whether or not it is printed is left to predicate_reference//2, which uses user_predicate_indicator/2.
2164:- public 2165 predicate_indicator/2. 2166 2167predicate_indicator(Spec, QPI) :- 2168 strip_module(user:Spec, Module, Spec1), 2169 ( is_predicate_indicator(Spec1) 2170 -> dcg_indicator(Module, Spec1, QPI) 2171 ; callable(Spec1), 2172 '$pi_head'(Module:PI, Module:Spec1), 2173 dcg_indicator(Module, PI, QPI) 2174 ).
// notation if the predicate
is a non-terminal.2181dcg_indicator(Module, Name//DCGArity, Module:Name//DCGArity) :- 2182 !. 2183dcg_indicator(Module, Name/Arity, QPI) :- 2184 ( Arity >= 2, 2185 current_predicate(Module:Name/Arity), 2186 functor(Head, Name, Arity), 2187 predicate_property(Module:Head, non_terminal) 2188 -> DCGArity is Arity-2, 2189 QPI = Module:Name//DCGArity 2190 ; QPI = Module:Name/Arity 2191 ).
user.2199predicate_head(Spec, QHead) :- 2200 strip_module(user:Spec, Module, Spec1), 2201 ( is_predicate_indicator(Spec1) 2202 -> '$pi_head'(Module:Spec1, QHead) 2203 ; callable(Spec1), 2204 QHead = Module:Spec1 2205 ). 2206 2207is_predicate_indicator(Name/Arity) :- 2208 atomic(Name), integer(Arity). 2209is_predicate_indicator(Name//Arity) :- 2210 atomic(Name), integer(Arity).
code and, if the location of the predicate is known and
the output is a terminal that supports it, it is a hyperlink to the
definition. Options:
auto (default), hide or show. Using auto, the
module qualification is removed if hidden_module/1 holds for it.false, do not try to create a hyperlink. Default true.code.true, add a tag that indicates the kind of predicate.
See predicate_kind/2. Default false. Only sensible if the
reference is the only thing on the line.
If Spec cannot be interpreted as a predicate it is printed using the
code class and ~p, i.e., we never fail on a malformed message.
2236:- public 2237 predicate_reference//1, 2238 predicate_reference//2. 2239 2240predicate_reference(Spec) --> 2241 predicate_reference(Spec, []). 2242 2243predicate_reference(Spec, Options) --> 2244 { predicate_indicator(Spec, QPI) }, 2245 !, 2246 { pref_option(style(Style), Options, code), 2247 pref_option(module(Mode), Options, auto), 2248 reference_pi(Mode, QPI, PI) 2249 }, 2250 predicate_link(QPI, ansi(Style, '~q', [PI]), Options), 2251 predicate_reference_tag(QPI, Options). 2252predicate_reference(Spec, _Options) --> 2253 [ ansi(code, '~p', [Spec]) ]. 2254 2255reference_pi(auto, QPI, PI) :- 2256 !, 2257 user_predicate_indicator(QPI, PI). 2258reference_pi(hide, _:PI, PI) :- !. 2259reference_pi(_, QPI, QPI). 2260 2261predicate_link(QPI, Label, Options) --> 2262 { pref_option(link(true), Options, true), 2263 predicate_location(QPI, Location) 2264 }, 2265 !, 2266 [ url(Location, Label) ]. 2267predicate_link(_, Label, _) --> 2268 [ Label ].
boot/messages.pl must
be able to print a message before the libraries are available.
2277pref_option(Option, Options, Default) :-
2278 functor(Option, Name, 1),
2279 functor(General, Name, 1),
2280 ( memberchk(General, Options)
2281 -> General = Option
2282 ; arg(1, Option, Default)
2283 ).File:Line for the definition of the predicate Spec.
Also deals with predicates defined in C. Note that predicates that
are not loaded but can be autoloaded are located from the autoload
index, i.e., printing a message never loads a library.2292:- public 2293 predicate_location/2. 2294 2295predicate_location(Spec, Location) :- 2296 predicate_head(Spec, Head), 2297 current_predicate(_, Head), % do not (auto)load 2298 '$predicate_source_location'(Head, Location).
2305:- public 2306 predicate_definition//2. 2307 2308predicate_definition(Spec, Message) --> 2309 { predicate_location(Spec, Location) }, 2310 !, 2311 [ nl, '~w at '-[Message], url(Location) ]. 2312predicate_definition(_, _) --> 2313 [].
library(Name)module(Module)2329:- public 2330 predicate_kind/2. 2331 2332predicate_kind(Spec, Kind) :- 2333 predicate_head(Spec, Head), 2334 ( current_predicate(_, Head) % do not autoload 2335 -> defined_predicate_kind(Head, Kind) 2336 ; predicate_property(Head, autoload(File)) 2337 -> library_name(File, Name), 2338 Kind = library(Name) 2339 ; Kind = undefined 2340 ). 2341 2342defined_predicate_kind(Head, Kind) :- 2343 ( predicate_property(Head, iso) 2344 -> Kind = iso 2345 ; predicate_property(Head, built_in) 2346 -> ( predicate_property(Head, foreign) 2347 -> Kind = foreign 2348 ; Kind = built_in 2349 ) 2350 ; predicate_property(Head, imported_from(Module)) 2351 -> module_kind(Module, Kind) 2352 ; predicate_property(Head, file(File)), 2353 library_file(File) 2354 -> library_name(File, Name), 2355 Kind = library(Name) 2356 ; Kind = user 2357 ). 2358 2359module_kind(Module, Kind) :- 2360 ( hidden_module(Module) 2361 -> Kind = user 2362 ; module_property(Module, file(File)), 2363 library_file(File) 2364 -> library_name(File, Name), 2365 Kind = library(Name) 2366 ; Kind = module(Module) 2367 ).
library(Name).2375library_file(File) :- 2376 absolute_file_name(library(.), LibDir, 2377 [ file_type(directory), 2378 solutions(all), 2379 file_errors(fail) 2380 ]), 2381 sub_atom(File, 0, _, _, LibDir), 2382 !. 2383 2384library_name(File, Name) :- 2385 ( file_name_extension(Base, Ext, File), 2386 Ext \== '' 2387 -> true 2388 ; Base = File 2389 ), 2390 file_base_name(Base, Name).
2397predicate_reference_tag(QPI, Options) --> 2398 { pref_option(tag(true), Options, false), 2399 predicate_kind(QPI, Kind) 2400 }, 2401 !, 2402 predicate_kind_tag(Kind). 2403predicate_reference_tag(_, _) --> 2404 []. 2405 2406predicate_kind_tag(Kind) --> 2407 { predicate_kind_label(Kind, Label) }, 2408 [ ansi(predicate(Kind), ' [~w]', [Label]) ]. 2409 2410predicate_kind_label(iso, 'ISO'). 2411predicate_kind_label(built_in, 'built-in'). 2412predicate_kind_label(foreign, 'built-in'). 2413predicate_kind_label(user, 'user'). 2414predicate_kind_label(undefined, 'undefined'). 2415predicate_kind_label(library(Name), Label) :- 2416 format(atom(Label), 'library(~w)', [Name]). 2417predicate_kind_label(module(Name), Name). 2418 2419 2420 /******************************* 2421 * DEFAULT THEME * 2422 *******************************/ 2423 2424:- public default_theme/2. 2425 2426default_theme(var, [fg(red)]). 2427default_theme(code, [fg(blue)]). 2428default_theme(comment, [fg(green)]). 2429default_theme(warning, [fg(red)]). 2430default_theme(error, [bold, fg(red)]). 2431default_theme(truth(false), [bold, fg(red)]). 2432default_theme(truth(true), [bold]). 2433default_theme(truth(undefined), [bold, fg(cyan)]). 2434default_theme(wfs(residual_program), [fg(cyan)]). 2435default_theme(frame(level), [bold]). 2436default_theme(goal(_,_), []). 2437default_theme(port(call), [bold, fg(green)]). 2438default_theme(port(exit), [bold, fg(green)]). 2439default_theme(port(fail), [bold, fg(red)]). 2440default_theme(port(redo), [bold, fg(yellow)]). 2441default_theme(port(unify), [bold, fg(blue)]). 2442default_theme(port(exception), [bold, fg(magenta)]). 2443default_theme(prompt, [bold]). 2444default_theme(input, []). 2445default_theme(answer(_), []). 2446default_theme(binding(name), [bold]). 2447default_theme(predicate(iso), [italic, fg(cyan)]). 2448default_theme(predicate(built_in), [italic, fg(cyan)]). 2449default_theme(predicate(foreign), [italic, fg(cyan)]). 2450default_theme(predicate(library(_)), [italic, fg(green)]). 2451default_theme(predicate(module(_)), [italic, fg(green)]). 2452default_theme(predicate(user), [italic, fg(default)]). 2453default_theme(predicate(undefined), [italic, fg(red)]). 2454default_theme(message(informational), [fg(green)]). 2455default_theme(message(information), [fg(green)]). 2456default_theme(message(debug(_)), [fg(blue)]). 2457default_theme(message(Level), Attrs) :- 2458 nonvar(Level), 2459 default_theme(Level, Attrs). 2460 2461 2462 /******************************* 2463 * PRINTING MESSAGES * 2464 *******************************/ 2465 2466:- multifile 2467 user:message_hook/3, 2468 prolog:message_prefix_hook/2. 2469:- dynamic 2470 user:message_hook/3, 2471 prolog:message_prefix_hook/2. 2472:- thread_local 2473 user:thread_message_hook/3. 2474:- '$notransact'((user:message_hook/3, 2475 prolog:message_prefix_hook/2, 2476 user:thread_message_hook/3)).
2483print_message(Level, _Term) :- 2484 msg_property(Level, stream(S)), 2485 stream_property(S, error(true)), 2486 !. 2487print_message(Level, Term) :- 2488 setup_call_cleanup( 2489 notrace(push_msg(Term, Stack)), 2490 ignore(print_message_guarded(Level, Term)), 2491 notrace(pop_msg(Stack))), 2492 !. 2493print_message(Level, Term) :- 2494 ( Level \== silent 2495 -> format(user_error, 'Recursive ~w message: ~q~n', [Level, Term]), 2496 autoload_call(backtrace(20)) 2497 ; true 2498 ). 2499 2500push_msg(Term, Messages) :- 2501 nb_current('$inprint_message', Messages), 2502 !, 2503 \+ ( '$member'(Msg, Messages), 2504 Msg =@= Term 2505 ), 2506 Stack = [Term|Messages], 2507 b_setval('$inprint_message', Stack). 2508push_msg(Term, []) :- 2509 b_setval('$inprint_message', [Term]). 2510 2511pop_msg(Stack) :- 2512 nb_delete('$inprint_message'), % delete history 2513 b_setval('$inprint_message', Stack). 2514 2515print_message_guarded(Level, Term) :- 2516 ( must_print(Level, Term) 2517 -> ( prolog:message_action(Term, Level), 2518 fail % forall/2 is cleaner, but not yet 2519 ; true % defined 2520 ), 2521 ( translate_message(Term, Lines, []) 2522 -> ( nonvar(Term), 2523 ( notrace(user:thread_message_hook(Term, Level, Lines)) 2524 -> true 2525 ; notrace(user:message_hook(Term, Level, Lines)) 2526 ) 2527 -> true 2528 ; '$inc_message_count'(Level), 2529 print_system_message(Term, Level, Lines), 2530 maybe_halt_on_error(Level) 2531 ) 2532 ) 2533 ; true 2534 ). 2535 2536maybe_halt_on_error(error) :- 2537 current_prolog_flag(on_error, halt), 2538 !, 2539 halt(1). 2540maybe_halt_on_error(warning) :- 2541 current_prolog_flag(on_warning, halt), 2542 !, 2543 halt(1). 2544maybe_halt_on_error(_).
2554print_system_message(_, silent, _) :- !. 2555print_system_message(_, informational, _) :- 2556 current_prolog_flag(verbose, silent), 2557 !. 2558print_system_message(_, banner, _) :- 2559 current_prolog_flag(verbose, silent), 2560 !. 2561print_system_message(_, _, []) :- !. 2562print_system_message(Term, Kind, Lines) :- 2563 catch(flush_output(user_output), _, true), % may not exist 2564 source_location(File, Line), 2565 Term \= error(syntax_error(_), _), 2566 msg_property(Kind, location_prefix(File:Line, LocPrefix, LinePrefix)), 2567 !, 2568 to_list(LocPrefix, LocPrefixL), 2569 insert_prefix(Lines, LinePrefix, Ctx, PrefixLines), 2570 '$append'([ [begin(Kind, Ctx)], 2571 LocPrefixL, 2572 [nl], 2573 PrefixLines, 2574 [end(Ctx)] 2575 ], 2576 AllLines), 2577 msg_property(Kind, stream(Stream)), 2578 ignore(stream_property(Stream, position(Pos))), 2579 print_message_lines(Stream, AllLines), 2580 ( \+ stream_property(Stream, position(Pos)), 2581 msg_property(Kind, wait(Wait)), 2582 Wait > 0 2583 -> sleep(Wait) 2584 ; true 2585 ). 2586print_system_message(_, Kind, Lines) :- 2587 msg_property(Kind, stream(Stream)), 2588 print_message_lines(Stream, kind(Kind), Lines). 2589 2590to_list(ListIn, List) :- 2591 is_list(ListIn), 2592 !, 2593 List = ListIn. 2594to_list(NonList, [NonList]). 2595 2596:- multifile 2597 user:message_property/2. 2598 2599msg_property(Kind, Property) :- 2600 notrace(user:message_property(Kind, Property)), 2601 !. 2602msg_property(Kind, prefix(Prefix)) :- 2603 msg_prefix(Kind, Prefix), 2604 !. 2605msg_property(_, prefix('~N')) :- !. 2606msg_property(query, color_class(Class)) :- 2607 !, 2608 '$answer_class'(Class). 2609msg_property(query, stream(user_output)) :- !. 2610msg_property(_, stream(user_error)) :- !. 2611msg_property(error, tag('ERROR')). 2612msg_property(warning, tag('Warning')). 2613msg_property(Level, 2614 location_prefix(File:Line, 2615 ['~N~w: '-[Tag], url(File:Line), ':'], 2616 '~N~w: '-[Tag])) :- 2617 include_msg_location(Level), 2618 msg_property(Level, tag(Tag)). 2619msg_property(error, wait(0.1)) :- !. 2620 2621include_msg_location(warning). 2622include_msg_location(error). 2623 2624msg_prefix(debug(_), Prefix) :- 2625 msg_context('~N% ', Prefix). 2626msg_prefix(Level, Prefix) :- 2627 msg_property(Level, tag(Tag)), 2628 atomics_to_string(['~N', Tag, ': '], Prefix0), 2629 msg_context(Prefix0, Prefix). 2630msg_prefix(informational, '~N% '). 2631msg_prefix(information, '~N% ').
message_context. Recognised context terms are:
time(Format)In addition, the hook message_prefix_hook/2 is called that allows for additional context information.
2645msg_context(Prefix0, Prefix) :- 2646 current_prolog_flag(message_context, Context), 2647 is_list(Context), 2648 !, 2649 add_message_context(Context, Prefix0, Prefix). 2650msg_context(Prefix, Prefix). 2651 2652add_message_context([], Prefix, Prefix). 2653add_message_context([H|T], Prefix0, Prefix) :- 2654 ( add_message_context1(H, Prefix0, Prefix1) 2655 -> true 2656 ; Prefix1 = Prefix0 2657 ), 2658 add_message_context(T, Prefix1, Prefix). 2659 2660add_message_context1(Context, Prefix0, Prefix) :- 2661 prolog:message_prefix_hook(Context, Extra), 2662 atomics_to_string([Prefix0, Extra, ' '], Prefix). 2663add_message_context1(time, Prefix0, Prefix) :- 2664 get_time(Now), 2665 format_time(string(S), '%T.%3f ', Now), 2666 string_concat(Prefix0, S, Prefix). 2667add_message_context1(time(Format), Prefix0, Prefix) :- 2668 get_time(Now), 2669 format_time(string(S), Format, Now), 2670 atomics_to_string([Prefix0, S, ' '], Prefix). 2671add_message_context1(thread, Prefix0, Prefix) :- 2672 \+ current_prolog_flag(toplevel_thread, true), 2673 thread_self(Id0), 2674 !, 2675 ( atom(Id0) 2676 -> Id = Id0 2677 ; thread_property(Id0, id(Id)) 2678 ), 2679 format(string(Prefix), '~w[Thread ~w] ', [Prefix0, Id]).
If PrefixOrKind is kind(Kind), the message as a whole may be
decorated. To this end the lines are wrapped in begin(Class, Ctx)
and end(Ctx), where Class is derived from Kind using
msg_color_class/2. Ctx is a variable that is bound by whoever
implements prolog:message_line_element/2 for begin/2 (normally
library(ansi_term)) and remains unbound if the decoration is not
available, e.g., because Stream is not a terminal.
The elements that need Ctx are rewritten by prefix_nl/4 to carry it. See there for the details.
2697print_message_lines(Stream, kind(Kind), Lines) :- 2698 !, 2699 msg_property(Kind, prefix(Prefix)), 2700 msg_color_class(Kind, Class), 2701 insert_prefix(Lines, Prefix, Ctx, PrefixLines), 2702 '$append'([ begin(Class, Ctx) 2703 | PrefixLines 2704 ], 2705 [ end(Ctx) 2706 ], 2707 AllLines), 2708 print_message_lines(Stream, AllLines). 2709print_message_lines(Stream, Prefix, Lines) :- 2710 insert_prefix(Lines, Prefix, _, PrefixLines), 2711 print_message_lines(Stream, PrefixLines).
message(Kind) (see
level_attrs/2).2719msg_color_class(Kind, Class) :- 2720 msg_property(Kind, color_class(Class0)), 2721 !, 2722 Class = Class0. 2723msg_color_class(Kind, Kind).
at_same_line the message continues the line and no initial
prefix is added. Ctx is the message context; see prefix_nl/4 and
print_message_lines/3.2732insert_prefix([at_same_line|Lines0], Prefix, Ctx, Lines) :- 2733 !, 2734 prefix_nl(Lines0, Prefix, Ctx, Lines). 2735insert_prefix(Lines0, Prefix, Ctx, [prefix(Prefix)|Lines]) :- 2736 prefix_nl(Lines0, Prefix, Ctx, Lines).
nl and make the message context Ctx
available to the elements that need it:
nl(Ctx), flush(Ctx) and eol(Ctx).
Their handler writes the sequence that paints the remainder of
the line before ending it if the message has a background
colour.ansi(Attrs, Fmt, Args) becomes ansi(Attrs, Fmt, Args, Ctx).
Its handler re-installs the decoration of the message as a
whole after writing the element, as the element ends with a
full reset. The same applies to an ansi/3 element used as the
label of an url/2 element.
The last line of a message is ended implicitly: if Lines does not
end in nl or flush an nl is added. This one does not paint:
what follows the message is not part of it. A message that wants
its last line painted ends it using eol.
2758prefix_nl([], _, _, [nl]). 2759prefix_nl([nl], _, Ctx, [nl(Ctx)]) :- !. 2760prefix_nl([flush], _, Ctx, [flush(Ctx)]) :- !. 2761prefix_nl([nl|T0], Prefix, Ctx, [nl(Ctx), prefix(Prefix)|T]) :- 2762 !, 2763 prefix_nl(T0, Prefix, Ctx, T). 2764prefix_nl([flush|T0], Prefix, Ctx, [flush(Ctx)|T]) :- 2765 !, 2766 prefix_nl(T0, Prefix, Ctx, T). 2767prefix_nl([eol|T0], Prefix, Ctx, [eol(Ctx)|T]) :- 2768 !, 2769 prefix_nl(T0, Prefix, Ctx, T). 2770prefix_nl([ansi(Attrs,Fmt,Args)|T0], Prefix, Ctx, 2771 [ansi(Attrs,Fmt,Args,Ctx)|T]) :- 2772 !, 2773 prefix_nl(T0, Prefix, Ctx, T). 2774prefix_nl([url(URL,ansi(Attrs,Fmt,Args))|T0], Prefix, Ctx, 2775 [url(URL,ansi(Attrs,Fmt,Args,Ctx))|T]) :- 2776 !, 2777 prefix_nl(T0, Prefix, Ctx, T). 2778prefix_nl([H|T0], Prefix, Ctx, [H|T]) :- 2779 prefix_nl(T0, Prefix, Ctx, T).
2783print_message_lines(Stream, Lines) :- 2784 with_output_to( 2785 Stream, 2786 notrace(print_message_lines_guarded(current_output, Lines))). 2787 2788print_message_lines_guarded(_, []) :- !. 2789print_message_lines_guarded(S, [H|T]) :- 2790 line_element(S, H), 2791 print_message_lines_guarded(S, T). 2792 2793line_element(S, E) :- 2794 prolog:message_line_element(S, E), 2795 !. 2796line_element(S, full_stop) :- 2797 !, 2798 '$put_token'(S, '.'). % insert space if needed. 2799line_element(S, nl) :- 2800 !, 2801 nl(S). 2802line_element(S, nl(_Ctx)) :- 2803 !, 2804 nl(S). 2805line_element(S, flush(_Ctx)) :- 2806 !, 2807 flush_output(S). 2808line_element(_, eol(_Ctx)) :- !. 2809line_element(S, prefix(Fmt-Args)) :- 2810 !, 2811 safe_format(S, Fmt, Args). 2812line_element(S, prefix(Fmt)) :- 2813 !, 2814 safe_format(S, Fmt, []). 2815line_element(S, flush) :- 2816 !, 2817 flush_output(S). 2818line_element(S, Fmt-Args) :- 2819 !, 2820 safe_format(S, Fmt, Args). 2821line_element(S, ansi(_, Fmt, Args)) :- 2822 !, 2823 safe_format(S, Fmt, Args). 2824line_element(S, ansi(_, Fmt, Args, _Ctx)) :- 2825 !, 2826 safe_format(S, Fmt, Args). 2827line_element(S, url(URL)) :- 2828 !, 2829 print_link(S, URL). 2830line_element(S, url(_URL, Label)) :- 2831 !, 2832 link_label(Label, Fmt, Args), 2833 safe_format(S, Fmt, Args). 2834line_element(_, begin(_Level, _Ctx)) :- !. 2835line_element(_, end(_Ctx)) :- !. 2836line_element(S, Fmt) :- 2837 safe_format(S, Fmt, []). 2838 2839print_link(S, File:Line:Column) :- 2840 !, 2841 safe_format(S, '~w:~d:~d', [File, Line, Column]). 2842print_link(S, File:Line) :- 2843 !, 2844 safe_format(S, '~w:~d', [File, Line]). 2845print_link(S, File) :- 2846 safe_format(S, '~w', [File]).
~.2854:- public 2855 link_label/3. 2856 2857link_label(Fmt-Args, Fmt, Args) :- 2858 atom(Fmt), 2859 is_list(Args), 2860 !. 2861link_label(ansi(_Class, Fmt, Args), Fmt, Args) :- !. 2862link_label(ansi(_Class, Fmt, Args, _Ctx), Fmt, Args) :- !. 2863link_label(Text, '~w', [Text]).
2867safe_format(S, Fmt, Args) :- 2868 E = error(_,_), 2869 catch(format(S,Fmt,Args), E, 2870 format_failed(S,Fmt,Args,E)). 2871 2872format_failed(S, _Fmt, _Args, E) :- 2873 stream_property(S, error(true)), 2874 !, 2875 throw(E). 2876format_failed(S, Fmt, Args, error(E,_)) :- 2877 format(S, '~N [[ EXCEPTION while printing message ~q~n\c 2878 ~7|with arguments ~W:~n\c 2879 ~7|raised: ~W~n~4|]]~n', 2880 [ Fmt, 2881 Args, [quoted(true), max_depth(10)], 2882 E, [quoted(true), max_depth(10)] 2883 ]).
2889message_to_string(Term, Str) :- 2890 translate_message(Term, Actions, []), 2891 !, 2892 actions_to_format(Actions, Fmt, Args), 2893 format(string(Str), Fmt, Args). 2894 2895actions_to_format([], '', []) :- !. 2896actions_to_format([nl(_)|T], Fmt, Args) :- % see prefix_nl/4 2897 !, 2898 actions_to_format([nl|T], Fmt, Args). 2899actions_to_format([nl], '', []) :- !. 2900actions_to_format([Term, nl], Fmt, Args) :- 2901 !, 2902 actions_to_format([Term], Fmt, Args). 2903actions_to_format([nl|T], Fmt, Args) :- 2904 !, 2905 actions_to_format(T, Fmt0, Args), 2906 atom_concat('~n', Fmt0, Fmt). 2907actions_to_format([ansi(_Attrs, Fmt0, Args0)|Tail], Fmt, Args) :- 2908 !, 2909 actions_to_format(Tail, Fmt1, Args1), 2910 atom_concat(Fmt0, Fmt1, Fmt), 2911 append_args(Args0, Args1, Args). 2912actions_to_format([url(Pos)|Tail], Fmt, Args) :- 2913 !, 2914 actions_to_format(Tail, Fmt1, Args1), 2915 url_actions_to_format(url(Pos), Fmt1, Args1, Fmt, Args). 2916actions_to_format([url(URL, Label)|Tail], Fmt, Args) :- 2917 !, 2918 actions_to_format(Tail, Fmt1, Args1), 2919 url_actions_to_format(url(URL, Label), Fmt1, Args1, Fmt, Args). 2920actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :- 2921 !, 2922 actions_to_format(Tail, Fmt1, Args1), 2923 atom_concat(Fmt0, Fmt1, Fmt), 2924 append_args(Args0, Args1, Args). 2925actions_to_format([Skip|T], Fmt, Args) :- 2926 action_skip(Skip), 2927 !, 2928 actions_to_format(T, Fmt, Args). 2929actions_to_format([Term|Tail], Fmt, Args) :- 2930 atomic(Term), 2931 !, 2932 actions_to_format(Tail, Fmt1, Args), 2933 atom_concat(Term, Fmt1, Fmt). 2934actions_to_format([Term|Tail], Fmt, Args) :- 2935 actions_to_format(Tail, Fmt1, Args1), 2936 atom_concat('~w', Fmt1, Fmt), 2937 append_args([Term], Args1, Args). 2938 2939action_skip(at_same_line). 2940action_skip(flush). 2941action_skip(flush(_Ctx)). 2942action_skip(eol). 2943action_skip(eol(_Ctx)). 2944action_skip(begin(_Level, _Ctx)). 2945action_skip(end(_Ctx)). 2946 2947url_actions_to_format(url(File:Line:Column), Fmt1, Args1, Fmt, Args) :- 2948 !, 2949 atom_concat('~w:~d:~d', Fmt1, Fmt), 2950 append_args([File,Line,Column], Args1, Args). 2951url_actions_to_format(url(File:Line), Fmt1, Args1, Fmt, Args) :- 2952 !, 2953 atom_concat('~w:~d', Fmt1, Fmt), 2954 append_args([File,Line], Args1, Args). 2955url_actions_to_format(url(File), Fmt1, Args1, Fmt, Args) :- 2956 !, 2957 atom_concat('~w', Fmt1, Fmt), 2958 append_args([File], Args1, Args). 2959url_actions_to_format(url(_URL, Label), Fmt1, Args1, Fmt, Args) :- 2960 !, 2961 link_label(Label, Fmt0, Args0), 2962 atom_concat(Fmt0, Fmt1, Fmt), 2963 append_args(Args0, Args1, Args). 2964 2965 2966append_args(M:Args0, Args1, M:Args) :- 2967 !, 2968 strip_module(Args1, _, A1), 2969 to_list(Args0, Args01), 2970 '$append'(Args01, A1, Args). 2971append_args(Args0, Args1, Args) :- 2972 strip_module(Args1, _, A1), 2973 to_list(Args0, Args01), 2974 '$append'(Args01, A1, Args). 2975 2976 /******************************* 2977 * MESSAGES TO PRINT ONCE * 2978 *******************************/ 2979 2980:- dynamic 2981 printed/2.
2987print_once(compatibility(_), _). 2988print_once(null_byte_in_path(_), _). 2989print_once(deprecated(_), _).
2995must_print(Level, Message) :- 2996 nonvar(Message), 2997 print_once(Message, Level), 2998 !, 2999 \+ printed(Message, Level), 3000 assert(printed(Message, Level)). 3001must_print(_, _)