<!--  vim: set sw=2 sts=2 et ft=docbk:

  Part of the A-A-P recipe executive: The documentation intro

  Copyright (C) 2002-2003 Stichting NLnet Labs
  Permission to copy and use this file is specified in the file COPYING.
  If this file is missing you can find it here: http://www.a-a-p.org/COPYING

-->

<bridgehead>Commands grouped by functionality</bridgehead>

<para>
  <informaltable frame='none'>
    <tgroup cols='2'>
      <colspec colwidth="200" colname="c1"/>
      <colspec colname="c2"/>
      <tbody>
        <row>
        <entry namest="c1" nameend="c2">Dependencies</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-program">:program</link></entry>
        <entry> Define the sources for an executable program.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-lib">:lib</link></entry>
        <entry> Define the sources for a static library.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-ltlib">:ltlib</link></entry>
        <entry> Define the sources for a library to be made with
          libtool.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-dll">:dll</link></entry>
        <entry> Define the sources for a shared (dynamically loaded)
        library.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-produce">:produce</link></entry>
        <entry> Generic way to build something from sources.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-totype">:totype</link></entry>
        <entry> Use routes to turn one filetype into another.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-rule">:rule</link></entry>
        <entry> Define build commands for files matching a pattern.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-delrule">:delrule</link></entry>
        <entry> Delete a specific rule.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-clearrules">:clearrules</link></entry>
        <entry> Delete all rules.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-update">:update</link></entry>
        <entry> Update a target, build it when it is outdated.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-changed">:changed</link></entry>
        <entry> Mark a file as changed.</entry>
        </row>
        <row>
        <entry>&nbsp;</entry>
        <entry></entry>
        </row>
        <row>
        <entry namest="c1" nameend="c2">Recipes</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-child">:child</link></entry>
        <entry> Read a child recipe.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-include">:include</link></entry>
        <entry> Include another recipe.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-import">:import</link></entry>
        <entry> Include a module from the &Aap; distribution.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-execute">:execute</link></entry>
        <entry> Execute a recipe.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-recipe">:recipe</link></entry>
        <entry> Define the URL where the recipe can be obtaind from.</entry>
        </row>
        <row>
        <entry>&nbsp;</entry>
        <entry></entry>
        </row>
        <row>
        <entry namest="c1" nameend="c2">Actions</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-action">:action</link></entry>
        <entry> Define commands for an action.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-do">:do</link></entry>
        <entry> Invoke an action.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-route">:route</link></entry>
        <entry> Define a route of actions to turn one filetype into another.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-filetype">:filetype</link></entry>
        <entry> Define filetype detection.</entry>
        </row>
        <row>
        <entry>&nbsp;</entry>
        <entry></entry>
        </row>
        <row>
        <entry namest="c1" nameend="c2">Up- and Downloading</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-fetch">:fetch</link></entry>
        <entry> Download files.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-fetchall">:fetchall</link></entry>
        <entry> Download all files with a "fetch" attribute.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-publish">:publish</link></entry>
        <entry> Upload the specified files.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-publishall">:publishall</link></entry>
        <entry> Upload all files with a "publish" attribute.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-mkdownload">:mkdownload</link></entry>
        <entry> Create a recipe to download files.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-proxy">:proxy</link></entry>
        <entry> Define a proxy server.</entry>
        </row>
        <row>
        <entry>&nbsp;</entry>
        <entry></entry>
        </row>
        <row>
        <entry namest="c1" nameend="c2">Version control</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-add">:add</link></entry>
        <entry> Add a file to the version control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-addall">:addall</link></entry>
        <entry> Add all files with a "commit" attribute to the version control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-checkin">:checkin</link></entry>
        <entry> Checkin a file into the version control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-checkinall">:checkinall</link></entry>
        <entry> Checkin all files with a "commit" attribute into the version
        control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-checkout">:checkout</link></entry>
        <entry> Checkout a file from the version control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-checkoutall">:checkoutall</link></entry>
        <entry> Checkout all files with a "commit" attribute from the version
        control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-commit">:commit</link></entry>
        <entry> Commit files to the version control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-commitall">:commitall</link></entry>
        <entry> Commit all files with a "commit" attribute to the version
        control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-remove">:remove</link></entry>
        <entry> Remove a file from the version control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-removeall">:removeall</link></entry>
        <entry> Remove all file without the "commit" attribute from the version
        control repository.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-reviseall">:reviseall</link></entry>
        <entry> combination of :checkinall and :removeall.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-tag">:tag</link></entry>
        <entry> Add a tag in the version control repository for a file.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-tagall">:tagall</link></entry>
        <entry> Add a tag in the version control repository for all files with
        the "commit" attribute .</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-unlock">:unlock</link></entry>
        <entry> Unlock a checked out file.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-unlockall">:unlockall</link></entry>
        <entry> Unlock all checked out files with the "commit" attribute.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-verscont">:verscont</link></entry>
        <entry> Generic version control command.</entry>
        </row>
        <row>
        <entry>&nbsp;</entry>
        <entry></entry>
        </row>
        <row>
        <entry namest="c1" nameend="c2">System commands</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-asroot">:asroot</link></entry>
        <entry> Execute a command as the system administrator.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-sys">:sys</link></entry>
        <entry> Execute a system command.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-sys">:system</link></entry>
        <entry> Execute a system command.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-start">:start</link></entry>
        <entry> Run a system command asynchronously.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-syseval">:syseval</link></entry>
        <entry> Execute a system command and catch the output.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-sysdepend">:sysdepend</link></entry>
        <entry> Execute a system command to figure out dependencies.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-syspath">:syspath</link></entry>
        <entry> Execute one of a number of commands.</entry>
        </row>
        <row>
        <entry>&nbsp;</entry>
        <entry></entry>
        </row>
        <row>
        <entry namest="c1" nameend="c2">Pipe commands</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-assign">:assign</link></entry>
        <entry> Assign stdin to a variable.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-cat">:cat</link></entry>
        <entry> List or concatenate files.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-print">:print</link></entry>
        <entry> Print a message</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-log">:log</link></entry>
        <entry> Write a message to the log file</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-tee">:tee</link></entry>
        <entry> Echo stdin to stdout and also write it in a file. </entry>
        </row>
        <row>
        <entry> <link linkend="cmd-eval">:eval</link></entry>
        <entry> Evaluate a Python expression</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-syseval">:syseval</link></entry>
        <entry> Execute a system command and catch the output.</entry>
        </row>
        <row>
        <entry>&nbsp;</entry>
        <entry></entry>
        </row>
        <row>
        <entry namest="c1" nameend="c2">File system commands</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-copy">:copy</link></entry>
        <entry> Copy files.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-move">:move</link></entry>
        <entry> Rename or move a file.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-symlink">:symlink</link></entry>
        <entry> Create a symbolic link.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-chmod">:chmod</link></entry>
        <entry> Change the protection bits of a file.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-del">:del</link></entry>
        <entry> Delete files.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-del">:delete</link></entry>
        <entry> Delete files.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-deldir">:deldir</link></entry>
        <entry> Delete directories.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-mkdir">:mkdir</link></entry>
        <entry> Create a directory.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-touch">:touch</link></entry>
        <entry> Create a file and/or update its timestamp.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-tree">:tree</link></entry>
        <entry> Execute commands for a directory tree.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-cd">:cd</link></entry>
        <entry> Change directory.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-chdir">:chdir</link></entry>
        <entry> Change directory.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-pushdir">:pushdir</link></entry>
        <entry> Change directory and remember the previous one.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-popdir">:popdir</link></entry>
        <entry> Change to an older directory.</entry>
        </row>
        <row>
        <entry>&nbsp;</entry>
        <entry></entry>
        </row>
        <row>
        <entry namest="c1" nameend="c2">Various</entry>
        <entry></entry>
        </row>
        <row>
        <entry> <link linkend="cmd-attr">:attr</link></entry>
        <entry> Attach attributes to items.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-attr">:attribute</link></entry>
        <entry> Attach attributes to items.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-buildcheck">:buildcheck</link></entry>
        <entry> Add a string to the build command signature.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-exit">:exit</link></entry>
        <entry> Stop execution.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-quit">:quit</link></entry>
        <entry> Stop execution.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-pass">:pass</link></entry>
        <entry> Do nothing.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-variant">:variant</link></entry>
        <entry> Define build variants.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-python">:python</link></entry>
        <entry> Execute Python commands.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-conf">:conf</link></entry>
        <entry> Do a configuration check.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-progsearch">:progsearch</link></entry>
        <entry> Search for an executable program.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-assertpkg">:assertpkg</link></entry>
        <entry> Check if a package is present, install it when not.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-installpkg">:installpkg</link></entry>
        <entry> Install a package unconditionally.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-usetool">:usetool</link></entry>
        <entry> Specify what tool to use.</entry>
        </row>
        <row>
        <entry> <link linkend="cmd-toolsearch">:toolsearch</link></entry>
        <entry> Search for tools that can be used.</entry>
        </row>
      </tbody>
    </tgroup>
  </informaltable>
</para>


<bridgehead>Alphabetical list of Commands</bridgehead>

  <para>
    This is the alphabetical list of all A-A-P commands.
    Common arguments are explained
    <link linkend="common-arguments">at the end</link>.
  </para>

  <para>
Some commands can be used in a pipe.  A pipe is a sequence of commands
separated by '|', where the output of one command is the input for the next
command.  Example:
<programlisting>
        :cat foo | :eval re.sub('this', 'that', stdin) | :assign bar
</programlisting>
Unix tradition calls the output that can be redirected or piped "stdout".
Reading input from a pipe is called "stdin".
  </para>

<para>
In the commands below [redir] indicates the possibility to redirect stdout.
</para>

<para>
<variablelist>

  <varlistentry id="cmd-action"><term><cmdsynopsis>
    <command>:action</command>
      <arg choice="plain"><replaceable>action</replaceable></arg>
      <arg choice="plain"><replaceable>filetype-out</replaceable></arg>
      <arg><replaceable>filetype-in</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Define the commands for an action.
        See <xref linkend="user-filetype"/>.
        <programlisting>
        :action makeme {primary} me moo
            :sys me &lt; $source &gt; $target
</programlisting>
        The optional {primary} attribute, just after the action name,
        indicates that this is the preferred action to be used for turning the
        specified input filetypes into the specified output filetypes.
      </para>
      <para>
        See <link linkend="cmd-do">:do</link> for executing actions.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id="cmd-add"><term><cmdsynopsis>
    <command>:add</command>
      <arg rep="repeat">{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice="plain"><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Add the files to the repository.  The files must exist locally.
      Implies a "commit" of the files.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id="cmd-addall"><term><cmdsynopsis>
    <command>:addall</command>
      <arg rep="repeat"><replaceable>option</replaceable></arg>
      <arg rep="repeat">{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep="repeat"><replaceable>directory</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Apply the <literal>:add</literal> command to all files in the directory that
      have been given the "commit" attribute in the recipe (and child recipes)
      but do not exist in the repository.
      </para>
      <para>
        <informaltable frame="none">
          <tgroup cols="2">
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
              <entry>{l} {local}</entry>
              <entry>don't do current directory recursively</entry>
              </row>
              <row>
              <entry>{r} {recursive}</entry>
              <entry>do handle arguments recursively</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        </para>
        <para>
                When no directory argument is given, the current directory is
                used.  It is inspected recursively, unless the "{local}"
                option was given.
        </para>
        <para>
                When directory arguments are given, each directory is
                inspected.  Recursively when the "{recursive}" option was
                given.
        </para>
        <para>
                When no "commit" attribute is specified here, it will be
                obtained from any node.
            </para>
    </listitem>
  </varlistentry>


  <varlistentry id="cmd-asroot"><term><cmdsynopsis>
    <command>:asroot</command>
      <arg choice="plain"><replaceable>command</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
    <para>
    Execute shell command "command" in a separate shell with super-user
    privileges.  Only the first time the root password will have to be
    entered.  Each executed command must be confirmed by the user (for
    safety).
    </para>

    <para>
    The command will be executed in the current directory of the recipe.
    Variables in "command" will be expanded (no attributes, shell quoting).
    stdin and stdout are redirected, this cannot be used for interactive
    commands.
    </para>

    <para>
    On non-Unix systems and when running &Aap; as root this command is
    equivalent to
    <link linkend="cmd-system">:system</link>
    .
    </para>

    <para>
    When the user types "n" to refuse executing the command, 
    $sysresult will be set to a non-zero value.  If the command is executed
    successfully $sysresult is set to zero.  When the command fails an error
    message is generated.
    </para>

    <para>
    To execute recipe commands you need to start &Aap;, for example:
    </para>

    <programlisting>
        :asroot $AAP -c 'copy {r} foodir /usr/local/share'
</programlisting>

    <para>
    $AAP includes the Python interpreter, so that it works the same way as how
    the current &Aap; was started.
    </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-assertpkg'><term><cmdsynopsis>
    <command>:assertpkg</command>
      <arg choice='plain' rep='repeat'><replaceable>package</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        For each argument check if the command by that name can be found.
        If not, ask the user and attempt installing the package for it.
      </para>
      <para>
        Option: {optional} after the package name indicates the user may chose
        not to install the package.  Without this option the user cannot chose
        to continue without the package being installed.
      </para>
      <para>
        See <xref linkend="user-package"/> about using packages.
        See <link linkend="cmd-installpkg">:installpkg</link> for installing a
        package unconditionally.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-assign'><term><cmdsynopsis>
    <command>:assign</command>
      <arg choice='plain'><replaceable>varname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
       Assign stdin to a variable.  Can only be used after a "|".
       </para>
      <para>
        See <link linkend='arg-redir'>here</link> about using stdin.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-attr'><term><cmdsynopsis>
    <command>:attr</command>
      <arg rep='repeat'><replaceable>{attrname}</replaceable></arg>
      <arg choice='plain'><replaceable>itemname</replaceable></arg>
      <arg rep='repeat'><replaceable>{attrname}</replaceable></arg>
    <command>:attribute</command>
      <arg rep='repeat'><replaceable>{attrname}</replaceable></arg>
      <arg choice='plain'><replaceable>itemname</replaceable></arg>
      <arg rep='repeat'><replaceable>{attrname}</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Any "{attrname"} given before the items is added to each item in the
      list of items "itemname ...".
      The "{attrname"} give later are only added to the item just before it.
      </para>
      <para>
      A node is created for each "itemname".  This also means wildcards in
      item names will be expanded.
      </para>

      <para>
      Example:
      </para>
      <programlisting>
        :attr {fetch = cvs://} foo.c patch12 {constant}
</programlisting>
      <para>
      This adds the "fetch" attribute to both foo.c and patch12, and
      the "constant" attribute only to patch12.  This does the same in
      two commands:
      </para>
      <programlisting>
        :attr {fetch = cvs://} foo.c patch12
        :attr {constant} patch12
</programlisting>

      <para>
      Note: the attributes are added internally.  When using ":print
      $var" this only shows the attributes given by an assignment, not
      the ones added with
      <link linkend="cmd-attr">:attr</link>.
      </para>

    </listitem>
  </varlistentry>

  <varlistentry id='cmd-buildcheck'><term><cmdsynopsis>
    <command>:buildcheck</command>
      <arg choice='plain' rep='repeat'><replaceable>argument</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Doesn't do anything.  Placeholder for variables that are used
      but don't show up in build commands, so that they will be
      included in the buildcheck.
      </para>

    </listitem>
  </varlistentry>

  <varlistentry id='cmd-cat'><term><cmdsynopsis>
    <command>:cat</command>
      <arg><replaceable>redir</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Concatenate the arguments and write the result to stdout.
        Files are read like text files.
        The "-" argument can be used to get the output of a previous pipe
        command.
        When redirecting to a file this output file is created before
        the arguments are read, thus you cannot use the same file for input.
      </para>
      <para>
        See <link linkend='arg-redir'>here</link> for [redir].
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-cd'><term><cmdsynopsis>
    <command>:cd</command>
      <arg rep='repeat' choice='plain'><replaceable>dir</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Change directory to "dir".  When "dir" is "-" it goes back to the
      previous directory (it is an error if there was no previous
      <link linkend="cmd-cd">:cd</link>
      command in the current command block).
      </para>
      <para>
      When multiple arguments are given, they are concatenated with path
      separators inserted where needed.  This is similar to doing a
      <link linkend="cmd-cd">:cd</link> for
      each argument, except that each argument but the first one is as handled
      as a relative path:
      <programlisting>
        :cd  /tmp  /usr/local  bin
</programlisting>
       Is equivalent to:
      <programlisting>
        :cd  /tmp
        :cd  ./usr/local
        :cd  bin
</programlisting>
       </para>
       <para>
       If the target directory does not exist this command fails.  Use
       <link linkend="cmd-mkdir">:mkdir</link>
       first if needed (note:
       <link linkend="cmd-mkdir">:mkdir</link>
       does not contatenate its
       arguments!).
       </para>
       <para>
       Note that at the start of each command block &Aap; changes directory to
       the directory of the recipe.
       </para>
       <para>
       WARNING: variables with a relative path
       become invalid!  This includes $source and $target.  Use 
       <link linkend="python-var-abspath">var_abspath()</link>.
       when needed.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-changed'><term><cmdsynopsis>
    <command>:changed</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>name</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Consider file "name" changed, no matter whether it was
      really changed.
      </para>
      <para>
      Similar to the command line argument "--changed FILE".
      </para>
      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
              <entry>{r} {recursive}</entry>
              <entry>Targets build from file "name" will also be considered
              changed, recursively.</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-chdir'><term><cmdsynopsis>
    <command>:chdir</command>
      <arg choice='plain'><replaceable>dir</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Same as
        <link linkend="cmd-cd">:cd</link> .
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-checkin'><term><cmdsynopsis>
    <command>:checkin</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Commit the files to the repository and unlock them.
      Just like <literal>:commit</literal> and <literal>:unlock</literal>.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-checkinall'><term><cmdsynopsis>
    <command>:checkinall</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Apply the <literal>:checkin</literal> command to all files in the recipe (and
      child recipes) that have the "commit" attribute.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-checkout'><term><cmdsynopsis>
    <command>:checkout</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Obtain the latest version of the files from the repository.
      Lock the files for editing if possible.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-checkoutall'><term><cmdsynopsis>
    <command>:checkoutall</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Apply the <literal>:checkout</literal> command to all files in the recipe (and
      child recipes) that have the "commit" attribute.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-checksum'><term><cmdsynopsis>
    <command>:checksum</command>
      <arg choice='plain' rep='repeat'><replaceable>file</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        For each file argument compute the MD5 checksum and compare it to the
        "md5" attribute of the file.
        An error is generated when a file doesn't exist or when the
        checksums differ.
      </para>
      <para>
        This command is useful to check if a downloaded file was not damaged
        when downloading it.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-child'><term><cmdsynopsis>
    <command>:child</command>
      <arg><replaceable>{nopass}</replaceable></arg>
      <arg choice='plain'><replaceable>name</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Read recipe "name" as a child.  Works like the commands were in the
      parent recipe, with a number of exceptions:
      <orderedlist>
      <listitem><para>
      When "name" is in another directory, change to that directory and accept
      all items in it relative to that directory.
      </para></listitem>
      <listitem><para>
      Build commands defined in the child are executed in the directory of the
      child.  Thus it works as if executing the child recipe in the directory
      where it is located.
      </para></listitem>
      <listitem><para>
      The child recipe defines a new scope.  Variables set there without a
      scope specification will be local to the child recipe.
      </para></listitem>
      <listitem><para>
      When the {nopass} option is used, the child recipe is used as if it is a
      toplevel recipe.  Variables from the parent recipe are not available to
      the child.
      </para></listitem>
      <listitem><para>
      Build commands defined in the child recipe will be executed in the scope
      of that recipe.
      </para></listitem>
      </orderedlist>
      </para>
      <para>
        The "fetch" attribute is supported like with
        <link linkend="cmd-include">:include</link>.
      </para>
      <para>
        The
        <link linkend="cmd-child">:child</link> command can only appear at the
        recipe level.
      </para>

    </listitem>
  </varlistentry>

  <varlistentry id='cmd-chmod'><term><cmdsynopsis>
    <command>:chmod</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>mode</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>name</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Change the protection flags of a file or directory.  Currently "mode"
      must be an octal number, like used by the Unix "chmod" command.  Useful
      values:
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
              <row><entry>mode</entry><entry>meaning</entry></row>
            </thead>
            <tbody>
              <row>
                 <entry>755</entry>
                 <entry>executable for everyone, writable by
              user</entry>
              </row>
              <row>
                <entry>444</entry>
                <entry>read-only</entry>
              </row>
              <row>
                <entry>600</entry>
                <entry>read-write for the user only</entry>
              </row>
              <row>
                <entry>660</entry>
                <entry>read-write for user and group</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

    </para>
    <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
                <entry>{c} {continue}</entry>
                <entry>when an item with a wildcard does not have matches
                  continue with the next item</entry>
              </row>
              <row>
              <entry>{f} {force}</entry>
              <entry> don't give an error when the file doesn't exist </entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
    </para>

    </listitem>
  </varlistentry>

  <varlistentry id='cmd-clearrules'><term><cmdsynopsis>
    <command>:clearrules</command>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Delete all rules.  Also see
        <link linkend="cmd-delrule">:delrule</link>.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-commit'><term><cmdsynopsis>
    <command>:commit</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Update the repository for each file that was changed.
      This is also done for a file that didn't change, it's
      up to the version control software to check for an
      unchanged file (it might have been changed in the
      repository).
      </para>
      <para>
      Do checkout/checkin when checkout is required.
      </para>
      <para>
      Don't change locking of the file.
      </para>
      <para>
      Uses a "logentry" attribute when a log entry is to be
      done.  When there is no "logentry" attribute the
      $LOGENTRY variable is used.  If neither is given you
      are prompted to enter a message.
      </para>
      <para>
      Adds new files when needed.
      </para>
      <para>
      Creates directories when needed (CVS: only one level).
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-commitall'><term><cmdsynopsis>
    <command>:commitall</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Apply the <literal>:commit</literal> command to all files in the recipe (and
      child recipes) that have the "commit" attribute.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-conf'><term><cmdsynopsis>
        <command>:conf</command>
        <arg choice='plain'><replaceable>checkname</replaceable></arg>
        <arg rep='repeat'><replaceable>arg</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Configuration command.  See <xref linkend="user-configure"/>.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-copy'><term><cmdsynopsis>
    <command>:copy</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>from</replaceable></arg>
      <arg choice='plain'><replaceable>to</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Copy files or directory trees.  "from" and "to" may be
        URLs.  This means :copy can be used to upload and
        download a file, or even copy a file from one remote
        location to another.  Examples:
        </para>
        <programlisting>
        :copy file_org.c  file_dup.c
        :copy {r}  onedir  twodir
        :copy *.c backups
        :copy http://vim.sf.net/download.php download.php
        :copy $ZIP ftp://upload.sf.net//incoming/$ZIP
        :copy ftp://foo.org/README ftp://bar.org//mirrors/foo/README
</programlisting>
        <para>
        Note that "ftp://machine/path" uses "path" relative to
        the login directory, while "ftp://machine//path" uses
        "/path" absolutely.
        </para>
        <para>
        When "from" and "to" are directories, "from" is
        created in "to".  Unlike the Unix "cp" command, where
        this depends on whether "to" exists or not.  Thus:
        </para>
        <programlisting>
        :copy {recursive} foo bar
</programlisting>
        <para>
        will create the directory "bar/foo" if it doesn't
        exist yet.  If the contents of "foo" is to be copied
        without creating "bar/foo", use this:
        </para>
        <programlisting>
        :copy {recursive} foo/* bar
</programlisting>

    <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
        <entry>{c} {continue}</entry>
        <entry>when an item with a wildcard does not have matches continue
          with the next item</entry>
              </row>
              <row>
        <entry>{e} {exist} {exists}</entry>
        <entry>don't overwrite an existing file or directory</entry>
              </row>
              <row>
        <entry>{f} {force}</entry>
        <entry>forcefully overwrite an existing file or dir (default)</entry>
              </row>
              <row>
        <entry>{i} {interactive}</entry>
        <entry>before overwriting a local file, prompt for confirmation
        (currently doesn't work for remote files)</entry>
              </row>
              <row>
        <entry>{k} {keepdir}</entry>
        <entry>keep the directory of the source file if the target is a
          directory; the targetfile name is the target directory with the
          source file name appended</entry>
              </row>
              <row>
        <entry>{m} {mkdir}</entry>
        <entry>create destination directory when needed</entry>
              </row>
              <row>
        <entry>{p} {preserve}</entry>
        <entry>preserve file permissions and timestamps as much as
        possible</entry>
              </row>
              <row>
        <entry>{q} {quiet}</entry>
        <entry>don't report copied files</entry>
              </row>
              <row>
        <entry>{r} {recursive}</entry>
        <entry>recursive, copy a directory tree.  "to" is created and should
        not exist yet.</entry>
              </row>
              <row>
        <entry>{u} {unlink}</entry>
        <entry>when used with {recursive}, don't copy a symlink, make a copy
        of the file or dir it links to</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
    </para>

    <para>
        Wildcards in local files are expanded.  This uses Unix
        style wildcards.  When there is no matching file the
        command fails (also when there are enough other
        arguments).
    </para>

      <para>
        When (after expanding wildcards) there is more than
        one "from" item, the "to" item must be a directory.
    </para>

      <para>
        For "to" only local files, ftp://, rcp://, rsync://
        and scp:// can be used.  See "URLs" for info on
        forming URLs.
    </para>

      <para>
        Attributes for "from" and "to" are currently ignored.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-del'><term><cmdsynopsis>
    <command>:del</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>file</replaceable></arg>
    <command>:delete</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>file</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Delete files and/or directories.
        </para>

    <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
        <entry>{f} {force}</entry>
        <entry>don't fail when a file doesn't exist</entry>
              </row>
              <row>
        <entry>{r} {recursive}</entry>
        <entry>delete directories and their contents recursively.</entry>
              </row>
              <row>
        <entry>{q} {quiet}</entry>
        <entry>don't report deleted files</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
    </para>

      <para>
        Wildcards in local files are expanded.  This uses Unix
        style wildcards.  When there is no matching file the
        command fails (also when there are enough other
        arguments).
      </para>

      <para>
        When deleting a symbolic link, the link itself is deleted, not the
        file or directory it refers to.
      </para>

      <para>
        CAREFUL: if you make a mistake in the argument,
        anything might be deleted.  For example, accidentally
        inserting a space before a wildcard:
        </para>
        <programlisting>
        :del {r} dir/temp *
</programlisting>

      <para>
        To give you some protection, the command aborts on the
        first error.  Thus if "dir/temp" didn't exist in the
        example, "*" would not be deleted.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-deldir'><term><cmdsynopsis>
    <command>:deldir</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>dir</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Delete a directory.  Fails when the directory is not empty.
      </para>
    <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
                <entry>{c} {continue}</entry>
                <entry>when an item with a wildcard does not have matches
                  continue with the next item</entry>
              </row>
              <row>
        <entry>{f} {force}</entry>
        <entry>don't fail when a directory doesn't exist; still fails when it exists but is not a directory or could not be deleted</entry>
              </row>
              <row>
        <entry>{q} {quiet}</entry>
        <entry>don't report deleted directories</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
          
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-delrule'><term><cmdsynopsis>
    <command>:delrule</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain' rep='repeat'><replaceable>tpat</replaceable></arg>
      <arg choice='plain' rep='repeat'><replaceable>spat</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Delete an existing rule.  Can be used when one of the
        default rules would be used when this is not wanted.
        </para>
    <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
        <entry>{q} {quiet}</entry>
        <entry>don't complain when there is no matching rule</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
          
      </para>

        <para>
        Also see <link linkend="cmd-clearrules">:clearrules</link>.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-dll'><term><cmdsynopsis>
    <command>:dll</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>target</replaceable></arg>
      <arg choice='plain'>:</arg>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg choice='plain' rep='repeat'><replaceable>source</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Specify that "target" is a shared (dynamic) library,
        build from "source".  Dependencies will be added to
        compile "source" into an object file and combine the
        object files together into "target".
        </para>
        <para>
        When the basename of "target" does not contain a dot,
        $DLLPRE will be prepended and $DLLSUF will be
        appended.  The original name becomes an alias name for
        the target, so that this works:
        </para>
        <programlisting>
        all: foo bar
        :dll foo : foo.c
        :dll bar : bar.c
</programlisting>
        <para>
        On Unix this builds libfoo.so and libbar.so.
        </para>
      <para>
        See <link linkend="cmd-produce">:produce</link> for the most important
        options.
        The default values used for ":dll" are:
        $DLLSUF for "targetsuffix", $DLLPRE for "targetprefix"
        $DLLOBJSUF for "objectsuffix", "dllobject" for "objecttype",
        "INSTALL_DLL" for "installvar" and "builddll" for "buildaction".
      </para>
      <para>
        In addition, the "{onestep}" option explained for
        <link linkend="cmd-program">:command</link> can be used.
      </para>
        <para>
        "{attr = val}" is an optional attribute that apply to the generated
        dependencies.  Use the "scope" attribute to
        specify a user scope to be used before other scopes
        (except the local scope) in the generated
        dependencies.
        </para>
        <para>
        The target will be added to $INSTALL_DLL.  Use the "installvar"
        option to select another variable name. Use {installvar=} when
        installing the target is not wanted.
        The target and intermediate files will be added to
        $CLEANFILES.  The source files will be added to
        $DISTFILES, except the ones with a {nodist} attribute.
      </para>
      <para>
      Can only be used at the recipe level.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-do'><term><cmdsynopsis>
    <command>:do</command>
      <arg choice='plain'><replaceable>action</replaceable></arg>
      <arg rep='repeat'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Execute an action.
        The commands executed may depend on the types of the first input file
        and/or the output file.
        See <xref linkend="user-filetype"/>.
        </para>
        <para>
        Attributes just after the "action", except the options mentioned
        below, are passed as variables to the build commands.  The name of the
        attribute is used as the name of the variable.  Prepending "var_" is
        optional.
        <programlisting>
        :do build {target = prog} foo.c
</programlisting>
        </para>

        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
        <entry>{filetype}</entry>
        <entry><para>
          The "filetype" attribute can be used to override the output filetype
          used to select the action to be executed.  Example:
          <programlisting>
        :do build {filetype = libtoolexe} $Objects
</programlisting>
          When this option is not used the filetype of the target is used. The
          filetype of source files must be given with the source file.
          </para></entry>
              </row>
              <row>
        <entry>{scope}</entry>
        <entry><para>
          The "scope" attribute has a special meaning: define the user scope
          from which variables are obtained first.  Variables in this scope
          overrule variables in the recipe or other scopes.  Only variables in
          the local scope come first.
        <programlisting>
        s_opti.DEFINE = -DFOOBAR
        ...
        :do build {scope = s_opti} foo.c
</programlisting>
                </para></entry>
              </row>
              <row>
        <entry>{remove}</entry>
        <entry><para>The "remove" attribute can be used to delete all the arguments
          after the action was executed.  This also happens when the action
          failed.  This can be used when the argument is a temporary file.
          Example:
        <programlisting>
        tmp = `tempfname()`
        :print >tmp  Buy more Spam!
        :do email {remove} {to = everybody@world.org} {subject = Spam} tmp
</programlisting>
              </para></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

        <para>
          See <link linkend='cmd-action'>:action</link> for defining actions.
        </para>
      </listitem>
  </varlistentry>

  <varlistentry id='cmd-eval'><term><cmdsynopsis>
    <command>:eval</command>
      <arg><replaceable>redir</replaceable></arg>
      <arg choice='plain'><replaceable>python-expression</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Filter stdin using a Python expression.
        See <link linkend='arg-redir'>here</link> for [redir].
      When not used after "|" evaluate the Python
      expression.
      </para>
      <para>
      The Python expression is evaluated as specified in the
      argument.  The "stdin" variable holds the value of the
      input as a string, it must be present when
      <link linkend="cmd-eval">:eval</link>
      is used after "|".
      </para>
      <para>
      See <link linkend="python-var2string">var2string()</link> for information
      about using &Aap; variables in the Python expression.
      </para>
      <para>
      The expression must result in the filtered string or
      something that can be converted to a string with
      str().  This becomes stdout.  The result may be empty.
      Examples:
      </para>

      <programlisting>
        :print $foo | :eval re.sub('&lt;.*?&gt;', '', stdin) &gt; tt
        :eval os.name | :assign OSNAME
</programlisting>

      <para>
      Note that the expression must not contain a "|"
      preceded by white space, it will be recognized as a
      pipe.  Also there must be no ">" preceded by white
      space, it will be recognized as redirection.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-execute'><term><cmdsynopsis>
    <command>:execute</command>
      <arg><replaceable>{pass}</replaceable></arg>
      <arg choice='plain'><replaceable>name</replaceable></arg>
      <arg rep='repeat'><replaceable>argument</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Execute recipe "name" right away.  This works like
      executing aap on "name".
      </para>
      <para>
      The recipe is executed in a new scope.  This is used
      as the toplevel scope, unless the "{pass}" option is
      used.
      </para>
      <para>
      The "fetch" attribute is supported like with
      <link linkend="cmd-include">:include</link>.
      </para>
      <para>
      Optional arguments may be given, like on the command
      line.  This is useful for specifying targets and
      variable values. "-f recipe" is ignored.
      Example:
      </para>
      <programlisting>
        TESTPROG = ./myprog
        :execute test.aap test1 test2
</programlisting>

      <para>
        The following command line options are also used for the executed
        recipe.  Thus when &Aap; was started with the --nobuild argument, this
        will also be applied to recipes executed with :execute.  All other
        command line arguments are not passed on.
      </para>

      <informaltable frame='none'>
        <tgroup cols='1'>
          <tbody>
            <row> <entry>-C --contents</entry> </row>
            <row> <entry>-k --continue</entry> </row>
            <row> <entry>-F --force</entry> </row>
            <row> <entry>-n --nobuild</entry> </row>
            <row> <entry>-a --nocache</entry> </row>
            <row> <entry>-N --nofetch-recipe</entry> </row>
            <row> <entry>-s --silent</entry> </row>
            <row> <entry>-S --stop</entry> </row>
            <row> <entry>-t --touch</entry> </row>
            <row> <entry>-v --verbose</entry> </row>
          </tbody>
        </tgroup>
      </informaltable>

      <para>
      This command is useful when a recipe does not contain
      dependencies that interfere with sources and targets
      in the current recipe.  For example, to build a
      command the current recipe depends on.  For example,
      when the program "mytool" is required and it doesn't
      exist yet, execute a recipe to build and install it:
      </para>
      <programlisting>
         @if not program_path("mytool"):
             :execute mytool.aap install
         :sys mytool
</programlisting>

      <para>
      See the <link linkend="python-program-path">program_path()</link>
      function.
      </para>
      <para>
      Another example: build two variants:
      </para>
      <para>
      <programlisting>
        :execute build.aap GUI=motif
        :execute build.aap GUI=gtk
</programlisting>
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-exit'><term><cmdsynopsis>
    <command>:exit</command>
      <arg><replaceable>exitval</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
       Quit executing recipes.  When used in build commands, the "finally"
       targets will still be executed.  But a
       <link linkend="cmd-quit">:quit</link>
       or
       <link linkend="cmd-exit">:exit</link> in the
       commands of a "finally" target will quit further execution.
      </para>
      <para>
        When "exitval" is given Aap will use it as the exit value of the
        program.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-fetch'><term><cmdsynopsis>
    <command>:fetch</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg choice='plain' rep='repeat'><replaceable>file</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Fetch the files mentioned according to their
      "fetch" or "commit" attribute.  When a file does not
      have these attributes or fetching fails you will get
      an error message.
      </para>
      <para>
      An attribute that appears before the files it is applied to all files.
      </para>
      <para>
      Files that exist and have a "fetch" attribute with
      value "no" are skipped.
      </para>
      <para>
      The name "." can be used to update the current
      directory:
      </para>
      <programlisting>
        :fetch . {fetch = cvs://$CVSROOT}
</programlisting>
      <para>
      The "{usecache}" attribute can be used to use a cached
      version of the file.  This skips downloading when the
      file was downloaded before, but may use an older
      version of the file.
      </para>
      <para>
      "{nocache}" does the opposite: never use a cached
      file.
      </para>
      <para>
      The "{constant}" attribute can be used to skip
      fetching a file that already exists.  This is useful
      for a file that will never change (when it includes a
      version number).  Implies "{usecache}".
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-fetchall'>
    <term><cmdsynopsis>
    <command>:fetchall</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
                Fetch all the files in the recipe (and child recipes) that
                have the "fetch" attribute.
                </para>
                <para>
                Extra attributes for fetching can be specified here, they
                overrule the attributes of the file itself.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-filetype'><term><cmdsynopsis>
    <command>:filetype</command>
      <arg rep='repeat'><replaceable>argument</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Specify filetype detection.  See <xref linkend="user-filetype"/>.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-import'>
    <term><cmdsynopsis>
    <command>:import</command>
      <arg choice='plain'><replaceable>name</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Read a module stored in the main &Aap; directory or elsewhere.
      This happens in a special scope, does not change
      directory, and has no effect on the recipe
      containing the <computeroutput>:import</computeroutput>
      command <emphasis>except</emphasis>
      that the actions, filetypes and routes
      defined in the module become available globally.
      This is the easiest way to add additional language
      support to &Aap;.  See <xref linkend="user-language"/>.
      </para>
      <para>
        The recipe(s) read have the name of the module with ".aap" appended.
        Thus for ":import java" the "java.aap" recipe is used.
      </para>
      <para>
        The directories searched for module recipes depend on the platform.
        The first module that is found is used, further directories are not
        searched.
        For Unix systems three directories are used:
        <simplelist>
          <member> - <filename>~/.aap/modules/</filename></member>
          <member> - <filename>/usr/local/share/aap/modules/</filename> </member>
          <member> - The <filename>modules</filename> directory of the &Aap; installation</member>
        </simplelist>
        For other systems these directories are used:
        <simplelist>
          <member> - <filename>$HOME/aap/modules/</filename> </member>
          <member> - <filename>$HOMEDRIVE/$HOMEPATH/aap/modules/</filename></member>
          <member> - <filename>c:/aap/modules/</filename></member>
          <member> - The <filename>modules</filename> directory of the &Aap; installation</member>
        </simplelist>
        $HOME, $HOMEDRIVE and $HOMEPATH are environment variables, not &Aap;
        variables.
      </para>
      <para>
        Additionally, recipes in the "modules2" subdirectory are loaded.
        This can be used to do additional settings without modifying a
        distributed module.
        All found recipes are loaded, ignoring wether a recipe was already
        found.  The same list of directories is used as mentioned above, with
        "modules" replaced with "modules2".  Although there is no "modules2"
        directory in the distribution, thus the last item in the directory
        lists above is not used.
      </para>
      <para>
        The scope that is used for the module recipe can be accessed from
        elsewhere under the name of the module with "m_" prepended.  Thus when
        doing ":import java" the "m_java" scope is available.  The recipes
        from the "modules2" directory use this same scope.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-include'>
    <term><cmdsynopsis>
    <command>:include</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>name</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Read recipe "name" as if it was included in the current recipe.  Does
        not change directory and file names in the included recipe are
        considered to be relative to the current recipe, not the included
        recipe.
        </para>
        <para>
        The <link linkend="option-include">-I</link> or
        <link linkend="option-include">--include</link> command line argument
        can be used to specify directories to look for the recipe.
        The current directory is always searched first.
        When the recipe name is an absolute path or starts with a dot (e.g.,
        "./foo.aap") only the current directory is used.
        </para>
        <para>
        The "fetch" attribute can be used to specify a list of locations where
        the recipe can be fetched from.  If the recipe is fetched, it is
        stored under the specified "name" in the current directory.
        </para>

        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
        <entry>{q} {quiet}</entry>
        <entry>Don't give a warning for a file that can't be read.
            Used to optionally include a recipe.</entry>
              </row>
              <row>
        <entry>{o} {once}</entry>
        <entry>Don't include the recipe if it was already read.
              Useful for project settings that are only to be included once,
              while you have sub-projects that can be build
              independendly.</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>

    </listitem>
  </varlistentry>


  <varlistentry id='cmd-installpkg'><term><cmdsynopsis>
    <command>:installpkg</command>
      <arg choice='plain' rep='repeat'><replaceable>package</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Install packages.  Each argument is the name of a package.
        This works like <link linkend="cmd-assertpkg">:assertpkg</link> but
        without checking if the package is already present or asking the user
        whether it should be installed.
      </para>
      <para>
        See <xref linkend="user-package"/> about using packages.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-lib'>
    <term><cmdsynopsis>
    <command>:lib</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>target</replaceable></arg>
      <arg choice='plain'>:</arg>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg choice='plain' rep='repeat'><replaceable>source</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Specify that "target" is a static library, build from
      "source".  Dependencies will be added to compile
      "source" into an object file and combine the object
      files together into "target".
      </para>
      <para>
      When the basename of "target" does not contain a dot,
      $LIBPRE will be prepended and $LIBSUF will be
      appended.  The original name becomes an alias name for
      the target, so that this works:
      </para>
      <programlisting>
        all: foo bar
        :lib foo : foo.c
        :lib bar : bar.c
</programlisting>
      <para>
      On Unix this builds libfoo.a and libbar.a.
      </para>
      <para>
        See <link linkend="cmd-produce">:produce</link> for the most important 
        options.
        The default values used for ":lib" are:
        $LIBSUF for "targetsuffix", $LIBPRE for "targetprefix"
        $LIBOBJSUF for "objectsuffix", "libobject" for "objecttype",
        "INSTALL_LIB" for "installvar" and "buildlib" for "buildaction".
      </para>
      <para>
        In addition, the "{onestep}" option explained for
        <link linkend="cmd-program">:command</link> can be used.
      </para>
      <para>
        "{attr = val}" is an optional attribute that apply to the generated
      dependencies.  Use the "scope" attribute to
      specify a user scope to be used before other scopes
      (except the local scope) in the generated
      dependencies.
      </para>
      <para>
        The target will be added to $INSTALL_LIB.  Use the "installvar"
        option to select another variable name. Use {installvar=} when
        installing the target is not wanted.
      The target and intermediate files will be added to
      $CLEANFILES.  The source files will be added to
      $DISTFILES.
      </para>
      <para>
      Can only be used at the recipe level.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-log'><term><cmdsynopsis>
    <command>:log</command>
      <arg rep='repeat'><replaceable>text</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Write the arguments to the log file AAPDIR/log.
        This is like <link linkend="cmd-print">:print</link>, but the text is
        not echoed.
        The output cannot be redirected or piped, since there isn't any.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-ltlib'>
    <term><cmdsynopsis>
    <command>:ltlib</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>target</replaceable></arg>
      <arg choice='plain'>:</arg>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg choice='plain' rep='repeat'><replaceable>source</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Specify that "target" is a library, build from
        "source" with the libtool program.  Dependencies will be added to
        compile each "source" into an object file and combine the object
        files together into "target".
      </para>
      <para>
        Very similar to <link linkend="cmd-lib">:lib</link>.
      </para>
      <para>
        Using libtool requires importing the libtool module.  Since
        <link linkend="cmd-ltlib">:ltlib</link> will not work without it, the
        libtool module is automatically imported.
      </para>
      <para>
        See <link linkend="cmd-produce">:produce</link> for the options.
        The default values used for ":ltlib" are:
        $LTLIBSUF for "targetsuffix", $LTLIBPRE for "targetprefix"
        $LTOBJSUF for "objectsuffix", "ltobject" for "objecttype",
        "INSTALL_LTLIB" for "installvar" and "buildltlib" for "buildaction".
      </para>
      <para>
        The target will be added to $INSTALL_LTLIB.  Use the "installvar"
        option to select another variable name. Use {installvar=} when
        installing the target is not wanted.
      The target and intermediate files will be added to
      $CLEANFILES.  The source files will be added to $DISTFILES.
      </para>
      <para>
      Can only be used at the recipe level.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-mkdir'>
    <term><cmdsynopsis>
    <command>:mkdir</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain' rep='repeat'><replaceable>dir</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Create directory.  This fails when "dir" already
      exists and is not a directory.
      </para>
      <para>
      Each argument is handled separately (they are not
      concatenated like with <link linkend="cmd-cd">:cd</link>!).
      A "mode" attribute on a directory can be used to
      specify the protection flags for the new directory.
      </para>
      <para>
      Example:
      </para>
      <programlisting>
        :mkdir {r} ~/secret/dir {mode = 0700}
</programlisting>
      <para>
      The default mode is 0644.  The effective umask may
      reset some of the bits though.
      </para>

      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
        <entry>{f} {force}</entry>
        <entry>Don't fail when a directory already exist; still fails when it
        is not a directory or could not be created.</entry>
              </row>
              <row>
        <entry>{q} {quiet}</entry>
        <entry>don't report created directories.</entry>
              </row>
              <row>
        <entry>{r} {recursive}</entry>
        <entry>Also create intermediate directories, not just the deepest
        one.</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        </para>

      <para>
      Note: automatic creation of directories can be done by
      adding the {directory} attribute to a source item.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-mkdownload'><term><cmdsynopsis>
    <command>:mkdownload</command>
      <arg choice='plain'><replaceable>name</replaceable></arg>
      <arg choice='plain' rep='repeat'><replaceable>file</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Generate a recipe "name" that downloads the specified
      files.  Each file must have a "fetch" attribute, which
      is used in the generated recipe.
      </para>
      <para>
      When the file "name" already exists it is overwritten
      without warning.
      </para>
      <para>
      Wildcards in "file ..." are expanded.  Not in "name".
      </para>
      <para>
      MD5 checksums are generated and used in the recipe to
      fetch a file only when the checksum differs.  Example
      of one item:
      </para>
      <programlisting>
        file = foobar.txt
        @if get_md5(file) != "a5dba5bce69918c040703e9b8eb35f1d":
            :fetch {fetch = ftp://foo.org/files/%file%} $file
</programlisting>
      <para>
      When there is a "fetch" attribute on "name", this will
      be used to add a
      <link linkend="cmd-recipe">:recipe</link> command at the start of the
      generated recipe.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-move'><term><cmdsynopsis>
    <command>:move</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain' rep='repeat'><replaceable>from</replaceable></arg>
      <arg choice='plain'><replaceable>to</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Move files or directories.  Mostly like
        <link linkend="cmd-copy">:copy</link>,
      except that the "from" files/directories are renamed
      or, when renaming isn't possible, copied and deleted.
      </para>

      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
                <entry>{c} {continue}</entry>
                <entry>when an item with a wildcard does not have matches
                  continue with the next item</entry>
              </row>
              <row>
              <entry>{e} {exist} {exists}</entry>
              <entry>don't overwrite an existing file or directory</entry>
              </row>
              <row>
              <row>
              <entry>{f} {force}</entry>
              <entry>forcefully overwrite an existing file or directory
              (default)</entry>
              </row>
              <entry>{i} {interactive}</entry>
              <entry>before overwriting a local file, prompt for confirmation
              (currently doesn't work for remote files)</entry>
              </row>
              <row>
              <entry>{m} {mkdir}</entry>
              <entry>create destination directory when needed</entry>
              </row>
              <row>
              <entry>{q} {quiet}</entry>
              <entry>don't report moved files</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        </para>

    </listitem>
  </varlistentry>


  <varlistentry id='cmd-pass'><term><cmdsynopsis>
    <command>:pass</command>
    </cmdsynopsis></term>
    <listitem>
      <para>
       Do nothing.  Useful to define a target with build commands to avoid a
       dependency is added automatically.
       </para>
       <programlisting>
        clean:
            :pass
</programlisting>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-popdir'><term><cmdsynopsis>
    <command>:popdir</command>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Change back to directory on top of the directory stack, undoing a
        previous
        <link linkend="cmd-pushdir">:pushdir</link>.  It is an error if the
        directory stack is empty (more :popdir than :pushdir used).
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-print'><term><cmdsynopsis>
    <command>:print</command>
      <arg><replaceable>redir</replaceable></arg>
      <arg rep='repeat'><replaceable>text</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Print the arguments on stdout.
        Without arguments a line feed is produced.
        $var items are expanded, otherwise the arguments are produced
        literally, including quotes:
        <programlisting>
        :print "hello"
</programlisting>
                      results in:
        <literallayout>        "hello" </literallayout>
                      Leading white space is skipped, but white space in
                      between arguments is kept.  To produce leading white
                      space write the first space as an escaped character:
        <programlisting>
        :print $( )   indented text
</programlisting>
                      results in:
        <literallayout>        indented text </literallayout>
                      When used in a pipe the <literal>stdin</literal> variable holds
                      the input.
      </para>
      <para>
        See <link linkend='arg-redir'>here</link> for [redir].
        See <link linkend='cmd-log'>:log</link> for writing a message to the
        log file without echoing.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-produce'>
    <term><cmdsynopsis>
    <command>:produce</command>
      <arg choice='plain'><replaceable>what</replaceable></arg>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>target</replaceable></arg>
      <arg choice='plain'>:</arg>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg choice='plain' rep='repeat'><replaceable>source</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Specify that "target" has filetype "what" and is build from "source
        ...".
        Aap will add dependencies to invoke the actions that will accomplish
        the task of building "target".
      </para>
      <para>
        For specific types of targets separate commands are available.  You
        don't need to specify the mandatory options then.
        For building a normal program use
        <link linkend="cmd-program">:program</link>, for building a shared
        library use
        <link linkend="cmd-dll">:dll</link>, for building a static library use
        <link linkend="cmd-lib">:lib</link>, for building a libtool library use
        <link linkend="cmd-ltlib">:ltlib</link>.
      </para>
      <para>
        The building is split up in two parts:
        <orderedlist>
          <listitem><para>
              Dependencies are
              added to compile the source files into files specified with the
              "objecttype" option.  The routes specified with
              <link linkend="cmd-route">:route</link> are used to decide which
              actions to invoke.
              These <link linkend="cmd-route">:route</link> commands must
              precede the <link linkend="cmd-produce">:produce</link> command!
              Each step in the route becomes a separate
              dependency, so that intermediate results are produced.
              This is similar to what the
              <link linkend="cmd-totype">:totype</link> command does.
          </para></listitem>
          <listitem><para>
              The second step is to build the "target" from the "objecttype"
              files.  This invokes the action defined with "buildaction",
              using "what" as the target filetype.  The "what" filetype is
              declared when necessary, to avoid a warning for defining an
              action for an unknown filetype.
          </para></listitem>
        </orderedlist>
      </para>
      <para>
        When the basename of "target" does not contain a dot,
        the "targetsuffix" option will be appended and "targetprefix"
        prepended.  The original name becomes an alias name for the target, so
        that this works:
      </para>
      <programlisting>
        all: foo bar
        :produce drink $drinkoptions foo : foo.c
        :produce snack $snackoptions bar : bar.c
</programlisting>
      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
                <entry>targetsuffix</entry>
                <entry>(optional) appended to the target if it doesn't contain
                  a dot</entry>
              </row>
              <row>
                <entry>targetprefix</entry>
                <entry>(optional) prepended to the target if it doesn't
                  contain a dot</entry>
              </row>
              <row>
                <entry>comment</entry>
                <entry>(optional) description of type of building displayed for
                  "aap --comment target".  A "comment" attribute on the
                  target overrules this.</entry>
              </row>
              <row>
                <entry>objectprefix</entry>
                <entry>(optional) prefix for the intermediate results.</entry>
              </row>
              <row>
                <entry>objectsuffix</entry>
                <entry>(optional) suffix for the intermediate results.</entry>
              </row>
              <row>
                <entry>objecttype</entry>
                <entry>(mandatory) filetype for the intermediate results.</entry>
              </row>
              <row>
                <entry>installvar</entry>
                <entry>(optional) name of the install variable to add the
                  target to (default: INSTALL_EXEC)  Set to an empty value to
                  omit installing</entry>
              </row>
              <row>
                <entry>buildaction</entry>
                <entry>(mandatory) name of the action used to turn the
                  intermediate results into the target</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </para>
      <para>
      Can only be used at the recipe level.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-program'>
    <term><cmdsynopsis>
    <command>:program</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>target</replaceable></arg>
      <arg choice='plain'>:</arg>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg choice='plain' rep='repeat'><replaceable>source</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Specify that "target" is a program, build from
      "source ...".  Dependencies will be added to compile
      "source ..." into an object file and link the object
      files together into "target".
      </para>
      <para>
      When the basename of "target" does not contain a dot,
      $EXESUF will be appended.  The original name becomes
      an alias name for the target, so that this works:
      </para>
      <programlisting>
        all: foo bar
        :program foo : foo.c
        :program bar : bar.c
</programlisting>
      <para>
      On MS-Windows this builds foo.exe and bar.exe.
      </para>
      <para>
        See <link linkend="cmd-produce">:produce</link> for the most important 
        options.
        The default values used for ":program" are:
        $EXESUF for "targetsuffix", nothing for "targetprefix"
        $OBJSUF for "objectsuffix", "object" for "objecttype", "INSTALL_EXEC"
        for "installvar" and "build" for "buildaction".
      </para>
      <para>
        In addition, "{onestep}" can be used to make A-A-P build the program
        without creating intermediate object files if it is supported by the
        tools (see <xref linkend="ref-tools"/>). This solution might be faster
        for very fast compilers.
      </para>
      <para>
        "{attr = val}" is an optional attribute that apply to the generated
        dependencies.  Use the "scope" attribute to specify a user scope to be
        used before other scopes, but after the local scope, in the generated
        dependencies.
      </para>
      <para>
        The target will be added to $INSTALL_EXEC.  Use the "installvar"
        option to select another variable name. Use {installvar=} when
        installing the target is not wanted.
      The target and intermediate files will be added to
      $_recipe.CLEANFILES.  The source files will be added
      to $_recipe.DISTFILES, except the ones with a {nodist}
      attribute.
      </para>
      <para>
      Can only be used at the recipe level.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-progsearch'>
    <term><cmdsynopsis>
    <command>:progsearch</command>
      <arg choice='plain'><replaceable>varname</replaceable></arg>
      <arg choice='plain' rep='repeat'><replaceable>progname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Check if an executable <literal>progname</literal> exists in $PATH.
        If not, check further arguments.  The first one found is assigned to
        variable <literal>varname</literal>.  If none of the
        <literal>progname</literal> could be found <literal>varname</literal>
        will be set to an empty string.
      </para>
      <para>
      Example:
      <programlisting>
        :progsearch BROWSER netscape opera
        @if BROWSER:
            :sys $BROWSER readme.html
</programlisting>
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-proxy'>
    <term><cmdsynopsis>
    <command>:proxy</command>
      <arg><replaceable>protocol</replaceable></arg>
      <arg choice='plain'><replaceable>address</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Specify a proxy server.  Examples:
      </para>
      <programlisting>
        :proxy ftp ftp://ftp.proxy.net:1234
        :proxy http://www.someproxy.com:1080
</programlisting>
      <para>
      The "protocol" can be "ftp", "http" or "gopher".  When
      omitted "http" is used.  Case doesn't matter.
      </para>
      <para>
      The {address} is a URL with the port number included.
      The result of this command is that an environment
      variable is set, as the Python library "urllib"
      requires.  Therefore it must be done early in the
      startup phase, before accessing the internet.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-publish'>
    <term><cmdsynopsis>
    <command>:publish</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg choice='plain' rep='repeat'><replaceable>file</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Publish the files mentioned according to their
      "publish" or "commit" attribute.
      </para>
      <para>
      Creates directories when needed (for CVS only one level).
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-publishall'>
    <term><cmdsynopsis>
    <command>:publishall</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
                Publish all the files in the recipe (and child recipes) that
                have the "publish" attribute and changed since the last time
                they were published.
                </para>
                <para>
                Note that this doesn't fall back to the "commit" attribute
                like
                <link linkend="cmd-publish">:publish</link> does.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-pushdir'><term><cmdsynopsis>
    <command>:pushdir</command>
      <arg choice='plain'><replaceable>dir</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Change directory to "dir".  The current directory is pushed onto the
        directory stack, so that
        <link linkend="cmd-popdir">:popdir</link> goes back to the old current
        directory.
        </para>
        <para>
        Note that at the start of each command block &Aap;
        changes directory to the directory of the recipe.
        </para>
        <para>
        WARNING: variables with a relative path become
        invalid!  This includes $source and $target.  Use
       <link linkend="python-var-abspath">var_abspath()</link>.
        when needed.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-python'><term><cmdsynopsis>
    <command>:python</command>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>python-command-block</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
       A block of Python code.  The block ends when the indent drops to the
       level of
       <link linkend="cmd-python">:python</link> or below.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-python-term'><term><cmdsynopsis>
    <command>:python</command>
      <arg choice='plain'><replaceable>terminator</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>python-command-block</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>terminator</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        A block of Python code.  The block ends when "terminator" is found on
        a line by itself.  The Python commands may have any indent.
        </para>
        <para>
         White space before and after "terminator" is allowod and a comment
         after "terminator" is also allowed.  "terminator" can contain any
         characters except white space.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-quit'><term><cmdsynopsis>
    <command>:quit</command>
      <arg><replaceable>exitval</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
            See <link linkend="cmd-exit">:exit</link>.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-recipe'><term><cmdsynopsis>
    <command>:recipe</command>
      <arg choice='plain'>{fetch =</arg>
      <arg rep='repeat' choice='plain'><replaceable>URL</replaceable></arg>
      <arg choice='plain'>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Location of this recipe.  The "fetch" attribute is
        used like with
        <link linkend="cmd-child">:child</link>: a list of locations.  The
        first URL that works is used.
        </para>
        <para>
        When aap was started with the "fetch" argument,
        fetch the recipe and restart reading it.  Using the
        "fetch" or "update" target causes this as well.
        The commands before
        <link linkend="cmd-recipe">:recipe</link> have already been
        executed, thus this may cause a difference from
        executing the new recipe directly.  The values of
        variables are restored to the values before executing
        the recipe.
        </para>
        <para>
        Fetching a specific recipe is done only once per session.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-remove'><term><cmdsynopsis>
    <command>:remove</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Remove the files from the repository.
      The file may still exist locally.
      Implies a "commit" of the file.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-removeall'><term><cmdsynopsis>
    <command>:removeall</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat'><replaceable>directory</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Apply the <literal>:remove</literal> command to all files in the directory that
      exist in the repository but do hot have been given a "commit" attribute
      in the recipe (and child recipes).
      </para>
      <para>
                Careful: Only use this command when it is certain that all
                files that should be in the VCS are explicitly mentioned and
                do have a "commit" attribute!
      </para>
      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
              <entry>{l} {local}</entry>
              <entry>don't do current directory recursively</entry>
              </row>
              <row>
              <entry>{r} {recursive}</entry>
              <entry>do handle arguments recursively</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
        </para>
        <para>
                When no directory argument is given, the current directory is
                used.  It is inspected recursively, unless the "{local}"
                option was given.
        </para>
        <para>
                When directory arguments are given, each directory is
                inspected.  Recursively when the "{recursive}" option was
                given.
        </para>
        <para>
                When no "commit" attribute is specified here, it will be
                obtained from any node.
        </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-reviseall'><term><cmdsynopsis>
    <command>:reviseall</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Just like using both <literal>:checkinall</literal> and
      <literal>:removeall</literal> on the current directory recursively.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-route'><term><cmdsynopsis>
    <command>:route</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>typelist</replaceable></arg>
      <arg choice='plain'><replaceable>typelist</replaceable></arg>
      <arg rep='repeat'><replaceable>{attr = value}</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>action</replaceable></arg>
      <arg choice='plain'><replaceable>filename</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'>...</arg>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>action</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Specify the actions to be used to build sources with
      a filetype in the first "typelist" into targets with a
      filetype in the last "typelist".  One or more steps
      can be defined, resulting in intermediate results.
      </para>
      <para>
      Each "typelist" is usually a single filetype name, but
      the first and the last can also be a comma separated
      list of filetype names.  The route is defined for each
      combination of the mentioned filetypes.
      </para>
      <para>
      The last "typelist" may have attributes.  These are passed to the final
      target.  A useful attribute is "buildaction", which tells the build
      action which special action has to be used for this item.
      </para>
      <para>
      There must be an "action" line for each step.  The
      number of steps is the number of "typelist" minus one.
      All "action" lines except the last one must define a
      "filename".  This is the file used for the
      result of the action, which becomes the input for the next action.
      If the filename is not an absolute path $BDIR will be prepended (the
      "var_BDIR" attribute is used if present on the source file).
      </para>
      <para>
      Example:
      <programlisting>
        :route yacc c object
            yacc $(source).c
            compile
</programlisting>
      </para>
      <para>
      This defines the route from a "yacc" file to an
      "object" file, with an intermediate "c" result.
      The step from "yacc" to "c" is done with an action
      called "yacc".  It will be invoked like this:
      </para>
      <programlisting>
        :do yacc {target = $(source).c} $source
</programlisting>
        <para>
      The step from "c" to "object" is done with a "compile"
      action.  It will be invoked like this:
      </para>
      <programlisting>
        :do compile {target = $target} $(source).c
</programlisting>
      <para>
      The steps will be generated as separate dependencies.
      Thus, for the above example,
      when an included header file of the intermediate C file
      changes, only the "compile" action will be invoked.
      </para>
      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
              <entry>{default}</entry>
              <entry>This is a default route.  No warning is given if the
                route is redefined later.</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </para>
      <para>
      The defined routes can be used explicitly with the
      <link linkend="cmd-totype">:totype</link> command.  They are also used
      with the <link linkend="cmd-produce">:produce</link> command and
      derivatives.
      </para>
      <para>
      Note: In a later version of &Aap; the defined routes may be used for
      dependencies without build commands and without a matching rule.
      Thus the routes may be used as rules based on filetypes.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-rule'><term><cmdsynopsis>
    <command>:rule</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>tpat</replaceable></arg>
      <arg choice='plain'>:</arg>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>spat</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>command-block</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Define a rule to build files matching the pattern
      "tpat" from a file matching "spat".
      </para>
      <para>
      Example:
      <programlisting>
        :rule %.html : header.part %.part footer.part
            :cat $source > $target
</programlisting>
      </para>
      <para>
      There can be several "tpat" patterns, the rule is used
      if one of them matches.
      </para>
      <para>
      There can be several "spat" patterns, the rule is used
      if they all exist (or no better rule is found).
      When "commands" is missing this only defines that
      "tpat" depends on "spat".
      </para>
      <para>
      Can only be used at the recipe level.
      </para>
      <para>
      A rule is used in the recipe where it is defined and
      in its siblings, unless an option is used to specify
      otherwise.
      </para>
      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
                <entry>{global}</entry>
                <entry>use this rule in all places</entry>
                </row>
                <row>
                <entry>{local}</entry>
                <entry>use this rule only for targets in this recipe</entry>
                </row>
                <row>
                <entry>{default}</entry>
                <entry>default rule, redefining it will not cause a
                  message</entry>
                </row>
                <row>
                <entry>{sourceexists}</entry>
                <entry>only use the rule when the matching source file exists;
                  useful for rules that generate source code</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </para>
      <para>
      "attributes" can be used to set attributes for when
      applying the rule.
      </para>
      <para>
      The "skip" attribute on 'tpat' can be used to skip
      certain matches.
      </para>
      <para>
      $target and $source can be used in "commands" for the
      actual file names.  $match is what the "%" in the
      pattern matched.
      </para>
      <para>
      Alternative: instead of matching the file name with a
      pattern,
      <link linkend="cmd-action">:action</link>
      uses filetypes to specify commands.
      On non-Unix systems the pattern should contain only
      lower case letters and forward slashes, because the
      name it is compared with is made lower case and
      backslashes have been replaced with forward slashes.
      </para>
      <para>
        <link linkend="cmd-rule">:rule</link> is introduced in <xref
          linkend="tutor-website"/> of the tutorial.
        Also see
        <link linkend="cmd-delrule">:delrule</link>
        and
        <link linkend="cmd-clearrules">:clearrules</link> .
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-start'><term><cmdsynopsis>
    <command>:start</command>
      <arg choice='plain'><replaceable>command</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Like <link linkend="cmd-sys">:sys</link>
        and <link linkend="cmd-sys">:system</link>,
        but don't wait for the commands to finish.  Errors of the executed
        command are ignored.
        </para>
        <para>
        Runs in the same terminal, which will cause problems
        when the command waits for input.  Open a new terminal
        to run that command in.  Example:
        </para>
        <programlisting>
        :start xterm -e more README
</programlisting>
        <para>
          WARNING: Using
          <link linkend="cmd-start">:start</link> probably makes your recipe non-portable.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-symlink'><term><cmdsynopsis>
    <command>:symlink</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>from</replaceable></arg>
      <arg choice='plain'><replaceable>to</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Create a symbolic link, so that "to" points to "from".
      Think of this as if making a copy of "from" without
      actually copying the file.
      </para>
      <para>
      Only for Unix and Mac OS X.
      </para>
      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
                <entry>{q} or {quiet}</entry>
                <entry>Don't complain when "to" already exists.</entry>
                </row>
                <row>
                <entry>{f} or {force}</entry>
                <entry>Overwrite an existing "to" file or symlink</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-sys'><term><cmdsynopsis>
    <command>:sys</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>command</replaceable></arg>
    <command>:system</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>command</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        <anchor id='cmd-system'/>
      Execute "cmds" as system (shell) commands.  Example:
      </para>
      <programlisting>
        :system filter &lt;foo &gt;bar
        :sys reboot universe
</programlisting>
      <para>
      The following lines with more indent are appended,
      replacing the indent with a single space.  Example:
      </para>
      <programlisting>
        :sys echo one
              two
</programlisting>

      <para>
      This echos "one two".
      </para>

      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
              <entry>{i} or {interactive}</entry>
              <entry>don't log output (see below)</entry>
              </row>
              <row>
              <entry>{q} or {quiet}</entry>
              <entry>Don't echo the command</entry>
              </row>
              <row>
              <entry>{l} or {log}</entry>
              <entry>Redirect all output to the log file, do not echo it</entry>
              </row>
              <row>
              <entry>{f} or {force}</entry>
              <entry>Ignore a non-zero exit value</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </para>

      <para>
      {interactive} and {log} cannot be used at the same
      time.
      </para>

      <para>
      When using the {f} or {force} argument the exit value
      of the command is available in $sysresult.
      </para>

      <para>
      Output is logged by default.  If this is undesirable
      (e.g., when starting an interactive command) prepend
      "{i}" or "{interactive}" to the command.  It will be
      removed before executing it.  Example:
      </para>

      <programlisting>
        :system {i} vi bugreport
</programlisting>

      <para>
      &Aap; attempts to execute consecutive commands with one
      shell, to speed up the execution.  This will not be
      done when the {f} or {force} attribute is used, these
      commands are executed separately.
      </para>

      <para>
       &Aap; waits for the command to finish.
       Alternatively you can use <link linkend="cmd-start">:start</link>,
       which runs the command asynchronously.
      </para>
      <para>
      When the "async" variable is set and it is not empty,
      <link linkend="cmd-sys">:sys</link> works like
      <link linkend="cmd-start">:start</link>, except that consecutive
      commands are executed all at once in one shell.
      </para>
      <para>
      Also see <link linkend="cmd-asroot">:asroot</link> for executing a shell
      command with super-user privileges.
      </para>

      <para>
        On MS-Windows several commands use a forward slash for options and
        require using backslashes in file names.  But in Aap most file names
        use forward slashes.  To obtain the value of variable "var" with
        slashes replaced with backslashes use "$/var".
        See <xref linkend="ref-varscope"/>.
      </para>

      <para>
        When using a variable as an argument, it may need to be put in quotes
        to avoid it being interpreted as two arguments when it contains a
        space.  To obtain the value of variable "var" with quotes for the
        shell use "$!var".  See <xref linkend="ref-varscope"/>.
      </para>

      <para>
        WARNING: Using
        <link linkend="cmd-sys">:sys</link> or
        <link linkend="cmd-system">:system</link> probably makes your
      recipe non-portable.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-sysdepend'><term><cmdsynopsis>
    <command>:sysdepend</command>
      <arg choice='plain'>{filepat = <replaceable>pattern</replaceable>}</arg>
      <arg>{srcpath = <replaceable>path ...</replaceable>}</arg>
      <arg choice='plain'><replaceable>command</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Execute shell command "command".  It is supposed to figure out
        automatic dependencies.  When an included file cannot be found by the
        shell command, an error message is expected that indicates which file
        is missing.  &Aap; will then attempt to fetch or update the file and
        run "command" again.
      </para>
      <para>
        Error messages that match "pattern" are recognized and handled in a
        special way.  The "pattern" must contain one group (a pattern in
        parenthesis), which matches the file name in an error message.
        The files where the pattern matches are then updated, like <link
          linkend="cmd-update">:update</link> is invoked.  The command is then
        executed again.
      </para>
      <para>
        The "srcpath" option is used to find the files from the error
        messages.  When it is omitted the following directories are searched: 
        <orderedlist>
          <listitem><para>
              Directories from the $INCLUDE variable.
          </para></listitem>
          <listitem><para>
              The first directory in the $source variable.
          </para></listitem>
          <listitem><para>
              The current directory.
          </para></listitem>
        </orderedlist>
      </para>
      <para>
        The repetition of executing the command and finding matching file
        names is repeated until there are no more matching error messages or
        the list of file names is the same as the previous time.
      </para>
      <para>
        An example:
      </para>
      <programlisting>
        :sysdepend {filepat = .*: ([^:]*): File not found} depcheck $source > $target
</programlisting>
      <para>
        Be careful to exactly match the filename with the pattern inside ().
        Leading and trailing white space is ignored.  When necessary to use
        another group, use "(?:pattern)" to avoid it's used as the file name.
      </para>

      <para>
        WARNING: Using
        <link linkend="cmd-syseval">:sysdepend</link> probably makes your recipe non-portable.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-syseval'><term><cmdsynopsis>
    <command>:syseval</command>
      <arg>{stderr}</arg>
      <arg><replaceable>redir</replaceable></arg>
      <arg choice='plain'><replaceable>command</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Execute shell command "command" and write its output
      to stdout.  Only stdout of the command is captured by default.
      When {stderr} is just after the command name, stderr
      is also captured.  Example:
      </para>
      <programlisting>
        :syseval hostname | :assign HOSTNAME
</programlisting>

      <para>
      When used in a pipe, the stdin is passed to the
      command.  Example:
      </para>

      <programlisting>
        :print $var | :syseval sort | :assign var
</programlisting>

      <para>
      Leading and trailing blanks, including line breaks,
      are removed.  Thus the last line never ends in a
      newline character.
      </para>

      <para>
        See <link linkend='arg-redir'>here</link> for [redir].
      </para>
      <para>
        Note the difference with the
        <link linkend="cmd-sys">:sys</link> command:
        redirection in
        <link linkend="cmd-sys">:sys</link> is handled by the shell, for
        <link linkend="cmd-syseval">:syseval</link> it is handled by &Aap;.
      </para>

      <para>
      When executing the command fails, the result is empty.
      The exit value of the command is available in $exit.
      </para>

      <para>
        WARNING: Using
        <link linkend="cmd-syseval">:syseval</link> probably makes your recipe non-portable.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-syspath'><term><cmdsynopsis>
    <command>:syspath</command>
      <arg choice='plain'><replaceable>path</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>arg</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Use "path" as a colon separated list of command names, use
      the first command that works.
      </para>
      <para>
      When %s appears in "path", it is replaced with the
      arguments.  If it does not appear, the arguments are appended.
      </para>
      <para>
      Other appearences of % in "path" are removed, thereby
      reducing %% to % and %: to : while avoiding their
      special meaning.
      </para>
      <para>
      Don't forget that "path" must be one argument, use
      quotes around it to include white space.
      </para>
      <para>
      Example:
      <programlisting>
        :syspath 'vim:vi:emacs' foobar.txt
</programlisting>
      </para>
      <para>
      Output is not logged.
      </para>
      <para>
      Note: on MS-Windows it's not possible to detect if a
      command worked, the first item in the path will always
      be used.
      </para>
      <para>
        WARNING: Using
        <link linkend="cmd-syspath">:syspath</link> probably makes your recipe non-portable.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-tag'><term><cmdsynopsis>
    <command>:tag</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Adds a tag to the current version of the files in the repository.
      Uses the "tag" attribute.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-tagall'><term><cmdsynopsis>
    <command>:tagall</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Adds a tag to all items with a "commit" and "tag" attribute.
      The tag should be simple name without special characters (no
      dot or dash).
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-tee'><term><cmdsynopsis>
    <command>:tee</command>
      <arg><replaceable>redir</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Write stdin to each file in the argument list and also
      write it to stdout.  This works like a T shaped
      connection in a water pipe.  Example:
      </para>
      <para>
      <programlisting>
      :cat file1 file2 | :tee totfile | :assign foo
</programlisting>
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-toolsearch'><term><cmdsynopsis>
    <command>:toolsearch</command>
      <arg rep='repeat' choice='plain'><replaceable>toolname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Specify a list of tools.  The Python code for each tool is imported
        and its "exist()" function invoked.  The first tool that exists
        becomes the default tool for the language(s) it supports.
        See <xref linkend="user-tools"/> for more info.
      </para>
      <para>
        For Unix systems three directories are used:
        <simplelist>
          <member> - <filename>~/.aap/tools/</filename></member>
          <member> - <filename>/usr/local/share/aap/tools/</filename> </member>
          <member> - The <filename>tools</filename> directory of the &Aap; installation</member>
        </simplelist>
        For other systems these directories are used:
        <simplelist>
          <member> - <filename>$HOME/aap/tools/</filename> </member>
          <member> - <filename>$HOMEDRIVE/$HOMEPATH/aap/tools/</filename></member>
          <member> - <filename>c:/aap/tools/</filename></member>
          <member> - The <filename>tools</filename> directory of the &Aap; installation</member>
        </simplelist>
        $HOME, $HOMEDRIVE and $HOMEPATH are environment variables, not &Aap;
        variables.
      </para>
      <para>
        <emphasis>Important:</emphasis> The "tools" directory must have a
        <filename>__init__.py</filename> file, so that it is recognized as a
        package.  The <filename>__init__.py</filename> file may be empty.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-totype'><term><cmdsynopsis>
    <command>:totype</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg choice='plain'><replaceable>targettype</replaceable></arg>
      <arg choice='plain'>:</arg>
      <arg rep='repeat'><replaceable>attribute</replaceable></arg>
      <arg choice='plain' rep='repeat'><replaceable>source</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Specify that each item in "source ..." is to be
        turned into filetype "targettype".  Dependencies
        will be added to turn each source file into a file of
        type "targettype".  How this is done must have been
        defined with
        <link linkend="cmd-route">:route</link> commands before using the
          <link linkend="cmd-totype">:totype</link> command!
        </para>
        <para>
        Example:
        </para>
        <programlisting>
        :totype footy {suffix = .foo} : aaa.cpp bbb.y
</programlisting>
        <para>
          This turns the file "aaa.cpp" into a file "aaa.foo" with filetype
          "footy".  Since "aaa.cpp" is recognized as a file with filetype
          "cpp", this will use the route from "cpp" to "footy".
          "bbb.y" is turned into "bbb.foo".  "bbb.y" is recognized as a file
          with filetype "yacc", this will use the route from "yacc" to
          "footy".
        </para>
        <para>
          If the resulting "targettype" files are additionally to be build
          together into a program you can use the
          <link linkend="cmd-program">:program</link> command instead.
          A more generic form is the
          <link linkend="cmd-produce">:produce</link> command.
        </para>
        <para>
        The filename of each target is made from the source
        file name, prepending $BDIR.  The "prefix" and "suffix" attributes of
        "targettype" are used ("prefix" is prepended, "suffix" replaces an
        existing suffix).
        When "targettype" is "object" the default for "suffix" is $OBJSUF, for
        "dllobject" the default is $DLLOBJSUF and for "libobject" the default
        is $LIBOBJSUF.  Otherwise the "suffix" attribute must
        be specified to avoid that the source and target have the same file
        name.
        </para>
        <para>
        [attributes] are optional attributes that apply to the
        generated dependencies.  Use the "scope" attribute to
        specify a user scope to be used before other scopes
        (except the local scope) in the generated
        dependencies.
        </para>
        <para>
        The targets and any intermediate files will be added
        to $_recipe.CLEANFILES.  The source files will be
        added to $_recipe.DISTFILES, except the ones with a
        {nodist} attribute.
      </para>
      <para>
      Can only be used at the recipe level.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-touch'><term><cmdsynopsis>
    <command>:touch</command>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
      <arg rep='repeat' choice='plain'><replaceable>name</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Update timestamp of file or directory "name".
      </para>
      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="150"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
                <entry>{f} {force}</entry>
                <entry>create the file when it doesn't exist</entry>
                </row>
                <row>
                <entry>{e} {exist}</entry>
                <entry>create the file when it doesn't exist, don't update timestamp when the
                file already exists</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </para>
      <para>
      If "name" doesn't exist and {force} and {exist} are
      not present the command fails.
      </para>
      <para>
      If "name" doesn't exist and {force} or {exist} is
      present an empty file will be created.
      </para>
      <para>
      If "name" does exist and {exist} is present nothing
      happens.
      </para>
      <para>
      A "directory" attribute can be used to specify a
      non-existing "name" is to be created as a directory.
      There is no check if an existing "name" actually is a
      directory.
      </para>
      <para>
      A "mode" attribute can be used to specify the mode
      with which a new file or directory is to be created.
      The value is in the usual octal form, e.g., "0644".
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-tree'><term><cmdsynopsis>
    <command>:tree</command>
      <arg choice='plain'><replaceable>dirname</replaceable></arg>
      <arg rep='repeat'><replaceable>option</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>command-block</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Inspect the directory tree "dirname" and invoke the
      command block for each selected file and/or directory.
      In the command block $name has the name of the
      selected item.
      </para>
      <para>
      Example:
      </para>
      <programlisting>
        :tree headers {filename = log}
            :delete $name
</programlisting>
      <para>
      This deletes all "log" files below the "headers"
      directory, possibly including "headers/log" and
      "headers/sub/log".
      </para>
      <para>

      The dirname itself is not part of the selected items.
      </para>
      <para>
        <informaltable frame='none'>
          <tgroup cols='2'>
            <colspec colwidth="200"/>
            <thead>
            <row><entry>options</entry></row>
            </thead>
            <tbody>
              <row>
                <entry>{filename = pattern}</entry>
                <entry>Select files where this Python re pattern matches 
                  the whole filename.</entry>
              </row>
              <row>
                <entry>{dirname = pattern}</entry>
                <entry>Select directories where this Python re pattern matches
                  the whole filename.</entry>
              </row>
              <row>
                <entry>{follow}</entry>
                <entry>Do follow symbolic links.</entry>
              </row>
              <row>
                <entry>{reject = pattern}</entry>
                <entry>Exclude files and directories where this Python re
                  pattern matches the basename (the last component in the
                  path).  Directories are still entered.  For example, when the
                  pattern is "CVS" a file "CVS/Entries" can still be
                  included.</entry>
              </row>
              <row>
                <entry>{skipdir = pattern}</entry>
                <entry>Do not enter directories where this Python re
                  pattern matches the basename (the last component in the
                  path).</entry>
              </row>
              <row>
                <entry>{contents = pattern}</entry>
                <entry>Include only files that match the pattern in the file
                contents.  Does not apply to directories.</entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable>
      </para>
      <para>
      When neither the "filename" nor "dirname" is given,
      all files are selected, as if {filename = .*} was used.
      </para>
      <para>
      When the system ignores case for filenames the
      patterns will ignore case differences for "filename",
      "dirname" and "reject".  The pattern for "contents" is
      used with matching case.
      </para>
      <para>
      The pattern for "filename", "dirname" and "reject"
      must match the whole name, "^" is prepended and "$" is
      appended.  The pattern for "contents" is matched with
      every line in the file, including the newline
      character, and may match part of the line.
      </para>
      <para>
      Hidden and system files are found as well, but the
      directory entries "." and ".." are never selected.
      </para>
      <para>
      The selected entries are ordered depth-first.  For
      example, "tree foo" would select:
      <literallayout>        foo/sub/f1
        foo/sub/subsub/f2
        foo/sub/subsub/
        foo/sub/f3
        foo/sub/
        foo/f4
</literallayout>
      </para>
      <para>
        Without the "{follow}" option symbolic links to are not followed.  The
        symbolic link itself is included in the results (if the pattern
      matches).  Use os.path.islink() to test for symbolic
      links.  Hard links are not detected and may cause an
      infinite loop.
      </para>
      <para>
        Example that creates a list of C files, skipping "old" directories and
        "test_" files:
      </para>
      <programlisting>
        source =
        :tree . {filename = .*\.c} {skipdir = old} {reject = test_.*}
            source += $name
</programlisting>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-unlock'><term><cmdsynopsis>
    <command>:unlock</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Remove any lock on the files, don't change the file in the repository.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-unlockall'><term><cmdsynopsis>
    <command>:unlockall</command>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Apply the <literal>:unlock</literal> command to all files in the recipe (and
      child recipes) that have the "commit" attribute.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-update'><term><cmdsynopsis>
    <command>:update</command>
      <arg>{force}</arg>
      <arg>{searchpath = <replaceable>path...</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>target</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Update "target" now, if it is outdated or when
        "{force}" is used.
      </para>
      <para>
        One or more targets can be specified, each will be
        updated.
      </para>
      <para>
        The "searchpath" argument can be used to search for the target in a
        series of directories.  Each item in "searchpath" is prepended to the
        target name, unless it is an absolute path.  The updating stops when
        a path plus target is found that can be successfully updated.
      </para>
      <para>
        When this appears at the top level, a dependency or
        rule for the target to be used must already have been
        specified, there is no look-ahead.
      </para>
      <para>
        When the target exists and no dependency or rule
        applies, the file is considered updated.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-usetool'><term><cmdsynopsis>
    <command>:usetool</command>
      <arg choice='plain'><replaceable>toolname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Specify a specific tool to be used.  When used in the toplevel recipe
      the tool becomes the default tool.  Can also be used in a child recipe.
      See <xref linkend="user-tools"/> for more info.
      </para>
    </listitem>
  </varlistentry>


  <varlistentry id='cmd-variant'><term><cmdsynopsis>
    <command>:variant</command>
      <arg choice='plain'><replaceable>varname</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>value</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'><replaceable>&nbsp;&nbsp;commands</replaceable></arg>
    <command>&nbsp;</command>
      <arg choice='plain'>...</arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
      Define build variants.  The "varname" is the name of a variable that
      selects one of the possible "value" items.
      </para>
      <para>
      The last "value" item can be a star.  This item will be used when the
      value of "varname" does not match one of the other values.
      </para>
      <para>
      When the variable "varname" is not set or has an empty value, the first
      entry is used.
      </para>
      <para>
      The value of $BDIR is changed by appending a dash and the value of
      "varname".  The value is modified to avoid using an illegal filename.
      </para>
      <para>
        See the User manual <xref linkend="user-variant"/> for examples.
      </para>
      <para>
      Can only be used at the recipe level.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry id='cmd-verscont'><term><cmdsynopsis>
    <command>:verscont</command>
      <arg choice='plain'><replaceable>action</replaceable></arg>
      <arg rep='repeat'>{<replaceable>attr</replaceable> = <replaceable>val</replaceable>}</arg>
      <arg rep='repeat' choice='plain'><replaceable>fname</replaceable></arg>
    </cmdsynopsis></term>
    <listitem>
      <para>
        Version control command, also see <xref linkend="user-version"/>.
      </para>
      <para>
      Perform the version control "action" on the files.
      This uses the "commit" attribute.
      What happens is specific for the VCS.
      </para>
    </listitem>
  </varlistentry>

</variablelist>
</para>


<bridgehead id='common-arguments'>Common arguments for Commands</bridgehead>

  <variablelist>

    <varlistentry id='arg-redir'><term><cmdsynopsis>
        <arg><replaceable>redir</replaceable></arg>
      </cmdsynopsis></term>
      <listitem>
        <para>
          Redirect the output of a command.
          Can be one of these items:
          <informaltable frame='none'>
            <tgroup cols='2'>
              <colspec colwidth="100"/>
              <tbody>
                <row>
                  <entry>&gt; <replaceable>fname</replaceable></entry>
                  <entry>write output to file "fname"; fails when "fname" already exists</entry>
                </row>
                <row>
                  <entry>&gt;! <replaceable>fname</replaceable></entry>
                  <entry>write output to file "fname"; overwrite an existing file</entry>
                </row>
                <row>
                  <entry>&gt;&gt; <replaceable>fname</replaceable></entry>
                  <entry>append output to file "fname"; create the file if it does not exist yet</entry>
                </row>
                <row>
                  <entry>| <replaceable>command</replaceable></entry>
                  <entry>pipe output to the following "command"</entry>
                </row>
              </tbody>
            </tgroup>
          </informaltable>
          The redirection can appear anywhere in the argument, except inside
          quotes.
          The normal place is either as the first or the last argument.
          The pipe to the next command must appear at the end.
        </para>

        <para>
        The file name can be a URL.  The text will first be written to a local
        file and then the file is moved to the final destination.
        </para>

        <para>
        The white space before the file name may be omitted.
        White space before the ">" and "|" is required.
        To avoid recognizing the ">" and "|" for redirection and pipes, use $gt
        and $pipe.
        </para>

        <para>
        When a command produces text on stdout and no redirection or pipe is
        used, the stdout is printed to the terminal.
        </para>

      </listitem>
    </varlistentry>

  </variablelist>

<bridgehead>URLs</bridgehead>

<para>
In various places URLs can be used to specify remote locations and the method
how to access it.
</para>

<para>
<variablelist>

  <varlistentry id='url-http'>
    <term> http://machine/path </term>
    <listitem>
      <para>
      HTTP protocol, commonly used for web sites.  read-only "machine" can
      also be "machine:port".
      </para>

      </listitem>
    </varlistentry>

  <varlistentry id='url-ftp'>
    <term> ftp://machine/path </term>
    <listitem>
      <para>
      FTP protocol.  "machine" can also be "machine:port".  When ":port" is
      omitted the default port 21 is used.
      </para>
      <para>
      For authentication the ~/.netrc file is used if
      possible (unfortunately, the Python netrc module has a
      bug that prevents it from understanding many netrc
      files).
      </para>
      <para>
      Alternatively, login name and password can be
      specified just before the machine name:
      <literallayout>              ftp://user@machine/path
              ftp://user:password@machine/path </literallayout>
      When ":password" is omitted, you will be prompted for
      entering the password.
      </para>
      <para>
      Either way: ftp sends passwords literally over the
      net, thus THIS IS NOT SECURE!  Should use "scp://"
      instead.
      </para>
      </listitem>
    </varlistentry>

  <varlistentry id='url-scp'>
    <term> scp://machine/path </term>
    <listitem>
      <para>
      SCP protocol (using SSH, secure shell).
      Requires the "scp" program installed (&Aap; will
      attempt installing it for you when needed).
      Additionally a user name can be specified:
      <literallayout>              scp://user@machine/path </literallayout>
      "path" is a relative path to the directory where "ssh"
      logs in to.  To use an absolute path prepend a slash:
      <literallayout>              scp://machine//path </literallayout>
      The resulting path for the "scp" command uses a ":"
      instead of the first slash.
      </para>
      <para>
      Uses "scp -C" by default.  Set the $SCPCMD variable to
      use another command.
      </para>
      </listitem>
    </varlistentry>

  <varlistentry id='url-rcp'>
    <term> rcp://machine/path </term>
    <listitem>
      <para>
      RCP protocol (using rcp, "remote copy").
      Very much like using "scp://", but WITHOUT SECURITY.
      Requires the "rcp" program installed (&Aap; will
      attempt installing it for you when needed).
      </para>
      <para>
      Uses "rcp" by default.  Set the $RCPCMD variable to
      use another command.
      </para>
      </listitem>
    </varlistentry>

  <varlistentry id='url-rsync'>
    <term> rsync://machine/path   </term>
    <listitem>
      <para>
      RSYNC protocol (using rsync, "remote sync").
      Like using "scp://", but only the difference between
      files is transported.  This is slower for transferring
      a whole file but a lot faster if a file has few
      changes.
      </para>
      <para>
      Requires the "rsync" program installed (&Aap; will
      attempt installing it for you when needed).
      Uses "rsync --rsh==ssh" by default.  Set the $RSYNCCMD
      variable to use another command.
      </para>
      </listitem>
    </varlistentry>

</variablelist>
</para>
