JamPlus manual
|
Jam variables are lists of zero or more elements, with each element being a string value. An undefined variable is indistinguishable from a variable with an empty list, however, a defined variable may have one more elements which are null strings. All variables are referenced as $(variable).
Variables are either global or target-specific. In the latter case, the variable takes on the given value only during the target's binding, header file scanning, and updating; and during the "on <i>target</i> <i>statement</I>" statement.
A variable is defined with:
variable = elements ; | The = operator replaces any previous elements of variable with elements |
variable += elements ; | The += operator adds elements to variable's list of elements |
variable -= elements ; | The -= operator removes elements from variable's list of elements |
variable ?= elements ; | The ?= operator sets variable only if it was previously unset |
variable on targets = elements ; | The = operator replaces any previous elements of variable with elements directly on targets |
variable on targets += elements ; | The += operator directly adds elements to targets's variable's list of elements |
variable on targets -= elements ; | The -= operator directly removes elements from targets's variable's list of elements |
variable on targets ?= elements ; | The ?= operator sets variable on targets only if it was previously unset |
Variables referenced in updating commands will be replaced with their values; target-specific values take precedence over global values. Variables passed as arguments ($(1) and $(2)) to actions are replaced with their bound values; the "bind" modifier can be used on actions to cause other variables to be replaced with bound values. See Action Modifiers above.
Jam variables are not re-exported to the environment of the shell that executes the updating actions, but the updating actions can reference Jam variables with $(variable).
During parsing, Jam performs variable expansion on each token that is not a keyword or rule name. Such tokens with embedded variable references are replaced with zero or more tokens. Variable references are of the form $(variable) or $(variable:modifiers), where variable is the variable name, and modifiers are optional modifiers.
A literal expansion is in the form @(literal) or @(literal:modifiers) or alternatively as $@(literal) or $@(literal:modifiers). Instead of expanding a variable's contents, as with a $(variable) expansion, the direct contents of literal are used. All other behavior is the same.
Variable expansion in a rule's actions is similar to variable expansion in statements, except that the action string is tokenized at whitespace regardless of quoting.
The result of a token after variable expansion is the product of the components of the token, where each component is a literal substring or a list substituting a variable reference. For example:
|
The variable name and modifiers can themselves contain a variable reference, and this partakes of the product as well:
|
Because of this product expansion, if any variable reference in a token is undefined, the result of the expansion is an empty list. If any variable element is a null string, the result propagates the non-null elements:
|
A variable element's string value can be parsed into grist and filename-related components. Modifiers to a variable are used to select elements, select components, and replace components. Modifiers are applied in the order of the table below:
[n] | Select element number n (starting at 1). If the variable contains fewer than n elements, the result is a zero-element list. |
[n-m] | Select elements number n through m. |
[n-] | Select elements number n through the last. |
:E=value | Use value instead if the variable is unset. Note that :E= by itself doesn't mean anything. |
:A | Expand a variable expansion within a string. When a string has been read from an external source and contains a variable in or @(var) syntax, the :A modifier can be used to expand it as if it had been inline in the Jam script. |
:W[=remove_path] | Populate the list with directory contents matching the string. If specified, remove_path is removed from the beginning of each found file. |
:Z[=target] | Provides an alternate and usually faster form of on target variable = $(VAR) . Instead, use variable = $(VAR:Z=target) for the same result. |
:T | Expand the bound name of the target. Just as when expanding within an action, the BINDING is applied first. If LOCATE is set, it is used for the path. If not, SEARCH is used to look up the file. |
:C | EsCapes the string as if it were a file path. On Windows, if the path has spaces, it is quoted. On other platforms, spaces, parentheses, and a few other special characters are escaped with a backslash. |
:B | Select filename base. |
:B=base | Replace the base part of file name with base. |
:B?=base | If the base part of the file name is empty, replace it with base. |
:S | Select (last) filename suffix. |
:S=suf | Replace the suffix of file name with suf. |
:S?=suf | If the suffix of the file name is empty, replace it with suf. |
:M | Select archive member name. |
:M=mem | Replace the archive member name with mem. |
:M?=mem | If the archive member name is empty, replace it with mem. |
:D | Select directory path. |
:D=path | Replace directory with path. |
:D?=path | If the directory is empty, replace it with path. |
:P | Select parent directory. On VMS, $(var:P) is the parent directory of $(var:D); on Unix and NT, $(var:P) and $(var:D) are the same. |
:G | Select grist. |
:G=grist | Replace grist with grist. |
:G?=grist | If the grist is empty, replace it with grist. |
:R=root | Prepend root to the whole file name, if not already rooted. |
:U | Replace lowercase characters with uppercase. |
:L | Replace uppercase characters with lowercase. |
:/ | Convert all backslashes (\) to forward slashes (/). |
:\\ | Convert all forward slashes (/) to backslashes (\). |
:chars | Select the components listed in chars. |
:J=joinval | Concatenate list elements into single element, separated by joinval. |
:I=regex | Include all list items matching regex. Remove everything else. More than one set of :I or :X modifiers may appear in a given expansion, and they are applied in order. |
:X=regex | Exclude all list items matching regex. Keep everything else. More than one set of :I or :X modifiers may appear in a given expansion, and they are applied in order. |
When using the :W
modifier, the following file globbing syntax is available.
Wildcard | Description |
? | Matches any single character of the file name or directory name. |
* | Matches 0 or more characters of the file name or directory name. |
/ at end of pattern | Any pattern with a closing slash will start a directory search, instead of the default file search. |
** | Search files recursively. |
| Search directories recursively. |
Some examples follow:
Example Pattern | Description |
File.txt | Matches a file or directory called File.txt. |
| Matches any file or directory starting with File and ending with a .txt extension. |
File?.txt | Matches any file or directory starting with File and containing one more character. |
F??e*.txt | Matches a file or directory starting with F, followed by any two characters, followed by e, then any number of characters up to the extension .txt. |
File* | Matches a file or directory starting with File and ending with or without an extension. |
* | Matches all files (non-recursive). |
| Matches all directories (non-recursive). |
| Matches any directory starting with A (non-recursive). |
**/* | Matches all files (recursive). |
** | Shortened form of above. Matches all files (recursive). Internally, expands to **/* |
| Matches all directories (recursive). |
**{filename chars} | Matches {filename chars} recursively. Internally, expands to **/*{filename chars} . |
{dirname chars}** | Expands to {dirname chars}*/**. |
{dirname chars}**{filename chars} | Expands to {dirname chars}*/**/*{filename chars} . |
**.h | Matches all *.h files recursively. Expands to **/*.h. |
| Matches all *resource.h files recursively. Expands to **/*resource.h. |
BK** | Matches all files in any directory starting with BK, recursively. Expands to BK*/**. |
BK**.h | Matches all *.h files in any directory starting with BK, recursively. Expands to BK*/**/*.h. |
| Matches all *.h files recursively, starting at c:/Src/. |
| Recursively matches all directories under c:/Src/ that end with Grid. |
| Recursively matches all directories under c:/Src/ that contain Grid. |
c:/Src/**/*Grid*/**/ABC/**/Readme.txt | Recursively matches all directories under c:/Src/ that contain Grid. From the found directory, recursively matches directories until ABC/ is found. From there, the file Readme.txt is searched for recursively. |
Finally, a couple flags are available. Flags are appended at the end of the pattern line. Each flag begins with an @ character. Spaces should not be inserted between flags unless they are intended as part of the string literal.
Flags and Other Expansions | Description |
@* | Search files and directories recursively. |
-pattern | Adds pattern to the file ignore list. Any file matching a pattern in the file ignore list is removed from the search. |
-pattern/ | Adds pattern/ to the directory ignore list. Any directory matching a pattern in the directory ignore list is removed from the search. |
=pattern | Adds pattern to the exclusive file list. Any file not matching a pattern in the exclusive file list is automatically removed from the search. |
=pattern/ | Adds pattern/ to the exclusive directory list. Any directory not matching a pattern in the exclusive file list is automatically removed from the search. |
More than two periods for going up parent directories. | Similar to 4DOS, each period exceeding two periods goes up one additional parent directory. So, a 4 period path expands to ../../../. |
Wildcards may appear anywhere in the pattern, including directories.
\verbatim */*/*/*.c\endverbatim
Note that *.* only matches files that have an extension. This is different than standard DOS behavior. Use * all by itself to match files, extension or not.
Recursive wildcards can be used anywhere:
\verbatim c:/Dir1/**/A*/**/FileDirs*/**.mp3\endverbatim
This matches all directories under c:/Dir1/ that start with A. Under all of the directories that start with A, directories starting with FileDirs are matched recursively. Finally, all files ending with an mp3 extension are matched.
And a few examples:
Example Pattern | Description |
| Recursively lists all directories under Src/, but directories called .git/ and .svn/ are filtered. |
| Recursively lists all files under Src/ which match *.lua or README. All other files are ignored. |
| Recursively lists all files under Src/ which match *.lua or README. The versions of those files that may exist in .git/ or .svn/ are ignored. |
| Expands to: ../../../../StartSearchHere/** |