Previous: Miscellaneous Functions, Up: Miscellaneous additional functionality [Contents][Index]
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.
When given nil
, just return nil
.
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.
The last #\/
-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 name
and type
are nil
.
if the string is empty, it’s the empty pathname with all slots nil
.
2- If type is nil
, the substring is a file-namestring,
and its name
and type
are separated by split-name-type
.
3- If type is a string, it is the given type
, and the whole string is the name
.
Directory components with an empty name the name .
are removed.
Any directory named ..
is read as dot-dot,
which must be one of :back
or :up
and defaults to :back
.
host
, device
and version
components are taken from defaults,
which itself defaults to *nil-pathname*
.
*nil-pathname*
is also used if defaults is nil
.
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 merge-pathnames
,
which is an important reason to always use merge-pathnames*
.
Arbitrary keys are accepted, and the parse result is passed to ensure-pathname
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 :want-relative t
so that 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
as per parse-unix-namestring
with :want-relative t :type
type,
then it is merged with the pathname-directory-pathname
of pathname,
as per merge-pathnames*
.
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 nil
,
otherwise acts like subpathname
.
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 3.0.2.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 *inferior-lisp*
buffer).
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, run-program
will
create a temporary stream for the program output;
the program output, in that stream,
will be processed by a call to slurp-input-stream
,
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
(or nil
if no call was needed)
will be the first value returned by run-program
.
E.g., using :output :string
will have it return the entire output stream as a string.
And using :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 run-program
.
t
designates the *error-output*.
Also :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,
and t
designates the *standard-input*.
element-type
and 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.
ignore-error-status
causes run-program
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
or :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 uiop:stripln
.
: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 :lines
above,
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 uiop:access-at
.
: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
uiop:with-safe-io-syntax
.
:form
, the content is captured as with :forms
above,
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
uiop:with-safe-io-syntax
.
Previous: Miscellaneous Functions, Up: Miscellaneous additional functionality [Contents][Index]