This file has been translated from LaTeX by HeVeA.

File: omake-doc, Node: Subsection 8-6-2,	Prev: Subsection 8-6-1,	Up: Section 8-6


8.6.2  Notes
============

  In most cases, you won't need to define scanners of your own. The
standard installation includes default scanners (both explicitly and
implicitly named ones) for C, OCaml, and LaTeX files.
  The 'SCANNER_MODE' variable controls the usage of implicit scanner
dependencies.
  The explicit :scanner: dependencies reduce the chances of scanner
mis-specifications. In large complicated projects it might be a good
idea to set SCANNER_MODE to error and use only the named .SCANNER rules
and explicit :scanner: specifications.

File: omake-doc, Node: Section 8-7,	Next: Section 8-8,	Prev: Section 8-6,	Up: Chapter 8


8.7  .DEFAULT
*************

   
  The .DEFAULT target specifies a target to be built by default if omake
is run without explicit targets. The following rule instructs omake to
build the program hello by default
<<   .DEFAULT: hello
>>


File: omake-doc, Node: Section 8-8,	Next: Section 8-9,	Prev: Section 8-7,	Up: Chapter 8


8.8  .SUBDIRS
*************

   
  The .SUBDIRS target is used to specify a set of subdirectories that
are part of the project. Each subdirectory should have its own
OMakefile, which is evaluated in the context of the current environment.
<<   .SUBDIRS: src doc tests
>>

  This rule specifies that the OMakefiles in each of the src, doc, and
tests directories should be read.
  In some cases, especially when the OMakefiles are very similar in a
large number of subdirectories, it is inconvenient to have a separate
OMakefile for each directory. If the .SUBDIRS rule has a body, the body
is used instead of the OMakefile.
<<   .SUBDIRS: src1 src2 src3
        println(Subdirectory $(CWD))
        .DEFAULT: lib.a
>>

  In this case, the src1, src2, and src3 files do not need OMakefiles.
Furthermore, if one exists, it is ignored. The following includes the
file if it exists.
<<   .SUBDIRS: src1 src2 src3
         if $(file-exists OMakefile)
            include OMakefile
         .DEFAULT: lib.a
>>


File: omake-doc, Node: Section 8-9,	Next: Section 8-10,	Prev: Section 8-8,	Up: Chapter 8


8.9  .INCLUDE
*************

   
  The .INCLUDE target is like the include directive, but it specifies a
rule to build the file if it does not exist.
<<   .INCLUDE: config
         echo "CONFIG_READ = true" > config

      echo CONFIG_READ is $(CONFIG_READ)
>>

  You may also specify dependencies to an .INCLUDE rule.
<<   .INCLUDE: config: config.defaults
        cp config.defaults config
>>

  A word of caution is in order here. The usual policy is used for
determining when the rule is out-of-date. The rule is executed if any of
the following hold.


   - the target does not exist, 
   - the rule has never been executed before, 
   - any of the following have changed since the last time the rule was
   executed, 

      - the target, 
      - the dependencies, 
      - the commands-text. 


  In some of the cases, this will mean that the rule is executed even if
the target file already exists. If the target is a file that you expect
to edit by hand (and therefore you don't want to overwrite it), you
should make the rule evaluation conditional on whether the target
already exists.
<<   .INCLUDE: config: config.defaults
         # Don't overwrite my carefully hand-edited file
         if $(not $(file-exists config))
            cp config.defaults config
>>


File: omake-doc, Node: Section 8-10,	Next: Section 8-11,	Prev: Section 8-9,	Up: Chapter 8


8.10  .PHONY
************

   
  A "phony" target is a target that is not a real file, but exists to
collect a set of dependencies. Phony targets are specified with the
.PHONY rule. In the following example, the install target does not
correspond to a file, but it corresponds to some commands that should be
run whenever the install target is built (for example, by running omake
install).
<<   .PHONY: install

     install: myprogram.exe
        cp myprogram.exe /usr/bin
>>


File: omake-doc, Node: Section 8-11,	Next: Section 8-12,	Prev: Section 8-10,	Up: Chapter 8


8.11  Rule scoping
******************

   
  As we have mentioned before, omake is a scoped language. This provides
great flexibility---different parts of the project can define different
configurations without interfering with one another (for example, one
part of the project might be compiled with CFLAGS=-O3 and another with
CFLAGS=-g).
  But how is the scope for a target file selected? Suppose we are
building a file dir/foo.o. omake uses the following rules to determine
the scope.


   - First, if there is an explicit rule for building dir/foo.o (a rule
   with no wildcards), the context for that rule determines the scope
   for building the target. 
   - Otherwise, the directory dir/ must be part of the project. This
   normally means that a configuration file dir/OMakefile exists
   (although, see the .SUBDIRS section for another way to specify the
   OMakefile). In this case, the scope of the target is the scope at the
   end of the dir/OMakefile. 

  To illustrate rule scoping, let's go back to the example of a "Hello
world" program with two files. Here is an example OMakefile (the two
definitions of CFLAGS are for illustration).
<<    # The executable is compiled with debugging
      CFLAGS = -g
      hello: hello_code.o hello_lib.o
         $(CC) $(CFLAGS) -o $@ $+

      # Redefine CFLAGS
      CFLAGS += -O3
>>

  In this project, the target hello is explicit. The scope of the hello
target is the line beginning with hello:, where the value of CFLAGS is
-g. The other two targets, hello_code.o and hello_lib.o do not appear as
explicit targets, so their scope is at the end of the OMakefile, where
the CFLAGS variable is defined to be -g -O3. That is, hello will be
linked with CFLAGS=-g and the .o files will be compiled with CFLAGS=-g
-O3.
  We can change this behavior for any of the targets by specifying them
as explicit targets. For example, suppose we wish to compile hello_lib.o
with a preprocessor variable LIBRARY.
<<    # The executable is compiled with debugging
      CFLAGS = -g
      hello: hello_code.o hello_lib.o
         $(CC) $(CFLAGS) -o $@ $+

      # Compile hello_lib.o with CFLAGS = -g -DLIBRARY
      section
          CFLAGS += -DLIBRARY
          hello_lib.o:

      # Redefine CFLAGS
      CFLAGS += -O3
>>

  In this case, hello_lib.o is also mentioned as an explicit target, in
a scope where CFLAGS=-g -DLIBRARY. Since no rule body is specified, it
is compiled using the usual implicit rule for building .o files (in a
context where CFLAGS=-g -DLIBRARY).
* Menu:

* Subsection 8-11-1::	Scoping of implicit rules
* Subsection 8-11-2::	Scoping of '.SCANNER' rules
* Subsection 8-11-3::	Scoping for '.PHONY' targets


File: omake-doc, Node: Subsection 8-11-1,	Next: Subsection 8-11-2,	Up: Section 8-11


8.11.1  Scoping of implicit rules
=================================
   
  Implicit rules (rules containing wildcard patterns) are not global,
they follow the normal scoping convention. This allows different parts
of a project to have different sets of implicit rules. If we like, we
can modify the example above to provide a new implicit rule for building
hello_lib.o.
<<    # The executable is compiled with debugging
      CFLAGS = -g
      hello: hello_code.o hello_lib.o
         $(CC) $(CFLAGS) -o $@ $+

      # Compile hello_lib.o with CFLAGS = -g -DLIBRARY
      section
          %.o: %.c
              $(CC) $(CFLAGS) -DLIBRARY -c $<
          hello_lib.o:

      # Redefine CFLAGS
      CFLAGS += -O3
>>

  In this case, the target hello_lib.o is built in a scope with a new
implicit rule for building %.o files. The implicit rule adds the
-DLIBRARY option. This implicit rule is defined only for the target
hello_lib.o; the target hello_code.o is built as normal.

File: omake-doc, Node: Subsection 8-11-2,	Next: Subsection 8-11-3,	Prev: Subsection 8-11-1,	Up: Section 8-11


8.11.2  Scoping of '.SCANNER' rules
===================================
   
  Scanner rules are scoped the same way as normal rules. If the .SCANNER
rule is explicit (containing no wildcard patterns), then the scope of
the scan target is the same as the the rule. If the .SCANNER rule is
implicit, then the environment is taken from the :scanner: dependency.
<<    # The executable is compiled with debugging
      CFLAGS = -g
      hello: hello_code.o hello_lib.o
         $(CC) $(CFLAGS) -o $@ $+

      # scanner for .c files
      .SCANNER: scan-c-%.c: %.c
         $(CC) $(CFLAGS) -MM $<

      # Compile hello_lib.o with CFLAGS = -g -DLIBRARY
      section
          CFLAGS += -DLIBRARY
          hello_lib.o: hello_lib.c :scanner: scan-c-hello_lib.c
             $(CC) $(CFLAGS) -c $<

      # Compile hello_code.c with CFLAGS = -g -O3
      section
          CFLAGS += -O3
          hello_code.o: hello_code.c :scanner: scan-c-hello_code.c
             $(CC) $(CFLAGS) -c $<
>>

  Again, this is for illustration---it is unlikely you would need to
write a complicated configuration like this! In this case, the .SCANNER
rule specifies that the C-compiler should be called with the -MM flag to
compute dependencies. For the target hello_lib.o, the scanner is called
with CFLAGS=-g -DLIBRARY, and for hello_code.o it is called with
CFLAGS=-g -O3.

File: omake-doc, Node: Subsection 8-11-3,	Prev: Subsection 8-11-2,	Up: Section 8-11


8.11.3  Scoping for '.PHONY' targets
====================================
   
  Phony targets (targets that do not correspond to files) are defined
with a .PHONY: rule. Phony targets are scoped as usual. The following
illustrates a common mistake, where the .PHONY target is declared after
it is used.
<<    # !!This example is broken!!
      all: hello

      hello: hello_code.o hello_lib.o
          $(CC) $(CFLAGS) -o $@ $+

      .PHONY: all
>>

  This doesn't work as expected because the .PHONY declaration occurs
too late. The proper way to write this example is to place the .PHONY
declaration first.
<<    # Phony targets must be declared before being used
      .PHONY: all

      all: hello

      hello: hello_code.o hello_lib.o
          $(CC) $(CFLAGS) -o $@ $+
>>

  Phony targets are passed to subdirectories. As a practical matter, it
is wise to declare all .PHONY targets in your root OMakefile, before any
.SUBDIRS. This will ensure that 1) they are considered as phony targets
in each of the subdirectories, and 2) you can build them from the
project root.
<<    .PHONY: all install clean

      .SUBDIRS: src lib clib
>>

  Note that when a .PHONY target is inherited by a subdirectory via a
.SUBDIRS, a whole hierarchy of .PHONY targets (that are a part of the
global one) is created, as described in
Section 8.12.2*Note Subsection 8-12-2:: below.

File: omake-doc, Node: Section 8-12,	Next: Section 8-13,	Prev: Section 8-11,	Up: Chapter 8


8.12  Running OMake from a subdirectory
***************************************

    Running omake foo asks OMake to
build the file foo in context of the whole project, even when running
from a subdirectory of the project. Therefore, if bar/baz is a regular
target (not a .PHONY one), then running omake bar/baz and running (cd
bar; omake baz) are usually equivalent.
  There are two noteworthy exceptions to the above rule: 

   - If the subdirectory is not a part of the project (there is no
   .SUBDIRS) for it, then OMake will complain if you try to run it in
   that directory. 
   - If a subdirectory contains an OMakeroot of its own, this would
   designate the subdirectory as a separate project (which is usually a
   bad idea and is not recommended). 

* Menu:

* Subsection 8-12-1::	Phony targets in a subdirectory
* Subsection 8-12-2::	Hierarchy of '.PHONY' targets


File: omake-doc, Node: Subsection 8-12-1,	Next: Subsection 8-12-2,	Up: Section 8-12


8.12.1  Phony targets in a subdirectory
=======================================
   
  Suppose you have a .PHONY: clean declared in your root OMakefile and
both the root OMakefile and the OMakefile in some of the subdirectories
contain clean: rules. In this case 

   - Running omake clean in the root directory will execute all the
   rules (each in the appropriate directory); 
   - Running omake clean in the subdirectory will execute just its local
   one, as well as the ones from the subdirectories of the current
   directory. 

  The above equally applies to the built-in .PHONY targets, including
'.DEFAULT'. Namely, if OMake is executed (without argument) in the root
directory of a project, all the .DEFAULT targets in the project will be
built. On the other hand, when OMake is executed (without argument) in a
subdirectory, only the .DEFAULT targets defined in and under that
subdirectory will be built.
  The following Section explains the underlying semantics that gives
rise to the above behavior.

File: omake-doc, Node: Subsection 8-12-2,	Prev: Subsection 8-12-1,	Up: Section 8-12


8.12.2  Hierarchy of '.PHONY' targets
=====================================
   
  When the the root OMakefile contains a .PHONY: clean directive, it
creates: 

   - A "global" phony target /.PHONY/clean (note the leading "/"); 
   - A "relative" phony target attached to the current directory ---
   .PHONY/clean (note the lack of the leading "/"); 
   - A dependency /.PHONY/clean: .PHONY/clean. 

  All the clean: ... rules in the root OMakefile following this .PHONY:
clean declaration would be interpreted as rules for the .PHONY/clean
target.
  Now when OMake then comes across a .SUBDIRS: foo directive (when it is
in scope of the above .PHONY: clean declaration), it does the following:


   - Creates a new .PHONY/foo/clean "relative" phony target; 
   - Creates the dependency .PHONY/clean: .PHONY/foo/clean; 
   - Processes the body of the .SUBDIRS: foo directive, or reads the
   foo/OMakefile file, if the body is empty. While doing that, it
   interprets its instructions relative to the foo directory. In
   particular, all the clean: ... rules will be taken to apply to
   .PHONY/foo/clean. 

  Now when you run omake clean in the root directory of the project, it
is interpreted as omake .PHONY/clean (similar to how it happens with the
normal targets), so both the rules for .PHONY/clean are executed and the
rules for its dependency  .PHONY/foo/clean. Running (cd foo; omake
clean) is, as for normal targets, equivalent to running omake
.PHONY/foo/clean and only those rules that apply to .PHONY/foo/clean
will be executed.

File: omake-doc, Node: Section 8-13,	Prev: Section 8-12,	Up: Chapter 8


8.13  Pathnames in rules
************************


  In rules, the targets and dependencies are first translated to file
values (as in the 'file' function). They are then translated to strings
for the command line. This can cause some unexpected behavior. In the
following example, the 'absname' function is the absolute pathname for
the file a, but the rule still prints the relative pathname.
<<    .PHONY: demo
      demo: $(absname a)
          echo $<

      # omake demo
      a
>>

  There is arguably a good reason for this. On Win32 systems, the /
character is viewed as an "option specifier." The pathname separator is
the \ character. OMake translates the filenames automatically so that
things work as expected on both systems.
<<   demo: a/b
         echo $<

     # omake demo (on a Unix system)
     a/b
     # omake demo (on a Win32 system)
     a\b
>>

  Sometimes you may wish that target strings to be passed literally to
the commands in the rule. One way to do this is to specify them
literally.
<<    SRC = a/b $(absname c/d)
      demo: $(SRC)
          echo $(SRC)

      # omake demo (on a Win32 system)
      a/b c:\...\c\d
>>

  Alternately, you might wish that filenames be automatically expanded
to absolute pathnames. For example, this might be useful when parsing
the OMake output to look for errors. For this, you can use the --absname
option (Section A.3.20*Note Subsection A-3-20::). If you call omake
with the --absname option, all filenames will be expanded to absolute
names.
<<    # omake --absname demo (on a Unix system)
      /home/.../a/b /home/.../c/d
>>

  Alternately, the --absname option is scoped. If you want to use it for
only a few rules, you can use the 'OMakeFlags' function to control how
it is applied.
<<   section
        OMakeFlags(--absname)
        demo: a
            echo $<

     # omake demo
     /home/.../a
>>

  N.B. The --absname option is currently an experimental feature.


File: omake-doc, Node: Chapter 9,	Next: Chapter 10,	Prev: Chapter 8,	Up: Top


Chapter 9   Base library
************************
     
* Menu:

* Section 9-1::	Builtin variables
* Section 9-2::	Logic, Boolean functions, and control flow
* Section 9-3::	Arrays and sequences
* Section 9-4::	Arithmetic
* Section 9-5::	First-class functions
* Section 9-6::	Iteration and mapping
* Section 9-7::	Boolean tests


File: omake-doc, Node: Section 9-1,	Next: Section 9-2,	Up: Chapter 9


9.1  Builtin variables
**********************


 OMAKE_VERSION
 Version of OMake. 
 STDLIB
 The directory where the OMake
standard library files reside. At startup, the default value is
determined as follows. 

   - The value of the OMAKELIB environment variable, if set (must
   contain an absolute path, if set), otherwise 
   - On Windows, the registry keys
   HKEY_CURRENT_USER\SOFTWARE\MetaPRL\OMake\OMAKELIB and
   HKEY_LOCAL_MACHINE\SOFTWARE\MetaPRL\OMake\OMAKELIB are looked up and
   the value is used, if exist. 
   - Otherwise a compile-time default it used. 
   The current default value may be accessed by running omake --version 
 OMAKEPATH
 An array of directories
specifying the lookup path for the include and open directives (see
Section 4.8*Note Section 4-8::). The default value is an array
of two elements --- . and $(STDLIB). 
 OSTYPE
 Set to the machine
architecture omake is running on. Possible values are Unix (for all Unix
versions, including Linux and Mac OS X), Win32 (for MS-Windows, OMake
compiled with MSVC++ or Mingw), and Cygwin (for MS-Windows, OMake
compiled with Cygwin). 
 CCOMPTYPE
 Set to to either "cc" when the
C compiler is invoked in Unix style, or "msvc" for Microsoft Visual C
(actually, this is the ccomp_type variable of ocamlc -config). This
setting is considered as a system preference. 
 SYSNAME
 The name of the operating
system for the current machine. 
 NODENAME
 The hostname of the current
machine. 
 OS_VERSION
 The operating system release.
 MACHINE
 The machine architecture,
e.g. i386, sparc, etc. 
 HOST
 Same as NODENAME. 
 USER
 The login name of the user
executing the process. 
 HOME
 The home directory of the
user executing the process. 
 PID
 The OMake process id. 
 TARGETS
 The command-line target
strings. For example, if OMake is invoked with the following command
line, 
<<      omake CFLAGS=1 foo bar.c
>>

  then TARGETS is defined as foo bar.c.
 BUILD_SUMMARY
 The BUILD_SUMMARY variable
refers to the file that omake uses to summarize a build (the message
that is printed at the very end of a build). The file is empty when the
build starts. If you wish to add additional messages to the build
summary, you can edit/modify this file during the build.
  For example, if you want to point out that some action was taken, you
can append a message to the build summary.
<<   foo: boo
         echo "The file foo was built" >> $(BUILD_SUMMARY)
         ...build foo...
>>

 VERBOSE
 Whether certain commands
should be verbose. A boolean flag that is false by default and is set to
true when OMake is invoked with the --verbose option. 

File: omake-doc, Node: Section 9-2,	Next: Section 9-3,	Prev: Section 9-1,	Up: Chapter 9


9.2  Logic, Boolean functions, and control flow
***********************************************

   
  Boolean values in omake are represented by case-insensitive strings.
The false value can be represented by the strings false, no, nil,
undefined or 0, and everything else is true.
* Menu:

* Subsection 9-2-1::	not
* Subsection 9-2-2::	equal
* Subsection 9-2-3::	and
* Subsection 9-2-4::	or
* Subsection 9-2-5::	if
* Subsection 9-2-6::	switch, match
* Subsection 9-2-7::	try
* Subsection 9-2-8::	raise
* Subsection 9-2-9::	exit
* Subsection 9-2-10::	defined
* Subsection 9-2-11::	defined-env
* Subsection 9-2-12::	getenv
* Subsection 9-2-13::	setenv
* Subsection 9-2-14::	unsetenv
* Subsection 9-2-15::	get-registry
* Subsection 9-2-16::	getvar
* Subsection 9-2-17::	setvar


File: omake-doc, Node: Subsection 9-2-1,	Next: Subsection 9-2-2,	Up: Section 9-2


9.2.1  not
==========

<<   $(not e) : String
        e : String
>>

  The not function negates a Boolean value.
  For example, $(not false) expands to the string true, and $(not hello
world) expands to false. 

File: omake-doc, Node: Subsection 9-2-2,	Next: Subsection 9-2-3,	Prev: Subsection 9-2-1,	Up: Section 9-2


9.2.2  equal
============

<<   $(equal e1, e2) : String
        e1 : String
        e2 : String
>>

  The equal function tests for equality of two values. This is defined
for anything that can be expanded to a string and for arrays.
  For example $(equal a, b) expands to false, and $(equal hello world,
hello world) expands to true. 

File: omake-doc, Node: Subsection 9-2-3,	Next: Subsection 9-2-4,	Prev: Subsection 9-2-2,	Up: Section 9-2


9.2.3  and
==========

<<    $(and e1, ..., en) : String
         e1, ..., en: Sequence
>>

  The and function evaluates to the conjunction of its arguments.
  For example, in the following code, X is true, and Y is false.
<<    A = a
      B = b
      X = $(and $(equal $(A), a) true $(equal $(B), b))
      Y = $(and $(equal $(A), a) true $(equal $(A), $(B)))
>>


File: omake-doc, Node: Subsection 9-2-4,	Next: Subsection 9-2-5,	Prev: Subsection 9-2-3,	Up: Section 9-2


9.2.4  or
=========

<<   $(or e1, ..., en) : String
        e1, ..., en: String Sequence
>>

  The or function evaluates to the disjunction of its arguments.
  For example, in the following code, X is true, and Y is false.
<<    A = a
      B = b
      X = $(or $(equal $(A), a) false $(equal $(A), $(B)))
      Y = $(or $(equal $(A), $(B)) $(equal $(A), b))
>>


File: omake-doc, Node: Subsection 9-2-5,	Next: Subsection 9-2-6,	Prev: Subsection 9-2-4,	Up: Section 9-2


9.2.5  if
=========

<<    $(if e1, e2[, e3]) : value
         e1 : String
         e2, e3 : value
>>

  The if function represents a conditional based on a Boolean value. For
example $(if $(equal a, b), c, d) evaluates to d.
  Conditionals may also be declared with an alternate syntax.
<<   if e1
        body1
     elseif e2
        body2
     ...
     else
        bodyn
>>

  If the expression e1 is not false, then the expressions in body1 are
evaluated and the result is returned as the value of the conditional.
Otherwise, if e1 evaluates to false, the evaluation continues with the
e2 expression. If none of the conditional expressions is true, then the
expressions in bodyn are evaluated and the result is returned as the
value of the conditional.
  There can be any number of elseif clauses; the else clause is
optional.
  Note that each branch of the conditional defines its own scope, so
variables defined in the branches are normally not visible outside the
conditional. The export command may be used to export the variables
defined in a scope. For example, the following expression represents a
common idiom for defining the C compiler configuration.
<<   if $(equal $(OSTYPE), Win32)
        CC = cl
        CFLAGS += /DWIN32
        export
     else
        CC = gcc
        CFLAGS += -g -O2
        export
>>


File: omake-doc, Node: Subsection 9-2-6,	Next: Subsection 9-2-7,	Prev: Subsection 9-2-5,	Up: Section 9-2


9.2.6  switch, match
====================

  The switch and match functions perform pattern matching.
  $(switch <arg>, <pattern_1>, <value_1>, ..., <pattern_n>, <value_n>)
$(match <arg>, <pattern_1>, <value_1>, ..., <pattern_n>, <value_n>)
  The number of <pattern>/<value> pairs is arbitrary. They strictly
alternate; the total number of arguments to <match> must be odd.
  The <arg> is evaluated to a string, and compared with <pattern_1>. If
it matches, the result of the expression is <value_1>. Otherwise
evaluation continues with the remaining patterns until a match is found.
If no pattern matches, the value is the empty string.
  The switch function uses string comparison to compare the argument
with the patterns. For example, the following expression defines the
FILE variable to be either foo, bar, or the empty string, depending on
the value of the OSTYPE variable.
<<    FILE = $(switch $(OSTYPE), Win32, foo, Unix, bar)
>>

  The match function uses regular expression patterns (see the grep
function). If a match is found, the variables $1, $2, ... are bound to
the substrings matched between \( and \) delimiters. The $0 variable
contains the entire match, and $* is an array of the matched substrings.
to the matched substrings.
<<    FILE = $(match foo_xyz/bar.a, foo_\\\(.*\\\)/\\\(.*\\\)\.a,
foo_$2/$1.o)
>>

  The switch and match functions also have an alternate (more usable)
form.
<<   match e
     case pattern1
        body1
     case pattern2
        body2
     ...
     default
        bodyd
>>

  If the value of expression e matches pattern_i and no previous
pattern, then body_i is evaluated and returned as the result of the
match. The switch function uses string comparison; the match function
uses regular expression matching.
<<   match $(FILE)
     case $".*\(\.[^\/.]*\)"
        println(The string $(FILE) has suffix $1)
     default
        println(The string $(FILE) has no suffix)
>>


File: omake-doc, Node: Subsection 9-2-7,	Next: Subsection 9-2-8,	Prev: Subsection 9-2-6,	Up: Section 9-2


9.2.7  try
==========

<<   try
        try-body
     catch class1(v1)
        catch-body
     when expr
        when-body
     ...
     finally
        finally-body
>>

  The try form is used for exception handling. First, the expressions in
the try-body are evaluated.
  If evaluation results in a value v without raising an exception, then
the expressions in the finally-body are evaluated and the value v is
returned as the result.
  If evaluation of the try-body results in a exception object obj, the
catch clauses are examined in order. When examining catch clause catch
class(v), if the exception object obj is an instance of the class name
class, the variable v is bound to the exception object, and the
expressions in the catch-body are evaluated.
  If a when clause is encountered while a catch body is being evaluated,
the predicate expr is evaluated. If the result is true, evaluation
continues with the expressions in the when-body. Otherwise, the next
catch clause is considered for evaluation.
  If evaluation of a catch-body or when-body completes successfully,
returning a value v, without encountering another when clause, then the
expressions in the finally-body are evaluated and the value v is
returned as the result.
  There can be any number of catch clauses; the finally clause is
optional. 

File: omake-doc, Node: Subsection 9-2-8,	Next: Subsection 9-2-9,	Prev: Subsection 9-2-7,	Up: Section 9-2


9.2.8  raise
============

<<   raise exn
        exn : Exception
>>

  The raise function raises an exception. The exn object can be any
object. However, the normal convention is to raise an 'Exception'
object.
  If the exception is never caught, the whole object will be verbosely
printed in the error message. However, if the object is an Exception one
and contains a message field, only that field will be included in the
error message. 

File: omake-doc, Node: Subsection 9-2-9,	Next: Subsection 9-2-10,	Prev: Subsection 9-2-8,	Up: Section 9-2


9.2.9  exit
===========

<<   exit(code)
        code : Int
>>

  The exit function terminates omake abnormally.
  $(exit <code>)
  The exit function takes one integer argument, which is exit code.
Non-zero values indicate abnormal termination. 

File: omake-doc, Node: Subsection 9-2-10,	Next: Subsection 9-2-11,	Prev: Subsection 9-2-9,	Up: Section 9-2


9.2.10  defined
===============

<<   $(defined sequence) : String
        sequence : Sequence
>>

  The defined function test whether all the variables in the sequence
are currently defined. For example, the following code defines the X
variable if it is not already defined.
<<    if $(not $(defined X))
         X = a b c
         export
>>

  It is acceptable to use qualified names.
<<    $(defined X.a.b)
      $(defined public.X)
>>


File: omake-doc, Node: Subsection 9-2-11,	Next: Subsection 9-2-12,	Prev: Subsection 9-2-10,	Up: Section 9-2


9.2.11  defined-env
===================

<<   $(defined-env sequence) : String
        sequence : String
>>

  The defined-env function tests whether a variable is defined as part
of the process environment.
  For example, the following code adds the -g compile option if the
environment variable DEBUG is defined.
<<if $(defined-env DEBUG)
      CFLAGS += -g
      export
>>


File: omake-doc, Node: Subsection 9-2-12,	Next: Subsection 9-2-13,	Prev: Subsection 9-2-11,	Up: Section 9-2


9.2.12  getenv
==============

<<   $(getenv name) : String
     $(getenv name, default) : String
>>

  The getenv function gets the value of a variable from the process
environment. The function takes one or two arguments.
  In the single argument form, an exception is raised if the variable
variable is not defined in the environment. In the two-argument form,
the second argument is returned as the result if the value is not
defined.
  For example, the following code defines the variable X to be a
space-separated list of elements of the PATH environment variable if it
is defined, and to /bin /usr/bin otherwise.
<<    X = $(split $(PATHSEP), $(getenv PATH, /bin:/usr/bin))
>>

  You may also use the alternate form. 
<<     getenv(NAME)
           default
>>


File: omake-doc, Node: Subsection 9-2-13,	Next: Subsection 9-2-14,	Prev: Subsection 9-2-12,	Up: Section 9-2


9.2.13  setenv
==============

<<   setenv(name, value)
        name : String
        value : String
>>

  The setenv function sets the value of a variable in the process
environment. Environment variables are scoped like normal variables.

File: omake-doc, Node: Subsection 9-2-14,	Next: Subsection 9-2-15,	Prev: Subsection 9-2-13,	Up: Section 9-2


9.2.14  unsetenv
================

<<   unsetenv(names)
        names : String Array
>>

  The unsetenv function removes some variable definitions from the
process environment. Environment variables are scoped like normal
variables.

File: omake-doc, Node: Subsection 9-2-15,	Next: Subsection 9-2-16,	Prev: Subsection 9-2-14,	Up: Section 9-2


9.2.15  get-registry
====================

<<   get-registry(hkey, key, field) : String
     get-registry(hkey, key, field, default) : String
         hkey : String
         key : String
         field : String
>>

  The get-registry function retrieves a string value from the system
registry on Win32. On other architectures, there is no registry.
  The hive (I think that is the right word), indicates which part of the
registry to use. It should be one of the following values.


   - HKEY_CLASSES_ROOT 
   - HKEY_CURRENT_CONFIG 
   - HKEY_CURRENT_USER 
   - HKEY_LOCAL_MACHINE 
   - HKEY_USERS 
   Refer to the Microsoft documentation if you want to know what these
mean.
  The key is the field you want to get from the registry. It should have
a form like A\B\C (if you use forward slashes, they will be converted to
backslashes). The field is the sub-field of the key.
  In the 4-argument form, the default is returned on failure. You may
also use the alternate form.
<<    get-registry(hkey, key, field)
         default
>>


File: omake-doc, Node: Subsection 9-2-16,	Next: Subsection 9-2-17,	Prev: Subsection 9-2-15,	Up: Section 9-2


9.2.16  getvar
==============

<<   $(getvar name) : String
>>

  The getvar function gets the value of a variable.
  An exception is raised if the variable variable is not defined.
  For example, the following code defines X to be the string abc.
<<    NAME = foo
      foo_1 = abc
      X = $(getvar $(NAME)_1)
>>

  It is acceptable to use qualified names.
<<    $(getvar X.a.b)
>>


File: omake-doc, Node: Subsection 9-2-17,	Prev: Subsection 9-2-16,	Up: Section 9-2


9.2.17  setvar
==============

<<   setvar(name, value)
        name : String
        value : String
>>

  The setvar function defines a new variable. For example, the following
code defines the variable X to be the string abc.
<<   NAME = X
     setvar($(NAME), abc)
>>

  It is acceptable to use qualified names.
<<    setvar(public.X, abc)
>>


File: omake-doc, Node: Section 9-3,	Next: Section 9-4,	Prev: Section 9-2,	Up: Chapter 9


9.3  Arrays and sequences
*************************


* Menu:

* Subsection 9-3-1::	array
* Subsection 9-3-2::	split
* Subsection 9-3-3::	concat
* Subsection 9-3-4::	length
* Subsection 9-3-5::	nth
* Subsection 9-3-6::	replace-nth
* Subsection 9-3-7::	nth-hd
* Subsection 9-3-8::	nth-tl
* Subsection 9-3-9::	subrange
* Subsection 9-3-10::	rev
* Subsection 9-3-11::	join
* Subsection 9-3-12::	string
* Subsection 9-3-13::	string-length
* Subsection 9-3-14::	subst
* Subsection 9-3-15::	string-escaped, ocaml-escaped, html-escaped, html-pre-escaped
* Subsection 9-3-16::	c-escaped, id-escaped, sql-escaped, uri-escaped
* Subsection 9-3-17::	hexify, unhexify
* Subsection 9-3-18::	decode-uri, encode-uri
* Subsection 9-3-19::	quote
* Subsection 9-3-20::	quote-argv
* Subsection 9-3-21::	html-string
* Subsection 9-3-22::	addsuffix
* Subsection 9-3-23::	mapsuffix
* Subsection 9-3-24::	addsuffixes, addprefixes
* Subsection 9-3-25::	removeprefix
* Subsection 9-3-26::	removesuffix
* Subsection 9-3-27::	replacesuffixes
* Subsection 9-3-28::	addprefix
* Subsection 9-3-29::	mapprefix
* Subsection 9-3-30::	add-wrapper
* Subsection 9-3-31::	set
* Subsection 9-3-32::	mem
* Subsection 9-3-33::	intersection
* Subsection 9-3-34::	intersects
* Subsection 9-3-35::	set-diff
* Subsection 9-3-36::	filter
* Subsection 9-3-37::	filter-out
* Subsection 9-3-38::	capitalize
* Subsection 9-3-39::	uncapitalize
* Subsection 9-3-40::	uppercase
* Subsection 9-3-41::	lowercase
* Subsection 9-3-42::	system
* Subsection 9-3-43::	shell
* Subsection 9-3-44::	export
* Subsection 9-3-45::	while
* Subsection 9-3-46::	break
* Subsection 9-3-47::	random, random-init


File: omake-doc, Node: Subsection 9-3-1,	Next: Subsection 9-3-2,	Up: Section 9-3


9.3.1  array
============

<<    $(array elements...) : Array
         elements : Sequence
>>

  The array function creates an array from a sequence of elements. Note
that $(array) constructs an empty array.
  In addition, array variables can be declared as follows.
<<    A[] =
         <val1>
         ...
         <valn>
>>

  In this case, the elements of the array are exactly <val1>, ...,
<valn>, and whitespace is preserved literally. 

File: omake-doc, Node: Subsection 9-3-2,	Next: Subsection 9-3-3,	Prev: Subsection 9-3-1,	Up: Section 9-3


9.3.2  split
============

<<   $(split separators, elements) : Array
        separators : String
        elements : Sequence
>>

  The split function takes two arguments, a string of separator
characters, and the string elements to be split. The result is an array
of strings determined by splitting the elements by all occurrences of
the separators in the elements' sequence. (Function split resembles the
C-library function strtok with arguments swapped.)
  For example, in the following code, the variable X is defined to be
the array /bin /usr/bin /usr/local/bin.
<<    PATH = /bin:/usr/bin:/usr/local/bin
      X = $(split :, $(PATH))
>>

  The separator argument may be omitted. In this case split breaks its
arguments along the white space. Quotations are not split. 

File: omake-doc, Node: Subsection 9-3-3,	Next: Subsection 9-3-4,	Prev: Subsection 9-3-2,	Up: Section 9-3


9.3.3  concat
=============

<<   $(concat separator, elements...) : String
        separator : String
        elements : Sequence
>>

  The concat function takes a separator string, and a sequence of
elements. The result is a string formed by concatenating the elements,
placing the separator between adjacent elements.
  For example, in the following code, the X variable is defined to be
the string foo_x_bar_x_baz.
<<    X = foo  bar     baz
      Y = $(concat _x_, $(X))
>>

  To abut elements without intervening separators use
<<    $(concat $(string), ...)
>>


File: omake-doc, Node: Subsection 9-3-4,	Next: Subsection 9-3-5,	Prev: Subsection 9-3-3,	Up: Section 9-3


9.3.4  length
=============

<<   $(length sequence) : Int
        sequence : Sequence
>>

  The length function returns the number of elements in its argument.
  For example, the expression $(length a  b "c d") evaluates to 3. 

File: omake-doc, Node: Subsection 9-3-5,	Next: Subsection 9-3-6,	Prev: Subsection 9-3-4,	Up: Section 9-3


9.3.5  nth
==========

<<   $(nth i, sequence) : value
        i : Int
        sequence : Sequence
     raises RuntimeException
>>

  The nth function returns the nth element of its argument, treated as a
list. Counting starts at 0. An exception is raised if the index is not
in bounds.
  For example, the expression $(nth 1, a "b c" d) evaluates to "b c".

File: omake-doc, Node: Subsection 9-3-6,	Next: Subsection 9-3-7,	Prev: Subsection 9-3-5,	Up: Section 9-3


9.3.6  replace-nth
==================

<<   $(replace-nth i, sequence, x) : value
        i : Int
        sequence : Sequence
        x : value
     raises RuntimeException
>>

  The replace-nth function replaces the nth element of its argument with
a new value x. Counting starts at 0. An exception is raised if the index
is not in bounds.
  For example, the expression $(replace-nth 1, a "b c" d, x) evaluates
to a x d. 

File: omake-doc, Node: Subsection 9-3-7,	Next: Subsection 9-3-8,	Prev: Subsection 9-3-6,	Up: Section 9-3


9.3.7  nth-hd
=============

<<   $(nth-hd i, sequence) : value
        i : Int
        sequence : Sequence
     raises RuntimeException
>>

  The nth-hd function returns the first i elements of the sequence. An
exception is raised if the sequence is not at least i elements long.
  For example, the expression $(nth-hd 2, a "b c" d) evaluates to a "b
c".

File: omake-doc, Node: Subsection 9-3-8,	Next: Subsection 9-3-9,	Prev: Subsection 9-3-7,	Up: Section 9-3


9.3.8  nth-tl
=============

<<   $(nth-tl i, sequence) : value
        i : Int
        sequence : Sequence
     raises RuntimeException
>>

  The nth-tl function skips i elements of the sequence and returns the
rest. An exception is raised if the sequence is not at least i elements
long.
  For example, the expression $(nth-tl 1, a "b c" d) evaluates to "b c"
d.

File: omake-doc, Node: Subsection 9-3-9,	Next: Subsection 9-3-10,	Prev: Subsection 9-3-8,	Up: Section 9-3


9.3.9  subrange
===============

<<   $(subrange off, len, sequence) : value
        off : Int
        len : Int
        sequence : Sequence
     raises RuntimeException
>>

  The subrange function returns a subrange of the sequence. Counting
starts at 0. An exception is raised if the specified range is not in
bounds.
  For example, the expression $(subrange 1, 2, a "b c" d e) evaluates to
"b c" d. 

File: omake-doc, Node: Subsection 9-3-10,	Next: Subsection 9-3-11,	Prev: Subsection 9-3-9,	Up: Section 9-3


9.3.10  rev
===========

<<    $(rev sequence) : Sequence
         sequence : Sequence
>>

  The rev function returns the elements of a sequence in reverse order.
For example, the expression $(rev a "b c" d) evaluates to d "b c" a. 

File: omake-doc, Node: Subsection 9-3-11,	Next: Subsection 9-3-12,	Prev: Subsection 9-3-10,	Up: Section 9-3


9.3.11  join
============

<<   $(join sequence1, sequence2) : Sequence
        sequence1 : Sequence
        sequence2 : Sequence
>>

  The join function joins together the elements of the two sequences.
For example, $(join a b c, .c .cpp .h) evaluates to a.c b.cpp c.h. If
the two input sequences have different lengths, the remainder of the
longer sequence is copied at the end of the output unmodified. 

File: omake-doc, Node: Subsection 9-3-12,	Next: Subsection 9-3-13,	Prev: Subsection 9-3-11,	Up: Section 9-3


9.3.12  string
==============

<<   $(string sequence...) : String
        sequence : Sequence
>>

  The string function flattens a sequence into a single string. This is
similar to the array function, but the elements are interpolated and
concatenated by a single space. The result always is a single string.
Whitespace in sequence is not significant. Note that $(string)
constructs an empty string.
  In addition, string variables can be declared as follows.
<<    S11 = $'<literal>'
      S12 = $"<literal-with-interpolation>"
      S21 = $'''<multi-line
      literal>
      '''
      S22 = $"""<multi-line
      literal
      with
      interpolation>"""
>>


File: omake-doc, Node: Subsection 9-3-13,	Next: Subsection 9-3-14,	Prev: Subsection 9-3-12,	Up: Section 9-3


9.3.13  string-length
=====================

<<   $(string-length sequence) : Int
        sequence : Sequence
>>

  The string-lenght returns a length (number of characters) in its
argument. If the argument is a sequence, it flattens it, so
$(string-length sequence) is equivalent to $(string-length $(string
sequence)). 

File: omake-doc, Node: Subsection 9-3-14,	Next: Subsection 9-3-15,	Prev: Subsection 9-3-13,	Up: Section 9-3


9.3.14  subst
=============

<<        $(subst from, to, text) : String
              from : Sequence
              to : Sequence
              text : Sequence
      >>

  Answer text with all occurences of from replaced with to. The
find-strings from are taken literally, this is, they are not interpreted
as regular expressions.
  If to is a single word all from strings are replaced with it. For more
than one to word, the number of from strings must match and each
from string is replaced with the corresponding to string. 

File: omake-doc, Node: Subsection 9-3-15,	Next: Subsection 9-3-16,	Prev: Subsection 9-3-14,	Up: Section 9-3


9.3.15  string-escaped, ocaml-escaped, html-escaped, html-pre-escaped
=====================================================================
 

File: omake-doc, Node: Subsection 9-3-16,	Next: Subsection 9-3-17,	Prev: Subsection 9-3-15,	Up: Section 9-3


9.3.16  c-escaped, id-escaped, sql-escaped, uri-escaped
=======================================================
\@n
ame{function:id-escaped}\@nam
e{function:sql-escaped}\@name
{function:uri-escaped}
<<   $(string-escaped sequence) : String Array
     $(ocaml-escaped sequence) : String Array
     $(html-escaped sequence) : String Array
     $(html-pre-escaped sequence) : String Array
     $(c-escaped sequence) : String Array
     $(id-escaped sequence) : StringArray
     $(sql-escaped sequence) : StringArray
     $(uri-escaped sequence) : StringArray
        sequence : Array
>>

  The string-escaped function converts each element of its argument to a
string, escaping it, if it contains symbols that are special to OMake.
The special characters include :()\,$'"# and whitespace. This function
can be used in scanner rules to escape file names before printing then
to stdout.
  The ocaml-escaped function converts each element of its argument to a
string, escaping characters that are special to OCaml.
  The c-escaped function converts a string to a form that can be used as
a string constant in C.
  The id-escaped function turns a string into an identifier that may be
used in OMake.
  The html-escaped function turns a literal string into a form
acceptable as HTML. The html-pre-escaped function is similar, but it
does not translate newlines into <br>.
<<    println($(string $(string-escaped $"a b" $"y:z")))
      a\ b y\:z
>>


File: omake-doc, Node: Subsection 9-3-17,	Next: Subsection 9-3-18,	Prev: Subsection 9-3-16,	Up: Section 9-3


9.3.17  hexify, unhexify
========================
\@name
{function:unhexify}
<<   $(hexify sequence) : sequence
         sequence : Sequence
>>

  The function hexify converts a string to a HEX ASCII representation.
The inverse function is unhexify.
<<   osh> hexify($"Hello world")
     - : <array <data "48656c6c6f"> <data "776f726c64">>
>>


File: omake-doc, Node: Subsection 9-3-18,	Next: Subsection 9-3-19,	Prev: Subsection 9-3-17,	Up: Section 9-3


9.3.18  decode-uri, encode-uri
==============================
\@
name{function:encode-uri}
<<    $(decode-uri sequence) : sequence
          sequence : Sequence
>>

  These two functions perform URI encoding, where special characters are
represented by hexadecimal characters.
<<    osh> s = $(encode-uri $'a b~c')
      "a+b%7ec"
      osh> decode-uri($s)
      "a b~c"
>>


File: omake-doc, Node: Subsection 9-3-19,	Next: Subsection 9-3-20,	Prev: Subsection 9-3-18,	Up: Section 9-3


9.3.19  quote
=============

<<   $(quote sequence) : String
        sequence : Sequence
>>

  The quote function flattens a sequence into a single string and adds
quotes around the string. Inner quotation symbols are escaped.
  For example, the expression $(quote a "b c" d) evaluates to "a \"b c\"
d", and $(quote abc) evaluates to "abc". 

File: omake-doc, Node: Subsection 9-3-20,	Next: Subsection 9-3-21,	Prev: Subsection 9-3-19,	Up: Section 9-3


9.3.20  quote-argv
==================

<<   $(quote-argv sequence) : String
        sequence : Sequence
>>

  The quote-argv function flattens a sequence into a single string, and
adds quotes around the string. The quotation is formed so that a
command-line parse can separate the string back into its components. 

File: omake-doc, Node: Subsection 9-3-21,	Next: Subsection 9-3-22,	Prev: Subsection 9-3-20,	Up: Section 9-3


9.3.21  html-string
===================

<<   $(html-string sequence) : String
        sequence : Sequence
>>

  The html-string function flattens a sequence into a single string, and
escapes special HTML characters. This is similar to the concat function,
but the elements are separated by whitespace. The result is treated as a
unit; whitespace inside sequence elements is preserved literally. 

File: omake-doc, Node: Subsection 9-3-22,	Next: Subsection 9-3-23,	Prev: Subsection 9-3-21,	Up: Section 9-3


9.3.22  addsuffix
=================

<<   $(addsuffix suffix, sequence) : Array
        suffix : String
        sequence : Sequence
>>

  The addsuffix function adds a suffix to each component of sequence.
The number of elements in the array is exactly the same as the number of
elements in the sequence.
  For example, $(addsuffix .c, a b "c d") evaluates to a.c b.c "c d".c. 

File: omake-doc, Node: Subsection 9-3-23,	Next: Subsection 9-3-24,	Prev: Subsection 9-3-22,	Up: Section 9-3


9.3.23  mapsuffix
=================

<<   $(mapsuffix suffix, sequence) : Array
        suffix : value
        sequence : Sequence
>>

  The mapsuffix function adds a suffix to each component of sequence. It
is similar to addsuffix, but uses array concatenation instead of string
concatenation. The number of elements in the array is twice the number
of elements in the sequence.
  For example, $(mapsuffix .c, a b "c d") evaluates to a .c b .c "c d"
.c. 

File: omake-doc, Node: Subsection 9-3-24,	Next: Subsection 9-3-25,	Prev: Subsection 9-3-23,	Up: Section 9-3


9.3.24  addsuffixes, addprefixes
================================
\
@name{function:addprefixes}
<<   $(addsuffixes suffixes, sequence) : Array
        suffixes : Sequence
        sequence : Sequence
     $(addprefixes prefixes, sequence) : Array
        prefixes : Sequence
        sequence : Sequence
>>

  The addsuffixes function adds all suffixes in its first argument to
each component of a sequence. If suffixes has n elements, and sequence
has m elements, the the result has n * m elements.
  For example, the $(addsuffixes .c .o, a b c) expressions evaluates to
a.c a.o b.c b.o c.o c.a.
  $(addprefixes prefixes, sequence) is roughly equivalent to
$(addsuffixes sequence, prefixes). 

File: omake-doc, Node: Subsection 9-3-25,	Next: Subsection 9-3-26,	Prev: Subsection 9-3-24,	Up: Section 9-3


9.3.25  removeprefix
====================

<<   $(removeprefix prefix, sequence) : Array
        prefix : String
        sequence : Array
>>

  The removeprefix function removes a prefix from each component of a
sequence. 

File: omake-doc, Node: Subsection 9-3-26,	Next: Subsection 9-3-27,	Prev: Subsection 9-3-25,	Up: Section 9-3


9.3.26  removesuffix
====================

<<   $(removesuffix sequence) : Array
        sequence : String
>>

  The removesuffix function removes the suffixes from each component of
a sequence.
  For example, $(removesuffix a.c b.foo "c d") expands to a b "c d". 

File: omake-doc, Node: Subsection 9-3-27,	Next: Subsection 9-3-28,	Prev: Subsection 9-3-26,	Up: Section 9-3


9.3.27  replacesuffixes
=======================

<<   $(replacesuffixes old-suffixes, new-suffixes, sequence) : Array
        old-suffixes : Sequence
        new-suffixes : Sequence
        sequence : Sequence
>>

  The replacesuffixes function modifies the suffix of each component in
sequence. The old-suffixes and new-suffixes sequences should have the
same length.
  For example, $(replacesuffixes .h .c, .o .o, a.c b.h c.z) expands to
a.o b.o c.z. 

File: omake-doc, Node: Subsection 9-3-28,	Next: Subsection 9-3-29,	Prev: Subsection 9-3-27,	Up: Section 9-3


9.3.28  addprefix
=================

<<   $(addprefix prefix, sequence) : Array
        prefix : String
        sequence : Sequence
>>

  The addprefix function adds a prefix to each component of a sequence.
The number of element in the result array is exactly the same as the
number of elements in the argument sequence.
  For example, $(addprefix foo/, a b "c d") evaluates to foo/a foo/b
foo/"c d". 

File: omake-doc, Node: Subsection 9-3-29,	Next: Subsection 9-3-30,	Prev: Subsection 9-3-28,	Up: Section 9-3


9.3.29  mapprefix
=================

<<   $(mapprefix prefix, sequence) : Array
        prefix : String
        sequence : Sequence
>>

  The mapprefix function adds a prefix to each component of a sequence.
It is similar to addprefix, but array concatenation is used instead of
string concatenation. The result array contains twice as many elements
as the argument sequence.
  For example, $(mapprefix foo, a b "c d") expands to foo a foo b foo "c
d". 
