% This LaTeX document was generated using the LaTeX backend of PlDoc, % The SWI-Prolog documentation system \section{library(main): Provide entry point for scripts} \label{sec:main} \begin{tags} \mtag{See also}- \file{library(prolog_stack)} to force backtraces in case of an uncaught exception. \\- XPCE users should have a look at \file{library(pce_main)}, which starts the GUI and processes events until all windows have gone. \end{tags} This library is intended for supporting PrologScript on Unix using the \verb$#!$ magic sequence for scripts using commandline options. The entry point \predref{main}{0} calls the user-supplied predicate \predref{main}{1} passing a list of commandline options. Below is a simle \const{echo} implementation in Prolog. \begin{code} #!/usr/bin/env swipl :- initialization(main, main). main(Argv) :- echo(Argv). echo([]) :- nl. echo([Last]) :- !, write(Last), nl. echo([H|T]) :- write(H), write(' '), echo(T). \end{code} \vspace{0.7cm} \begin{description} \predicate{main}{0}{} Call \predref{main}{1} using the passed command-line arguments. Before calling \predref{main}{1} this predicate installs a signal handler for \verb$SIGINT$ (Control-C) that terminates the process with status 1. When \predref{main}{0} is called interactively it simply calls \predref{main}{1} with the arguments. This allows for debugging scripts as follows: \begin{code} $ swipl -l script.pl -- arg ... ?- gspy(suspect/1). % setup debugging ?- main. % run program \end{code} \predicate[det]{argv_options}{3}{:Argv, -Positional, -Options} Parse command line arguments. This predicate acts in one of two modes. \begin{itemize} \item If the calling module defines \predref{opt_type}{3}, full featured parsing with long and short options, type conversion and help is provided. \item If \predref{opt_type}{3} is not defined, only unguided transformation using long options is supported. See \predref{argv_untyped_options}{3} for details. \end{itemize} When \textbf{guided}, three predicates are called in the calling module. \predref{opt_type}{3} \textbf{must} be defined, the others need not. Note that these three predicates \textit{may} be defined as \textit{multifile} to allow multiple modules contributing to the provided commandline options. Defining them as \textit{discontiguous} allows for creating blocks that describe a group of related options. \begin{description} \termitem{opt_type}{Opt, Name, Type} Defines \arg{Opt} to add an option \arg{Name}(Value), where Value statisfies \arg{Type}. \arg{Opt} does not include the leading \verb$-$. A single character implies a short option, multiple a long option. Long options use \verb$_$ as \textit{word separator}, user options may use either \verb$_$ or \verb$-$. \arg{Type} is one of: \begin{description} \infixtermitem{\Sbar}{\arg{A}}{\arg{B}} Disjunctive type. Disjunction can be used create long options with optional values. For example, using the type \verb$nonneg|boolean$, for an option \const{http} handles \verb$--http$ as \verb$http(true)$, \verb$--no-http$ as \verb$http(false)$, \verb$--http=3000$ and \verb$--http 3000$ as \verb$http(3000)$. With an optional boolean an option is considered boolean if it is the last or the next argument starts with a hyphen (\verb$-$). \termitem{boolean}{Default} \termitem{boolean}{} Boolean options are special. They do not take a value except for when using the long \verb$--opt=value$ notation. This explicit value specification converts \verb$true$, \verb$True$, \verb$TRUE$, \verb$on$, \verb$On$, \verb$ON$, \verb$1$ and the obvious false equivalents to Prolog \const{true} or \const{false}. If the option is specified, Default is used. If \verb$--no-opt$ or \verb$--noopt$ is used, the inverse of Default is used. \termitem{integer}{} Argument is converted to an integer \termitem{float}{} Argument is converted to a float. User may specify an integer \termitem{nonneg}{} As \const{integer}. Requires value \Sge{} 0. \termitem{natural}{} As \const{integer}. Requires value \Sge{} 1. \termitem{number}{} Any number (integer, float, rational). \termitem{between}{Low, High} If both one of \arg{Low} and \arg{High} is a float, convert as \const{float}, else convert as \const{integer}. Then check the range. \termitem{atom}{} No conversion \termitem{oneof}{List} As \const{atom}, but requires the value to be a member of \arg{List} (\textit{enum} type). \termitem{string}{} Convert to a SWI-Prolog string \termitem{file}{} Convert to a file name in Prolog canonical notation using \predref{prolog_to_os_filename}{2}. \termitem{directory}{} Convert to a file name in Prolog canonical notation using \predref{prolog_to_os_filename}{2}. No checking is done and thus this type is the same as \const{file} \termitem{file}{Access} As \const{file}, and check access using \predref{access_file}{2}. A value \verb$-$ is not checked for access, assuming the application handles this as standard input or output. \termitem{directory}{Access} As \const{directory}, and check access. \arg{Access} is one of \const{read} \const{write} or \const{create}. In the latter case the parent directory must exist and have write access. \termitem{term}{} Parse option value to a Prolog term. \termitem{term}{+Options} As \const{term}, but passes \arg{Options} to \predref{term_string}{3}. If the option \verb$variable_names(Bindings)$ is given the option value is set to the \textit{pair} \verb$Term-Bindings$. \end{description} \termitem{opt_help}{Name, HelpString} Help string used by \predref{argv_usage}{1}. \termitem{opt_meta}{Name, Meta} If a typed argument is required this defines the placeholder in the help message. The default is the uppercase version of the type \textit{functor name}. This produces the \verb$FILE$ in e.g. \verb$-f FILE$. \end{description} By default, \verb$-h$, \verb$-?$ and \verb$--help$ are bound to help. If \verb$opt_type(Opt, help, boolean)$ is true for some \arg{Opt}, the default help binding and help message are disabled and the normal user rules apply. In particular, the user should also provide a rule for \verb$opt_help(help, String)$. \predicate[det]{argv_options}{4}{:Argv, -Positional, -Options, +ParseOptions} As \predref{argv_options}{3} in \textbf{guided} mode, Currently this version allows parsing argument options throwing an exception rather than calling \predref{halt}{1} by passing an empty list to \arg{ParseOptions}. \arg{ParseOptions}: \begin{description} \termitem{on_error}{+Goal} If \arg{Goal} is \verb$halt(Code)$, exit with Code. Other goals are currently not supported. \termitem{options_after_arguments}{+Boolean} If \const{false} (default \const{true}), stop parsing after the first positional argument, returning options that follow this argument as positional arguments. E.g, \verb$-x file -y$ results in positional arguments \verb$[file, '-y']$ \end{description} \predicate[det]{argv_usage}{1}{:Level} Use \predref{print_message}{2} to print a usage message at \arg{Level}. To print the message as plain text indefault color, use \const{debug}. Other meaningful options are \const{informational} or \const{warning}. The help page consists of four sections, two of which are optional: \begin{enumerate} \item The \textbf{header} is created from \verb$opt_help(help(header), String)$. It is optional. \item The \textbf{usage} is added by default. The part behind \verb$Usage: $ is by default \verb$[options]$ and can be overruled using \verb$opt_help(help(usage), String)$. \item The actual option descriptions. The options are presented in the order they are defined in \predref{opt_type}{3}. Subsequent options for the same \textit{destination} (option name) are joined with the first. \item The \textit{footer_} is created from \verb$opt_help(help(footer), String)$. It is optional. \end{enumerate} The help provided by \verb$help(header)$, \verb$help(usage)$ and \verb$help(footer)$ are either a simple string or a list of elements as defined by \predref{print_message_lines}{3}. In the latter case, the construct \verb$\Callable$ can be used to call a DCG rule in the module from which the user calls \predref{argv_options}{3}. For example, we can add a bold title using \begin{code} opt_help(help(header), [ansi(bold, '~w', ['My title'])]). \end{code} \predicate[det]{cli_parse_debug_options}{2}{+OptionsIn, -Options} Parse certain commandline options for debugging and development purposes. \arg{Options} processed are below. Note that the option argument is an atom such that these options may be activated as e.g., \verb$--debug='http(_)'$. \begin{description} \termitem{debug}{Topic} Call \verb$debug(Topic)$. See \predref{debug}{1} and \predref{debug}{3}. \termitem{spy}{Predicate} Place a spy-point on \arg{Predicate}. \termitem{gspy}{Predicate} As spy using the graphical debugger. See \predref{tspy}{1}. \termitem{interactive}{true} Start the Prolog toplevel after \predref{main}{1} completes. \end{description} \predicate{cli_debug_opt_type}{3}{-Flag, -Option, -Type} \nodescription \predicate{cli_debug_opt_help}{2}{-Option, -Message} \nodescription \predicate{cli_debug_opt_meta}{2}{-Option, -Arg} Implements \predref{opt_type}{3}, \predref{opt_help}{2} and \predref{opt_meta}{2} for debug arguments. Applications that wish to use these features can call these predicates from their own hook. Fot example: \begin{code} opt_type(..., ..., ...). % application types opt_type(Flag, Opt, Type) :- cli_debug_opt_type(Flag, Opt, Type). % similar for opt_help/2 and opt_meta/2 main(Argv) :- argv_options(Argv, Positional, Options0), cli_parse_debug_options(Options0, Options), ... \end{code} \predicate{cli_enable_development_system}{0}{} Re-enable the development environment. Currently re-enables xpce if this was loaded, but not initialised and causes the interactive toplevel to be re-enabled. This predicate may be called from \predref{main}{1} to enter the Prolog toplevel rather than terminating the application after \predref{main}{1} completes. \end{description}