Customizing Filetype Detection and Actions

A-A-P home page | A-A-P Recipe Executive
--- | ---
Prev |  | Next

# Chapter 23. Customizing Filetype Detection and Actions

    See the tutorial for a simple example how to define a new filetype.

    FILETYPE DETECTION

    A-A-P detects the type of a file automatically.  This is used to decide
    what tools can be used for a certain file.

    To manually set the file type of an item add the "filetype" attribute.  This
    overrules the automatic detection.
    Example:
    	foo.o : foo.x {filetype = cpp}

    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:

    	:filetype  filename
    	:filetype
    		suffix p pascal
    		script .*bash$ sh

    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.

    For the syntax of the file see filetype.txt.

    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:

    	:attr {filetype = c_opt} bar.c foo.c
    	:action compile c_opt
    		CFLAGS = -O3
    		:do compile $source

    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!)

    Care should be taken that an action should not invoke itself.  For example, to
    always compile "version.c" when linking a program:

    	: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

    Without "{filetype = program}" on the :do build" command, the action would
    invoke itself, since the filetype for $TARGET is "my_prog".

    EXECUTING ACTIONS

    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.

    To start an application:

    	:do action filename

    This starts the "action" application for file "filename".
    Attributes for the commands can be specified after the action:

    	:do action {arg = -r} filename

    The filetype is automatically detected from the file name and possibly its
    contents.  Extra suffixes like ".in" and ".gz" are ignored.
    To overrule the automatic filetype detection, specify the filetype as an
    attribute on the file:

    	:do action filename {filetype = text}

    Multiple filename arguments can be used:

    	:do action file1 file2 file3

    For some actions a target can or must be specified.  This is done as an
    attribute on the action:

    	:do action {target = outfile} infile1 infile2

    Attributes of the filenames other than "filetype" are not used!

    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:

    	:do email {async} {remove} {to = piet} {subject = done building} logmessage

    The "remove" attribute specifies that the files are to be deleted after the
    command is done, also when it fails.

    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.

    "action" is usually one of these:

    	view		Look at the file.  The "readonly" attribute is
    			normally set, it can be reset to allow editing.
    	edit		Edit the file.
    	email		Send the file by e-mail.  Relevant attributes:
    			    edit	edit before sending
    			    subject	subject of the message
    			    to		destination
    	build		Build the file(s), resulting in a program file.  The
    			"target" attribute is needed to specify the output
    			file.

    	compile		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 $BDIR/root$OBJSUF.

    	extract		Unpack an archive.  Requires the program for unpacking
    			to be available.  Unpacks in the current directory.

    	preproc		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 by using the ".i" suffix.

    	reference	Run a cross referencer, creating or updating a symbol
    			database.

    	strip		Strip symbols from a program.  Used to make it smaller
    			after installing.

    Examples:

    	: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

    Default actions:

    These are defined in the default.aap recipe.  TODO: update this info

    :action edit default
    	Uses the environment variable $VISUAL or $EDITOR.  Falls back to "vi"
    	for Posix systems or "notepad" otherwise

    :action view html,xml,php
    	Uses the environment variable $BROWSER.  Searches a list of known
    	browsers if it's not set.

    :action email default
    	Uses the environment variable $MAILER.  Falls back to "mail".

    :action build default default
        	Does: ":sys $CC $LDFLAGS $CFLAGS -o $target $source $?LIBS"

    :action compile object c,cpp
        	Does ":sys $CC $CPPFLAGS $CFLAGS -c -o $target" $source

    :action preproc default c,cpp
        	Does ":sys $CC $CPPFLAGS -E $source > $target"

    Specifying actions:

    Applications for an action-filetype pair can be specified with this command:

    	:action action in-filetype
    		commands

    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.

    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 ":rule" command, but using
    filetypes instead of patterns.

    	:action action out-filetype in-filetype
    		commands

    Actually, specifying an action with one filetype is like using "default" for
    the out-filetype.

    Several variables are set and can be used by the commands:
    	$fname		The first file name of the ":do" command.
    	$source		All the file names of the ":do" command.
    	$filetype	The detected or specified filetype for the input.
    	$targettype	The detected or specified filetype for the output.
    	$action		The name of the action for which the commands are
    			executed.

    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:

    	:action view foo
    		:sys fooviewer $?arg $source

    In Python code check if the {edit} attribute is specified:

    	: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 < $fname

    "action" and "ftype" can also be a comma-separated list of filetypes.  There
    can't be any white space though.  Examples:

    	:action view html,xml,php
    		:sys netscape --remote $source
    	:action edit,view text,c,cpp
    		:sys vim $source

    "filetype" can be "default" to specify an action used when there is no action
    specifically for the filetype.

    Note that the "async" attribute of the ":do" command may cause the ":sys"
    command to work asynchronously.  That is done because the "async" attribute is
    turned into the "async" variable for the ":action" commands.  If you don't
    want a specific ":sys" command to work asynchronously, reset "async":

    	:action view foo
    		tt = $?async
    		async =
    		:sys foo_prepare
    		async = $tt
    		:sys foo $source

    However, since two consecutive ":sys" commands are executed together, this
    should do the same thing:

    	:action view foo
    		:sys foo_prepare
    		:sys foo $source

    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:

    	BROWSER =
    	:action view html
    	    @if not BROWSER:
    		:progsearch BROWSER netscape mozilla konquerer
    	    :sys $BROWSER $source
    	    :export BROWSER

    The generic form form :progsearch is:

    	:progsearch varname progname ...

    ":export" needs to be used for variables set in the commands and need to be
    used after the action is finished.

    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.

    More examples:
    	:action compile c,cpp
    		:sys $CC $CPPFLAGS $CFLAGS -c $source
    	:action build object
    		:sys $CC $LDFLAGS $CFLAGS -o $target $source

Prev | Contents | Next
Differences from make | Up | Customizing Automatic Depedencies