Project xenv


4.0  —  2022-08-25
* Stash storage

Stash is a special kind of storage to hold temporary data.  It is
used to implement several preprocessor features: diversions,
conditionals and loops.  Data are written to the memory for as long
as their amount fits the memory buffer allotted for stash.  The size
of this buffer is controlled by the feature value "stashsize".  When
the buffer gets full, surplus data are written to a temporary
file.  Number of temporary files that can be open simultaneously is
controlled by the feature value "stashfiles".  This works as follows:
when a new stash file needs to be open and the number of already open
files hits the limit, the program will close the least recently used
stash file, thereby freeing a file descriptor for use in the new
stash.  The closed file will eventually be reopened when it is needed,
using the same process.

Default values are: for "stashsize" - the size of the system memory
page, and for "stashfiles" - 2/3 of the soft limit for open files.

* Sink streams

On systems where fopencookie(3) call is available, xenv uses special
"sink" streams for text that's going to be discarded.  This speeds up
the operation and spares open file descriptors.

* New directives: $$ifcom, $$ifncom

  $$ifcom COMMAND

Runs COMMAND and substitutes TEXT1 if it exits with code 0 and TEXT2
otherwise.  $$incom is similar, but expands to TEXT1 if COMMAND exits
with a non-zero status and to TEXT2 otherwise.

COMMAND is passed to the shell verbatim, i.e. any variable an command
references in it are expanded by the shell and not by xenv (this is
similar to how command expansion behaves).

* Bugfixes

** $$set and $$unset ignored if evaluated in a false conditional branch

Xenv is a text preprocessor. It reads input from files (or the standard input, if none are supplied) and prints it on the standard output, replacing references to environment variables with their actual values. Variables are referenced using POSIX-compatible shell syntax: $NAME, ${NAME}, ${NAME:-word}, ${NAME+=word}, ${NAME:=word}, ${NAME:?word}. A special ternary construct is provided: ${NAME:|word1|word2}, which substitutes the expansion of word1 if NAME is set and the expansion of word2 otherwise. Preprocessor directives provide support for inclusion of external files, conditional text expansion (depending on the value of an environment variable or exit code of an external command), diversions, for and foreach loops etc.