The below functions are not exported by ASDF itself, but by UIOP, available since ASDF 3. Some of them have precursors in ASDF 2, but we recommend that for active developments, you should rely on the package UIOP as included in ASDF 3. UIOP provides many, many more utility functions, and we recommend you read its README.md and sources for more information.
Coerce name into a pathname using standard Unix syntax.
Unix syntax is used whether or not the underlying system is Unix;
on non-Unix systems it is only usable for relative pathnames.
In order to manipulate relative pathnames portably, it is crucial
to possess a portable pathname syntax independent of the underlying OS.
This is what
parse-unix-namestring provides, and why we use it in ASDF.
When given a
pathname object, just return it untouched.
nil, just return
When given a non-null
symbol, first downcase its name and treat it as a string.
When given a
string, portably decompose it into a pathname as below.
#\/ separates directory components.
#\/-separated substring is interpreted as follows:
1- If type is
:directory or ensure-directory is true,
the string is made the last directory component, and its
if the string is empty, it’s the empty pathname with all slots
2- If type is
nil, the substring is a file-namestring,
type are separated by
3- If type is a string, it is the given
type, and the whole string is the
Directory components with an empty name the name
. are removed.
Any directory named
.. is read as dot-dot,
which must be one of
:up and defaults to
version components are taken from defaults,
which itself defaults to
*nil-pathname* is also used if defaults is
No host or device can be specified in the string itself,
which makes it unsuitable for absolute pathnames outside Unix.
For relative pathnames, these components (and hence the defaults) won’t matter
if you use
merge-pathnames* but will matter if you use
which is an important reason to always use
Arbitrary keys are accepted, and the parse result is passed to
with those keys, removing type, defaults and dot-dot.
When you’re manipulating pathnames that are supposed to make sense portably
even though the OS may not be Unixish, we recommend you use
parse-unix-namestring will throw an error if the pathname is absolute.
This function is a replacement for
merge-pathnames that uses the host and device
from the defaults rather than the specified pathname when the latter
is a relative pathname. This allows ASDF and its users to create and use relative pathnames
without having to know beforehand what are the host and device
of the absolute pathnames they are relative to.
This function takes a pathname and a subpath and a type.
If subpath is already a
pathname object (not namestring),
and is an absolute pathname at that, it is returned unchanged;
otherwise, subpath is turned into a relative pathname with given type
:want-relative t :type type,
then it is merged with the
pathname-directory-pathname of pathname,
We strongly encourage the use of this function for portably resolving relative pathnames in your code base.
This function returns
nil if the base pathname is
otherwise acts like
run-program takes a command argument that is either
a list of a program name or path and its arguments,
or a string to be executed by a shell.
It spawns the command, waits for it to return,
verifies that it exited cleanly (unless told not too below),
and optionally captures and processes its output.
It accepts many keyword arguments to configure its behaviour.
run-program returns three values: the first for the output,
the second for the error-output, and the third for the return value.
(Beware that before ASDF 220.127.116.11, it didn’t handle input or error-output,
and returned only one value,
the one for the output if any handler was specified, or else the exit code;
please upgrade ASDF, or at least UIOP, to rely on the new enhanced behaviour.)
output is its most important argument;
it specifies how the output is captured and processed.
If it is
nil, then the output is redirected to the null device,
that will discard it.
If it is
:interactive, then it is inherited from the current process
(beware: this may be different from your *standard-output*,
and under SLIME will be on your
If it is
t, output goes to your current *standard-output* stream.
Otherwise, output should be a value that is a suitable first argument to
slurp-input-stream (see below), or
a list of such a value and keyword arguments.
In this case,
create a temporary stream for the program output;
the program output, in that stream,
will be processed by a call to
using output as the first argument
(or if it’s a list the first element of output and the rest as keywords).
The primary value resulting from that call
nil if no call was needed)
will be the first value returned by
will have it return the entire output stream as a string.
:output '(:string :stripped t)
will have it return the same string stripped of any ending newline.
error-output is similar to output, except that
the resulting value is returned as the second value of
t designates the *error-output*.
:output means redirecting the error output to the output stream,
in which case
nil is returned.
input is similar to output, except that
vomit-output-stream is used, no value is returned,
t designates the *standard-input*.
external-format are passed on
to your Lisp implementation, when applicable, for creation of the output stream.
One and only one of the stream slurping or vomiting may or may not happen in parallel in parallel with the subprocess, depending on options and implementation, and with priority being given to output processing. Other streams are completely produced or consumed before or after the subprocess is spawned, using temporary files.
force-shell forces evaluation of the command through a shell,
even if it was passed as a list rather than a string.
If a shell is used, it is /bin/sh on Unix or CMD.EXE on Windows,
except on implementations that (erroneously, IMNSHO)
insist on consulting
$SHELL like clisp.
to not raise an error if the spawned program exits in error.
Following POSIX convention, an error is anything but
a normal exit with status code zero.
By default, an error of type
subprocess-error is raised in this case.
run-program works on all platforms supported by ASDF, except Genera.
See the source code for more documentation.
slurp-input-stream is a generic function of two arguments, a target object and an input stream,
and accepting keyword arguments.
Predefined methods based on the target object are as follows:
:string, the content is captured into a string. Accepted keywords include the element-type and a flag stripped, which when true causes any single line ending to be removed as per
:lines, the content is captured as a list of strings, one per line, without line ending. If the count keyword argument is provided, it is a maximum count of lines to be read.
:line, the content is captured as with
:linesabove, and then its sub-object is extracted with the at argument, which defaults to
0, extracting the first line. A number will extract the corresponding line. See the documentation for
:forms, the content is captured as a list of s-expressions, as read by the Lisp reader. If the count argument is provided, it is a maximum count of lines to be read. We recommend you control the syntax with such macro as
:form, the content is captured as with
:formsabove, and then its sub-object is extracted with the at argument, which defaults to
0, extracting the first form. A number will extract the corresponding form. See the documentation for
uiop:access-at. We recommend you control the syntax with such macro as