Sophie

Sophie

distrib > Mandriva > 2010.0 > x86_64 > by-pkgid > a6d417e36f6bb1154f4c003e6717e298 > files > 155

a-a-p-1.090-2mdv2009.0.noarch.rpm

<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Chapter 28. Customizing Filetype Detection and Actions</title><meta name="generator" content="DocBook XSL Stylesheets V1.71.1"><link rel="start" href="index.html" title="A-A-P Recipe Executive"><link rel="up" href="user.html" title="Part II. User Manual"><link rel="prev" href="user-makedif.html" title="Chapter 27. Differences from make"><link rel="next" href="user-autodep.html" title="Chapter 29. Customizing Automatic Depedencies"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table width="100%" id="navtable"><tbody><tr><td align="left" class="left" width="33%"><b><a href="http://www.a-a-p.org">A-A-P home page</a></b></td><td align="center" class="center" width="34%"><b><a href="index.html">A-A-P Recipe Executive</a></b></td><td align="right" class="right" width="33%"></td></tr><tr><td align="left" class="left"><a accesskey="p" href="user-makedif.html">Prev</a></td><td align="center" class="center">User Manual</td><td align="right" class="right"><a accesskey="n" href="user-autodep.html">Next</a></td></tr></tbody></table><hr><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="user-filetype"></a>Chapter 28. Customizing Filetype Detection and Actions</h2></div></div></div><p>
  See <a href="tutor-actions.html" title="Chapter 8. Filetypes and Actions">Chapter 8, <i>Filetypes and Actions</i></a> for a simple example how to define a new
  filetype.
</p><h2><a name="id2658964"></a>Filetype Detection</h2><p>
A-A-P detects the type of a file automatically.  This is used to decide
what tools can be used for a certain file.
</p><p>
  The detection often uses the name of the file, especially the suffix.
  Extra suffixes like ".in" and ".gz" are ignored.  Sometimes the contents of
  the file is inspected.  for example, on Unix a shell script is recognized
  by "#!/bin/sh" in the first line.
</p><p>
To manually set the file type of an item add the "filetype" attribute.  This
overrules the automatic detection.
Example:
</p><pre class="programlisting">
        foo.o : foo.x {filetype = cpp}
</pre><p>
Most detection is already built in.  If this is not sufficient for your work,
filetype detection instructions can be used to change the way file type
detection works.  These instructions can either be in a file or directly in
the recipe:
</p><pre class="programlisting">
        :filetype  filename
        :filetype
            suffix p pascal
            script .*bash$ sh
</pre><p>
The advantage of using a file is that it will also be possible to use it when
running the filetype detection as a separate program.  The advantage of using
the instructions directly in the recipe is that you don't have to create
another file.
</p><p>
For the syntax of the file see <a href="ref-filetype.html" title="Chapter 38. Filetype Detection">Chapter 38, <i>Filetype Detection</i></a>.
</p><p>
It is sometimes desired to handle a group of files in a different way.  For
example, to use a different optimizer setting when compiling C files.  An easy
way to do this is to give these files a different filetype.  Then define a
compile action specifically for this filetype.  Example:
</p><pre class="programlisting">
        :attr {filetype = c_opt} bar.c foo.c
        :action compile c_opt
            OPTIMIZE = 3
            :do compile $source
</pre><p>

When you define an action (or a route), <span class="application">Aap</span> checks
that the filetypes you use are known filetypes, i.e. mentioned
somewhere in a <a href="ref-commands.html#cmd-filetype">:filetype</a>
command. If you just make up filetypes and use them in actions,
<span class="application">Aap</span> will give you a warning.
This helps detect misspellings and the like.
However, for the "optimized C" filetype above,
this leads to a warning where you do not want one:
<code class="literal">c_opt</code> is a proper filetype in this context.
In order to declare a filetype without giving 
any rules to detect files of that type,
use <code class="literal">declare</code> in a 
<a href="ref-commands.html#cmd-filetype">:filetype</a> command:
</p><pre class="programlisting">
    :filetype
	declare c_opt
</pre><p>
</p><p>
The detected filetypes never contain an underscore.  A-A-P knows that the
underscore separates the normal filetype from the additional part.  When no
action is found for the whole filetype, it is tried by removing the "_" and
what comes after it.  (This isn't fully implemented yet!)
</p><p>
Care should be taken that an action should not invoke itself.  For example, to
always compile "version.c" when linking a program:
</p><pre class="programlisting">
        :attr {filetype = my_prog} $TARGET
        :action build my_prog object
            :do compile {target = version$OBJSUF} version.c
            :do build {target = $target} {filetype = program}
                                        $source version$OBJSUF
</pre><p>
Without "{filetype = program}" on the :do build" command, the action would
invoke itself, since the filetype for $TARGET is "my_prog".
</p><p>
  Attributes on source arguments of the
  <a href="ref-commands.html#cmd-do">:do</a> that start with "var_" are passed
on to the executed action as variables.  Examples:
</p><pre class="programlisting">
          :do build foo.c {var_OPTIMIZE = 2}

          :attr {var_OPTIMIZE = 2} foo.c
          :do build foo.c
</pre><p>
In the same way an attribute starting with "add_" is added to a variable.
Example:
</p><pre class="programlisting">
          :do build foo.c {add_DEFINE = -DBIG}
</pre><p>
  The value of the attribute is not added when it already appears in the
  variable.  This avoids adding it two or more times.
</p><p>
Variable values for the executed action can also be passed by giving an
attribute just after the action:
</p><pre class="programlisting">
          :do build {OPTIMIZE = 2} foo.c
</pre><p>
And yet another method is to define a user scope and use this for the action:
</p><pre class="programlisting">
          s_foo.OPTIMIZE = 4
          :do build {scope = s_foo} foo.c
</pre><h2><a name="id2660486"></a>Executing Actions</h2><p>
The user can select how to perform an action for each type of file.  For
example, the user may specify that the "view" action on a file of type "html"
uses Netscape, and the "edit" action on a "html" file uses Vim.
</p><p>
To start an application:

</p><pre class="programlisting">
        :do actionname filename
</pre><p>
</p><p>
This starts the action "actionname" for file "filename".
Variables to be used by the commands can be specified after the action as
attributes:
</p><pre class="programlisting">
        :action convert default
            :sys convertcmd $?arg $source &gt;$target
        ...
        :do convert {arg = -r} filename
</pre><p>
The filetype is automatically detected from the file name(s) and possibly its
contents.
To overrule the automatic filetype detection, specify the filetype as an
attribute on the file:
</p><pre class="programlisting">
        :do convert filename {filetype = text}
</pre><p>
  This changes the filetype of the source file, the input of the action.  To
  change the filetype of the output, the target of the action, use a
  "filetype" attribute on the action name:
</p><pre class="programlisting">
  :do convert {filetype = html} filename {filetype = text}
</pre><p>
Multiple filename arguments can be used:
</p><pre class="programlisting">
        :do action file1 file2 file3
</pre><p>
For some actions a target can or must be specified.  This is done as an
attribute on the action name:
</p><pre class="programlisting">
        :do convert {target = outfile} infile1 infile2
</pre><p>
Attributes of the input filenames other than "filetype" are not used to select
the action that will be executed.
</p><p>
The "async" attribute can be used to start the application without waiting for
it to finish.  However, this only works for system commands and when
multi-tasking is possible.  Example:
</p><pre class="programlisting">
        :do email {async} {remove} {to = piet} {subject = done building} logmessage
</pre><p>
The "remove" attribute specifies that the files are to be deleted after the
command is done, also when it fails.
</p><p>
When the filetype contains a "_" and no action can be found for it, the search
for an action is done with the part before the "_".  This is useful for
specifying a variant on a filetype where some commands are different and the
rest is the same.
</p><p>
"action" is usually one of these:
  </p><div class="informaltable"><table border="0"><colgroup><col width="150"><col></colgroup><tbody><tr><td>view</td><td>Look at the file.  The "readonly" attribute is
              normally set, it can be reset to allow editing.</td></tr><tr><td>edit</td><td>Edit the file.</td></tr><tr><td>email</td><td><table border="0"><colgroup><col><col></colgroup><tbody><tr><td>
                  Send the file by e-mail.  Relevant attributes:
                </td><td class="auto-generated"> </td></tr><tr><td>edit</td><td>edit before sending</td></tr><tr><td>subject</td><td>subject of the message</td></tr><tr><td>to</td><td>destination</td></tr></tbody></table></td></tr><tr><td>build</td><td>Build the file(s), resulting in a program file.  The "target"
            attribute is needed to specify the output file.</td></tr><tr><td>compile</td><td>Build the file(s), resulting in object file(s).  The "target"
            attribute may be used to specify the output file.  When "target" is
            not specified the action may use a default, usually
            `src2obj(fname)`.  See <a href="ref-python.html#python-src2obj">here</a>
          </td></tr><tr><td>extract</td><td>Unpack an archive.  Requires the program for unpacking to be
            available.  Unpacks in the current directory.</td></tr><tr><td>preproc</td><td>Run the preprocessor on the file.  The "target" attribute can
            be used to specify the output file.  When it is missing the output
            file name is formed from the input file name with
            `src2obj(fname, sufname = None)`  and then appending ".i".
          </td></tr><tr><td>reference</td><td>Run a cross referencer, creating or updating a symbol
            database.</td></tr><tr><td>strip</td><td>Strip symbols from a program.  Used to make it smaller after
            installing.</td></tr></tbody></table></div><p>
</p><p>
Examples:
</p><pre class="programlisting">
        :do view COPYRIGHT {filetype = text}
        :do edit configargs.xml
        :do email {edit} bugreport
        :do build {target = myprog} main.c version.c
        :do compile foo.cpp
</pre><h2><a name="id2660800"></a>Default Actions</h2><p>
These are defined in the default.aap recipe.
</p><div class="variablelist"><dl><dt><span class="term">
      :action edit default
    </span></dt><dd><p>
        Uses the environment variable $VISUAL or $EDITOR.  Falls back to "vi"
        for Posix systems or "notepad" otherwise.  You can set the <span class="application">Aap</span>
        variable <a href="ref-variables.html#var-editor">$EDITOR</a> to the editor
        program to be used.
      </p><p>
        The {line = 999} attribute can be used to specify a line number to
        jump to.  The {byte = 999} attribute can be used to jump to a
        character position in the file.
      </p></dd><dt><span class="term">
      :action edit gif,jpeg,png
    </span></dt><dd><p>
        Uses the environment variable $PAINTER.  You can set the <span class="application">Aap</span>
        variable <a href="ref-variables.html#var-editor">$PAINTER</a> to the image
        editor program to be used.
      </p><p>
        The {line = 999} attribute can be used to specify a line number to
        jump to.  The {byte = 999} attribute can be used to jump to a
        character position in the file.
      </p></dd><dt><span class="term">
      :action depend
    </span></dt><dd><p>
        The default dependency checker.  Works for C and C++ files.
        Uses gcc when available, because it is faster and more reliable.
        Uses an internal function otherwise.
        This attempts to handle the situation that a header file doesn't exist
        (when it needs to be fetched or build)
        but that is not fully implemented yet.
      </p></dd><dt><span class="term">
      :action view html,xml,php
    </span></dt><dd><p>
        Uses the environment variable 
        <a href="ref-variables.html#var-browser">$BROWSER</a>.  Searches a list of known
        browsers if it's not set.
      </p></dd><dt><span class="term">
      :action email default
    </span></dt><dd><p>
        Uses the environment variable $MAILER.  Falls back to "mail".
      </p></dd><dt><span class="term">
      :action build default default
    </span></dt><dd><p>
        Does: ":sys $CC $LDFLAGS $CFLAGS -o $target $source $?LIBS"
      </p></dd><dt><span class="term">
      :action compile object c,cpp
    </span></dt><dd><p>
        Does ":sys $CC $CPPFLAGS $CFLAGS -c -o $target" $source
      </p></dd><dt><span class="term">
      :action preproc default c,cpp
    </span></dt><dd><p>
        Does ":sys $CC $CPPFLAGS -E $source &gt; $target"
      </p></dd></dl></div><p>
</p><h2><a name="specify-actions"></a>Specifying Actions</h2><p>
Applications for an action-filetype pair can be specified with this command:
</p><pre class="programlisting">
        :action action in-filetype
                commands
</pre><p>
This associates the commands with action "action" and filetype "in-filetype".
The commands are A-A-P commands, just like what is used in the build commands
in a dependency.
</p><p>
The "in-filetype" is used for the source of the action, the type of the target
is undefined.  It is also possible to specify an action for turning a file of
one filetype into another filetype.  This is like a
<a href="ref-commands.html#cmd-rule">:rule</a> command, but using
filetypes instead of patterns.
</p><pre class="programlisting">
        :action action out-filetype in-filetype
                commands
</pre><p>
Actually, specifying an action with one filetype is like using "default" for
the out-filetype.
</p><p>
Several variables are set and can be used by the commands:
  </p><div class="informaltable"><table border="0"><colgroup><col width="150"><col></colgroup><tbody><tr><td>$fname</td><td>The first file name of the
            <a href="ref-commands.html#cmd-do">:do</a> command.</td></tr><tr><td>$source</td><td>All the file names of the
          <a href="ref-commands.html#cmd-do">:do</a> command.</td></tr><tr><td>$filetype</td><td>The detected or specified filetype for the input.</td></tr><tr><td>$targettype</td><td>The detected or specified filetype for the output.</td></tr><tr><td>$action</td><td>The name of the action for which the commands are
          executed.</td></tr></tbody></table></div><p>
</p><p>
Furthermore, all attributes of the action are turned into variables.  Thus
when ":do action {arg = -x} file " is used, $arg is set to "-x".  Example for
using an optional "arg" attribute:
</p><pre class="programlisting">
        :action view foo
                :sys fooviewer $?arg $source
</pre><p>
In Python code check if the {edit} attribute is specified:
</p><pre class="programlisting">
        :action email default
            # when $subject and/or $to is missing editing is required
            @if not globals().get("subject") or not globals().get("to"):
                edit = 1
            @if globals().get("edit"):
                :do edit $fname
            :sys mail -s $subject $to &lt; $fname
</pre><p>
"action" and "ftype" can also be a comma-separated list of filetypes.  There
can't be any white space though.  Examples:
</p><pre class="programlisting">
        :action view html,xml,php
            :sys netscape --remote $source
        :action edit,view text,c,cpp
            :sys vim $source
</pre><p>
"filetype" can be "default" to specify an action used when there is no action
specifically for the filetype.
</p><p>
  When using a variable in the commands of an action without specifying a
  scope, or using the "_no" scope, its value is obtained from the first scope
  where it is defined from this list:
</p><div class="orderedlist"><ol type="1"><li><p>
  The local scope, the scope of the action commands.
</p></li><li><p>
  Invoking command blocks.  That is, the scope of the command block that
  invoked the action with a
  <a href="ref-commands.html#cmd-do">:do</a> command.
  Then the scope of the command block that invoked that command block, and so
  on.  This excludes the toplevel.
</p></li><li><p>
 The recipe in which the ":do" command was invoked, its parent and so on.
 This goes on until and including the toplevel.
</p></li><li><p>
 The recipe in which the action was defined, its parent and so on.  This goes
 on until the toplevel.
</p></li></ol></div><p>
</p><p>
  The meaning of this all is that when using a variable such as $FOOCMD, you
  can give it a default value in the recipe where the action is defined.
  The location where the action is later invoked from can define a different
  value.  Example:
</p><pre class="programlisting">
        FOOCMD = foocc
        done =
        :action compile object foo
            :sys $FOOCMD $source &gt; $target
            _recipe.done += $-source
        :action foolist default
            :print Compiled $_recipe.done
</pre><p>
The action can be used like this:
</p><pre class="programlisting">
        all:
            FOOCMD = foocc -O            # used instead of the default $FOOCMD
            :do compile {target = opt/piet.o} piet.f
            done = nothing               # This has no effect
            :do foolist any
</pre><p>
  In action the "done" variable is used with the "_recipe" scope prepended,
  thus a "done" variable in the scope of the commands that invoked this action
  will not be used.
</p><p>
  Note that the "async" attribute of the
  <a href="ref-commands.html#cmd-do">:do</a> command may cause the
  <a href="ref-commands.html#cmd-sys">:sys</a>
command to work asynchronously.  That is done because the "async" attribute is
turned into the "async" variable for the
<a href="ref-commands.html#cmd-action">:action</a> commands.  If you don't
want a specific
<a href="ref-commands.html#cmd-sys">:sys</a> command to work asynchronously, reset "async":
</p><pre class="programlisting">
        :action view foo
            tt = $?async
            async = 
            :sys foo_prepare
            async = $tt
            :sys foo $source
</pre><p>
  However, since two consecutive
  <a href="ref-commands.html#cmd-sys">:sys</a> commands are executed together, this
should do the same thing:
</p><pre class="programlisting">
        :action view foo
            :sys foo_prepare
            :sys foo $source
</pre><p>
Quite often the program to be used depends on whether it is available on the
system.  For example, viewing HTML files can be done with netscape, mozilla,
konquerer or another browser.  We don't want to search the system for all
kinds of programs when starting, it would make the startup time quite long.
And we don't want to search each time the action is invoked, the result of the
first search can be used.  This construct can be used to achieve this:
</p><pre class="programlisting">
        BROWSER =
        :action view html
            @if not _recipe.BROWSER:
                :progsearch _recipe.BROWSER netscape mozilla konquerer
            :sys $_recipe.BROWSER $source
</pre><p>
The generic form form :progsearch is:
</p><pre class="programlisting">
        :progsearch varname progname ...
</pre><p>
The "_recipe" scope needs to be used for variables set in the commands and
need to be used after the action is finished.
</p><p>
The first argument is the variable name to which to assign the resulting
program name.  When none of the programs is found an error message is given.
Note that shell aliases are not found, only executable programs.
</p><p>
When the action uses a temporary file, make sure it is deleted even when one
of the commands fail.  The Python try/finally construction is ideal for this.
Example:
</p><pre class="programlisting">
        :action filter .pdf .txt
            tmp = `tempfname()`
            @try:
                :sys extract_docs $source &gt;$tmp
                :sys docs2pdf $tmp $target
            @finally:
                :delete $tmp
            :print Converted $source to $target
</pre><p>
When the ":sys" commands execute without trouble the ":delete" and ":print"
commands are executed.
When the first ":sys" commands causes an exception, execution continues with
the ":delete" command and then the exception is handled.  Thus the second
":sys" command is skipped and the ":print" command is not reached.
</p><p>
More examples:
</p><pre class="programlisting">
        :action compile object c,cpp
            :sys $CC $CPPFLAGS $CFLAGS -c $source
        :action build object
            :sys $CC $LDFLAGS $CFLAGS -o $target $source
</pre><h2><a name="id2660226"></a>Specifying Actions in Python</h2><p>
  When an action needs to be defined with more properties, a Python function
  can be used.  Example:
</p><pre class="programlisting">
        :python
            define_action("buildme", 1, """
                @if DEFER_ACTION_NAME:
                    :do $DEFER_ACTION_NAME {target = $target} $source
                @else
                    :sys me &lt; $source &gt; $target
                """,
                outtypes = ["me"],
                intypes = ["moo"],
                defer_var_names = ["BUILDME_ACTION"])
</pre><p>
  This defines an action almost like this :action command
</p><pre class="programlisting">
        :action buildme {primary} me moo
            @if _no.get("BUILDME_ACTION"):
                :do $BUILDME_ACTION {target = $target} $source
            @else:
                :sys me &lt; $source &gt; $target
</pre><p>
  An important difference is that when the action defined with $BUILDME_ACTION
  supports different input and output filetypes, the action defined with
  define_action() will use these.  The action defined with ":action" will
  always support "me" and "moo", even though the actually used $BUILDME_ACTION
  action supports different types.
</p><p>
  More info about the define_action() function in the 
  <a href="ref-python.html#python-define-action">reference manual</a>.
</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="user-makedif.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="user.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="user-autodep.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 27. Differences from make </td><td width="20%" align="center"><a accesskey="h" href="index.html">
		    Contents</a></td><td width="40%" align="right" valign="top"> Chapter 29. Customizing Automatic Depedencies</td></tr></table></div></body></html>