This file has been translated from LaTeX by HeVeA.

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'.

Node: Subsection 8-11-3,	Next: Section 8-12,	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.

Node: Section 8-12,	Next: Subsection 8-12-1,	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


Node: Subsection 8-12-1,	Next: Subsection 8-12-2,	Prev: Section 8-12,	Up: Section 8-12
  

8.12.1   Phony targets in a subdirectory
========================================
   \@n
ame{@default65}
  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.

Node: Subsection 8-12-2,	Next: Section 8-13,	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.

Node: Section 8-13,	Next: Chapter 9,	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.
   

Node: Chapter 9,	Next: Section 9-1,	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


Node: Section 9-1,	Next: Section 9-2,	Prev: Chapter 9,	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). 
 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. 

Node: Section 9-2,	Next: Subsection 9-2-1,	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


Node: Subsection 9-2-1,	Next: Subsection 9-2-2,	Prev: Section 9-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'. 

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.
  For example '$(equal a, b)' expands to 'false', and '$(equal hello
world, hello world)' expands to 'true'. 

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

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

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

9.2.5   if
==========
\@na
me{@default88}
<<    $(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
>>

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

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. 

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. 

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. 

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

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

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

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.

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.

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

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

Node: Subsection 9-2-17,	Next: Section 9-3,	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)
>>

Node: Section 9-3,	Next: Subsection 9-3-1,	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::	string-escaped, ocaml-escaped, html-escaped, html-pre-escaped
* Subsection 9-3-15::	c-escaped, id-escaped, sql-escaped, uri-escaped
* Subsection 9-3-16::	hexify, unhexify
* Subsection 9-3-17::	decode-uri, encode-uri
* Subsection 9-3-18::	quote
* Subsection 9-3-19::	quote-argv
* Subsection 9-3-20::	html-string
* Subsection 9-3-21::	addsuffix
* Subsection 9-3-22::	mapsuffix
* Subsection 9-3-23::	addsuffixes, addprefixes
* Subsection 9-3-24::	removeprefix
* Subsection 9-3-25::	removesuffix
* Subsection 9-3-26::	replacesuffixes
* Subsection 9-3-27::	addprefix
* Subsection 9-3-28::	mapprefix
* Subsection 9-3-29::	add-wrapper
* Subsection 9-3-30::	set
* Subsection 9-3-31::	mem
* Subsection 9-3-32::	intersection
* Subsection 9-3-33::	intersects
* Subsection 9-3-34::	set-diff
* Subsection 9-3-35::	filter
* Subsection 9-3-36::	filter-out
* Subsection 9-3-37::	capitalize
* Subsection 9-3-38::	uncapitalize
* Subsection 9-3-39::	uppercase
* Subsection 9-3-40::	lowercase
* Subsection 9-3-41::	system
* Subsection 9-3-42::	shell
* Subsection 9-3-43::	export
* Subsection 9-3-44::	while
* Subsection 9-3-45::	break
* Subsection 9-3-46::	random, random-init


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

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

<<    $(array elements) : Array
         elements : Sequence
>>
  
  The 'array' function creates an array from a sequence. If the '<arg>'
is a string, the elements of the array are the whitespace-separated
elements of the string, respecting quotes.
  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. 

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

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

<<   $(split sep, elements) : Array
        sep : String
        elements : Sequence
>>
  
  The 'split' function takes two arguments, a string of separators, and
a string argument. The result is an array of elements determined by
splitting the elements by all occurrence of the separator in the
'elements' sequence.
  For example, in the following code, the 'X' variable is defined to be
the array '/bin /usr/bin /usr/local/bin'.
<<    PATH = /bin:/usr/bin:/usr/local/bin
      X = $(split :, $(PATH))
>>
  
  The 'sep' argument may be omitted. In this case 'split' breaks its
arguments along the white space. Quotations are not split. 

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

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

<<   $(concat sep, elements) : String
        sep : String
        elements : Sequence
>>
  
  The 'concat' function takes two arguments, 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))
>>

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. 

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"'.

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'. 

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"'.

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'.

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'. 

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'. 

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. 

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 'concat' function, but the elements are separated by
whitespace. The result is treated as a unit; whitespace is significant. 

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))'. 

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

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

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

9.3.15   c-escaped, id-escaped, sql-escaped, 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
>>

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

9.3.16   hexify, 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">>
>>

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

9.3.17   decode-uri, 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"
>>

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

9.3.18   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"'. 

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

9.3.19   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. 

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

9.3.20   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. 

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

9.3.21   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'. 

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

9.3.22   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'. 

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

9.3.23   addsuffixes, 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)'. 

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

9.3.24   removeprefix
=====================

<<   $(removeprefix prefix, sequence) : Array
        prefix : String
        sequence : Array
>>
  
  The 'removeprefix' function removes a prefix from each component of a
sequence. 

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

9.3.25   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"'.

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

9.3.26   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'. 

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

9.3.27   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"'. 

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

9.3.28   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"'. 

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

9.3.29   add-wrapper
====================

<<   $(add-wrapper prefix, suffix, sequence) : Array
        prefix : String
        suffix : String
        sequence : Sequence
>>
  
  The 'add-wrapper' functions adds both a prefix and a suffix to each
component of a sequence. For example, the expression '$(add-wrapper
dir/, .c, a b)' evaluates to 'dir/a.c dir/b.c'. String concatenation is
used. The array result has the same number of elements as the argument
sequence. 

Node: Subsection 9-3-30,	Next: Subsection 9-3-31,	Prev: Subsection 9-3-29,	Up: Section 9-3
  

9.3.30   set
============

<<   $(set sequence) : Array
        sequence : Sequence
>>
  
  The 'set' function sorts a set of string components, eliminating
duplicates.
  For example, '$(set z y z "m n" w a)' expands to '"m n" a w y z'. 

Node: Subsection 9-3-31,	Next: Subsection 9-3-32,	Prev: Subsection 9-3-30,	Up: Section 9-3
  

9.3.31   mem
============

<<   $(mem elem, sequence) : Boolean
        elem : String
        sequence : Sequence
>>
  
  The 'mem' function tests for membership in a sequence.
  For example, '$(mem "m n", y z "m n" w a)' evaluates to 'true', while
'$(mem m n, y z "m n" w a)' evaluates to 'false'. 

Node: Subsection 9-3-32,	Next: Subsection 9-3-33,	Prev: Subsection 9-3-31,	Up: Section 9-3
  

9.3.32   intersection
=====================

<<   $(intersection sequence1, sequence2) : Array
        sequence1 : Sequence
        sequence2 : Sequence
>>
  
  The 'intersection' function takes two arguments, treats them as sets
of strings, and computes their intersection. The order of the result is
undefined, and it may contain duplicates. Use the 'set' function to sort
the result and eliminate duplicates in the result if desired.
  For example, the expression '$(intersection c a b a, b a)' evaluates
to 'a b a'. 

Node: Subsection 9-3-33,	Next: Subsection 9-3-34,	Prev: Subsection 9-3-32,	Up: Section 9-3
  

9.3.33   intersects
===================

<<   $(intersects sequence1, sequence2) : Boolean
        sequence1 : Sequence
        sequence2 : Sequence
>>
  
  The 'intersects' function tests whether two sets have a non-empty
intersection. This is slightly more efficient than computing the
intersection and testing whether it is empty.
  For example, the expression '$(intersects a b c, d c e)' evaluates to
'true', and '$(intersects a b c a, d e f)' evaluates to 'false'. 

Node: Subsection 9-3-34,	Next: Subsection 9-3-35,	Prev: Subsection 9-3-33,	Up: Section 9-3
  

9.3.34   set-diff
=================

<<   $(set-diff sequence1, sequence2) : Array
        sequence1 : Sequence
        sequence2 : Sequence
>>
  
  The 'set-diff' function takes two arguments, treats them as sets of
strings, and computes their difference (all the elements of the first
set that are not present in the second one). The order of the result is
undefined and it may contain duplicates. Use the 'set' function to sort
the result and eliminate duplicates in the result if desired.
  For example, the expression '$(set-diff c a b a e, b a)' evaluates to
'c e'. 

Node: Subsection 9-3-35,	Next: Subsection 9-3-36,	Prev: Subsection 9-3-34,	Up: Section 9-3
  

9.3.35   filter
===============

<<   $(filter patterns, sequence) : Array
        patterns : Sequence
        sequence : Sequence
>>
  
  The 'filter' function picks elements from a sequence. The patterns is
a non-empty sequence of patterns, each may contain one occurrence of the
wildcard '%' character.
  For example '$(filter %.h %.o, a.c x.o b.h y.o "hello world".c)'
evaluates to 'x.o b.h y.o'. 

Node: Subsection 9-3-36,	Next: Subsection 9-3-37,	Prev: Subsection 9-3-35,	Up: Section 9-3
  

9.3.36   filter-out
===================

<<   $(filter-out patterns, sequence) : Array
        patterns : Sequence
        sequence : Sequence
>>
  
  The 'filter-out' function removes elements from a sequence. The
patterns is a non-empty sequence of patterns, each may contain one
occurrence of the wildcard '%' character.
  For example '$(filter-out %.c %.h, a.c x.o b.h y.o "hello world".c)'
evaluates to 'x.o y.o'. 

Node: Subsection 9-3-37,	Next: Subsection 9-3-38,	Prev: Subsection 9-3-36,	Up: Section 9-3
  

9.3.37   capitalize
===================

<<   $(capitalize sequence) : Array
        sequence : Sequence
>>
  
  The 'capitalize' function capitalizes each word in a sequence. For
example, '$(capitalize through the looking Glass)' evaluates to 'Through
The Looking Glass'. 

Node: Subsection 9-3-38,	Next: Subsection 9-3-39,	Prev: Subsection 9-3-37,	Up: Section 9-3
  

9.3.38   uncapitalize
=====================

<<   $(uncapitalize sequence) : Array
        sequence : Sequence
>>
  
  The 'uncapitalize' function uncapitalizes each word in its argument.
  For example, '$(uncapitalize through the looking Glass)' evaluates to
'through the looking glass'. 

Node: Subsection 9-3-39,	Next: Subsection 9-3-40,	Prev: Subsection 9-3-38,	Up: Section 9-3
  

9.3.39   uppercase
==================

<<   $(uppercase sequence) : Array
        sequence : Sequence
>>
  
  The 'uppercase' function converts each word in a sequence to
uppercase. For example, '$(uppercase through the looking Glass)'
evaluates to 'THROUGH THE LOOKING GLASS'. 

Node: Subsection 9-3-40,	Next: Subsection 9-3-41,	Prev: Subsection 9-3-39,	Up: Section 9-3
  

9.3.40   lowercase
==================

<<   $(lowercase sequence) : Array
        sequence : Sequence
>>
  
  The 'lowercase' function reduces each word in its argument to
lowercase.
  For example, '$(lowercase through tHe looking Glass)' evaluates to
'through the looking glass'. 

Node: Subsection 9-3-41,	Next: Subsection 9-3-42,	Prev: Subsection 9-3-40,	Up: Section 9-3
  

9.3.41   system
===============

<<   system(s)
        s : Sequence
>>
  
  The 'system' function is used to evaluate a shell expression. This
function is used internally by omake to evaluate shell commands.
  For example, the following program is equivalent to the expression
'system(ls foo)'.
<<   ls foo
>>

Node: Subsection 9-3-42,	Next: Subsection 9-3-43,	Prev: Subsection 9-3-41,	Up: Section 9-3
  

9.3.42   shell
==============

<<   $(shell command) : Array
     $(shella command) : Array
     $(shell-code command) : Int
        command : Sequence
>>
  
  The 'shell' function evaluates a command using the command shell, and
returns the whitespace-separated words of the standard output as the
result.
  The 'shella' function acts similarly, but it returns the lines as
separate items in the array.
  The 'shell-code' function returns the exit code. The output is not
diverted.
  For example, if the current directory contains the files 'OMakeroot',
'OMakefile', and 'hello.c', then '$(shell ls)' evaluates to 'hello.c
OMakefile OMakeroot' (on a Unix system). 

Node: Subsection 9-3-43,	Next: Subsection 9-3-44,	Prev: Subsection 9-3-42,	Up: Section 9-3
  

9.3.43   export
===============
 The 'export'
function allows one to capture the current environment in a variable.
  For example, the following code: 
<<A = 1
  B = 1
  C = 1
  SAVE_ENV = $(export A B)
  A = 2
  B = 2
  C = 2
  export($(SAVE_ENV))
  println($A $B $C)
>>
  will print '1 1 2'.
  The arguments to this function are interpreted the exact same way as
the arguments to the 'export' special form (see
Section 6.3*Note Section 6-3::).  

Node: Subsection 9-3-44,	Next: Subsection 9-3-45,	Prev: Subsection 9-3-43,	Up: Section 9-3
  

9.3.44   while
==============

<<   while <test>
        <body>
>>
  
  --or--
<<    while <test>
      case <test1>
         <body1>
      ...
      case <testn>
         <bodyn>
      default
         <bodyd>
>>
  
  The loop is executed while the test is true. In the first form, the
'<body>' is executed on every loop iteration. In the second form, the
body '<bodyI>' is selected, as the first case where the test '<testI>'
is true. If none apply, the optional default case is evaluated. If no
cases are true, the loop exits. The environment is automatically
exported.
  Examples.
  Iterate for 'i' from '0' to '9'.
<<    i = 0
      while $(lt $i, 10)
         echo $i
         i = $(add $i, 1)
>>
  
  The following example is equivalent.
<<   i = 0
     while true
     case $(lt $i, 10)
        echo $i
        i = $(add $i, 1)
>>
  
  The following example is similar, but some special cases are printed.
value is printed.
<<    i = 0
      while $(lt $i, 10)
      case $(equal $i, 0)
         echo zero
         i = $(add $i, 1)
      case $(equal $i, 1)
         echo one
         i = $(add $i, 1)
      default
         echo $i
         i = $(add $i, 1)
>>
  
  The 'break' function can be used to break out of the 'while' loop
early.  

Node: Subsection 9-3-45,	Next: Subsection 9-3-46,	Prev: Subsection 9-3-44,	Up: Section 9-3
  

9.3.45   break
==============

<<   break
>>
  
  Terminate execution of the innermost loop, returning the current
state. 
