diff --git a/library/main.pl b/library/main.pl index f87feea0b4..acacce7a0f 100644 --- a/library/main.pl +++ b/library/main.pl @@ -3,7 +3,7 @@ Author: Jan Wielemaker E-mail: J.Wielemaker@vu.nl WWW: http://www.swi-prolog.org - Copyright (c) 2002-2016, University of Amsterdam + Copyright (c) 2002-2017, University of Amsterdam VU University Amsterdam All rights reserved. @@ -49,7 +49,7 @@ == #!/usr/bin/env swipl -:- initialization main. +:- initialization(main, main). main(Argv) :- echo(Argv). @@ -71,7 +71,9 @@ %! main % -% Call main/1 using the passed command-line arguments. +% Call main/1 using the passed command-line arguments. Before calling +% main/1 this predicate installs a signal handler for =SIGINT= +% (Control-C) that terminates the process with status 1. main :- context_module(M), diff --git a/man/builtin.doc b/man/builtin.doc index 070789d6d1..f8d248119d 100644 --- a/man/builtin.doc +++ b/man/builtin.doc @@ -809,13 +809,40 @@ compatibility issue. Similar to initialization/1, but allows for specifying when \arg{Goal} is executed while loading the program text: - \begin{description} - \termitem{now}{} Execute \arg{Goal} immediately. - \termitem{after_load}{} Execute \arg{Goal} after loading - program text. This is the same as initialization/1. - \termitem{restore}{} Do not execute \arg{Goal} while loading - the program, but \emph{only} when restoring a state. - \end{description} +\begin{description} + \termitem{now}{} Execute \arg{Goal} immediately. + + \termitem{after_load}{} Execute \arg{Goal} after loading the +program text in which the directive appears. This is the same as +initialization/1. + + \termitem{restore}{} +Do not execute \arg{Goal} while loading the program, but \emph{only} +when restoring a saved state. + + \termitem{program}{} +Execute \arg{Goal} once after executing the \cmdlineoption{-g} goals +at program startup. Registered goals are executed in the order +encountered and a failure or exception causes the Prolog to exit with +non-zero exit status. These goals are \emph{not} executed if the +\cmdlineoption{-l} is given to merely \emph{load} files. In that case +they may be executed explicitly using initialize/0. See also +\secref{plscript}. + + \termitem{main}{} +When Prolog starts, the last goal registered using +\term{initialization}{Goal, main} is executed as main goal. If +\arg{Goal} fails or raises an exception, the process terminates with +non-zero exit code. If \arg{Goal} succeeds, the process terminates +with zero exit code. See also \secref{plscript}. +\end{description} + + \predicate[det]{initialization}{0}{} +Run all initialization goals registered using +\term{initialization}{Goal, program}. Raises an error +\term{initialization_error}{Reason, Goal, File:Line} if \arg{Goal} +fails or raises an exception. \arg{Reason} is \const{failed} or +the exception raised. \predicate{compiling}{0}{} True if the system is compiling source files with the \cmdlineoption{-c} diff --git a/man/overview.doc b/man/overview.doc index 6223a9ed17..8dff1e9f87 100644 --- a/man/overview.doc +++ b/man/overview.doc @@ -844,16 +844,14 @@ vs.\ Windows). \subsubsection{Using PrologScript} \label{sec:plscript} A Prolog source file can be used directly as a Unix program using the -Unix \verb$#!$ magic start. The same mechanism is useful for specifying -additional parameters for running a Prolog file on Windows. The Unix -\verb$#!$ magic is allowed because if the first letter of a Prolog file -is \verb$#$, the first line is treated as a comment.\footnote{The -\texttt{\#}-sign can be the legal start of a normal Prolog clause. In -the unlikely case this is required, leave the first line blank or add a -header comment.} To create a Prolog script, use one of the two -alternatives below as first line. The first can be used to bind a script -to a specific Prolog installation, while the latter uses the default -prolog installed in \verb"$PATH". +Unix \verb$#!$ magic start. The Unix \verb$#!$ magic is allowed because +if the first letter of a Prolog file is \verb$#$, the first line is +treated as a comment.\footnote{The \texttt{\#}-sign can be the legal +start of a normal Prolog clause. In the unlikely case this is required, +leave the first line blank or add a header comment.} To create a Prolog +script, use one of the two alternatives below as first line. The first +can be used to bind a script to a specific Prolog installation, while +the latter uses the default prolog installed in \verb"$PATH". \begin{code} !/path/to/swipl @@ -866,26 +864,25 @@ portability, the \verb$#!$ must be followed immediately with an absolute path to the executable and should have none or one argument. Neither the executable path, nor the argument shall use quotes or spaces. When started this way, the Prolog flag \prologflag{argv} contains the command -line arguments that follow the script invocation. Below is a simple -script doing expression evaluation: +line arguments that follow the script invocation. + +Starting with version 7.5.8, initialization/2 support the \arg{When} +options \const{program} and \const{main}, allowing for the following +definition of a Prolog script that evaluates an arithmetic expression on +the command line. Note that main/0 is defined lib the library +\pllib{main}. It calls main/1 with the command line arguments after +disabling signal handling. \begin{code} #!/usr/bin/env swipl -:- initialization main. +:- initialization(main, main). -eval :- - current_prolog_flag(argv, Argv), +main(Argv) :- concat_atom(Argv, ' ', SingleArg), term_to_atom(Term, SingleArg), Val is Term, format('~w~n', [Val]). - -main :- - catch(eval, E, (print_message(error, E), fail)), - halt. -main :- - halt(1). \end{code} And here are two example runs: @@ -895,7 +892,6 @@ And here are two example runs: 3 % ./eval foo ERROR: is/2: Arithmetic: `foo/0' is not a function -% \end{code} The Windows version simply ignores the \verb$#!$ line.\footnote{Older diff --git a/man/summary.doc b/man/summary.doc index 562e0502c0..ab3504bad3 100644 --- a/man/summary.doc +++ b/man/summary.doc @@ -337,6 +337,7 @@ suggest predicates from a keyword. \predicatesummary{include}{1}{Include a file with declarations} \predicatesummary{initialization}{1}{Initialization directive} \predicatesummary{initialization}{2}{Initialization directive} +\predicatesummary{initialize}{0}{Run program initialization} \predicatesummary{instance}{2}{Fetch clause or record from reference} \predicatesummary{integer}{1}{Type check for integer} \predicatesummary{interactor}{0}{Start new thread with console and top level}