Commands for Interactive
or Shell Scripts

use [-alqv] [pkg ...]
unuse [-alqv] [pkg ...]

Read the dotkits named as arguments, and interpret their contents in the current
shell process. If no arguments are given, run the program $DK_ROOT/etc/use-usage,
which normally provides a view of the current state of your environment and a
list of available packages.

The -a "append" option
causes any components added to environment variables by pkg
to be appended instead of prepended. If -a
is given with no package arguments, it causes use-usage
to list all packages, including any whose name begins with "." (dot).

The -l "long listing"
option turns off the interpretation (sourcing) of any pkg
arguments that follow. With no other arguments, this option produces a summary
of available dotkits. If a pkg argument
follows, the descriptive text and any help text for that pkg
is printed to the screen. The -l
option can be combined with -v to
produce more verbose output. With no arguments, -lv
prints a usage message, a list of packages currently in use, a summary of available
packages, and a list of all nodes in the Dotkit search path. With a pkg
argument, -lv prints the entire
contents of the pkg. The -l
option is quietly ignored by unuse.

The -q "quiet" option
causes use or unuse
to be entirely quiet in operation. It is commonly used inside dotfiles or inside
nested (recursive) dotkits. A special dotkit called "bequiet" is available
to make the -q option persistent.

Output behavior similar to -q,
but allowing notice of particular errors, can be achieved by setting the dk_taciturn
environment variable to a non-zero value. A special "taciturn" dotkit
is available to make this mode persistent. Precise control over the warnings printed
in taciturn mode is achieved by setting the dk_smask environment variable, which
has a default value of 4094. Dk_smask is a bitmask applied to the return status
of use or unuse, detailed below. Each bit set in dk_smask allows a warning for
that particular error status, if in taciturn mode.

The -v "verbose" option
causes use or unuse
to print the full path name of each pkg
argument as it is found and sourced. This option overrides -q
and taciturn mode. Note that Dotkit also checks whether stdin appears to be a
tty. If not, output messages are turned off for any option except -v.

Unuse normally reverses the action of use.
It finds and reads the pkg argument files but causes
their actions to be undone relative to use.

Return status: 0 if a dotkit is found and read without apparent error. 1 means
the dotkit was found, but ignored (previously read), and 2 means that _dk_err
was set during package execution, indicating a package error. 4 indicates a dotkit
was not found at the initial (zeroth) recursion level. 8 indicates a dotkit was
not found at the second recursion level, and so on, up to recursion level nine.
If more than one argument is given, use and unuse
return the status of their last operation.

Add (alter) or remove (unalter)
one component to or from the named VARIABLE,
a list of zero or more components delimited by SEPARATOR,
which defaults to the value of DK_IFS, or colon if that is not set. These commands
provide interactive or shell script access to the machinery of the dk_alter function.
Inside a dotkit, you should generally choose dk_alter instead, as it utilizes
its calling context (use or unuse)
to add or remove the COMPONENT, respectively.

WORDLIST_VALUE is a list of components
separated by SEPARATOR, which defaults to
the value of DK_IFS, or colon if that is not set. (The value of $PATH is one example.)
Car returns (echoes) the NTH
component of the list, where NTH defaults
to 0, the index of the first component. Cdr echoes
all components remaining after the NTH,
with NTH defaulting to 1 in this case. Some
examples are:

car a:b:c 0 :

# => a, equivalent to car a:b:c

car a:b:c 1 :

# => b

car a:b:c 3 :

# => (nil), the empty list

cdr a:b:c 0 :

# => a:b:c, the entire list

cdr a:b:c 1 :

# => b:c, equivalent to cdr a:b:c

cdr a:b:c 3 :

# => (nil), the empty list

If WORDLIST_VALUE contains white space,
it should generally be surrounded by quotes.

Basic Functions for Use in Dotkits

Note: These functions should be accessed only from within
a dotkit or package context. Calling them directly from the command line or from
within a personal script will yield incorrect results.

dk_alter VARIABLECOMPONENT [SEPARATOR]

Dk_alter adds to, in the case of use,
or deletes from, in the case of unuse, the given
component for the given VARIABLE. VARIABLE
is a list of zero or more components, separated by SEPARATOR,
such as the PATH environment variable. The default SEPARATOR
is the value of DK_IFS, or colon (:) if that is not set. In particular, SEPARATOR
can be a single space or tab character, generally given inside single quotes.
If a (properly quoted) COMPONENT itself
contains space characters, the SEPARATOR
cannot also be space. For any given VARIABLE,
SEPARATOR is a constant value. The [t]csh
implementation of dk_alter may temporarily modify
the contents of VARIABLE, converting space
characters to ^B (Control-B).

dk_setenv VARIABLE [VALUE]

In the case of use, set VARIABLE
to VALUE. In the case of unuse,
unset the given environment variable.

To be more precise, in the case of use, dk_setenv
checks the variable about to be set, and if it already has a non-null value, saves
the old value before setting the new. In the case of unuse,
dk_setenv re-installs the value for the duration
of the package read but places a deferred restore or unsetenv command onto a list
to be executed when the package read is complete.

Thus, subsequent dk_alter or dk_setenv
commands in the same dotkit that use the variable in question will operate as
expected. Moreover, if variables in your environment are reset by a given package,
they will normally be restored to their original value when the package is unused.

Otherwise, dk_alter and dk_setenv
take immediate effect, so the following sequence in a package file has the manifest
outcome:

For example, if ABC_HOME has a pre-existing value,
it is first saved by dk_setenv, then ABC_HOME
is set to the value /usr/abc. A new component is
added to PATH with value /usr/abc/bin,
and a new component to MANPATH with value /usr/abc/man.
Unusing the package will remove those components
from PATH and MANPATH,
and will restore ABC_HOME to the value (if any) it
had before the package was used in the first place.

Return status: 1 if the second argument is null, otherwise 0.

dk_setdef VARIABLE [VALUE]

This is a variant of dk_setenv that sets VARIABLE
to VALUE only if VARIABLE
is currently unset or has the null (empty string) value. It is otherwise the same
as dk_setenv.

For the unuse operation, dk_setdef
unsets VARIABLE only if the prior use set
it to the the given default VALUE, (or if
the variable's previous value was identically VALUE.)

Advanced Functions for Use in Dotkits

Note: These functions should be accessed only from within
a dotkit or package context. Calling them directly from the command line or from
within a personal script will yield incorrect results.

dk_alias ALIAS_NAME 'ALIAS_DEFINITION'

Create (or remove, in the case of unuse), the
alias ALIAS_NAME with the given definition.
The syntax of dk_alias is essentially identical to
that of the csh or tcsh alias command, except that
alias arguments are not allowed. (To be precise,
arguments can be given, but such syntax cannot, at present, be
part of a shell-independent dotkit.)

Dotkits containing the dk_alias command normally
should be marked as idempotent by appending '++'
to the dotkit name (e.g., foo++.dk.) This allows Dotkit to read the package more
than once, a requirement if subshells are to receive proper alias definitions.

dk_cev VARIABLE

Print the value 1 if you can safely evaluate VARIABLE,
or 0 otherwise. Typical usage:

dk_test `dk_cev FOO` -eq 1 && dk_setenv BAR $FOO

This provides shell-independent code equivalent to the csh test:

if ($?FOO) then
dk_setenv BAR $FOO
endif

Dk_cev always prints 1 for bash or ksh, as those
shells traditionally do not distinguish between unset variables and variables
that are set, but whose value is the empty string.

Return status for this function is always 0. The relevant value is the one
that it prints.

dk_op [-alqv] pkg [...]

Use or unuse the
pkg, depending on the context in which
dk_op occurs. This command is used inside recursive
or nested dotkits, to read and source sub-packages. If the parent dotkit was used,
then dk_op also means use.
If the parent dotkit was unused, then dk_op
unuses its argument list. Options, usage, and return values are otherwise identical
to use and unuse. However,
the -l option should never be used
with this command.

dk_rep 'PATTERN' ['PATTERN' ...]

Print the names, if any, of dotkits presently in use whose name matches PATTERN,
in the sense of shell pattern matching. If no names match, the token "__NIL__"
is printed. One or more patterns can be given and can include the usual shell
meta-characters. Single quotes around the pattern are generally required. The
dk_rep function is commonly used in the case of mutex
(mutually exclusive) dotkits.

Return status: 0 if at least one dotkit currently in use matches the given
pattern(s); otherwise 1.

dk_source FILE

This
command is equivalent to source for csh or tcsh,
or "." for bash and ksh, with the same return values as those commands.
It allows you to read the contents of another file in your current shell from
within a package file. This is occasionally useful. If FILE
is itself a dotkit, use dk_op instead.

dk_test EXPRESSION

Apply the standard UNIX test(1) command to EXPRESSION.
Dk_test takes the same expressions as that program,
with the same return values, and can be used to construct simple if-else tests
in your dotkits, in shell-independent fashion:

dk_test -d /usr/local/gribble && dk_setenv GRIBBLE YES

sets GRIBBLE to YES
if /usr/local/gribble is a directory. See the test(1) man page for more information
on that command.

dk_where PROGRAM_NAME

Print the full path of PROGRAM_NAME if
found, returning status 0, or be silent, with return status 1. Dk_where
searches first in the current PATH, then searches the in order /bin, /usr/bin,
/sbin, /usr/sbin, /usr/ucb, /usr/bsd, /usr/local/bin for PROGRAM_NAME.
Dk_where is implemented as an external script, located
at $DK_ROOT/etc/where.

Special Variables for Use in Dotkits

Note: These variables should be accessed only from within
a dotkit or package context. Calling them directly from the command line or from
within a personal script will yield incorrect results.

Also note the leading underscore in the names of these variables and that their
value is properly set using setenv, not dk_setenv. They are reset automatically
by Dotkit before the next operation.

setenv _dk_err "<error message>"

The _dk_err variable is used to indicate that
something went wrong while reading a package file. Set it to a string value, which
will be printed in place of the usual "(ok)" when Dotkit returns after
reading the package file. After _dk_err is set in
a package file, subsequent dk_alter, dk_setenv,
use, unuse, or dk_op
commands inside that file are ignored, and the package name is not added to the
list of current packages in use.

setenv _dk_ok "<custom reply>"

The _dk_ok variable allows a package author to
customize the reply message from Dotkit after attempting to read a package. By
default, if the package is found and read successfully, the reply is "(ok)".
If _dk_ok is set, its value is substituted for the
default text. Setting _dk_ok does not affect return
status. If _dk_err is also set, its value will dominate
_dk_ok.

setenv _dk_hide 0|1

_Dk_hide is a boolean variable whose value is
normally 0 (FALSE). Set it to 1 (TRUE) if you wish to hide (not include) the current
package in the list of packages in use. This is occasionally useful in a "worker"
package that is called from various places but which should not show up itself
as in use. Obviously, such a package needs to be
written with reuse in mind, since hiding it also
prevents Dotkit from ignoring it in any future use
request.

setenv _dk_pream "PREFIX"

The _dk_pream variable allows a package author
to overrule the -a flag if necessary, or conversely,
to force an append operation even if the user does not provide -a.
Typical use is as follows:

Environment Variables

DK_ROOT

Path to the root of a Dotkit installation. The code implementing Dotkit is
stored in the various *sh subdirectories of $DK_ROOT, and at $DK_ROOT/etc. DK_ROOT
is also the root node on the tree of directories searched for package files.

DK_NODE

Optional colon-separated list of directories added to the path searched by
Dotkit. This is often used to add site-specific dotkits to an installation.

SYS_TYPE

A string identifying the current architecture. SYS_TYPE may be pre-set for
you by the network administrators. If not, a script is provided at $DK_ROOT/etc/systype
to compute some common values of SYS_TYPE.

DK_USEUSAGE

Optional path name to a replacement for the $DK_ROOT/etc/use-usage program.

_dk_shell

The base name of your shell interpreter program: bash, csh, ksh, or tcsh.

DK_SUBNODE

A colon-separated list of directories searched for package files within each
node of the package file tree. The default value for DK_SUBNODE has four components:

$_dk_shell/$SYS_TYPE:$_dk_shell:$SYS_TYPE:.

It can be useful to change or add to this list in certain special circumstances.

_dk_inuse

A space-separated list of package names currently in use. A trailing digit
identifies the recursion level at which the package was loaded, with 0 being the
top (command line) level and 9 the deepest (maximum) level.

_dk_rl

The "recursion level" for Dotkit: An integer variable with legal
values in the range -1, 0, 1, ..., 9. When not actually processing a use
or unuse command, the correct value for _dk_rl is
-1.

DK_EXPORT_BASH_FNS

Dotkit is implemented primarily using shell functions for bash and ksh. By
default, those functions are not exported to the environment for bash users. Bash
users can choose to export the Dotkit shell functions by defining this environment
variable to YES (or any other non-null string) before executing the eval
`.../dotkit/init` initialization command.

DK_IFS

Defines the character used to separate components of wordlist variables. If
unset, the default is ':' (colon).

DK_UEQRU

If this variable is set to a non-null value, the use
command behaves as a reuse. That is, any package
arguments are first (quietly) unused, then re-read. This can occasionally be helpful
if processes other than Dotkit are changing the environment. A reuse dotkit is
available to conveniently set or unset this variable.

Bugs

It would be nice if the dk_alias command would
save and restore alias definitions, like dk_setenv
does for environment variables. It would be nice if dk_alias
accepted arguments for all shells and wrote an appropriate shell function in the
case of bash or ksh.

Handling of null (empty) components in dk_alter,
alter, unalter is inconsistent
and sometimes incorrect. Adding a null component to an empty word list produces
a double null; removing one null component then removes them both. Once added,
a null component is difficult to remove for the [t]csh version. Null components
in a context where the SEPARATOR
character is white space will often produce incorrect results.