Chapter 41. A-A-P Python functions

This chapter documents the Aap specific functions that can be used in Python code.

Python functions grouped by functionality

Variable Values 
expand2dictlist() Expands wildcards and turns it into a list of dictionaries.  
expand2list() Expands wildcards and turns it into a list of items.  
expand2string() Expand wildcards, "~user" and "~/user". 
wildescape() Avoid expansion of wildcard characters.  
var2dictlist() Turns a string into a list of dictionaries.  
var2list() Turns a string into a list of items.  
var2string() Does delayed evaluation of "var" when necessary.  
get_attr() Returns a dictionary with the attributes of a node.  
get_var_attr() Returns the value of a specific attribute used in a list of items.  
   
Dependencies 
has_target() Checks the kind of dependencies a target has.  
has_targetarg() Checks if one of the arguments was used as an Aap argument.  
has_build_target() Checks if Aap was started that builds something.  
src2obj() Transform source file names into object file names.  
skipbuild() Returns non-zero when build commands are to be skipped.  
   
Installing 
ask_prefix() Ask the user for an installation prefix.  
do_BSD_port() Attempt to install a BSD port.  
do_Debian_pkg() Attempt to install a Debian package.  
install_files() Install files to a specified directory.  
uninstall_files() Uninstall files from a specified directory.  
   
Filesystem 
file2string() Return the contents of a file as a string.  
program_path() Search for a program and return the full path.  
tempfname() Returns the name of a temporary file.  
var_abspath() Turn filenames into absolute paths.  
childdir() Prepend $CHILDDIR to every item in the argument.  
parentdir() Prepend $PARENTDIR to every item in the argument.  
topdir() Prepend $TOPDIR to every item in the argument.  
basedir() Prepend $BASEDIR to every item in the argument.  
bdir() Prepend $BDIR as needed to an argument, optionally stripping attributes.  
   
Various 
aap_has() Check if Aap supports a feature.  
redir_system() Execute a system command are return its stdout.  
sort_list() Sort a list and return the resulting list.  
get_html_images() Extract list of images used in a HTML file.  
suffix() Return the filename suffix.  
sufreplace() Replace filename suffix in a list of filenames.  
sufadd() Add filename suffix in a list of filenames.  
define_action() Define an action.  

Alphabetical list of Python functions

aap_has(name)

Returns non-zero if Aap supports feature "name". These features can be checked:

: command-nameWhether the command "command-name" is supported.

Example:

        @if aap_has(":tree"):
           :tree . {filename = .*\.aap}
              :print recipe found: $name

ask_prefix(name)

Ask the user where to install the package "name". Returns a tuple (asroot, prefix). "asroot" is a boolean indicating whether the package is to be installed as root (using :asroot). "prefix" is the root for the install.

If the user is root it will return (1, "/usr/local/") without asking. When aborted it returns an empty prefix.

basedir(arg)

Prepend $BASEDIR to every item in "arg". This makes items with a path relative to the toplevel recipe relative to the current recipe. Example:

         LibFiles = `basedir(LibNames)`

Also see topdir() and var_abspath().

bdir(file, with_attributes=1)

Prepend $BDIR to the single filename "file", but only if this is needed -- that is, if $BDIR isn't already there. This makes the filename point into $BDIR, which is useful for creating temporary files (say, generating C from Yacc input). Unlike just prepending $BDIR, though, bdir() only prepends $BDIR if needed (so if the Yacc input was already in $BDIR because it was generated from another source, bdir() will do the right thing and prepending $BDIR/ won't).

         :sys uic -tr i18n $source > `bdir(target,0)`

In this example, the output is written to the target file, and the target is forced into the build directory. In general, bdir() is used most when there are multi-stage compilations going on, and should probably be well-hidden in Aap modules.

The function bdir() returns a string. If "with_attributes" has a non-zero value, the attributes for the file are preserved in the string. This is useful for further processing by Aap. For the case where you want just the filename in the build directory, set "with_attributes" to 0, as in the example above (if you don't, you get very strange filenames depending on the attributes attached to the file).

childdir(arg)

Prepend $CHILDDIR to every item in "arg". This makes items with a path relative to the child recipe relative to the parent recipe. Example:

         _parent.DISTFILES += `childdir(DISTFILES)`

Can only be used in a child recipe. Also see parentdir(), topdir() and var_abspath().

define_action(action, primary, commands, attr = {}, intypes = [], outtypes = [], defer_var_names = [], outfilename = '')

Define an action with the name "action". Also see the section called “Specifying Actions”.

The "primary" argument must be zero for a normal action, one for a primary action. A primary action is the preferred way to turn the specified input filetypes into the output filetypes.

The "commands" argument is a string with the Aap commands that are executed for the action. Normally a multi-line string is used. Make sure the indent of each command is correct!

The optional "attr" argument specifies extra attributes for the action.

The optional "intypes" argument specifies the list of input filetypes. When omitted the get_in_types() function must be specified, see below.

The optional "outtypes" argument specifies the list of output filetypes. When omitted the get_out_types() function must be specified, see below.

The optional "defer_var_names" argument specifies a list of variable names that are used to make the action invoke another action. The special name "{buildaction}" can be used to check the "buildaction" attribute of the source files for a specific build action to be used.

For example, if "defer_var_names" is ["BUILD_ACTION", "{buildaction}"] then first $BUILD_ACTION is looked at. If it is defined its value is used as the name of the action to be invoked. If it is not set then the "buildaction" attribute of the source files is obtained.

In the "commands" argument the $DEFER_ACTION_NAME variable can be used, it is set to the found action name. Otherwise it is empty.

The optional "outfilename" argument specifies a string that forms the target file name. It normally includes "$source". When this argument is defined the action can be used in a route with a following action. Example: "$(source).c". The target file name is the source file name with ".c" appended.

Return Value: The define_action() function returns an Action object. This can be used to overrule the get_out_types() and get_in_types() functions. These should return a list of the currently supported output and input filetypes for the action. See the "default.aap" recipe for more examples. The defer_action_name() function can also be overruled. It must return the name of an action to defer the work to or None. Example:

          :python
              act = define_action("buildme", 1, """
                        @if DEFER_ACTION_NAME:
                            :do $DEFER_ACTION_NAME {target = $target} $source
                        @else:
                            :sys me < $source > $target
                        """,
                        outtypes = ["me"],
                        intypes = ["moo"])
              def buildme_name(source = ""):
                  name = get_var_attr(source, "buildaction")
                  if name:
                      return name
                  return None
              act.defer_action_name = buildme_name
              def buildme_outtypes(source = "", intype = None):
                  if intype and intype not in self.intypes:
                      return []
                  return ["me"]

Note that the defer_action_name() function must support an optional argument "source", which is a string containing the source files used. In the example the "buildaction" attributes of the source files are used to find a specific action to be used for building.

do_BSD_port(name, target)

Attempt to install the BSD port "name". This includes the directory in which the port lives, e.g.: "devel/templ".

The BSD port system will take care of dependencies. This may result in many more ports to be installed than the one you asked for.

"target" is passed to the "make" command for the port. When "target" is "all" the port is build but not installed. When "target" is "install" it will be build and installed.

When needed the user will be asked to enter the root password. The "make" command is run in a separate root shell (every command must be confirmed for security reasons).

Returns non-zero for success.

do_Debian_pkg(name, target)

Attempt to install the Debian package "name". This is the name that "apt-get" uses.

When not on a Debian system or when "apt-get" cannot be found the function returns with a zero value.

The Debian "apt-get" will take care of dependencies. This may result in many more packages to be installed than the one you asked for.

"target" specifies what to do. When "target" is "install" the package will be installed.

When needed the user will be asked to enter the root password. The "make" command is run in a separate root shell (every command must be confirmed for security reasons).

Returns a non-zero number for success.

expand2dictlist(expr)

Turns a variable with a string value into a list of dictionaries. Each dictionary has a "name" entry for the item itself and other entries are attributes. Wildcards in "expr" are expanded. See var2dictlist() for not expanding wildcards. Example:

        source = file1 {force} file2 file3
        @for item in expand2dictlist(source):
        @    if item.get("force"):
                 :print forced item: `item["name"]`

expand2list(expr)

Turns a variable with a string value into a list of items. Attributes are discarded. Delayed evaluation is taken care of.

Wildcards in "expr" are expanded. See var2list() for not expanding wildcards. Example:

         source = file1 file2 file3
         @for fname in expand2list(source):
             :sys prog $fname

expand2string(expr)

Expand wildcards, "~user" and "~/user" in "expr". Returns the expanded string. "expr" is handled as a list of items, white space is collapsed into a single space.

file2string(fname, dict = None)

Reads the file "fname" and concatenates the lines into one string. Lines starting with a '#' are ignored. One space is inserted in between joined lines, other white space (including CR and VT) at the start and end of a line is removed.

When "fname" doesn't exist or can't be read an error message is given and an empty string is returned. Aap does continue with the following commands.

"dict" is used to obtain the value for $MESSAGE. The default is None. To avoid the error message for a not existing file use something like this:

        @foofile = file2string("foo", {"MESSAGE" : ""})

get_attr(name)

Returns a dictionary with the attributes of "name". If "name" is unknown or has no attributes, an empty dictionary is returned. Example:

        :attr {logical = yes} foobar
        @print "foobar attributes: ", get_attr("foobar")

get_html_images(files, add_dir = 1)

Returns a list of the images used in HTML files. The argument "files" can be a Python list of file names (e.g., what glob() returns) or an Aap list of files (white separated). Only images with a relative path and no URL are included and each name is included only once.

Since the image file names are relative to the HTML file name, the directory of the HTML file is prepended to the image file name. If this is not wanted set the "add_dir" argument to zero. The returned file names are then as they appear in the HTML files.

This function is useful to make a list of image files that needs to be uploaded to a web server. Example:

        Files = index.html burp.html contact.html
        Files += `get_html_images(Files)`

Note that this function is not perfect, it only works for relative file names, ignores Javascript and PHP, etc.

get_var_attr(expr, attr_name)

"expr" is handled as a list of items with attributes. For each item the attribute "attr_name" is obtained. If the item in "expr" does not specify an attribute it is obtained from the node (attributes previously added with :attr). If none of the items has an attribute "attr_name" the function returns None. if two items have a different value for attribute "attr_name" a UserError exception is raised. Otherwise the value of attribute "attr_name" is returned. Example:

          action = `get_var_attr(source, "buildaction")`
          @if action:
              :do $action $source

has_target(target)

Returns a number, depending on whether a dependency exists in which "target" is a target item:

0there is no dependency for "target"
1a dependency for "target" exists, there is no dependency with build commands
2a dependency for "target" with build commands exists

Example:

        @if not has_target("fetch"):

has_targetarg(targets)

Returns non-zero if one of the items in "targets" was used as a build target in the aap command. Example:

        @if has_targetarg("commit tar"):
            :include maintainer.aap

has_build_target()

Returns non-zero if Aap was started with a target that will build something or no target at all (the default target is expected to build something). Returns zero if the only targets are "clean", "cleanmore", "cleanALL" or "fetch".

Useful to skip configuration when it's pointless.

install_files(dir, sources, mode)

Install the files specified in "sources" in the directory "$DESTDIR/$PREFIX/dir". Set the file protection to "mode". Attributes on the items in "sources" can change the destination directory and mode, see the section called “Destination Directories”.

"dir" can be any directory. When "dir" is an absolute path (starts with a slash) then $PREFIX is not prepended. $DESTDIR is always prepended.

Note that only the tails of the filenames in "sources" are used, thus installing "foo/bar.txt" into the "/tmp" directory results in "/tmp/bar.txt".

"mode" is normally a string with octal digits, e.g., "0644".

Example:

          Files = test/foo.txt test/bar.txt
          Dir = /usr/local/share
          ...
          install-local:
             @install_files(_no.Dir, _no.Files, '0644')

For uninstalling see uninstall_files()

parentdir(arg)

Prepend $PARENTDIR to every item in "arg". This makes items with a path relative to the parent recipe relative to the current recipe. Example:

         ImgFiles = `parentdir(ImgNames)`

Can only be used in a child recipe. Also see childdir() and var_abspath().

program_path(name, path = None, pathext = None, skip = None)

Returns the path for program "name". This uses the $PATH environment variable or os.defpath if it isn't set.

Additionally, the directory where Aap is installed and the "bin" subdirectory are searched. This finds tools supplied with Aap and installed packages. This is not done when the optional "path" argument is supplied.

On MS-Windows and OS/2 also checks with extensions added. This uses the $PATHEXT environment variable if set (The separator used is ';' if there is one, the system-dependent separator otherwise). Otherwise the extnsions ".exe", ".com", ".bat", ".cmd" are used. When "name" includes a suffix (a dot in the last component) adding extensions is not done.

Returns the first program found. Returns None when "name" could not be found.

Only finds executable files, not ordinary files.

Optional arguments:

pathsearch path to use instead of $PATH; when a string items are separated with os.pathsep
pathextextensions to try. Can be a list or a string. When a string is used items must be separated with os.pathsep
skipname of directory to skip, "name" is not found in this directory

Example, search for program "foo.py" and "foo.sh":

        p = `program_path("foo", pathext = [ '.py', '.sh' ])`

redir_system(cmd, use_tee = 1)

Execute shell commands "cmd" and return two items: a number indicating success and the stdout.

By default "tee" is used to display the output as well as redirecting it. When no output is desired set "use_tee" to zero. Example:

        ok, text = redir_system("ls", 0)
        if ok:
             print "ls output: %s" % text
        else:
             print "ls failed"

skipbuild()

Returns non-zero when build commands are to be skipped. This is when Aap was started with the --nobuild or --touch argument.

sort_list(list)

sorts a list and returns the list. Example:

        INP = `sort_list(glob("*.inp"))`

The Python list.sort() method doesn't return the sorted list.

src2obj(source, sufname = "OBJSUF", auto = 1)

Transform a string, which is a list of source files, into the corresponding list of object files. Each item in "source" is changed by prepending $BDIR and changing or appending the suffix specified with "sufname" (defaults to $OBJSUF).

The attribute "var_BDIR" is used instead of $BDIR when the attribute exists. The attribute "suffix" is used for the suffix instead of using the "suffix" argument when the attribute exists.

When the "auto" argument is non-zero (the default) then the filetype of the source file will be prepended to the "sufname" (in upper case and adding an underscore). Thus for a Java source file, $JAVA_OBJSUF will be used. When it does not exists "sufname" is used. When this is not wanted the "auto" argument must be set to zero.

suffix(name)

Return the filename suffix. If there isn't one an empty string is returned. Example: suffix("foo.c") returns "c".

Note that the dot isn't included, while variables like $OBJSUF do include the dot.

sufadd(suf, expr, always = 0)

Returns "expr" with suffix "suf" appended. When "always" is non-zero the suffix is also added to items that already have a suffix. If "always" is omitted or zero the suffix is only added to items without a suffix. "expr" can be a list of filenames. Example:

        libs = `sufadd(".lib", libs)`

sufreplace(from, to, expr)

Returns "expr" with all occurences of the suffix "from" changed to "to". When "from" is empty any suffix is changed to "to". When "from" is None the suffix "to" is also appended to items that do not have a suffix yet. "expr" can be a list of filenames. Example:

        OBJECT = `sufreplace("", OBJSUF, SOURCE)`

tempfname()

Returns the name of a file which does not exist and can be used temporarily.

The recipe should take of deleting the file, but Aap may delete the directory in which the file resides when it exits. Thus don't depend on the file to continue to exist after Aap exits.

topdir(arg)

Prepend $TOPDIR to every item in "arg". This makes items with a path relative to the current recipe relative to the toplevel recipe. Example:

        _top.DISTFILES += `topdir(DISTFILES)`

Also see childdir() and var_abspath().

uninstall_files(dir, sources)

Uninstall the files specified in "sources" from the directory "$DESTDIR/$PREFIX/dir". When given the same arguments as install_files() it will delete the installed files.

Example:

          Files = test/foo.txt test/bar.txt
          Dir = /usr/local/share
          ...
          uninstall-local:
             @uninstall_files(_no.Dir, _no.Files)

var_abspath(var)

Returns "var" with all filenames turned into absolute paths. Prepends the current directory to each item in "var" which isn't an absolute path name. Example:

        :print `var_abspath("foo bar")`

Running this in "/home/mool/test" results in:

        /home/mool/test/foo /home/mool/test/bar 

var2dictlist(var)

Turns "var" into a list of dictionaries. "var" must be a string or a variable. Each dictionary has a "name" entry for the item itself and other entries are attributes. Example:

        source = file1 {force} file2 file3
        @for item in var2dictlist(source):
        @    if item.get("force"):
            :print forced item: `item["name"]`

See expand2dictlist() for expanding wildcards.

var2list(var)

Turns "var" into a list of items. "var" must be a string or a variable. Attributes are discarded. Delayed evaluation is taken care of. Example:

        source = file1 file2 file3
        @for fname in var2list(source):
            :sys prog $fname

See expand2list() for expanding wildcards.

var2string(var)

Does delayed evaluation of "var" when necessary. Variables that should be expanded when used use the ExpandVar class and cannot be used directly. The unexpanded value is accessible with "var.val". Illustration:

        bar = aaa
        foo $= $bar
        bar = bbb
        :print $$foo: $foo
        :print Unexpanded: `foo.val`
        :print Expanded: `var2string(foo)`

Output:

        $foo: bbb
        Unexpanded: $bar
        Expanded: bbb 

This also takes care of changing a Python list and other variable types to a string. A None value is turned into an empty string.

wildescape(expr)

Return the string "expr" with wildcard characters escaped, so that expanding wildcards will result in "expr". This puts the characters '*', '?' and '[' inside []. Example:

                  files = `glob("images/*")`
                  :attr {asdf} `wildescape(files)`

Equivalent to:

                  :attr {asdf} images/*

While developing Aap some functions have been renamed. The old names are still available to keep old recipes from working. But some day these will be removed.

obsolete name new name
aap_sufreplace() sufreplace()
aap_abspath() var_abspath()
aap_expand() var2string()
expandvar() expand2string()