ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 11.0

# aclfree-aligned

Function, excl package

Arguments: aligned

Makes available again to the system the space occupied by the object at the address which is represented by the aligned argument, which must be a fixnum. The object must have been allocated by either aclmalloc or aclmalloc-aligned.

If the argument is recognized as indicating a valid object, then this function returns the number of bytes that had originally been requested in the allocation. Otherwise 0 is returned. The actual number of bytes freed is at least the (non-zero value) returned and may be more if the original request was filled from a pool or larger areas.

The 0 return value is more complicated and means one of the following things:

1. The argument pointer is zero.

2. The argument pointer is not within the recorded allocations that aclmalloc-aligned has tracked.

3. A specific byte in the pointer's putative header is not the magic value it was originally set to.

4. The original aclmalloc request was for 0 bytes.

Cases 1 - 3 indicate a failure of some kind and no action is taken. Case 4 is odd but legal and does not indicated a failure.

Note on various Allegro CL malloc and free functions

The space allocated by excl:malloc and its C counterpart malloc() (described here collectively as "malloc") is different than the space allocated by excl:aclmalloc and the C aclmalloc() (described collectively as "aclmalloc"). Malloc allocates in space defined and maintained by the system, in whatever manner the system defines. Some operating systems allow the linking in of alternate versions of malloc() and its cohorts (usually including free(), calloc(), realloc(), and others), giving some flexibility in debugging malloc bugs (but of course this need arises much less often in Lisp programming). The aclmalloc functionalities are part of the Allegro CL library and allocate from space usually known as Aclmalloc heap space. aclmalloc is useful for allocating objects which should survive the rebirth of a dumped lisp.

The free and aclfree functionalities must always match objects to free with the mallocs of the same kind; i.e. one should never free an aclmalloc'd object, nor should one call an aclfree function on an object created with malloc. Note that one can mix aclmalloc/aclfree with aclmalloc-aligned/aclfree-aligned, but only after proper conversions are done; see ff:address-to-aligned and ff:aligned-to-address.

# aclfree

Function, excl package

Arguments: address

Frees a data block previously allocated with aclmalloc.

address - an integer that has been returned by aclmalloc and that has not previously been passed to aclfree. The block represented by this integer should no longer be used after this call.

aclmalloc calls the C function aclmalloc(). aclfree calls the C function aclfree(). address must not have been freed with that function either, of course.

If the argument is recognized as indicating a valid object, then this function returns the number of bytes that had originally been requested in the allocation. Otherwise 0 is returned. The actual number of bytes freed is at least the (non-zero value) returned and may be more if the original request was filled from a pool or larger areas.

1. The argument pointer is zero.

2. The argument pointer is not within the recorded allocations that aclmalloc has tracked.

3. A specific byte in the pointer's putative header is not the magic value it was originally set to.

4. The original aclmalloc request was for 0 bytes.

Cases 1 - 3 indicate a failure of some kind and no action is taken. Case 4 is odd but legal and does not indicated a failure.

Note on various Allegro CL malloc and free functions

The space allocated by excl:malloc and its C counterpart malloc() (described here collectively as "malloc") is different than the space allocated by excl:aclmalloc and the C aclmalloc() (described collectively as "aclmalloc"). Malloc allocates in space defined and maintained by the system, in whatever manner the system defines. Some operating systems allow the linking in of alternate versions of malloc() and its cohorts (usually including free(), calloc(), realloc(), and others), giving some flexibility in debugging malloc bugs (but of course this need arises much less often in Lisp programming). The aclmalloc functionalities are part of the Allegro CL library and allocate from space usually known as Aclmalloc heap space. aclmalloc is useful for allocating objects which should survive the rebirth of a dumped lisp.

The free and aclfree functionalities must always match objects to free with the mallocs of the same kind; i.e. one should never free an aclmalloc'd object, nor should one call an aclfree function on an object created with malloc. One can mix aclmalloc/aclfree with aclmalloc-aligned/aclfree-aligned, but only after proper conversions are done; see ff:address-to-aligned and ff:aligned-to-address.

# aclmalloc-aligned

Function, excl package

Arguments: size

Returns a fixnum which represents a location in the Aclmalloc heap with size octets. The fixnum has the same bit pattern as the address of the object. The actual address of the object can be obtained by multiplying the fixnum by 4 in a 32-bit lisp, and by 8 in a 64-bit lisp. Negative fixnums represent addresses in the upper half of memory. If no space of sufficient size is available, aclmalloc-aligned returns 0, just like malloc.

See also aclfree-aligned and aclmalloc.

# aclmalloc

Function, excl package

Arguments: size &key restart-relocation

Uses the C aclmalloc() function to allocate a data block that is persistent across dumplisp/restarts. The location in the restarted image is guaranteed to be the same as in the dumped image (if Lisp is unable to map it to that location, Lisp startup will fail). This means that addresses in locations allocated by aclmalloc will be valid.

The block is guaranteed to be aligned to at least an 8-byte boundary. The returned value is an integer whose magnitude is the machine address of the allocated block. (0 is returned if aclmalloc is unable to get the requested space.)

The size argument specifies the number of bytes to allocate.

The restart-relocation keyword argument has no effect in Allegro CL. It is intended for possible future enhancements.

aclfree frees space allocated by aclmalloc.

Note on various Allegro CL malloc and free functions

The space allocated by excl:malloc and its C counterpart malloc() (described here collectively as "malloc") is different than the space allocated by excl:aclmalloc and the C aclmalloc() (described collectively as "aclmalloc"). Malloc allocates in space defined and maintained by the system, in whatever manner the system defines. Some operating systems allow the linking in of alternate versions of malloc() and its cohorts (usually including free(), calloc(), realloc(), and others), giving some flexibility in debugging malloc bugs (but of course this need arises much less often in Lisp programming). The aclmalloc functionalities are part of the Allegro CL library and allocate from saclmallocpace usually known as Aclmalloc heap space. aclmalloc is useful for allocating objects which should survive the rebirth of a dumped lisp.

The free and aclfree functionalities must always match objects to free with the mallocs of the same kind; i.e. one should never free an aclmalloc'd object, nor should one call an aclfree function on an object created with malloc. Note that one can mix aclmalloc/aclfree with aclmalloc-aligned/aclfree-aligned, but only after proper conversions are done; see ff:address-to-aligned and ff:aligned-to-address.

# add-breakpoint

Function, excl package

Arguments: func pc &optional temporary verbose

Adds a breakpoint to the breakpoint table, if one does not already exist. Breakpoints are identified by func, which must be either a function object or an fboundp function name, and pc, which must be a integer indicating the relative pc offset (look at a disassembly of func produced by cl:disassemble for offsets). When adding a breakpoint, if the pc specified is not exact, a "close" one is found. The exact algorithm is not easily described and is subject to change. The breakpoint structure is returned.

If temporary is true, the breakpoint is considered temporary (subject to removal after the next breakpoint is hit). Temporary breakpoints have less "priority" than non-temporaries; a temporary will not replace a non-temporary in the same location, but a non-temporary will replace a temporary. Breakpoints of the same priority will not replace each other at the same location.

The verbose argument, when true, will show the disassembly of the breakpoint being added.

See The Lisp DeBug (ldb) stepper in debugging.html.

# add-package-local-nickname

Function, excl package

Arguments: local-nickname actual-package &optional (housing-package *package*)

Release 10.1 and later only. Returns the housing-package, which must be a package designator and defaults to the value of *package*, after adding a mapping for the string designator local-nickname to the package designated by actual-package. If local-nickname is any of the package-descriptors for the `common-lisp` or `keyword` packages, an error is signaled.

Example

    cl-user(8): (defpackage :p1)
    #<The p1 package>
    cl-user(9): (defpackage :p2)
    #<The p2 package>
    cl-user(10): (defpackage :hpack (:use :cl :excl)
                 (:local-nicknames (:p-one :p1)))
    #<The hpack package>
    cl-user(11): (package-local-nicknames :hpack)
    (("p-one" . #<The p1 package>))
    cl-user(12): (add-package-local-nickname "p-two" :p2 :hpack)
    #<The hpack package>
    cl-user(13): (package-local-nicknames :hpack)
    (("p-one" . #<The p1 package>) ("p-two" . #<The p2 package>))
    cl-user(14): (add-package-local-nickname "p-one-a" :p1 :hpack)
    #<The hpack package>
    cl-user(15): (package-local-nicknames :hpack)
    (("p-one" . #<The p1 package>) ("p-two" . #<The p2 package>)
     ("p-one-a" . #<The p1 package>))
    cl-user(16):

See Package-local Nicknames in packages.html for more information in package-local nicknames.

# add-signal-handler

Function, excl package

Arguments: U800number function &key delay-interrupts

function is added as a signal handler for signal number.

The handling of operating system dependent signals generated during program execution is not part of Common Lisp. A signal is a small integer. The list of valid signals is given in a system dependent file, usually on UNIX something like /usr/include/signals.h. Signals are either synchronous or asynchronous, but there is no distinction made in this interface--the handling of both types of signals is the same. Such signals are attached at the unix level to foreign functions gotsig and syncsig1, respectively, if they are normally handled by the Lisp, via the UNIX signal() function. Other signals are not so attached, and will either perform some default UNIX action, or some action unrelated to Lisp operation.

Users adding code to handle UNIX signals should use the foreign function lisp_signal() rather than signal(). lisp_signal() (supplied by Franz), which does the right and safe thing with signals. Note lisp_signal() is used in the example below. (Some earlier versions of this documentation had a call to signal() in that example. On many platforms, it does not make a difference but on some it does.)

At the Lisp level, a handler for a signal is a function of two arguments, signal number and t. If there is no handler for a particular signal, then some default action is invoked, which is usually to signal an error. Signal handlers should return a true value if they handle the signal, so that other, nested handlers are not invoked to handle the signal. A signal that is posted during a gc is processed immediately after the gc finishes.

Be warned that once a programmer starts dealing with the signal interface at the operating system level, the effects might be far reaching and unintended. Please consider contacting Franz Inc. Technical Support before proceeding to do so. Further, such low-level modifications to signal handling could be non-portable across UNIX platforms, could break existing usages of signals by Allegro CL and thus affect its operation, or it could break existing usages of other systems running along with Allegro CL.

If the delay-interrupts argument is true, then the handler be run in a with-delayed-interrupts, else it will be run with interrupts enabled.

Here is an example of adding a signal handler from a UNIX machine:

    user(16): (defun foo (signal &optional ignore)
           (format t "~&; got signal ~d~%" signal)
           t)
    foo
    user(17): (add-signal-handler 2 'foo)
    ((2 . foo) (14 . mp::sigalrm-handler))
    user(18):        <<<< Control-C was typed here at this prompt
    ; got signal 2
    user(18):
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Now, we show how a signal that has not yet been attached at the UNIX
    ;; level to either gotsig or syncsig1 can be so attached, so that
    ;; add-signal-handler will have an effect at the lisp level.  It is the
    ;; programmer's responsibiluty to take care that the signal number is
    ;; not already attached to some conflicting Unix signal handling function.
    ;; Although the foreign function interface is used, no foreign
    ;; files need to be loaded.
    ;;  Define a function SETUP-FOR-NEW-SIGNAL
    user(1): (let ((gotsig-address
            (ff:get-entry-point (ff:convert-to-lang "gotsig"))))
           (unless gotsig-address
             (error "couldn't find address of gotsig"))
           (ff:def-foreign-call (unix-signal "lisp_signal")
                                    (signal old-handler))
           (defun setup-for-new-signal (number)
             (unix-signal number gotsig-address)))
    setup-for-new-signal
    ;;  Define a constant holding our new signal number.
    user(2): (defconstant *additional-signal* 30
           "This is the signal number of the signal we want to catch.")
    *additional-signal*
    ;;  The lisp function that handles the signal
    user(3): (defun additional-signal-handler (signal &optional ignore)
           (format t "additional-signal-handler: ~s~%" signal)
           (finish-output)
           t)
    additional-signal-handler
    ;;  Now we generate a test signal
    user(4): (ff:def-foreign-call getpid (:void))
    t
    user(5): (ff:def-foreign-call kill (pid signal))
    t
    ;;  Tell the system about the new signal
    user(6): (setup-for-new-signal *additional-signal*)
    0
    ;;  Send the signal, and notice that the debugger handles it
    user(7): (kill (getpid) 30)
    Error: Received signal number 30 (user defined signal 1)
      [condition type: simple-break]
    Restart actions (select using :continue):
     0: continue computation
    [1c] user(8): :pop
    ;;  Have our handler added...
    user(9): (add-signal-handler *additional-signal* 'additional-signal-handler)
    ((30 . additional-signal-handler) (14 . mp::sigalrm-handler))
    ;;  ...and try it again
    user(10): (kill (getpid) 30)
    additional-signal-handler: 30          ;; <<< our function handles it
    0
    user(11):

See with-signal-handler, set-signal-handler, *signals*, and remove-signal-handler

# add-stream-instance-flags

Macro, excl package

Arguments: stream &rest flag-names

This macro adds (via logior) instance flags to or zeroes instance flags out of the standard-instance object that is the stream. Note that this flags field has no correlation to a flags slot in the stream. You may inspect a stream in raw mode to see the instance-flags (see inspector.html).

The behavior depends on the first of the flag-names arguments. If it is a keyword specifying a valid instance flag, then it and all the remaining keyword-named instance flags are added. But if the first of the flag-names arguments is a list of flag names, then those are zeroed out before the remaining flag-names (if any) are added. For example, the form

    (add-stream-instance-flags stream (:gray :dual :string) :simple)

first ensures that the `:gray`, `:dual`, and `:string` bits are zero, before ensuring that the `:simple` bit is set. This is done without modifiying the `:input` or `:output` bits. On the other hand, this form

    (add-stream-instance-flags stream :string :simple)

simply ensures the `:string` and `:simple` flags are set.

Valid instance flags are placed into the following groups:

- Direct stream subclass (select exactly one): `:gray` (identifies a Gray or fundamental-stream) or `:simple` (identifies a simple-stream). A stream instance that has neither bit set is not considered a stream.

- Open-ness (select one, both, or none): `:input` (stream may perform input operations); `:output` (stream may perform output operations). A stream instance that has neither bit set is not considered an open stream.

- Direct simple-stream subclass (select zero or one): `:dual` (stream is a dual-channel stream); `:string` (stream is a string-stream). A stream with neither bit set is considered a single-channel stream

You must load the `:iodefs` module to use this macro. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This macro is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# add-typep-transformer

Function, excl package

Arguments: type function

This function is called for its side effects. The return value has no meaning. This function tells the compiler that a typep form:

    (typep x 'type)

can be transformed into the form:

    (funcall predicate x)

The compiler will make the transformation where possible.

type must be a type, typically defined by the user with deftype. predicate should be a function object or a symbol naming a function. That function must accept any Lisp object as a single argument and return `nil` if the object is not of type type, true if it is of type type. remove-typep-transformer removes the transform.

See compiling.html for general information on compiling and see Adding typep-transformers in that document for more information on typep transforms.

# advise-1

Function, excl package

Arguments: fspec class name position forms

Starting in Allegro CL release 6.0, the new fwrapper facility, described in fwrappers-and-advice.html, replaces the advice facility, and continued use of the advice facility is deprecated.

This function actually does the work of advising. With the exception of the forms argument, its arguments have the same meaning as in advise, except here they are evaluated (of course). The forms argument is not an &rest argument, so instead it is a list of forms to be evaluated. Warning: forms cannot be the single form `nil`. If you want the single form `nil` (in, for example, :around advice to not call the function and return `nil`), specify `(progn nil)` instead.

See the definition of advise for further explanation of the arguments.

The following examples demonstrate the differences between a call to advise and a call to advise-1. The two forms have exactly the same effect.

    (excl:advise foo :before jim 100
     (format t "hello~%") (format t "hello again~%"))
    (excl:advise-1 'foo :before 'jim 100
     '((format t "hello~%") (format t "hello again~%")))

Even a single form must be in a list in calls to advise-1.

See also fwrappers-and-advice.html for general information on the new fwrapper facility and the older, now deprecated, advice facility in Allegro CL.

# advise

Function, excl package

Arguments: fspec class name position &rest forms

The fwrapper facility, described in fwrappers-and-advice.html, should be used in place the advice facility, and continued use of the advice facility is deprecated.

None of the arguments are evaluated. This macro advises the function fspec appropriately with code defined by the forms.

fspec specifies the function (or macro) to advise. This argument is normally a symbol but it can be any function name (see implementation.html). See fwrappers-and-advice.html for information on advising macros. The information in the remainder of this definition relates to functions only.

class specifies the type of advice. The three choices are `:before`, `:around`, and `:after`. `:before` advice will be evaluated before the advised function is called; `:around` advice will be evaluated around the calling of the advised function (in the sense that the call to the function will be embedded within the `:around` code); `:after` advice will be evaluated after the advised function has been called. See below for more information on classes of advice.

name specifies the name of the advice. Its value may be `nil`, but it is convenient to refer to advice by name. Note that there can be only one piece of advice of each class with a given name. (But there may be as many as you like without a name, i.e. with `nil` as the specified name.) If more advice is defined with the same name and class as existing advice, the new advice will replace the existing advice, thus taking its place.

position specifies the location of advice relative to other advice of the same class on the same function. The important point about this argument is that it is used only when the advice is first defined and is then forgotten. Therefore, the position is calculated with respect to already existing advice of the same class, whose positions are 0, 1, 2... regardless of the value of the position argument when they were defined. See fwrappers-and-advice.html for examples that further explain this point.

There can be many pieces of advice of each class on a function. position specifies where the piece of advice currently being defined will go. position may be a non-negative integer, a name or `nil`. If it is a number, then the lower the number, the farther the advice will be from the actual evaluation of the forms defining the function itself. Thus for `:before` and `:around` advice, advice 0 will be run first, then 1, 2, 3, and so on, while for `:after` advice, advice 0 will be run last, preceded by 1, 2, 3, and so on. Say there are n pieces of advice of the class of the advice being defined. The existing advice is numbered 0, 1, 2, ..., `n-`1, inclusive. Then a position of 0 will result in the new advice being placed farther from the function call than all the rest of the advice, a position of `k` where `k` is between 1 and `n-1` will be placed farther then the `k`th piece of existing advice, and a position `n` or larger will be placed nearest the function call.

If position is `nil`, the advice is put farther from the function call then all currently-defined advice of the same class. If position is a name of existing advice, the advice will be placed next farther from the function call (before for `:before` and `:around`, after for `:after`) than the named advice. Note that if new advice has the same name and class as existing advice, it will replace the existing advice and take the position of the existing advice. In that case, the position argument will be ignored.

forms are the actual forms that will be evaluated. All advice on a function is combined in an enclosing cl:prog, so a return placed anywhere in any type of advice will cause the advised function to return with the values specified with the return, without any further advice code being evaluated and (if it has not already done so) without the advised function being evaluated. Syntactically, `:around` advice should be a single form. If multiple forms are specified, however, they are automatically wrapped in a cl:progn. Warning: forms cannot be the single form `nil`. If you want the single form `nil` (in, for example, :around advice to not call the function and return `nil`), specify `(progn nil)` instead.

## Advice of class :before

`:before` advice will be evaluated before the function call. The argument list with which the function was called is available to `:before` advice. The argument list is stored as the value of the variable `excl:arglist` (this symbol also names a function which returns the arguments list of an operator). You may check the values in this list, change the values or replace the list altogether with a new list. (If you replace the list, be careful that it have the correct format for the function -- number and types of arguments in the list -- or you may get an error, or worse, a wrong result but no error.) `:before` advice is used only for its side effects. Any value returned by `:before` advice code is ignored.

## Advice of class :around

`:around` advice places the function call inside the code of the advice. The keyword `:do-it` signals where the function should be called within the advice code. When Lisp encounters the `:do-it`, it calls the next piece of `:around` advice, if there is more, or the function. When the function returns, the `:around` advice code continues execution. `:do-it` may appear several times in `:around` advice. Normally, it is placed in conditional code, as shown in this code fragment:

    (advise myfunction :around example nil
      (... [do stuff before function call in :around advice code]
       (if (zerop (car excl:arglist)) (+ 5 :do-it) (* 7 :do-it))
       ... [do stuff after function call] ))

In that case, the system will encounter one or the other `:do-it`, but not both. However, it is allowed to have several `:do-it`s all of which are evaluated. In that case, the succeeding `:around` advice and the advised function are evaluated more than once. `:after` advice is still evaluated only once, however. `:around` advice can work with `excl:arglist` before the `:do-it`. Since the advised function is run at the location specified by the `:do-it`, the values the function return are available to `:around` advice just like with any function call. The list bound to the variable `values` is not set up until after all `:around` advice is run, then `values` is bound to the list of values returned by the final piece of `:around` advice. Note that if the function returns multiple values, these should be caught with multiple-value-bind or multiple-value-list or some similar function if you are interested in the values beyond the first.

## Advice of class :after

advice is evaluated after the function has completed, but before control is passed back to whatever called the function. `:after` advice may examine and change the list of returned values from the last piece of `:around` advice (or the function, if there is no `:around` advice) stored in the variable `values`. `:after` advice is used only for its side effects. Any value returned by the `:after` advice code is ignored. The list bound to `values` is returned from the now completed function call.

See also fwrappers-and-advice.html for general information on the new fwrapper facility and the older, now deprecated, advice facility in Allegro CL.

# advised-functions

Function, excl package

Arguments:

Starting in Allegro CL release 6.0, the new fwrapper facility, described in fwrappers-and-advice.html, replaces the advice facility, and continued use of the advice facility is deprecated.

This function, which takes no arguments, returns a list of all advised functions and macros which have active advice of any kind.

See also fwrappers-and-advice.html for general information on the new fwrapper facility and the older, now deprecated, advice facility in Allegro CL.

# all-external-formats

Function, excl package

Arguments:

This function returns the list of all active external-format objects. This function is setf-able. Thus, one can effectively remove an external-format from the Lisp system by using (setf all-external-formats) specifying a list that does not include that external-format.

Examples:

    (let ((before (all-external-formats)))
       (def-external-format :test)
       (set-difference (all-external-formats) before))
          -> (#<external-format :test>)

See iacl.html for more information on international character support in Allegro CL.

# all-locales

Function, excl package

Arguments:

This function returns the list of all active locale objects.

Examples:

    (let ((before (all-locales)))
       (def-locale :test :external-format (find-external-format :latin1))
       (set-difference (all-locales) before))
           -> (#<locale :test [:latin1-base]>)

See iacl.html for more information on international character support in Allegro CL.

# apropos-regexp

Function, excl package

Arguments: string &optional package external-only case-insensitive

This function is just like apropos except the first string argument (which must be a string or a symbol) is interpreted as a regular expression. For example (the exact symbols listed may be different for you):

    cl-user(2): (apropos-regexp "^def.n-.*")
    excl::defun-like    [function] (xp list &rest args)
    excl::defun-spec
    excl::defun-proto-1
    defun-proto         [macro] (name varlist &rest body)
    ff::defun-foreign-callable-1 [function] (name arglist body)
    ff:defun-c-callable [macro] (&whole form &rest args)
    ff:defun-foreign-callable [macro] (name arglist &rest body)
    sys::defun-noicheck
    cl-user(3):

The first optional argument, package, is similar to the same optional argument to apropos. It can be `nil` or a package designator. If it is a package designator, only symbols accessible in that package are considered.

The second and third optional arguments are Allegro CL extensions to apropos, as described in apropos in implementation.html. If external-only is specified non-`nil`, only external symbols are considered. If case-insensitive is specified non-`nil`, a case-insensitive search is done, rather than a case-sensitive search. All the optional arguments default to `nil`. See apropos in implementation.html for more information on the optional arguments.

# arglist

Function, excl package

Arguments: *function &environment env

Returns two values: if the the argument list of the operator (function, generic function, or macro) specified by the argument is known, it and `t` are returned. If the argument list is not known (that information can be discarded to save space), `nil` and `nil` are returned.

If the env environment argument is supplied and non-`nil`, is must be an environment object as returned by make-compilation-unit-environment or augment-environment. This environment is used to find the current lexical definition of the function in place of the global definition.

Note that some argument lists may be uninformative (perhaps simply &rest args) when a function does all argument processing within its body. Also, the compiler may have simplified the argument list for its purposes. This function is designed to assist only. The argument list returned, even when the second returned argument is `t`, may not accurately describe all valid lists of arguments that can be passed to the function. (For example, the `&allow-other-keys` lambda-list keyword is often dropped.)

See also the variable *save-function-lambda-expression*, which, when true, tells the compiler to save lambda expressions and make them available to the function function-lambda-expression.

# argument-saving

Function, excl package

Arguments:

This setf'able function controls whether Lisp saves arguments passed to Lisp functions which happen to be stored in registers rather than on the stack. Passing some arguments in registers is very efficient and is done when possible. However, the values in those registers will be overwritten when an unhandled error occurs and thus not be available for debugging. If argument saving is enabled, the argument values in registers will be saved and available for debugging. If argument saving is disabled, those argument values will not be saved. Unsaved arguments show up as `:unknown` in stack backtraces (as printed by :zoom.

Note: if arguments are being saved, code may not run as fast as possible.

This function returns `t` if arguments are being saved, `nil` if they are not.

setf can be used with this function to set argument saving, so

    (setf (argument-saving) t)

causes arguments to be saved and

    (setf (argument-saving) nil)

causes them not to be saved.

The top-level command :args is roughly equivalent to this function.

Note that on some architectures, arguments are always saved. On those architectures, this command has no effect.

# assert-enabled-p

Macro, excl package

Arguments: name

If name names a registered assert-enable, returns its set value (see set-assert-enable). If name is not registered, an error is signaled.

This function is used to test whether an assertion should be tested or ignored (typically because assertions can be costly, they might be used in development but ignored in production). See Conditionalizing assert calls in miscellaneous.html for more information and an example.

# atomic-conditional-setf

macro, excl package

Arguments: place newval-form oldval-form

This is the primitive form on which some other atomic operations (update-atomic, incf-atomic, decf-atomic, pop-atomic, and push-atomic) are based. It acts very much like

    (when (eq place oldval-form)
      (setf place newval-form)
      t)

In atomic-conditional-setf, the computation of place subforms, oldvalform, and newval-form are not atomic with respect to anything but the comparison and store (if there is one) are an atomic sequence.

A technical compiler issue limits it to appearing only as the test form in a conditional, as in the following example of an atomic increment equivalent to `(incf-atomic (car x))`:

    (loop
      (let* ((old (car x))
             (new (1+ old)))
        (when (atomic-conditional-setf (car x) new old)
          (return))))

Not all places legal as the first argument of setf can be used as the place argument to this macro. The list of allowable places can be found in Atomic read-modify-write primitives in smp.html.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# atomic-conditional-setq

special operator, excl package

Arguments: symbol newval-form oldval-form

This special operator returns a boolean of success or failure to store the value into the symbol's value location. It is intended to be a synchronizing mechanism for symbols which represent variables shared by multiple threads. It is undefined for symbols which represent a purely local (i.e. non-shared) value. Currently, the interpreted form of atomic-conditional-setq accepts such local variables, but the compiler will signal an error if the variable is not special or closed-over.

Arguments

- symbol may name either a special or a closed-over variable. If the symbol names a symbol-macro or is currently shadowed by a symbol-macrolet, then the excl:atomic-conditional-setf is used to handle the macroexpansion (which might then eventually get back to atomic-conditional-setq if the place value is symbolic after full macroexpansion).

  Note that the compilation of atomic-conditional-setq does not error if the symbol names a special variable and that special is currently let/lambda bound in the current thread even though such a value is thread-local. Also, the compilation of atomic-conditional-setq does not error if the variable is closed over but can't possibly be seen by another thread.

- newval-form is any form which will be evaluated and the result used as a new value to store into the symbol.

- oldval-form is evaluated to a value, presumably taken from the symbol's value at an earlier time.

In an atomic operation, if the variable's current value is EQ to the old value then the new value is stored into the variable location and the special operator returns True. Otherwise, the new value is not stored, and the special-operator returns false. Note that none of the evaluations of the symbol as a variable, or of the newval-form, or of the oldval-form, are atomic; the only operations that are atomic are the comparison and store, if there is one.

# base64-decode-stream

Function, excl package

Arguments: instream outstream &key count (error-p t)

base64-decode-stream reads bytes from instream, does base64 decoding on them, and writes the decoded bytes to outstream. Non-base64 characters are ignored. Invalid base64 encodings will result in an error being generated. instream is read until base64 terminating characters are seen or until end-of-file. If end-of-file is seen at an improper place (such as in the middle of a base64 chunk) an error will be generated.

If the count keyword argument is supplied, it must be an integer indicating the maximum number of bytes to read from instream. If count is not supplied, or is `nil` (the default), the instream will be read until base64 terminating bytes are seen, or until end-of-file.

If the error-p keyword argument is true (the default), then errors during base64 decoding (such as unexpected end of input, or invalid encodings) will result in an error being generated. If error-p is `nil`, base64 decoding will simply stop processing and return.

Notes: instream must be a stream capable of being read in an octet-oriented manner (i.e, it must be a stream for which read-byte will succeed). In particular, instream cannot be a string stream. Likewise, outstream must be a stream capable of being written in an octet-oriented manner.

See Base64 Support in miscellaneous.html for information on Base64 and Base64 support in Allegro CL.

See also: base64-encode-stream.

# base64-encode-stream

Function, excl package

Arguments: instream outstream

base64-encode-stream reads bytes from instream and writes the base64 encoding of those bytes to outstream (as characters). Outstream lines will be at most wrap-at (which defaults to 72) characters in length. If wrap-at is `nil`, no wrapping will occur.

Notes: instream must be a stream capable of being read in an octet-oriented manner (i.e, it must be a stream for which read-byte will succeed). In particular, instream cannot be a string stream.

See Base64 Support in miscellaneous.html for information on Base64 and Base64 support in Allegro CL.

See also: base64-decode-stream documentation.

# base64-string-to-integer

Function, excl package

Arguments: string

This function converts the base64 string which is the value of string to an integer. See the function integer-to-base64-string which is the inverse of this function (the page for integer-to-base64-string includes examples).

See Base64 Support in miscellaneous.html for information on Base64 and Base64 support in Allegro CL.

# base64-string-to-string

Function, excl package

Arguments: string &key start end (external-format (crlf-base-ef :latin1))

The inverse of string-to-base64-string. Similar to base64-string-to-usb8-array except a string rather than a usb8 array is returned.

The start and end keyword argument can be used to specify the portion of the input string to use. If unspecified, the whole string is used. The external-format keyword argument allows the external format of the output string to be specified. See crlf-base-ef.

See Base64 Support in miscellaneous.html for information on Base64 and Base64 support in Allegro CL.

# base64-string-to-usb8-array

Function, excl package

Arguments: string &key start end output

This function converts the base64 string which is the value of string to an (unsigned-byte 8) array (with the six bits of the first converted character of string becoming the most significant six bit of the first element of the result array and so on). Two values are returned: the array and the number of bytes added to the returned array.

The start and end keyword argument specify the portion of the input string to convert. If unspecified, the whole string is used.

The output keyword argument allows specification of a (unsigned-byte 8) array in which to place the result. The result whill be written into the output array starting at index 0. The number of bytes written is the second returned value. If the output array is not large enough to hold the result or if output is unspecified or nil, a new array is created abd returned.

See the function usb8-array-to-base64-string which is the inverse of this function (the page for usb8-array-to-base64-string includes examples).

See Base64 Support in miscellaneous.html for information on Base64 and Base64 support in Allegro CL.

# bignump

Function, excl package

Arguments: object

Returns true if the argument is a bignum and returns `nil` otherwise.

# blowfish-decrypt

Function, excl package

Arguments: encrypted &key key end context (pad t) *string in-place (external-format :utf-8) (mode :ecb) iv

This function decrypts encrypted, which should be an (unsigned-byte 8) array returned by a call to blowfish-encrypt.

This function returns one or two values, as the string keyword argument is true or false. If string is true, a string is returned as the only returned value. If string is false, an (unsigned-byte 8) array representing the decryption and an integer specifying how many bytes there are in the decrypted result are returned. The second returned value is the length of the array returned as the first returned value when the in-place keyword argument is false, and is a value less than or equal to the length when in-place is true.

The arguments are:

- encrypted (the single required argument): an (unsigned-byte 8) array as returned by blowfish-encrypt.

- `:key`: a string or (unsigned-byte 8) array. It must be the same key used by blowfish-encrypt to produce the value encrypted. Do not specify a value for this argument and for context.

- `:end`: an integer or `nil`. If an integer, the length of the encrypted portion of encrypted (the same value as the second value returned by blowfish-encrypt). If `nil`, then the whole of encrypted is used. (The in-place argument to both this function and to blowfish-encrypt allows using an existing (unsigned-byte 8) array, which may be larger than necessary to hold the encrypted value. This argument allows you to specify the actual encrypted portion and ignore the remainder of the array.)

- `:context`: an object (again, an (unsigned-byte 8) array) returned by blowfish-init when passed the key used to encrypt encrypted. This argument is typically used when a number of things need to be encrypted or decrypted using the same key. (The first step in encryption and decryption is to convert the key into a context object. Using the context object directly avoids repeating this step for each encryption/decryption.) Do not specify a value for this argument and for key.

- `:pad` (default is `t`): the value should be the same as was passed as the pad argument to blowfish-encrypt. It tells whether the encrypted value was padded out to have an octet length of 8.

- `:string`: if specified true, the (unsigned-byte 8) array raw decryption result is converted to be a string using the `:utf-8` external format, and the resulting string is returned as the single returned value. If `nil`, the raw (unsigned-byte 8) array is returned as the first value and the length of the decrypted portion in the array is returned as the second value.

- `:in-place`: if specified true, the value of encrypted will be modified to hold the decrypted value (if possible). If it is not possible to decrypt in place then this argument will be ignored and a new (unsigned-byte 8) array will be created. If encrypted is used and string is `nil`, the second returned value (the number of bytes in the decryption) may be less than the length of the first returned value.

- `:external-format`: this argument specifies the external format to be used when decrypting the string to be encrypted. Its value should be the same as used when the string was encrypted. The default is `:utf-8` and that is in general a good choice. When `:default` is specified, the value returned by `(find-external-format :default)` is used (see find-external-format). That value is not recommended because the value of the default external format (which depends on the value of *locale*) may change between encryption and decryption.

- `:mode`: this argument allows specifying ECB (Electronic Code Book) decryption of CBC (Cipher Block Chaining) decryption. The default is `:ecb`, meaning use ECB. Specify `:cbc` for CBC. The text must be decrypted in the same mode as was used for encryption. If CBC encryption mode is requested, the initialization vector (IV) must be provided by using keyword argument iv. The IV must be an (unsigned-byte 8) array of at least 8 elements. The IV will be modified so that it may be used for subsequent encrypt/decrypt calls.

- `:iv`: ignored unless mode is specified `:cbc`. When mode is `:cbc`, the value, called the initialization vector or IV, must be the same (unsigned-byte 8) array of at least 8 elements as was usedf for encryption. The IV will be modified so that it may be used for subsequent encrypt/decrypt calls.

See also blowfish-encrypt and blowfish-init.

See also the new auxilliary functions hex-string-to-usb8-array and usb8-array-to-hex-string.

See Support for Blowfish encryption in miscellaneous.html for information on Blowfish encryption and Blowfish encryption support in Allegro CL. There are examples of blowfish encryption and decryption in that section. Support for encryption in the same document discusses encryption support in Allegro CL in general.

# blowfish-encrypt

Function, excl package

Arguments: value &key key end context pad in-place (external-format :utf-8) (mode :ecb) iv

This function encrypts value using the specified key or context and returns two values: an (unsigned-byte 8) array holding the encryption and an integer specifying the index into that array just after the end of the encrypted result (equivalently, the length of the encrypted result). The second value will also be the length of the array returned as the first value if the in-place is `nil` (which is its default). If in-place is true, the second returned value will be less than or equal to the length of the first returned value.

The arguments are:

- value (the single required argument): an (unsigned-byte 8) array or string to be encrypted.

- `:key`: a string or (unsigned-byte 8) array which serves as the encryption key. Do not specify a value for this argument and for context.

- `:end`: an integer or `nil`. If an integer, the length of the portion of value to be encrypted. If `nil`, then the whole of value is encrypted. (The in-place argument to both this function and to blowfish-decrypt allows using an existing (unsigned-byte 8) array, which may be larger than necessary to hold the encrypted value. This argument allows you to specify the portion of interest and ignore the remainder of the array.)

- `:context`: an object (again, an (unsigned-byte 8) array) returned by blowfish-init when passed the key to be used to encrypt value. This argument is typically used when a number of things need to be encrypted or decrypted using the same key. (The first step in encryption and decryption is to convert the key into a context object. Using the context object directly avoids repeating this step for each encryption/decryption.) Do not specify a value for this argument and for key.

- `:pad` (default is `t`): if pad is true then the value to be encrypted will be padded out to have an octet length that is a multiple of 8. The pad is constructed such that it contains information specifying how much padding was added so that when the result is decrypted, the padding can be removed. Thus if pad is true then at least one and as many as eight more octets will be added to the returned value. If pad is `:pkcs5`, then standard PKCS#5 padding will be used. If pad is `:zero`, then null padding will be used. Note that null padding is only suitable if the value to be encrypted contains no null octets. If pad is `nil` then an error is signaled if the value to be encrypted doesn't have a length that is a multiple of 8.

- `:in-place`: if specified true, the value of value will be modified to hold the encrypted value (if possible), thus avoiding the creation of a new array. If it is not possible to encrypt in place then this argument will be ignored and a new (unsigned-byte 8) array will be created. (This would happen when value is a string rather than an (unsigned-byte 8) array or when value is not large enough to hold the result.) If value is used, the second returned value (the number of bytes in the decryption) may be less than the length of the first returned value.

- `:external-format`: this argument specifies the external format to be used when interpreting the string to be encrypted. The same external format should be used when decrypting. The default is `:utf-8` and that is in general a good choice. When `:default` is specified, the value returned by `(find-external-format :default)` is used (see find-external-format). That value is not recommended because the value of the default external format (which depends on the value of *locale*) may change between encryption and decryption.

- `:mode`: this argument allows specifying ECB (Electronic Code Book) encryption or CBC (Cipher Block Chaining) encryption. The default is `:ecb`, meaning use ECB. Specify `:cbc` for CBC. The text must be decrypted in the same mode. If CBC encryption mode is requested, the initialization vector (IV) must be provided by using keyword argument iv. The IV must be a usb8 array of at least 8 elements. The IV will be modified so that it may be used for subsequent encrypt/decrypt calls. CBC encryption is generally considered superior to ECB encryption and should be used unless there is a reason not to.

- `:iv`: ignored unless mode is specified `:cbc`. When mode is `:cbc`, the value, called the initialization vector or IV, must be an (unsigned-byte 8) array of at least 8 elements. The IV will be modified so that it may be used for subsequent encrypt/decrypt calls.

See also the new auxilliary functions hex-string-to-usb8-array and usb8-array-to-hex-string.

See also blowfish-decrypt and blowfish-init.

See Support for Blowfish encryption in miscellaneous.html for information on Blowfish encryption and Blowfish encryption support in Allegro CL. There are examples of blowfish encryption and decryption in that section. Support for encryption in the same document discusses encryption support in Allegro CL in general.

# blowfish-init

Function, excl package

Arguments: key &key (external-format :utf8)

Returns an object that is suitable as a value for the context keyword argument to blowfish-encrypt and blowfish-decrypt. Blowfish keys are converted to these objects as the first step in encryption or decryption. When multiple things are to be encrypted or decrypted with the same key, you can save time by passing the value returned by this function as the value of context rather than passing the actual key.

external-format: this argument specifies the external format to be used when encrypting and decrypting. Its value should be the same in calls to blowfish-encrypt and blowfish-decrypt as in the call to blowfish-init. The default is `:usb-8` for all three functions.

See also blowfish-encrypt and blowfish-decrypt.

See Support for Blowfish encryption in miscellaneous.html for information on Blowfish encryption and Blowfish encryption support in Allegro CL. There are examples of blowfish encryption and decryption in that section. Support for encryption in the same document discusses encryption support in Allegro CL in general.

# build-lisp-image

Function, excl package

Arguments: image-file &rest rest &key * aclmalloc-heap-size aclmalloc-heap-start additional-arguments additional-forms additional-plus-arguments autoload-warning build-debug build-executable build-input build-output case-mode close-oldspace copy-shared-libraries destination-directory discard-arglists discard-compiler discard-local-name-info discard-source-file-info discard-xref-info dst exit-on-missing-shared-library generate-fonts include-clim include-compiler include-composer include-debugger include-devel-env include-ide include-tpl include-xcw lisp-heap-size lisp-heap-start lisp-files load-local-names-info load-source-file-info load-xref-info newspace oldspace opt-debug opt-safety opt-space opt-compilation-speed opt-speed pll-file pll-from-sys post-load-form pre-dump-form pre-load-form preserve-documentation-strings presto presto-flush-to-code-file presto-lib print-startup-message read-init-files record-source-file-info record-xref-info require-search-list restart-app-function restart-init-function runtime server-name show-window splash-from-file temporary-directory us-government user-shared-libraries verbose*

The complete description of this function can be found in building-images.html. Please refer to that document for descriptions of the arguments and their meanings. That allows the description to be in one place only. The following are links to particular sections of that document:

- The template of a call to build-lisp-image

- Arguments to build-lisp-image 1: defaults inherited from the running image

- Arguments to build-lisp-image 2: defaults not inherited from the running image

Please note that build-lisp-image does not inherit anything from the currently running Lisp process other than the defaults for certain arguments (listed here). If the function foo is defined in the currently running image, it will not be defined in the newly built image unless you force the load of some file which defines foo. Neither will variables have their values in the running image unless that is also the initial value, even if they are defined. Some arguments take symbols for values. The symbol will be present (assuming the package is present) in the new image but its function definition and its value will, in general, not be. You cannot specify a function object to an argument calling for a symbol naming a function.

# bundle-pathname

Function, excl package

Arguments:

This function returns the pathname of the bundle file, the file where the autoloaded portions of the Lisp library are kept. You may use setf to change the pathname but be sure that the bundle file is at the new location before changing its path in Lisp.

# call-finalizer

Function, excl package

Arguments: finalizer

If a finalization is scheduled with schedule-finalization with the queue argument non-`nil` (which must be a queue, then when the object associated with the finalization is marked as garbage, the system puts a finalization object on the queue specified by the queue argument (and takes no further action).

The program must then deal with the finalization object by applying this function to it. The finalization object is a list of the finalization function and the object. call-finalizer calls the finalization function and ensures that the object is marked as garbage (unless the finalization function did something to make the object not garbage), just as the system would do if the finalization was scheduled with queue `nil`.

Example:

    ;; We create a queue object:

    cl-user(2): (setq queue (make-instance 'mp:queue))
    #<multiprocessing:queue @ #x20c4641a>

    ;; We will add a non-queued finalization to this object:
    cl-user(3): (setq aa (make-array 4))
    #(nil nil nil nil)
    cl-user(4): (defun foo (x) (format t "I, ~s, am garbage!!!" x))
    foo

    ;; Here we create the non-queued finalization:
    cl-user(5): (schedule-finalization aa 'foo)
    #(#(nil nil nil nil) foo nil)

    ;; We dereference it:
    cl-user(6): (setq aa nil)
    nil

    ;; And it is run when the object is marked as garbage:
    cl-user(7): (gc)
    I, #(nil nil nil nil), am garbage!!!
    cl-user(8): (gc)

    ;; A new object, which we will schedule a queued finalization:
    cl-user(9): (setq bb (make-array 5))
    #(nil nil nil nil nil)

    ;; We schedule the finalization:
    cl-user(10): (schedule-finalization bb 'foo :queue queue)
    #(#(nil nil nil nil nil) (#<multiprocessing:queue @ #x2097b332> . foo) nil)

    ;; We dereference the object:
    cl-user(11): (setq bb nil)
    nil
    cl-user(12): (gc)
    cl-user(13): (gc)
    cl-user(14): (gc)

    ;; Finalization is not run even after three gc's.

    ;; We run the finalization ourselves:
    cl-user(15): (call-finalizer (mp:dequeue queue))
    I, #(nil nil nil nil nil), am garbage!!!
    nil
    cl-user(16):

# call-next-fwrapper

Macro, excl package

Arguments:

Wherever placed in an fwrapper, this form results in a call made to the next more inner fwrapper on the primary-function being wrapped. If this fwrapper is the innermost fwrapper, then the primary function is called instead.

The arguments passed to the next more inner fwrapper (or primary function) are the current arguments as the function was originally called, modified by any storing forms in fwrappers which have already executed. Storing forms might be a setq of a required, optional, or keyword argument, or it may be a `(setf nth)` on any element of the &rest list. The presence or absence of Keyword arguments cannot be changed.

The form returns the value(s) returned by the next more inner fwrapper (or by the primary function, if this is the innermost fwrapper). It is the responsibility of each fwrapper to propagate return values as expected, or to substitute new return values to be returned. A standard construct for returning values untouched from within an fwrapper is

     (multiple-value-prog1
       (call-next-fwrapper)
      ;; Do some more stuff here
      ...
     )

See fwrappers-and-advice.html for information of fwrapping functions (and on the older, deprecated advice facility).

# case-failure-name

Generic Function, excl package

Arguments: case-failure

Returns the name of the macro called causing the case-failure condition. The argument must be a case-failure condition. (The top-level command :error sets * to the condition as well as printing the error message.)

# case-failure-possibilities

Generic Function, excl package

Arguments: case-failure

Returns a list of the case possibilities when a case-failure condition is signaled (none of the possibilities satisfied the case causing the error). The argument must be a case-failure condition. (The top-level command :error sets * to the condition as well as printing the error message.)

# case-translation-gravity

function, excl package

Arguments:

This returns the case translation gravity of the running Lisp. This value is determine at startup and is either `:local` (in modern Lisps, where the case mode is `:case-sensitive-lower`) or `:common` (in ANSI Lisps, where the case mode is `:case-insensitive-upper`). The value is changed if the case mode is changed. This function is used by in-case-mode. See that macro for more information.

# char-to-octets

Macro, excl package

Arguments: ef-name char state-loc &key put-next-octet external-format

ef-name should be a symbol. char should be a character. state-loc should be a place suitable as the first argument to setf. put-next-octet should be a form. external-format should be an external-format object or symbol naming an external-format.

The char-to-octets macro expands to the macro stored in the char-to-octets-macro slot of the external-format named by name. See the description of def-char-to-octets-macro for descriptions of the macro's expansion as well as of the get-next-char, put-next-octet, and external-format arguments.

Users generally do not need to invoke the char-to-octets macro. In most cases, it is more convenient to use string-to-octets.

Examples:

    ;; Ensure utf8 conversion macros are available by explicitly loading the
    ;; external-format definition.  This suppresses the macro removal
    ;; optimizations that may occur when external-format is autoloaded.
    ;;
    (let ((*modules* (remove "ef-utf8" *modules* :test #'string-equal)))
      (require "ef-utf8"))

    (let ((utf8-vector (make-array 10
                       :element-type '(unsigned-byte 8)
                       :initial-element 255))
          (state nil)
          (str "hello"))
      (do ((s 0 (1+ start-s))
           (start-s 0 s)
           (v 0))
          ((>= s (length str)) utf8-vector)
          ;; :utf8-base is (crlf-base-ef :utf8)
          (char-to-octets :utf8-base (prog1 (schar str s) (incf s)) state
                  :put-next-octet (lambda (b)
                         (setf (aref utf8-vector v) b)
                         (incf v)))))

           ==> #(104 101 108 108 111 255 255 255 255 255)

See iacl.html for more information on international character support in Allegro CL.

# charpos

Function, excl package

Arguments: &optional output-stream

For a Gray stream, charpos calls stream-line-column.

Otherwise:

The output line-character-position may be tracked on a per-character basis, or it may be calculated when needed. If for any reason the charpos cannot be determined it is deemed to be `nil`.

If the stream tracks charpos, the current value is returned as the result of this function. Otherwise, the calculation is performed and the result returned.

See Details of stream-line-column and charpos in streams.html. See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# char*-strlen

Function, excl package

Arguments: address &optional aligned

Returns the length of the C string located at address. This function is useful when calling char*-to-string with the optional string argument specified. Since the length of the Lisp string provided as the receptacle of the C string is not modified, you may not know how much was copied from the C string without the aid of this function.

If the optional aligned argument is true, then address is an aligned address. Aligned addresses are returned by functions like lispval-to-aligned-malloc-address.

See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.

# check-system-constants

Function, excl package

Arguments: &optional errorp

System constants (`nil` and `t` currently) are checked for correctness (e.g. the car and cdr of `nil` are `nil`, the symbol-value of `nil` and `t` are themselves). If these constants are correct, `nil` is returned. Otherwise, the first value found is fixed up, and if errorp is true (the default value), error is called and the bad value that was found and fixed is described. If errorp is false, then instead of calling error, two values are returned:

1. a symbol which describes the bad value found.

2. a representation of the bad value. This could be just a regular Lisp object, or it may be a non-lisp-value struct with the address of the value contained as the addr slot of the struct. Note: if the :frame module is not currently loaded into the Lisp (which would happen if the `:include-tpl nil` option is given to build-lisp-image or generate-application) then if the bad-value is not a valid Lisp object the value `:foreign-value` is returned.

Note 1: An internal version of this function is called at the beginning of error and cerror. If finer control is desired, user code can call this function anywhere. The purpose of exporting this function is so that if some user code is trashing `t` or `nil`, and the offending code can't be easily found, calls to this function can be judiciously placed so as to isolate the offending code at run-time. Often these trashes are not discovered until the offending code is already no longer on the stack, so honing in on the offending code can be aided with this function.

Note 2: If multiple constants are damaged since the last time checked, only one will be chosen for fixup. Although it is not likely for multiple constants to be damaged, the call to error by the validation will then recurse on this function and eventually find all bad values that are tested by this function.

See damaged-system-constant-error in excl-classes.html for a description of the error that is signalled by this function.

# chdir

Function, excl package

Arguments: &optional directory

The `:osi` module has additional functionality relating to file handling. The symbol `excl:chdir` is exported from the new `excl.osi` package (as well as from the `excl` package). See OSI file handling functionality in os-interface.html.

This function is designed to mimic the UNIX/DOS cd utility. directory, if supplied, must be a pathname or sting naming a directory (it cannot name a file). Assuming it exists, that directory will become the current working directory. If the directory is relative, the new directory is determined relative to the current working directory (as returned by current-directory). If directory is a string and does not contain a trailing / (so "/usr/tmp" rather than "/usr/tmp/" -- backslashes can be used when on Windows), it is filled in automatically.

If you happen to have the pathname of a file, applying either path-namestring or path-pathname to it will return a value suitable as an argument to chdir:

    (setq path (pathname "/net/gemini/home/dm/xml-fns.cl"))
    (chdir path) -> ERROR
    (chdir (path-pathname path)) RETURNS "/net/gemini/home/dm/"
    (chdir (path-namestring path)) RETURNS "/net/gemini/home/dm/"

This function does not modify the value of *default-pathname-defaults*. Therefore, after calling this function, it is likely that the current directory, as returned by current-directory, will be differrent from the directory specified in *default-pathname-defaults*. The related top-level command :cd does modify the value of *default-pathname-defaults*. The following form modifies both the current directory and *default-pathname-defaults*:

    (setf *default-pathname-defaults* (pathname (chdir directory)))

Because of a mismatch between UNIX and Common Lisp interpreting of strings naming directories, string arguments are handled specially, as we describe now. The following table shows the behavior of chdir given various values of pathname:

1. pathname is not specified
   - Action by chdir: change to the current user's home directory. (See What user-homedir-pathname does on Windows in implementation.html for a discussion of what a home directory means on Windows.)
2. pathname is a pathname object naming a directory
   - Action by chdir: extract the directory component of the pathname (translating first if it is a logical pathname). Change to that directory. Relative pathnames are resolved with respect to the current working directory (as returned by current-directory). This will not work is the pathname object names a file.
3. pathname is a string containing a /, : (colon), or ; (semicolon) naming a directory pathname (perhaps missing a final /)
   - Action by chdir: convert to a pathname object, then continue as specified by item (2). See Note 1 below.
4. pathname is a string without a /, : (colon), or ; (semicolon).
   - Action by chdir: add a / to the end of the string, convert to a pathname object, then continue as specified by item (2). See Note 1 below.

Note 1. A / is added to the end of a string that may contain a /, ;, or : but does not end in a / in order that `(chdir "tmp")` will work as `cd tmp` does in UNIX and DOS: change to the tmp subdirectory of the current directory. Also `(chdir "/usr/tmp")` will work as `cd /usr/tmp` does, change to the tmp subdirectory of the /usr/ directory. Following the ANSI CL spec, `(make-pathname :directory "tmp")` creates the absolute pathname object with namestring "/tmp/" while `(make-pathname :directory "tmp/")` creates the relative pathname with namestring "tmp/". It is the second that follows the UNIX paradigm. Appending a / guarantees that effect. This means the directory argument cannot name a file. If there is a file named tmp in the /usr/ directory, when `(chdir "/usr/tmp")` adds a trailing /, it will then error because /usr/tmp/ does not name a directory.

Examples. The current Unix user's home directory is /usr/tech/doe/. The directory /usr/tech/doe/tmp/ exists. The Allegro directory for the Lisp image is assumed to be /usr/local/acl/ though the actual value contains by default the release number and is in any case user-settable.

    user(15): (chdir) ;; no argument: change to user home directory
    "/usr/tech/doe/"
    user(16): (chdir "sys:")
       ;; a string naming a logical pathname which translates
       ;; to the Allegro directory (the value you see may be different
       ;; usually containing the release number).
    "/usr/local/acl/"
    user(17): (chdir)
    "/usr/tech/doe/"
    user(18): (chdir "tmp") ;; change to the tmp/ subdirectory
    "tmp/"
    user(19): (chdir (make-pathname :directory "tmp"))
       ;; The absolute directory
    "/tmp/"
    user(20): (chdir)
    "/usr/tech/doe/"
    user(21):

chdir returns the namestring of the directory component of the pathname changed to. This may not be the new current directory (as returned by current-directory).

Warning about interaction between chdir and foreign loading and dumplisp: if the command line used to start Lisp identified the Allegro CL image with a relative pathname (`./mlisp`, for example), you cannot do the first load of foreign code or dump an image with dumplisp after changing the directory with this function. Therefore, if you started Lisp with a relative pathname, do at least one foreign load before calling chdir and do not call dumplisp after calling chdir. (The problem is that when doing the first foreign load or a dumplisp, Lisp needs to examine the running image, which it finds by examining the command line that invoked the image. If Lisp is identified on the command line with a relative pathname and the current directory has been changed, the relative pathname merged with the current directory no longer points to the running image. Changing back to the original current directory fixes the problem.)

See :cd, :popd, and :pushd, which also change the current directory. See also os-interface.html for general information on the interface between Allegro CL and the operating system.

# clean-system

Generic Function, excl package

Arguments: system &key silent simulate &allow-other-keys

This generic function removes the product files of the modules in system.

The value of the silent keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means do not print anything while performing the operation. A true value of simulate overrides `:silent t`. If the value of the silent keyword argument is `t` (and simulate is `nil`), then the functionality is similar to make -s.

The value of the simulate keyword argument can be `t` or `nil`. `t` means print the list of actions that would be taken if the operations were to be performed at this time, but do not actually perform the operations. The value `nil` means perform the actions. If the value of this keyword argument is `t`, then the functionality is similar to make -n.

Although the home package of the symbol naimg this operator is the excl package, it is also exported from the defsystem package.

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# code-to-utf16-char

Function, excl package

Arguments: code

The code argument must be a fixnum. It is interpreted as a Unicode character code and converted into the UTF-16 encoding used internally in the Allegro CL string representation.

Returns two values:

1. A character and `nil`: if code is smaller than #x10000.

2. A high-surrogate-character and a low-surrogate-character if code is in the high Unicode range.

3. `nil` and `nil` if code is not a valid Unicode code point.

See iacl.html for more information on international characters and external formats.

# compile-advice

Function, excl package

Arguments: fname

Starting in Allegro CL release 6.0, the new fwrapper facility, described in fwrappers-and-advice.html, replaces the advice facility, and continued use of the advice facility is deprecated.

fname must be a function name (it is typically a symbol). Calling this function causes all advice currently defined on fname to be compiled. The advice is not changed in any other way.

See also fwrappers-and-advice.html for general information on the new fwrapper facility and the older, now deprecated, advice facility in Allegro CL.

# compile-file-if-needed

Function, excl package

Arguments: input-filename &rest allargs &key force-compile

Compiles (with compile-file) input-filename if

1. there is no compiled version of that file, or

2. the compiled version is older than input-filename, or

3. the force-compile keyword argument is specified true.

All arguments acceptable to compile-file can also be specified to this function. input-filename must be a string naming a file or a pathname object identifying a file.

compile-file-if-needed returns what compile-file returns if a compilation is actually done (that is, it returns three values). If no compilation is done, compile-file-if-needed returns the name of the compiled file as a single return value. To determine whether a compilation was in fact done, capture the returned values in a list (with, say, multiple-value-list) and see whether its length is 3 (compilation performed) or 1 (no compilation performed).

See compiling.html for general information on compiling.

# compile-lambda-expr-in-env

function, excl package

Arguments: lambda env

compile-lambda-expr-in-env is like compile but compiles its argument lambda expression in the specified environment and returns a compiled function object. lambda must be a lambda expression. env must be an environment object such as returned by make-compilation-unit-environment or augment-environment.

CL semantics are preserved during compilation, except that declarations such as optimize are not processed by the interpreter and therefore cannot be retrieved from the environment. The optimization settings seen by compile will be that in the global environment.

This function is used by ensuring-compiled-body. That macro is more suitable for user code than this rather low-level function.

See Compiling individual forms or groups of forms in compiling.html.

# compile-re

Function, excl package

Arguments: string &key case-fold ignore-whitespace multiple-lines single-line (return :unknown) back-end

Given a string that describes a regular expression, creates a compiled regular expression object.

The keyword argument case-fold controls whether the result matcher becomes case-sensitive or not by default. `nil`, the default, means case-sensitive, true means case-insensitive. (The 'i' flag of Perl RE).

If the keyword argument ignore-whitespace is given and true, whitespace characters within string are ignored as regexp spec. (The 'x' flag of Perl RE).

If the keyword argument multiple-lines is given and true, the created matcher recognizes multiple lines, i.e. ^ and $ matches beginning and end of individual lines. Without this argument, ^ and $ matches only beginning and end of the input string. (The 'm' flag of Perl RE).

If the keyword argument single-line is given and true, '.' will match any character including newline. Without single-line, '.' matches any character except newline. (The 's' flag of Perl RE).

The keyword argument return specifies how the created matcher returns the result. If it is `nil`, the matcher will return only a boolean value which indicates whether the input string matches the regexp or not. If it is `:string`, the matcher also returns the substrings of the matched region and all submatches of the input string. If it is `:index`, the matcher returns pairs of start and end indices of the matched region and all submatches. If the keyword argument is not given at compile time, the matcher is created so that it will accept return keyword argument at the matching time; however, compile-re will generate more efficient code if it knows the return type at the compile time. (The default is `:unknown`, which has the effect just described.)

The back-end keyword argument can only have its default value `regexp:vm` and should not be specified. Additional allowable values may be added later. (The value `regexp:native`, incorrectly mentioned as an allowable value in earlier documentation versions, is not supported at this time.)

The symbol naming this operator is also exported from the regexp package.

See The new regexp2 module in regexp.html for further information on this function and the regexp2 module.

# compile-regexp

Function, excl package

Arguments: string

Compiles the regular expression in string into a regular expression object and returns that object. If there are syntax errors in string, an error will be signaled.

Use of this function is deprecated and it is maintained for backward compatibility only. See regexp.html for information on the newer regular expression compiler in Allegro CL. You should use the functionality described there instead of this function is new code.

# compile-system

Generic Function, excl package

Arguments: system &key recompile no-warn reload silent simulate include-components module-keys

Note: if recompile is `nil` and not all files are in fact recompiled, unnecessary warnings about undefined functions may be signaled. For example, if a module contains file1 and file2, and file1 defines function bar which calls foo and file2 defines function foo and function baz which calls bar, and neither file has been loaded into Lisp, recompiling the module when file1 is up to date and file2 is not will signal a warning that function foo is undefined. Similarly recompiling when file2 is up to date and file1 is not will signal that bar is undefined. Specifying `:recompile t` will supress such warnings.

This generic function compiles (if necessary) each module in system. This function returns `t` if any actions are necessary to bring system up-to-date. If no actions are necessary, then this function returns `nil`.

The value of the recompile keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means recompile all the files even if an up-to-date compiled file already exists. It is recommeded that the value be specified as `t`. Recompiling all files has benefits beyond the supression of bogus warnings mentioned above.

The value of the no-warn keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means do not print warnings of any kind during compilation of the system.

The value of the reload keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means that when a dependency requires that a module be loaded, the module is loaded even if the most up-to-date version has been previously loaded.

The value of the silent keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means do not print anything while performing the operation. A true value of simulate overrides `:silent t`. If the value of this keyword argument is `t`, then the functionality is similar to make -s.

The value of the simulate keyword argument can be `t` or `nil`. `t` means print the list of actions that would be taken if the operations were to be performed at this time, but do not actually perform the operations. If the value of this keyword argument is `t`, then the functionality is similar to make -n.

The value of the include-components keyword argument can be `t` or `nil`. The default value is `t`, which means perform a compile-system operation on all component systems of system. A value of `nil` means ignore component systems.

The value of the module-keys keyword should be a list of keywords and arguments to be passed as a keyword list to the compile-module-action method for each module-group.

Although the home package of the symbol naimg this operator is the excl package, it is also exported from the defsystem package.

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# compiler-let

special-operator, excl package

Arguments: (&rest bindings) &body body

This is the compiler-let from the first edition of Steele 'Common Lisp: the Language'. It establishes the bindings, which are (variable value) lists, or just variables, which are bound to `nil`. (When run interpreted, the bindings are implicitly declared special.) This special form is typically used in code which is being compiled to affect the compilation.

# compose-encapsulating-streams

Function, excl package

Arguments: stream format

This function is called for its side-effects. Its return value is unspecified. This function configures the stream by adding or subtracting as many composing-stream encapsulations as are necessary to make it appropriate for the external-format specified by the format. This function will not be called directly. It is needed for lower-level things, like writing a setf method for stream-external-format on custom stream classes. (If you simply want to change the external format of an instance of an existing stream class, you simply setf its stream-external-format.)

This function configures the stream by adding or subtracting as many composing-stream encapsulations as are necessary to match the shape of the external-format. An encapsulating-stream-based composing format (see Composed external formats in iacl.html) has exactly one base stream and zero or more encapsulating composer formats. As of the 6.1 release, zero or one encapsulating composer formats can be used, and only `:e-crlf` and `:e-crcrlf` composer formats have been created, but the potential exists for chains of encapsulations, including ligatures and other character-translation mappings.

If the format argument's name (as returned by ef-name) is atomic (i.e. not a list), the external-format is a base format and the stream is configured with no composing-streams encapsulating it. If the name is a list, then the format is an encapsulating format, and the stream is configured with as many composing-streams as there are composer formats. In the case of `(:e-crlf :latin1-base)`, for example, there is one composer format, `:e-crlf`, and thus the stream will be configured to have one composing-stream associated with it.

Usually, stream encapsulations are accomplished by wrapping the encapsulator around the encapsulatee. However, this would force the user to use a different stream than the one which was originally opened, and the encapsulation as a whole would not have the same class/type as the original, nor would it have the same slots as the original stream, which would have been buried somewhere in the encapsulation chain. Therefore, when encapsulations are made for external-formats, the base stream stays on top, and retains its identity, class, and most of its slots, and the composing-stream encapsulations are instead placed within the base-stream.

You must load the `:iodefs` module to use this function. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html.

# compose-external-formats

Function, excl package

Arguments: name1 name2 &optional name

All arguments should be symbols.

compose-external-formats creates a new external-format with name name, or, if name is `nil`, a keyword symbol whose symbol-name is the concatenation of names name1 followed by #- followed by name2. The composed external-format is returned.

name1 is called the composer and name2 is called the composee. External formats have slots for the composer and composee. If the value in those slots is `nil`, the external format is not composed. The functions ef-composer-ef and ef-composee-ef access those slots. The function composed-external-format-p returns true or false as its argument is or is not a composed external format.

The `chars-to-octets` and `octets-to-char` macros of the composed external-format are formed as if by evaluation of forms equivalent to the following:

    (def-char-to-octets-macro name (char state
                    &key put-next-octet external-format)
       `(chars-to-octets NAME1
                 ,char
                 ,state
               :put-next-octet ,put-next-octet
               :external-format NAME2))

    (def-octets-to-chars-macro name (state
                     &key get-next-octet external-format)
       `(octets-to-char NAME1
                ,state
                :get-next-octet ,get-next-octet
                :external-format NAME2))

See iacl.html for more information on international character support in Allegro CL.

# compose-octet-array-fn

Function, excl package

Arguments: &rest parts

This function is similar to the compose-octet-array macro, but the arguments are all evaluated, and each must evaluate to a string, character, integer, or a sequence of these.

See iacl.html for more information on international characters and external formats.

# compose-octet-array

Macro, excl package

Arguments: &rest parts

This macro implements a convenient notation for representing a vector of octets in a source file. The value of the macro call is a vector of type `(array * (unsigned-byte 8))` initialized to all the octets specified in the arguments with the forms:

- string: The character code of each character in the string specifies one octet in the result vector.

- A character: The character code specifies the octet.

- An integer: The number specifies the octet.

- `:[`: The arguments following this argument up to an occurrence of `:]` are converted to hexadecimal numbers that specify each octet.

- A symbol: The symbol is treated as the name of a character that specifies the octet.

- `:eval`: The following argument is evaluated at run time. The value must be a sequence of values allowed as arguments to compose-octet-array-fn.

Each octet value must be in the octet value range. If not an error is signaled.

If there are no occurrences of the `:eval` argument, the result emitted by the macro is a constant vector. If the `:eval` argument is used, the macro emits a call to the compose-octet-array-fn function.

See iacl.html for more information on international characters and external formats.

# compose-string-fn

Function, excl package

Arguments: &rest args

This function is similar to the compose-string macro but the arguments must evaluate to strings, characters, or integers.

See iacl.html for more information on international characters and external formats.

# compose-string

Macro, excl package

Arguments: &rest args

This macro implements a convenient notation for representing a character string containing characters that may be difficult to edit into a source code file. The value is a string that is concatenated from the string form of the arguments:

- A string: The string is inserted verbatim into the result string.

- A character: The character is inserted verbatim.

- An integer: If the integer is in the 16-bit Unicode range, insert the corresponding Unicode character. If the integer is in the high Unicode range, insert the two corresponding surrogate characters. Otherwise signal an error.

- `:[` -- The arguments following this argument up to an occurrence of `:]` are converted to hexadecimal character codes and the corresponding characters are inserted.

  The sequence `:[ aa bb 20 e3b4 10a234 :]` denotes the 6 characters: four with character codes #xaa #xbb #x20 #xe3b4 and the two surrogate characters needed to represent the Unicode code point #x10a234.

- `:eval`: The following argument is an expression that will be evaluated to compute a string or character component of the result string.

- A symbol: If the name of the symbol is a single character, that character is inserted; otherwise, the symbol is treated as the name of a character and the named character is inserted.

If there are no occurrences of the `:eval` argument, the result emitted by the macro is a constant string. If the `:eval` argument is used, the macro emits a call to the compose-string-fn function.

See iacl.html for more information on international characters and external formats.

# composed-external-format-p

Function, excl package

Arguments: external-format

This function returns true for external-format if and only if the argument is a composed external-format. See compose-external-formats.

See iacl.html.

# concatenate-system

Generic Function, excl package

Arguments: system destination &key [keyword arguments for system use only]

This generic function concatenates the fasl files of the modules in system into destination. This is useful for creating one fasl from which the entire system can be loaded. Such a file can then be placed in a library or distributed.

Note that fasl files can be concatenated with Operating System tools such as the UNIX cat command. (Indeed, concatenate-system works as if it used cat, performing a byte-for-byte copying of the files with no pre/postpended or intervening headers or noise.

When concatenated fasl files are loaded, the four variables bound by load (*package*, *readtable*, *load-pathname*, and *load-truename*) are bound only once around the entire operation, not around each component file.

Concatenation of fasl files has no effect whatever on the source file information recorded for definitions in the fasl files since source-file information is entirely determined at compile-file time. (See *source-pathname*.)

Although the home package of the symbol naming this operator is the `excl` package, it is also exported from the `defsystem` package.

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# console-close

Generic Function, excl package

Arguments: console-check

Methods on this generic function are called when the close box on the Console window in Allegro CL on Windows is clicked and that action causes Lisp or the Lisp application to exit. Pressing the Alt-F4 keys when the console window is selected and choosing Exit Lisp from the tray icon menu are equivalent actions and trigger the methods whenever clicking the close button would.

See the function console-control, which allows you to specify what action clicking the close box should have (exit the application, minimize the console, hide the console, or nothing).

console-close methods are primarily intended to affect the action when the close box is clicked for the purpose of exiting Lisp, particularly when using the Integrated Development Environment or an application developed for Windows where the console is used. (You might want to ensure files are saved, or you might want to display a confirmation window, etc.)

On Unix, there is no Console window and the default method simply calls exit.

On Windows, the default action of console-close is to call `(excl::mp-safe-exit 0)`.This causes Lisp to exit, unless errors occur during the stack unwinding process preceding the exit. If the exiting process gets hung up due to errors, then the user can try to close the Console again and this time the whole Lisp process will exit without trying to clean up the Lisp threads.

For example, the following code will cause the close of the Console to be ignored:

    (defmethod excl:console-close :around (x)
     (setf (sys::memref-int x 0 0 :unsigned-natural) 1))

An application can put an `:around` or `:before` method on console-close to change the default behavior. The argument passed in is the address of the flag which determines whether to call console-close the next time the Close button is clicked.

The default value is zero, meaning don't call console-close again. Set the flag to a non-zero value to cause console-close to be called again.

# console-control

Function, excl package

Arguments: &key tray tray-exit title close maximize minimize size show

This function is useful on Windows only. The function is not defined on UNIX and Linux (the symbol exists but does not have a function definition). This function controls the behavior and features of the program icon in the Windows system tray.

This function only works if the Lisp or Lisp application was started with the Lisp console. If Lisp was started with the `+c` command-line argument (meaning no console), console-control has no effect. See Command line arguments in startup.html for details of command-line arguments. Note that arguments other than +c allow you to have the console created but hidden. The Common Graphics project system allows you to specify no console: see the Enable Debugging of Runtime Errors checkbox on the Project Manager Build Tab.

The keyword arguments are as follows. They are orthogonal, meaning that any can be specified to any value regardless of the values of the other arguments (although specifying `:tray nil` and `:tray-exit t` is illogical, since there is no tray icon to use to exit). A call that specifies no value for a keyword argument does not change the current value (does not, that is, cause it to revert to some initial value or default).

- `:tray`: the value can be `nil`, meaning do not show the tray icon, or `t`, meaning do show it.

- `:tray-exit`: if `nil`, you cannot exit Lisp (or the Lisp application) from the tray icon. If `t`, you can. There is an Exit Lisp menu item on the right button menu on the tray icon. That item will still be there, but the submenu item Yes, Exit Lisp will be inactive.

- `:title`: the value, if one is specified, must be a simple string. That string will be the console title (instead of the usual one which starts "Allegro Common Lisp Console ...")

- `:close`: specifies the action when the close button on the console is clicked. The value can be: `:minimize` (close button, menu and Alt-F4 minimize the console); `:hide` (close button, menu and Alt-F4 hide the console); `nil` (close button, menu and Alt-F4 are not active); and `t` (close button, menu and Alt-F4 behave normally, i.e. close the running Lisp or Lisp application). When t, see also console-close.

- `:maximize`: provides control of the console window maximize button and the maximize item on the system menu on the window title bar. The possible values are `nil`, which disables the button and menu item), and `t` (the default), which enables the button and menu item.

- `:minimize`: provides control of the console window minimize button and the minimize item on the system menu on the window title bar. The possible values are `nil`, which disables the button and menu item; `t` (the default), which enables the button and menu item; and `:hide`, which causes clicking on the minimize button or choosing the menu item to hide rather than minimize the console window.

- `:size`: the value should be a positive integer greater that 1000 (but substantially higher values are typical). It specifies the size, in bytes, to which the console edit control (i.e. text in the console) can grow. After the console edit control hits this size, it is truncated. This value is also set by the `+<number>` command-line argument (that is, something like +50000 on the command line). It can reset with this function. If unspecified on the command-line, the value defaults to 100,000 bytes on versions of Windows other than 98 and Me. the size is 25,000 on Windows 98 and Me and, on those platforms, cannot be changed. This argument and the associated `+<number>` command-line argument are ignored on Windows 98 and Me. See Command line arguments in startup.html for a list of command-line arguments accepted by Allegro CL.

- `:show`: the value can be a keyword or `t` or `nil`, indicating a win32 API action as indicated in the table:

  Value of :show | win32 API constant
  --- | ---
  nil, :hide | SW_HIDE
  t, :normal, :shownormal | SW_SHOWNORMAL (aka SW_NORMAL)
  :showminimized | SW_SHOWMINIMIZED
  :maximize, :showmaximized | SW_SHOWMAXIMIZED (aka SW_MAXIMIZE)
  :shownoactivate | SW_SHOWNOACTIVATE
  :show | SW_SHOW
  :minimize | SW_MINIMIZE
  :showminnoactive | SW_SHOWMINNOACTIVE
  :showna | SW_SHOWNA
  :restore | SW_RESTORE
  :showdefault | SW_SHOWDEFAULT

  See the WinAPI documentation for details of the various actions. We encourage you to test your choices thoroughly because some find the Windows documentation somewhat sparse, and you may not be able to determine the differences among the various options by documentation alone.

# convert-mixed-case-symbols

Function, excl package

Arguments: bool &key push pop

This function affects the behavior of set-case-mode to convert, or not, symbols with mixed upper and lower case characters when it is doing a symbol name conversion operation. It also affects how symbols are created during fasl file reading. If called with the required argument `t`, set-case-mode will convert mixed case symbols. If this function is called with the required argument `nil`, set-case-mode will not convert mixed-case symbols.

The initial value returned by this function, starting in release 6.0, is `t`. Note that in releases prior to 6.0, the initial value was `nil`.

Symbol name conversion is done for two reasons:

1. When a call to set-case-mode requires it (when going between upper case and lower case preferred modes).
2. When reading a fasl file compiled in a case mode other than the current case mode, and those case modes differ in whether upper case or lower case was the preferred mode.

convert-mixed-case-symbols returns the previous value of this switch.

Note that it is not easy to determine the currently in force value using this function. To see the current value, look at the value of the unexported variable `excl::*convert-mixed-case-symbols*`. Do not set the value of that variable except by using this function, however.

This function is used automatically during `(require :winapi)` and `(require :ole)` (both on Windows only) since these modules intentionally contain symbols with mixed case.

The keyword arguments can be used to manage a private stack of values for this function (the stack itself is not accessible directly). If the keyword argument `:push` is given a true value, then the old value (i.e. the value when this function is called) is pushed on the private stack kept for this function. The call `(excl::convert-mixed-case-symbols nil :pop t)` restores the setting to the old value at the top of the stack (and pops that value off the saved values stack). When pop is specified true, the required argument is ignored (since the new value comes off the stack).

See also case.html and *current-case-mode*, *ignore-package-name-case*, and set-case-mode.

# copy-directory

Function, excl package

Arguments: from-dir to-dir &key quiet &allow-other-keys

Recursively copy the contents of from-dir to to-dir. If to-dir does not exist, then it is created. copy-file is used to copy the files. Keyword arguments to copy-file are accepted by copy-directory and passed on. The copy-file arguments only affect the copying of files. They do not affect copy-directory's work of copying the directory (or subdirectories). See the description of copy-file for the list of its keyword arguments.

See also os-interface.html for general information on the interface between Allegro CL and the operating system. See section Filesystem manipulation functions in that document for information on file and directory information and manipulation functions in Allegro CL.

# create-newline-ef

Macro, excl package

Arguments: &key name base-name nicknames

This macro is used for its side effect of creating new external formats. name should be a symbol. base-name should be an external-format. nicknames should be a list of symbols.

This macro creates two new external-formats. The newly created external-formats are effectively the results of executing the following two forms (which call compose-external-formats):

    (compose-external-formats :crlf base-name)
    (compose-external-formats :crcrlf base-name)

If Allegro CL is running on the Microsoft Windows platform, the name and nicknames arguments are combined with the list of existing nicknames for base-name into a single list and set as the nicknames for the result of the first form above.

If Allegro CL is running on the Microsoft Windows platform, and Allegro CL is started with the -crcrlf flag, then the name and nicknames arguments are combined with the list of existing nicknames for base-name into a single list and set as the nicknames for the result of the second form above.

If Allegro CL is running on a Unix platform, then the name and nicknames arguments are combined with the list of existing nicknames for base-name into a single list and set as the nicknames for base-name.

Examples:

    (def-external-format :test-base)

    (create-newline-ef :name :test
               :base-name :test-base
               :nicknames '(:test-nickname))

    ;; On Windows
    (find-external-format :test) -> #<external-format :crlf-test-base>

    ;; On Unix
    (find-external-format :test) -> #<external-format :test-base>

See iacl.html for more information on international character support in Allegro CL.

# critical-section

macro, excl package

Arguments: (&key block non-smp) &body body

This macro expands into code that uses a unique basic-lock associated with the expansion to control execution of the body code. Only one process at a time can acquire ownership of the lock and execute the forms in body. Ownership of the lock is relinquished when control leaves body by falling through or by non-local exit. The result of evaluating the critical-section code is the result of the last form in body.

The arguments are:

- `:block`: used for special internal functions. Users should not specify a value for this argument.

- `:non-smp`: what code to generate in a non-smp lisp. Legal values are:

  - `:without-scheduling`: to get the equivalent of `(mp:without-scheduling . body)`

  - `:without-interrupts`: to get the equivalent of `(excl:without-interrupts . body)`

  - `:atomically`: to get the equivalent of `(excl::atomically . body)`

  - [omitted]: to get object-locking code like SMP. This may be inefficient or even problematic in a non-SMP Lisp.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# crlf-base-ef

Function, excl package

Arguments: external-format-or-name

find-external-format is applied to the argument, so if the argument is the name of an external format (such as `:latin1`), then the associated external format is returned.

If the resulting external format is a composed external-format with the composer being either the crlf external-format or the crcrlf external-format or the cr external-format, then the composee is returned; otherwise the original external-format is returned.

See Composed External-Formats in iacl.html. See iacl.html in general for information on international character support in Allegro CL.

# current-directory

Function, excl package

Arguments: &optional use-cache drive

Return a pathname with the directory component holding the current directory. Note that when processing pathnames and filling in missing components (for example, when a filename is passed, as an argument to load), the system typically uses the value of *default-pathname-defaults* instead of the current directory as returned by this function. The value of *default-pathname-defaults* may not be the same as the value returned by this function. chdir modifies the current directory (what is returned by this function) but does not modify *default-pathname-defaults*. In contrast, :cd modifies both.

On UNIX, current-directory caches information about the current directory in each call. If the use-cache optional argument is non-`nil` and you call current-directory from the same directory, current-directory does not compute the current working directory, it just returns the previous value (so the returned value will be eq to the previous returned value). It checks that the directory has not changed by comparing the inode of (and other relevant data about) `.` to cached information, and returning the cached pathname value if the comparisons are true. use-cache is accepted but ignored on Windows.

The drive optional argument should only be specified in Windows. Its value should be a string naming a drive (like "d:" or "d"). If given, current-directory will return the current working directory on that drive. If `nil`, current-directory will return the current working directory on the current drive. The current drive is the drive letter of the pathname in *default-pathname-defaults* or the last call to chdir that specified a path that contained a drive letter.

See :pwd and :dirs, which both print the current directory. See also os-interface.html for general information on the interface between Allegro CL and the operating system.

# current-thread

Function, excl package

Arguments:

This function returns the thread object which is currently running. It is not setf'able.

# damaged-system-constant-error-code

Generic Function, excl package

Arguments: condition

Returns the code value in the condition. The meaning of the code is maintained by the damaged-system-constant-error condition - see its description for current interpretations.

# date+

Function, excl package

Arguments: ut number-of-days &key work-days

Release 10.1 and later only. The value returned by date+ and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

This function returns a universal time whose year/month/date is number-of-days later than the year/month/date of ut. ut must be a non-negative integer and is interpreted as a universal time (see get-universal-time). If work-days is specified true, then Saturdays and Sundays are not counted in the calculation. The hour, minute, and second of the returned universal time may be different from the hour, minute, and second of ut.

So if ut falls on a Friday, `(date+ ut 2 :work-days nil)` falls on a Sunday and `(date+ ut 2 :work-days t)` falls on a Tuesday. See Examples below for more examples.

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    cl-user(106): (setq ut-fri (encode-universal-time 0 0 12 1 12 2017))
    3721104012  ;; Friday, December 1, 2017
    cl-user(107): (setq ut-sat (encode-universal-time 0 0 12 2 12 2017))
    3721233600  ;; Saturday, December 2, 2017
    cl-user(110): (day-number ut-fri)
    335
    cl-user(111): (setq ut-fri-plus-3 (date+ ut-fri 3))
    3721363212
    cl-user(112): (day-number ut-fri-plus-3)
    338  ;; 3 days after Friday, December 1, 2017
    cl-user(115): (setq ut-fri-plus-3w (date+ ut-fri 3 :work-days t))
    3721536012
    cl-user(116): (day-number ut-fri-plus-3w)
    340  ;; 5 days after Friday, December 1, 2017 becaue Saturday and Sunday
         ;; are not counted
    cl-user(117): (day-of-week ut-fri-plus-3w)
    2  ;; Wednesday
    cl-user(118): (setq ut-sat-plus-1 (date+ ut-sat 1))
    3721320000
    cl-user(119): (day-of-week ut-sat-plus-1)
    6  ;; Sunday
    cl-user(121): (setq ut-sat-plus-1w (date+ ut-sat 1 :work-days t))
    3721406400
    cl-user(122): (day-of-week ut-sat-plus-1w)
    0  ;; Monday
    cl-user(123):

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# date=

Function, excl package

Arguments: ut1 ut2

Release 10.1 and later only. The value returned by date= and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

ut1 and ut2 should be non-negative integers and are interpreted as universal times (see get-universal-time). If the date of ut1 is the same as the date of ut2, this function returns `t`. Otherwise it returns `nil`. The date is determined by the date, month, and year obtained by applying decode-universal-time to a universal time (that is, the fourth, fifth, and sixth values returned by decode-universal-time.)

That is each time is decoded (with decode-universal-time) using the system timezone, and the year (sixth value), month (fifth value) and date (fourth value) are compared. `t` is returned of the year, month, and day are the same for both ut1 and ut2, `nil` is returned otherwise.

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    cl-user(32): (setq ut1 (encode-universal-time 0 0 8 4 12 2017))
    3721392000             ;; December 4, 2017
    cl-user(33):
    cl-user(33): (setq ut2 (encode-universal-time 0 0 20 4 12 2017))
    3721435200             ;; also December 4, 2017
    cl-user(34): (date= ut2 ut1)
    t
    cl-user(35): (date= ut1 ut2)
    t
    ;; True for both argument orders because the same day

    cl-user(36): (setq ut3 (encode-universal-time 0 0 8 4 11 2017))
    3718796400             ;; November 4, 2017
    cl-user(37): (date= ut1 ut3)
    nil
    cl-user(38): (date= ut3 ut1)
    nil
    ;; Different days false for both argument orders

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# date/=

Function, excl package

Arguments: ut1 ut2

Release 10.1 and later only. The value returned by date/= and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

ut1 and ut2 should be non-negative integers and are interpreted as universal times (see get-universal-time). This function returns the opposite of date= (`nil` when date= returns `t`, `t` when date= returns `nil`).

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    cl-user(32): (setq ut1 (encode-universal-time 0 0 8 4 12 2017))
    3721392000             ;; December 4, 2017
    cl-user(33):
    cl-user(33): (setq ut2 (encode-universal-time 0 0 20 4 12 2017))
    3721435200             ;; also December 4, 2017
    cl-user(34): (date/= ut2 ut1)
    nil
    cl-user(35): (date/= ut1 ut2)
    nil
    ;; False for both argument orders because the same day

    cl-user(36): (setq ut3 (encode-universal-time 0 0 8 4 11 2017))
    3718796400             ;; November 4, 2017
    cl-user(37): (date> ut1 ut3)
    t
    cl-user(38): (date> ut3 ut1)
    t
    ;; Different days so true for both orders of arguments

See also date=, which returs `t` when this function returns `nil` and vice versa. See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# date>

Function, excl package

Arguments: ut1 ut2

Release 10.1 and later only. The value returned by date> and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

ut1 and ut2 should be non-negative integers and are interpreted as universal times (see get-universal-time). If the date of ut1 is later than the date of ut2, this function returns `t`. Otherwise it returns `nil`. The date is determined by the date, month, and year obtained by applying decode-universal-time to a universal time (that is, the fourth, fifth, and sixth values returned by decode-universal-time.)

If ut1 is less than or equal to ut2, this function returns `nil` (as the date of ut1 must then be less than or equal to the date of ut2).

If ut1 is greater than ut2, then each time is decoded (with decode-universal-time) using the system timezone, and the year (sixth value), month (fifth value) and date (fourth value) are compared. `t` is returned if the year of ut1 is greater than the year of ut2, or, if they are the same, the month of ut1 is greater than the month of ut2, or, if they are also the same, the date of ut1 is greater than the date of ut2. If the year, month, and date are the same for ut1 and ut2, `nil` is returned.

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    cl-user(32): (setq ut1 (encode-universal-time 0 0 8 4 12 2017))
    3721392000             ;; December 4, 2017
    cl-user(33):
    cl-user(33): (setq ut2 (encode-universal-time 0 0 20 4 12 2017))
    3721435200             ;; also December 4, 2017
    cl-user(34): (date> ut2 ut1)
    nil
    cl-user(35): (date> ut1 ut2)
    nil
    ;; False for both argument orders because the same day

    cl-user(36): (setq ut3 (encode-universal-time 0 0 8 4 11 2017))
    3718796400             ;; November 4, 2017
    cl-user(37): (date> ut1 ut3)
    t
    cl-user(38): (date> ut3 ut1)
    nil
    ;; Different days so one direction true, the other false.

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# date>=

Function, excl package

Arguments: ut1 ut2

The value returned by date>= and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

This function returns `t` if either date> returns true or date= returns `t` and returns `nil` otherwise.

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    cl-user(32): (setq ut1 (encode-universal-time 0 0 8 4 12 2017))
    3721392000             ;; December 4, 2017
    cl-user(33):
    cl-user(33): (setq ut2 (encode-universal-time 0 0 20 4 12 2017))
    3721435200             ;; also December 4, 2017
    cl-user(34): (date>= ut2 ut1)
    t
    cl-user(35): (date>= ut1 ut2)
    t
    ;; The same day so equal dates

    cl-user(36): (setq ut3 (encode-universal-time 0 0 8 4 11 2017))
    3718796400             ;; November 4, 2017
    cl-user(37): (date>= ut1 ut3)
    t
    cl-user(38): (date>= ut3 ut1)
    nil
    ;; Different days so one direction true, the other false.

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# date<

Function, excl package

Arguments: ut1 ut2

The value returned by date< and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

ut1 and ut2 should be non-negative integers and are interpreted as universal times (see get-universal-time). If the date of ut1 is earlier than the date of ut2, this function returns `t`. Otherwise it returns `nil`. The date is determined by the date, month, and year obtained by applying decode-universal-time to a universal time (that is, the fourth, fifth, and sixth values returned by decode-universal-time.)

If ut1 is greater than or equal to ut2, this function returns `nil` (as the date of ut1 must then be greater than or equal to the date of ut2).

If ut1 is less than ut2 the difference is less than 90000, then each time is decoded (with decode-universal-time) using the system timezone, and the year (sixth value), month (fifth value) and date (fourth value) are compared. `t` is returned if the year of ut1 is less than the year of ut2, or, if they are the same, the month of ut1 is less than the month of ut2, or, if they are also the same, the date of ut1 is less than the date of ut2. If the year, month, and date are the same for ut1 and ut2, `nil` is returned.

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    cl-user(32): (setq ut1 (encode-universal-time 0 0 8 4 12 2017))
    3721392000             ;; December 4, 2017
    cl-user(33):
    cl-user(33): (setq ut2 (encode-universal-time 0 0 20 4 12 2017))
    3721435200             ;; also December 4, 2017
    cl-user(34): (date< ut2 ut1)
    nil
    cl-user(35): (date< ut1 ut2)
    nil
    ;; False for both argument orders because the same day

    cl-user(36): (setq ut3 (encode-universal-time 0 0 8 4 11 2017))
    3718796400             ;; November 4, 2017
    cl-user(37): (date< ut1 ut3)
    nil
    cl-user(38): (date< ut3 ut1)
    t
    ;; Different days so one direction true, the other false.

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# date<=

Function, excl package

Arguments: ut1 ut2

Release 10.1 and later only. The value returned by date<= and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

This function returns `t` if either date< returns true or date= returns `t` and returns `nil` otherwise.

## Examples

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    cl-user(32): (setq ut1 (encode-universal-time 0 0 8 4 12 2017))
    3721392000             ;; December 4, 2017
    cl-user(33):
    cl-user(33): (setq ut2 (encode-universal-time 0 0 20 4 12 2017))
    3721435200             ;; also December 4, 2017
    cl-user(34): (date<= ut2 ut1)
    t
    cl-user(35): (date<= ut1 ut2)
    t
    ;; True for both argument orders because the same day

    cl-user(36): (setq ut3 (encode-universal-time 0 0 8 4 11 2017))
    3718796400             ;; November 4, 2017
    cl-user(37): (date<= ut1 ut3)
    nil
    cl-user(38): (date<= ut3 ut1)
    t
    ;; Different days so one direction true, the other false.

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# day-difference

Function, excl package

Arguments: start end &key work-days

Release 10.1 and later only. The value returned by day-difference and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

start and end must be non-negative integers which are interpreted as univeral times (see get-universal-time). This function returns the number of days between start and end, completely ignoring the time of day portion of the time values. When start and end represent the same day, this function returns 0.

If work-days is `nil` (the default), all days are considered. When work-days is true, Saturdays and Sundays are not counted.

If work-days is `nil`, the start date is always included and the end date is never included in the returned count, and the return value for consecutive days is 1.

If work-days is true, the situation is more complicated. The start date is included if it is a weekday but not if it is a Saturday or Sunday. The end date is again never included. The return value for consecutive days is 0 if start is a Saturday or Sunday and is 1 if start is any other day. So:

    ;; *friday*, *saturday*, *sunday*, and *monday* are universal times
    ;; representing consecutive dates which fall on a Friday, Saturday,
    ;; Sunday, and Monday, respectively.

    (day-difference *sunday* *monday* :work-days t) RETURNS 0
    (day-difference *saturday* *sunday* :work-days t) RETURNS 0
    (day-difference *friday* *saturday* :work-days t) RETURNS 1

    ;; and also

    (day-difference *saturday* *monday* :work-days t) RETURNS 0
    (day-difference *friday* *sunday* :work-days t) RETURNS 1
    (day-difference *friday* *monday* :work-days t) RETURNS 1

If start is greater than end, the negative of the day-difference between end and start is returned.

If date1 <= date2 <= date3, then

    (= (day-difference date1 date3 :work-days *wd*)
       (+  (day-difference date1 date2 :work-days *wd*)
           (day-difference date2 date3 :work-days *wd*)))
    ;; for any value of *wd*.

Note: only proper Common Lisp universal times (that is, non-negative integers representing seconds since midnight 1/1/1900 GMT) are supported. Negative universal times, supported in the date-time module (see date-time.html), are not supported by this function.

Examples

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    (day-difference
     (string-to-universal-time "2000-01-02T15:16:17-08:00")
     (string-to-universal-time "2001-01-02T15:16:17-08:00"))
    RETURNS 366 ;; the year 2000 was a leap year

    (day-difference
     (string-to-universal-time "2001-01-02T15:16:17-08:00")
     (string-to-universal-time "2002-01-02T15:16:17-08:00"))
    RETURNS 365  ;; the year 2001 was not a leap year

    (day-difference
     (string-to-universal-time "2002-01-02T15:16:17-08:00")
     (string-to-universal-time "2001-01-02T15:16:17-08:00"))
    RETURNS -365  ;; same as previous example with the arguments reversed.
                  ;; When START is greater than END, the value is negative or 0.

    (day-difference
     (string-to-universal-time "2001-01-01T00:00:01-08:00")
     (string-to-universal-time "2001-01-01T23:59:59-08:00"))
    RETURNS 0 ;; the DAY-DIFFERENCE of times on the same day is 0

    (day-difference
     (string-to-universal-time "2017-08-20") ; Sun
     (string-to-universal-time "2017-08-26") ; the next Sat
     )
    RETURNS 6

    (day-difference
     (string-to-universal-time "2017-08-20") ; Sun
     (string-to-universal-time "2017-08-27") ; The next Sun
     )
    RETURNS 7

    ;; Same times as the previous examples, but only counting work days
    (day-difference
     (string-to-universal-time "2017-08-20") ; Sun
     (string-to-universal-time "2017-08-26") ; the next Sat
     :work-days t)
    RETURNS 5

    (day-difference
     (string-to-universal-time "2017-08-20") ; Sun
     (string-to-universal-time "2017-08-27") ; The next Sun
     :work-days t)
    RETURNS 5

    ;; Consecutive days return 1 when WORK-DAYS is NIL:
    (day-difference
     (string-to-universal-time "2017-08-20") ; Sun
     (string-to-universal-time "2017-08-21") ; the following Mon
     )
    RETURNS 1

    ;; Consecutive days return 0 or 1 when WORK-DAYS is true
    ;; depending on whether START is a SATURDAY or SUNDAY or not:
    (day-difference
     (string-to-universal-time "2017-08-20") ; Sun
     (string-to-universal-time "2017-08-21") ; the following Mon
     :work-days t)
    RETURNS 0

    (day-difference
     (string-to-universal-time "2017-08-19") ; Sat
     (string-to-universal-time "2017-08-20") ; the following Sun
     :work-days t)
    RETURNS 0

    (day-difference
     (string-to-universal-time "2017-08-18") ; Fri
     (string-to-universal-time "2017-08-19") ; the following Sat
     :work-days t)
    RETURNS 1

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# day-number

Function, excl package

Arguments: ut

Release 10.1 and later only. The value returned by day-number and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

This function returns the day number of the universal time ut, which must be a non-negative integer and is interpreted as a universal time (see get-universal-time). January 1 has day number 1 and December 31 has day number 365 in non-leap years and 366 in leap years.

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    ;; January 1 has day-number 1. Here is January 1, 2005:
    cl-user(94): (day-number (encode-universal-time 0 0 12 1 1 2005))
    1

    ;; December 31 has day number 365 in non-leap years (like 2005)
    ;; and 366 in leap years (like 2004):

    cl-user(97): (day-number (encode-universal-time 0 0 12 31 12 2005))
    365
    cl-user(98): (day-number (encode-universal-time 0 0 12 31 12 2004))
    366
    cl-user(99):

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# day-of-week

Function, excl package

Arguments: ut

Release 10.1 and later only. The value returned by day-of-week and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

day-of-week returns the number corresponding to the day of the week of the universal time ut (which must be a non-negative integer). The value is the same as the seventh return value of decode-universal-time when the optional time-zone argument is not specified. Monday is day 0, Tuesday is day 1, and so on through Sunday, day 6.

The values of the constants *decoded-time-monday*, *decoded-time-tuesday*, *decoded-time-wednesday*, *decoded-time-thursday*, *decoded-time-friday*, *decoded-time-saturday*, and *decoded-time-sunday* are the integers corresponding to the named day of the week.

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    cl-user(101): (setq ut (encode-universal-time 0 0 12 4 5 2017))
    3702913200
    cl-user(102): (day-of-week ut)
    3
    cl-user(103): (decode-universal-time ut)
    0 0 12 4 5 2017 3 t 8 ;; same as the seventh value (3)
    cl-user(106):

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# decf-atomic

macro, excl package

Arguments: place &optional (increment-form 1)

This macro acts like decf with the same arguments except that the update is atomic with respect to any other processes looking at the same place. That is, if several processes simultaneously try to decf-atomic (or incf-atomic) the same location, all operations occur sequentially in some unspecified order. As a result, the final value will be what is expected. (If you just used decf's and incf's, the first decf could read the value and while it is calculating the decrement, another decf could run, and then the initial decf could store its result effectively cancelling the action of the second decf.)

Note on the place argument: not all places legal as the first argument of setf can be used as the place argument to this macro. The list of allowable places can be found in Atomic read-modify-write primitives in smp.html.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# decode-extended-time

Function, excl package

Arguments: time &optional time-zone

Like the related decode-universal-time, this function returns nine values representing the clock time, day, month, and year, whether daylight saving time is in effect, and the time zone. Specifically, this function returns the following as multiple values:

1. The clock second: from 0 to 59.

2. The clock minute: for 0 to 59.

3. The clock hour: in 24-hour time, midnight being 0.

4. The day of the month: a value from 1 to 31.

5. The month: January is 1 and December is 12.

6. The year

7. The weekday: an integer from 0 to 6 indicating the day of the week, Monday being 0 and Sunday being 6.

8. Daylight saving time: a boolean indicating whether DST is or is not in effect.

9. The time zone: the current time zone will be used if the time-zone optional argument is not specified. Otherwise time-zone will be used.

time should be an integer. If time is non-negative, this function is the same as decode-universal-time. If time is negative, this function assume the value is a number of seconds prior to midnight, January 1, 1900 GMT and returns the time, date and year. Even negative years (those prior to 1 CE) are returned for sufficiently large negative times.

Note that for year prior to 1 CE, there is a year 0 even though the standard calendar does not have a year 0, so any non-positive year must be dimished by 1 to get the BCE equivalent. Further, this function assumes that the Gregorian Calendar (introduced in 1582 CE and not adopted more or less worldwide until the twentieth century) is in effect everywhere and for all time. That means that dates and times from inscriptions and historic documents, when entered, will not be to the second the instant a historic event likely happened (see the examples).

    ;; For positive time arguments, this function and
    ;; DECODE-UNIVERSAL-TIME are the same:
    cg-user(22): (get-universal-time)
    3638637699
    cg-user(23): (decode-universal-time 3638637699)
    39
    41
    13
    21
    4
    2015
    1
    t
    8
    cg-user(24): (decode-extended-time 3638637699)
    39
    41
    13
    21
    4
    2015
    1
    t
    8
    cg-user(25):

    ;; For negative times, DECODE-UNIVERSAL-TIME will signal an error
    ;; but DECODE-EXTENDED-TIME works:
    ;;
    cg-user(14): (encode-extended-time 0 0 10 15 3 -43 -1)
    -61308802800
    cg-user(15): (decode-extended-time * -1)
    0
    0
    10
    15
    3
    -43
    4
    nil
    -1
    ;; That is 10:00 AM, March 15, 44 BCE (remember, subtract 1 from
    ;; non-positive years to get the BCE year) in timezone -1 (Rome, Italy).
    ;; The Ides of March 44 BCE, when Julius Caesar was assassinated in the
    ;; Theater of Pompey in Rome (according to many historical accounts).
    ;; Assuming 10:00 AM is correct, did that happen 61308802800 seconds
    ;; before midnight, January 1, 1900 GMT? Likely not, even if the descriptions
    ;; from history books are accurate about the day and time, because
    ;; calendar changes from that time to now means that dates that far back
    ;; are likely some number of days off. But the answer is quite close.

See also encode-extended-time, string-to-universal-time, and universal-time-to-string.

# def-char-to-octets-macro

Macro, excl package

Arguments: name arglist &body body

name should be a symbol. arglist should be a macro lambda list with two required arguments and two specified keyword arguments `:put-next-octet`, and `:external-format`. (You may choose your own names for the required arguments, of course. The arglist argument is present mostly to make this macro similar in form to defmacro.) body should be a list of forms.

This macro is just like defmacro except that name names an external-format, and the actual macro name (a gensym) for the macro being defined is stored in the external-format's chars-to-octets-macro slot. Also, if no external-format with name name exists, then a new external-format with name name is created.

The macro being defined must accept two required arguments, which we will call char, and state-loc (but you can, of course, call anything) and two keyword arguments which must be called put-next-octet and external-format. (The external-format argument is only used if name names an external-format that is a wrapper (ie, a composing external-format)).

When the macro actually being defined is called, the char will be a character to convert, and the state-loc will be a setf-able locative (similar to the first argument to setf) that can be used by the convertor to hold state information.

The put-next-octet argument to the macro being defined is a single-argument expression that is invoked in the macro's expansion at the point or points where the translation procedure requests that the next translated external-element (eg, octet) be output.

If the external-format named by name is a composing external-format, then the external-format argument to the macro being defined is the name of the external-format being wrapped.

Examples:

    ;; Defines a chars -> octets procedure for latin1 characters.
    ;;
    (def-char-to-octets-macro :latin1-base (char
                                            state-loc
                                            &key put-next-octet external-format)
      (declare (ignore external-format state-loc))
      (let ((code-var (gensym))
            (char-var (gensym)))
        `(let ((,char-var ,char))
           (let ((,code-var (char-int ,char-var)))
             (,put-next-octet ,code-var)))))

    ;; Defines a chars -> octets procedure for utf-8 characters.
    ;;
    (def-char-to-octets-macro :utf8-base (char
                                          state
                                          &key put-next-octet external-format)
      (declare (ignore external-format state))
      (let ((code-var (gensym)))
        `(let ((,code-var (char-code ,char)))
           (if* (< ,code-var #x7f)
              thenret ;; ascii
            elseif (< ,code-var #x7ff)
              then (,put-next-octet (logior #xc0 (ash ,code-var -6)))
                   (setq ,code-var (logior #x80 (logand ,code-var #x3f)))
              else (,put-next-octet (logior #xe0 (ash ,code-var -12)))
                   (,put-next-octet (logior #x80 (logand (ash ,code-var -6)
                                                         #x3f)))
                   (setq ,code-var (logior #x80 (logand ,code-var #x3f))))
           (,put-next-octet ,code-var))))

    ;; Defines a composing external format that splits up #\newline into
    ;; #\return #\linefeed.
    ;;
    (def-char-to-octets-macro :crlf (char
                                     state
                                     &key put-next-octet external-format)
      (declare (ignorable state))
      (let ((char-var (gensym)))
        `(let ((,char-var ,char))
           (when (eq #\newline ,char-var)
             (char-to-octets ,external-format #\return ,state
                             :put-next-octet ,put-next-octet)
             (setq ,char-var #\linefeed))
           (char-to-octets ,external-format ,char-var ,state
                           :put-next-octet ,put-next-octet))))

    ;; The following uses the above defined wrapper external-format to
    ;; create a latin1 convertor with #\newline mapped to octets for
    ;; ASCII Carriage-Return and Linefeed.
    ;;
    ;; Note: Using (compose-external-formats :crlf :latin1-base) achieves as one
    ;; of its side-effects the same effect as evaluating the following:
    ;;
    (def-char-to-octets-macro :crlf-latin1-base (char state
                                                 &key put-next-octet
                                                      external-format)
      (declare (ignore external-format))
      `(char-to-octets :crlf ,char ,state
                       :put-next-octet ,put-next-octet
                       :external-format :latin1-base))

See also char-to-octets.

See iacl.html for more information on international character support in Allegro CL.

# def-ef-switch-to-runtime

Macro, excl package

Arguments: name function

name should be a symbol naming an external format or external-format object (as returned by def-external-format). function should be a function object (not a symbol).

Associates a function object with an external-format. The function object is funcalled when switch-ef-to-runtime is called for the external-format named by name.

Examples:

    (def-external-format :jis-base)

    ;; As part of the char-to-octets and octets-to-char macros, global data
    ;; may be used which is not needed once the macros are eliminated for the
    ;; external-format's runtime mode.  Supposing the global data can be
    ;; eliminated by calling (delete-trie ...), here's how to have that call
    ;; be made when the external-format is being switched to runtime mode.
    ;;
    (def-ef-switch-to-runtime :jis-base
      #'(lambda ()
          (delete-trie :unicode-to-jis)
          (delete-trie :jis-to-unicode)))

See iacl.html for more information on international character support in Allegro CL.

# def-external-format

Macro, excl package

Arguments: name &key nicknames nulls width

In releases prior to 6.1, there was a size keyword argument but no width or nulls arguments. The size argument confounded the width and nulls values. It is no longer accepted.

The arguments are:

- name should be a symbol. ef-name accesses the name slot of an external format.

- `:nicknames` should be a list of symbols which can be used interchangeably with name.

- `:width` specifies how many octets it takes to build a character. It may have an integer value, or else the value `character`, which is the default value. The width slot is used to optimize listen techniques in a stream; by default listen requires at least width octets to be available before returning true. Normally this means having to go through the process of building a character, but in simple formats, like latin1, availability of a single octet can allow a true return from listen. ef-width accesses the width slot of an external format.

- `:nulls` specifies how many 0 octets must trail a string. It defaults to 1 and is only ever different in :fat and :unicode formats (where the value is 2). ef-nulls accesses the nulls slot of an external format.

This macro defines name as an external-format. If name already names an existing external-format, then that external-format is modified to have its nicknames, width, and nulls slots set to the values specified in the call to def-external-format. A slot is only modified in this call if it is specified in the call to def-external-format.

An error is signaled if any of the symbols specified in nicknames is a nickname to an external-format other than that being defined or modified.

Example:

    (def-external-format :utf-8 :nicknames '(:utf8))

Here is an overview of how external-formats are used:

The main purpose for the external-format object is as a place to store Lisp coded procedures for translating octets in external representation to/from lisp strings. In order to use these routines as efficiently as possible, the translation procedures are defined as macros. The effect is that with these macros, the code to translate octets to and from characters is directly mixed in with the code to retrieve/store octets/characters. The macros themselves take as arguments expressions to get/put the next octet or character to translate. The return value of the macros' expansions are the number of octets or characters translated. (See def-char-to-octets-macro and def-octets-to-char-macro.)

Some external-formats may be composed with other external-formats to form new external-formats. For example, a wrapper external-format may be defined which combines external bytes representing 'f' and 'i' to create #\latin_small_ligature_fi. This wrapper external-format could be composed with the utf8 external-format to create a ligature-utf8 external-format. The wrapper external-format could also be composed with the euc external-format to create a ligature-euc external-format. Wrapped or composed external-formats are created using the compose-external-formats operator.

See iacl.html for more information on international character support in Allegro CL.

# def-function-spec-handler

Macro, excl package

Arguments: symbol arglist &body body

def-function-spec-handler defines a new kind of function spec handler keyed on symbol, a symbol which is the fspec-first of the function spec. The handler must accept three arguments so arglist must be a list of three elements. The arguments are:

1. The function spec, which may be in internal or external form. The external form is a list of two or three elements.

2. The operation. The list of operations is given below.

3. The extra argument. This argument will be used when needed and ignored when not needed. When the operation is setf, for example, the extra argument is the new value.

The body must return an appropriate value for the operation. The operations are:

- `:validate`: Return a boolean indicating whether the place named by the spec exists. This must never signal error.
- `fboundp`: Return the function if the function is defined and return `nil` if the function is not defined. An error must never be signaled on a validated function spec.
- `:setfable`: A boolean indicating whether (setf fdefinition) is allowed.
- `setf`: Set the function to the third (extra) argument value.
- `boundp`: Boolean whether fmakunbound is allowed. Note that this is not the same meaning as the CL function boundp.
- `fmakunbound`: Make the function funbound.
- `block`: For certain functions (e.g. setf functions) defun is required to wrap the body in a block with a certain name. This operation must return the name based on the spec and is called by the defun macro and the compiler top level. This is a good place to put an error check for functions that may not be defined by defun.
- `unintern`: Detach the function-spec from its oblist for potential garbage-collection of the entire function spec. Does not do an fmakunbound; i.e. if an operation has squirrelled the function-spec away, it remains fully operational, just as unintern of an fboundp symbol still leaves it fboundp.
- `:defunable`: A boolean indicating whether defun can be used on this function-spec.

The function function-name-p returns true when passed a valid function spec defined with def-function-spec-handler. fboundp can be used to determine whether a valid function spec defined with def-function-spec-handler actually names an operator.

Note: with def-function-spec-handler, Allegro CL extends the concept of (setf fdefinition), but it does not extend the concept of defun. So, for example, it is sometimes useful to

    (setf (fdefinition '(method foo (bar))) (lambda (<args>) <body>))

but it is not appropriate to

    (defun (method foo (bar)) (<args>) <body>)

because defun does not supply enough mechanism to accomodate MOP requirements.

See Function specs in implementation.html for more information on function specs.

# def-fwrapper

Macro, excl package

Arguments: name arglist &body body

Produces a form which returns name and defines an fwrapper as a side effect. This fwrapper is suitable for use as the fwrap-function in a call to fwrap.

name can be any function spec.

arglist is an ordinary lambda list. All ordinary lambda list keywords may be used, including &allow-other-keys, &aux, &key, &optional, and &rest. If either &key or &rest are present, then the arglist is automatically forced to be a list. (Note: the current implementation also forces a list when optional arguments are specified, because of some potential problems when a not-given optional argument is setq'd).

Argument accesses are provided for by means of symbol-macrolets, in a manner that is mostly intuitive. The arguments can simply be accessed by name, and they can be setq'd under most circumstances, with exceptions given below. The values of these setq'd arguments become part of the argument list that is sent to the next more inner fwrapper.

Exceptions:

- If the &rest arg is setq'd, the change only takes place for the current fwrapper, and is not passed inward. However, any changes made to the structure of the rest arg (via (setf car) or (setf cdr) or similar functions) will result in a change that will be passed inward.

- Any &key value that is setq'd will not replace or add the key value to the arglist that is passed inward, although the change will be in effect for the duration of the fwrapper.

#### def-fwrapper is a defining macro like defun

def-fwrapper is a additional defining macro in Allegro CL, joining the standard defining macros like defun. Among other things, this means that the resulting code is wrapped in a block named by the wrapper name which can be returned from. As with any defining macro, one can use macroexpand and pprint to see what is actually happening (you may see a different macroexpansion -- this is shown only to see how to get a macroexpansion):

    CL-USER(1): (pprint (macroexpand '(def-fwrapper foo (a b) nil)))

    (PROGN (EVAL-WHEN (COMPILE)
             (EXCL::CHECK-LOCK-DEFINITIONS-COMPILE-TIME 'FOO 'FUNCTION
               'DEF-FWRAPPER (FBOUNDP 'FOO)))
           (SETF (FDEFINITION 'FOO)
                 (NAMED-FUNCTION FOO
                   (LAMBDA (EXCL::NEXT-FWRAPPERS EXCL::FWRAP-ENV
                            EXCL::PRIMARY-FUNCTION ARGLIST EXCL::NARGS)
                     (DECLARE
                      (IGNORABLE EXCL::NEXT-FWRAPPERS EXCL::FWRAP-ENV
                       EXCL::PRIMARY-FUNCTION))
                     (EXCL::FWRAPPER-ARGUMENT-CHECK 'FOO 2 2 ARGLIST
                       EXCL::NARGS)
                     (BLOCK FOO
                       (SYMBOL-MACROLET ((A
                                          (EXCL::GET-FWRAPPER-ARG
                                           EXCL::NARGS
                                           0
                                           ARGLIST))
                                         (B
                                          (EXCL::GET-FWRAPPER-ARG
                                           EXCL::NARGS
                                           1
                                           ARGLIST)))
                         (LET* ()
                           (LET* ((#:G4 NIL))
                             (DECLARE (IGNORABLE #:G4))
                             NIL)))))))
           (REMPROP 'FOO 'EXCL::%FUN-DOCUMENTATION)
           (RECORD-SOURCE-FILE 'FOO) 'FOO)
    CL-USER(2):

See fwrappers-and-advice.html for information of fwrapping functions (and on the older, deprecated advice facility).

# def-hash-table-implementation

Macro, excl package

Arguments: implementation-name &rest keys

Returns the given implementation-name. As a side-effect, the specified implementation replaces or is added to the current implementation list. Once an implementation is installed, make-hash-table can be called to create a hash-table using that implementation. The default implementation is the :acl implementation, and while it is not advisable to replace it, it is possible; replacing `:acl` causes a continuable error and the restart can force the redefinition anyway.

Keyword options:

Except for the based-on option, keyword options from the keys list specify what will go into the descriptor vector (see Descriptor vector sections). Each option's value can be specified as an explicit function, with either `(function foo)` or `#'foo`, in which case the function must be independent of the hash-function and test functions at make-hash-table time and must accept the correct arguments as specified for each descriptor function. Alternatively, each option's value can be a symbol specifying a getter function, which returns either a function or a closure that incorporates or closes over one or both of the hash-function and test options that will be specified in the make-hash-table call. The symbolic hash-function and test values are the arguments of the getter, and the function returned must accept the correct arguments as specified for each descriptor function. An exanple of this getter style is `get-alist-hash-gethash-fcn` in alisthash.cl.

### The :based-on option

If the based-on keyword option is provided and names a valid implementation, then all descriptor functions will default to be the same as the based-on implementation (but any descriptor function can be modified explicitly by specifying it as a keyword argument to this macro). If based-on is given and is explicitly `nil`, then no functionality is inherited from any existing implementation and all desired dispatch functions must be explicitly supplied in this macro form, and run-time errors will result if the required minimum dispatch functions are not specified. What determines this required minimum depends on the hash-table usage. If based-on is given but the implementation does not exist, an error is signaled. If based-on is not given, it defaults to the :acl implementation.

#### Additional inherited :based-on behavior for the :acl implementation

In addition to providing a default for normal hash-table behaviors which the new implementation can then modify, it is important to understand a behavior that is inherited from the `:acl` implementation, or any hash-table implementations that have been based-on `:acl` or any of its descendants; If a hash-table that is acl-based is created with the default eq or eql `:test` argument, the `:hash-function` for that hash-table automatically defaults to be an internal address-based hashing function. An address-based hash-code will cause the hash-table to become "dirty", where after any gc that might move the key object, the first subsequent access to the hash-table will require the hash-table to be rehashed. Not all hash-codes generated from this hashing-function are address-based; if the hashing algorithm can generate a hash-code that does not change (usually due to a hash-code slot being present in the object) then storing the key into the hash-table will not cause the hash-table to become dirty.

Note that regardless whether the `:acl` behavior is inherited, a `:hash-function` that is explicitly specified should never depend on its key's address, because other than the internal address-based hash function, there is no way to account for key movement by the garbage-collector, and keys will otherwise be lost in the hash-table.

If an eq or eql hash-table is desired with the new implementation, but the address-based behavior is not desired, then a based-on option of `nil` should be specified, and all other behaviors must be provided explicitly.

### Other options:

The other keyword options are described in Descriptor vector sections. Any options specified will shadow the defaults given by the based-on option.

New keywords can be given to extend the functionality of the descriptor vector. If they are provided, they will be added to the end of the descriptor vector, so as not to interfere with the placement of other functions (even if those functions are not specified as part of the implementation).

Note that although it is possible for a user to base a hash-table implementation on the `:acl` implementation or any other which is indirectly based on `:acl`, at the present time no user interface is supplied for dealing with the special hash-table-instance object that the `:acl` implementation allocates and uses. The recommendation is to not base a user hash-table implementation on `:acl` at all, but to create alternate data structures like the one given in the alisthash.cl example.

Examples:

These examples of hash table implementations are provided:

1. alisthash: This example demonstrates that a hash-table can be represented purely as an alist. Not all of the standard operators are defined, but can be easily added. See alisthash.cl on the githuib site.

2. quickhash: The quickhash implementation is a refactoring of agraph's quicktab hash-table implementation. See quickhash.cl on the github site.

See Creating user-defined hash-table implementations in miscellaneous.html for information about creating hash-table implementations.

# def-locale

Macro, excl package

Arguments: name &key external-format

The name should be a string. external-format should be an external-format.

This macro defines name as a locale.

Examples:

    (def-locale "ru"
            :external-format (find-external-format :iso8859-5))
      -> #<locale "ru" [:iso8859-5-base]>

# def-octets-to-char-macro

Macro, excl package

Arguments: name arglist &body body

name should be a symbol, arglist the macro lambda list `(state-loc &key get-next-octet octets-count-loc unget-octets external-format)` (this argument is present to make a def-octets-to-char-macro form similar to a defmacro form, the required argument may have any name of course.). body should be a list of forms.

def-octets-to-char-macro is just like defmacro except that name names an external-format, and the actual macro name (a gensym) for the macro being defined is stored in the external-format's octets-to-char-macro slot. Also, if no external-format with name name exists, then a new external-format with name name is created.

The macro being defined must accept one required argument (which we call state-loc but may, of course, have any name), and the following keyword arguments:

- `:get-next-octet`

- `:octets-count-loc`

- `:unget-octets`

- `:external-format` (see note)

Note external-format is used only if the external-format is a wrapper external-format (that is, a composing external-format).

The state-loc should be a place argument acceptable as the first argument to setf. It is used by the convertor for holding state information. The state should be immutable so it can be copied. In other words, one should not use a structure for a state and then change the state using setf.

The get-next-octet argument to the macro being defined is an expression that is invoked in the macro's expansion at the point or points where the translation procedure requests the next external element (octet) to be input.

The octets-count-loc argument should be a place argument acceptable as the first argument to setf. It is set by the convertor to hold the number of octets consumed in order to create the character being returned. The octets-to-char caller must initialize this argument to 1 (the number one). Thus, if the get-next-octet routine is invoked exactly once by the octets-to-char macro, the octets-count-loc argument is left unaltered. If get-next-octets is invoked more than once, octets-count-loc must be incremented before each call to get-next-octets.

If the external-format convertor does not use all the octets retrieved by get-next-octet (ie, it was peeking ahead), then octets-count-loc must be decremented so that its value reflects the actual count of octets used.

In addition to decrementing the octets-count-loc when not all acquired octets are used, the unget-octets argument is also used to inform the octets-to-char caller to place the unused octets back into the sequence for future calls to octets-to-char. unget-octets is a single-argument expression that is invoked in the macro's expansion at the point or points where the translation procedure requests that recently received octets be "un-received". The argument to unget-octets is the count of the most recently received octets to be considered un-received.

If the external-format named by name is a wrapper external-format, then the external-format argument to the macro being defined is the name of the external-format being wrapped.

The defined macro returns a single value, a character. If an error occurs during the conversion, a condition object is returned instead of the values. It is intended that the macro not signal errors directly but that the caller of the chars-to-octets macro (where this macro definition is used) be responsible for signaling any errors.

Examples:

    ;; Defines an octets -> char procedure for latin1 characters.
    ;;
    ;; Note: There's no change to octets-count-loc since it is initialized to
    ;; 1 (the number one) and that's as many octets as we take.
    ;;
    (def-octets-to-char-macro :latin1-base (state-loc
                        &key get-next-octet external-format
                             octets-count-loc unget-octets)
      (declare (ignore external-format state-loc octets-count-loc unget-octets))
      `(code-char ,get-next-octet))

    ;; Defines an octets -> char procedure for utf8.
    ;;
    (def-octets-to-char-macro :utf8-base (state-loc
                          &key get-next-octet external-format
                               octets-count-loc unget-octets)
      (declare (ignore external-format state-loc unget-octets))
      (let ((code-var (gensym)))
        `(let ((,code-var ,get-next-octet))
           (if* (< ,code-var #x7f)
          then (code-char ,code-var)
        elseif (eql #xf0 (logand #xf0 ,code-var))
          then ;; 32-bit unicode value, which we don't support.
               (dotimes (i 3)
             (incf ,octets-count-loc)
             ,get-next-octet)
               #\?
        elseif (eql #xe0 (logand #xe0 ,code-var))
          then (sys::fixnum-to-char
            (logior (ash (logand #x0f ,code-var) 12)
                (progn (incf ,octets-count-loc)
                       (ash (logand #x3f ,get-next-octet) 6))
                (progn (incf ,octets-count-loc)
                       (logand #x3f ,get-next-octet))))
          else (sys::fixnum-to-char
            (logior (ash (logand #x1f ,code-var) 6)
                (progn (incf ,octets-count-loc)
                       (logand #x3f ,get-next-octet))))))))

    ;; Defines a wrapper external-format that looks for ASCII <CR> followed by
    ;; <LF> to combine into #\newline.
    ;;
    (def-octets-to-char-macro :crlf (state
                     &key get-next-octet external-format
                     octets-count-loc unget-octets)
      (let ((char1-var (gensym))        ; first char.
        (char2-var (gensym))        ; second char.
        (state0-var (gensym))       ; original state.
        (state1-var (gensym))       ; after first char state.
        (state2-var (gensym))       ; after second char state.
        (char1-size-var (gensym))   ; first char size.
        (char2-size-var (gensym)))  ; second char size.
        `(let* ((,state0-var ,state)
            (,state1-var ,state0-var))
           (let ((,char1-var (octets-to-char ,external-format ,state1-var
                         :octets-count-loc ,octets-count-loc
                         :unget-octets ,unget-octets
                         :get-next-octet ,get-next-octet
                         ;; Pass eof through
                         :oc-eof-macro nil)))
         (if* (eq #\return ,char1-var)
            then (let* ((,char1-size-var ,octets-count-loc)
                (,state2-var ,state1-var)
                (,char2-var
                 (catch ':crlf-eof-catch-tag
                   (incf ,octets-count-loc) ; pre-increment
                   (octets-to-char
                    ,external-format ,state2-var
                    :octets-count-loc ,octets-count-loc
                    :unget-octets ,unget-octets
                    :get-next-octet ,get-next-octet
                    :oc-eof-macro ((hard-eof)
                           `(throw ':crlf-eof-catch-tag
                              ,hard-eof))))))
               (declare (type adim ,char1-size-var))
               (if* (eq #\linefeed ,char2-var)
                  then (unless (eq ,state2-var ,state0-var)
                     (setf ,state ,state2-var))
                   #\newline
                elseif ,char2-var
                  then ;; char2 is a character.  Peel back to char1, which
                   ;; is #\return.
                   (let ((,char2-size-var (- ,octets-count-loc
                                 ,char1-size-var)))
                     (declare (type adim ,char2-size-var))
                     (,unget-octets ,char2-size-var)
                     (decf ,octets-count-loc ,char2-size-var)
                     (unless (eq ,state1-var ,state0-var)
                       (setf ,state ,state1-var))
                     #\return)
                  else ;; char2 indicates soft eof.  Peel back everything
                   ;; and pass on the soft eof.
                   (,unget-octets ,octets-count-loc)
                   (setf ,octets-count-loc 0)
                   (oc-eof-macro nil)
                   (error "
     The crlf external-format was not terminated by a call to oc-eof-macro")))
            else (unless (eq ,state1-var ,state0-var)
               (setf ,state ,state1-var))
             ,char1-var)))))

    ;; The following uses the above defined wrapper external-format to create a
    ;; octets -> char transform of latin1 to crlf-latin1.
    ;;
    ;; Note: Using (compose-external-formats :crlf :latin1) achieves as one of its
    ;; side-effects the same effect as evaluating the following:
    ;;
    (def-octets-to-char-macro :crlf-latin1-base (char state
                                                 &key get-next-octet
                                  external-format
                              octets-count-loc
                              unget-octets)
      (declare (ignore external-format))
      `(octets-to-char :crlf ,char ,state
                       :get-next-octet ,get-next-octet
               :external-format :latin1-base))

See also octets-to-char.

See iacl.html for more information on international character support in Allegro CL.

# def-stream-class

Macro, excl package

Arguments: class-name superclasses slots &rest options

This macro is similar to defclass, except that various stream accounting is performed. If a slot is mentioned that is already known to the Allegro CL streams system, it is given a fixed-index value. Also, if an `:initform` or `:logior` option is specified, then an initialize-instance `:before` method is automatically created to ensure that the slot has the specified value before shared-initialize time.

The `:logior` option is an Allegro CL-specific variant of an initform. Specifying `:logior 128` means apply logior to 128 and the previous value of the slot (which should be numeric and defaults to 0). This is a shorthand for specifying a value for the slot in a much more complicated way, and it requires the `:before` referenced above because it is not a standard CLOS feature.

You must load the `:iodefs` module to use this macro. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This macro is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# defadvice

Macro, excl package

Arguments: fspec where &rest forms

Starting in Allegro CL release 6.0, the new fwrapper facility, described in fwrappers-and-advice.html, replaces the advice facility, and continued use of the advice facility is deprecated.

This macro allows advice to be defined in a format similar to a function definition (with defun).

fspec must name a function. It is typically a symbol but can be any function name, as in advise. fspec is not evaluated.

where is either a symbol or a list. If it is a symbol, it can either be the name of the advice or the class. If where is one of `:before`, `:around`, or `:after`, it is interpreted as the class. Any other symbol is interpreted as a name. When where is a symbol, the position of the advice defaults to `nil`. When where defines the name, the class of the advice defaults to `:after`. When where is the class, the name of the advice defaults to `nil`.

If where is a list, the first element (if there is one) is interpreted as the name, the second element as the class, and the third element, if there is one, as the position. If there is no second element, or the second element is `nil`, the class will be `:after`. Please refer to the definition of advise for information on the interpretation and behavior of the class, name and position of advice.

forms are Lisp forms which will be evaluated as if in a progn. Warning: forms cannot be the single form `nil`. If you want the single form `nil` (in, for example, :around advice to not call the function and return `nil`), specify `(progn nil)` instead.

See also fwrappers-and-advice.html for general information on the new fwrapper facility and the older, now deprecated, advice facility in Allegro CL.

# defsystem

Macro, excl package

Arguments: system-name options &body modules

This macro creates a new system with name system-name and options taken from options, containing module-groups specified by modules. system-name must be a symbol (we recommend using a keyword) which will identify the system. options must be a (possibly empty) list of keyword/value pairs. modules is a list consisting of one or more short form module-specifications and/or long form module-specifications.

This macro returns the symbol system-name.

The allowable options keywords are shown in the table below.

See also defsystem.html for general information on the defsystem facility in Allegro CL and for a description of module specifications.

- `:pretty-name`, a string
  - default value: print-name of system-name symbol
  - This name will be used for printing.
- `:default-module-class`, a symbol identifying a class
  - default value: `ds:lisp-module`
  - Predefined classes are: `ds:lisp-module`, `ds:text-module`, `ds:c-module`. Users may define additional classes, see defsystem.html.
- `:default-package`, a package object or string or symbol naming a package
  - default value: the value of *package*
  - Can be overridden for a module or module-group with the package option in the long module form. Also can be overridden during an operation with the package argument.
- `:default-pathname`, a pathname object or string or symbol naming pathname
  - default value: *default-pathname-defaults*
  - This pathname will be merged with the filenames of the modules of the system in order to find files.
- `:default-file-type`, a string
  - default value: depends on value of `:default-module-class`
  - Specifies file type (extension) for source files for modules in system. If :default-module-class is ds:lisp-module, default is value of *source-file-types*; if ds:text-module, default is `nil`; if ds:c-module, default is "c".
- `:property-list`, a property list
  - default value: `nil`
  - The value is added to the property list of the system.

# defun-proto

Macro, excl package

Arguments: name varlist &body body

This macro is very similar to defun, except that only declarations are noticed from the first part of the body; the rest of the body is ignored (and the operator is not actually defined -- a defun form or equivalent must be or have been supplied at some point). This macro allows the programmer to declare dynamic arguments for a function before its first use, which might come before the actual definition. If the prototype and the actual definition give different specifications, then it is treated just like a redefinition, and warnings are given subject to with-compilation-unit behavior.

# defvar-nonbindable

macro, excl package

Arguments: symbol &optional initial-value-form documentation-string

This macro acts like a defvar, with the additional function of flagging symbol so that it cannot be lambda-bound. This means all references to symbol's value are to `(sys:global-symbol-value 'symbol)`.

Here is an example showing the error signaled when there is an attempt to bind a non-bindable variable.

    cl-user(1): (defvar-nonbindable *foo*)
    *foo*
    cl-user(2): (setq *foo* 10)
    10
    cl-user(3): (let ((*foo* 20)) *foo*)
    Error: Cannot bind *foo* -- it is an unbindable symbol.
      [condition type: program-error]

    Restart actions (select using :continue):
     0: Prompt for a new variable name.
     1: Return to Top Level (an "abort" restart).
     2: Abort entirely from this (lisp) process.
    [1c] cl-user(4):

In the initial SMP implementation, only symbols defined with defvar-nonbindable were suitable as places for atomic update operators like push-atomic. This is not longer true. Any symbol can be used as such a place. This macro is therefore no longer associated with atomic updates but is retained because it may be useful for other purposes.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# delete-breakpoint

Function, excl package

Arguments: func pc &optional verbose

Deletes an existing breakpoint specified by the function object func and pc. The func argument may be either a function object or an fboundp function name. The pc argument must be exact; it will not be adjusted as it is with add-breakpoint.

The verbose argument, when true, will show the disassembly of the breakpoint being deleted. See the top-level command :break.

See The Lisp DeBug (ldb) stepper in debugging.html for information on ldb stepping.

# delete-directory-and-files

Function, excl package

Arguments: directory &key (if-does-not-exist :error) (quiet t) force

The new `:osi` module (see Operating System Interface Functionality in os-interface.html), released after the release of Allegro CL 6.2, has new operators relating to directory and file manipulation. This symbol naming this function, `delete-directory-and-files` has also been exported from the `excl.osi` package. The new operators are described in OSI file handling functionality in os-interface.html.

With the addition of the new `:osi` module, this function was changed: the force keyword argument has been added; the default value of the quiet keyword argument is now `t`; and the default value of the if-does-not-exist keyword argument is now `:error`.

Delete all the files in directory and all subdirectories of directory. directory itself is also removed. If if-does-not-exist is `:ignore` then no error will be signaled if directory does not exist. Its default is `:error` which causes an error to be signaled on failure. If quiet is `nil`, then informative text about the operations performed is printed. quiet defaults to `t`.

On Windows, the force keyword can be used to remove filespec when it is read-only. On UNIX, this is the default behavior so force is effectively ignored.

See also os-interface.html for general information on the interface between Allegro CL and the operating system. See section Filesystem manipulation functions in that document for information on file and directory information and manipulation functions in Allegro CL.

# delete-directory

Function, excl package

Arguments: pathname

The new `:osi` module (see Operating System Interface Functionality in os-interface.html), released after the release of Allegro CL 6.2, has new operators relating to directory manipulation, including the function rmdir. The new operators do not have separate description pages. They are described in OSI file handling functionality in os-interface.html.

Deletes the directory named by pathname. The directory must be empty. Use delete-directory-and-files to delete a non-empty directory and all its files and subdirectories.

See also os-interface.html for general information on the interface between Allegro CL and the operating system. See section Filesystem manipulation functions in that document for information on file and directory information and manipulation functions in Allegro CL.

# delimited-string-to-list

Function, excl package

Arguments: string delimiter-string-or-char

This function returns a list of substrings of string, separating the original string wherever delimiter-string-or-char appears (the delimiter characters do not appear in any of the substrings). See also list-to-delimited-string.

Examples:

    (delimited-string-to-list "one two three" #\space)

    -> ("one" "two" "three")
    (delimited-string-to-list "one, two, three" ", ")

    -> ("one" "two" "three")

# describe-advice

Function, excl package

Arguments: fspec &optional stream

Starting in Allegro CL release 6.0, the new fwrapper facility, described in fwrappers-and-advice.html, replaces the advice facility, and continued use of the advice facility is deprecated.

This function prints a description of the advice on fspec and then returns `nil`. fspec must be a function name (it is typically a symbol) identifying a function or macro. stream specifies the stream where the description will be written. The default value for stream is `t`, indicating the stream which is the value of *standard-output*.

Advice is described by name and listed in the order in which it runs. The following (rather simple-minded) example shows how the output looks.

See also fwrappers-and-advice.html for general information on the new fwrapper facility and the older, now deprecated, advice facility in Allegro CL.

    ;; Define the function and the advice:
    (defun foo nil nil)
    (excl:advise foo :before jack nil (format t "jack~%"))
    (excl:advise foo :before nil nil (format t "nil 1~%"))
    (excl:advise foo :before nil 100 (format t "nil 2~%"))
    (excl:advise foo :after jill nil (format t "jill~%"))
    (excl:advise foo :after nil nil (format t "nil 3~%"))

    ;; Now when foo is run, the following is printed:

    USR(12): (foo)
    nil 1
    jack
    nil 2
    jill
    nil 3

    nil
    USER(13): (excl:describe-advice 'foo)
    Before advice:
    (nil (format t "nil 1~%"))
    (jack (format t "jack~%"))
    (nil (format t "nil 2~%"))
    After advice:
    (jill (format t "jill~%"))
    (nil (format t "nil 3~%"))

    nil
    USER(14):

# device-buffer-length

Generic Function, excl package

Arguments: stream

Returns the desired length of buffers to be allocated for the stream, if any. This method may be called from almost anywhere (the exceptions are noted in the bulleted list below), and should return a value that is constant for each instance. The method may query the stream (to determine the optimum buffer length for the underlying device), and so the stream must exist before device-buffer-length methods are executed. Therefore, device-buffer-length methods must never be called by

- any before methods on device-open

- any methods on allocate-instance or initialize-instance,

- any methods on device-open, make-instance, or shared-initialize called before the most specific device-open primary method has had a chance to make the actual connection.

Defined methods

- On class: simple-stream: returns 4096.

- On class: null-simple-stream: returns 256.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# device-clear-input

Generic Function, excl package

Arguments: stream buffer-only

When buffer-only is `nil`, clears any pending input on the device connected to stream. May do nothing if buffer-only is true or if the underlying device has no buffering of its own. The buffer-only argument circumvents any hanging when a stream is re-established after a dumped (see dumplisp.html) image has been restarted.

Defined methods

- On class: simple-stream: returns `nil`.

- On class: terminal-simple-stream: non-blocking read-octets is done repeatedly until 0 is returned.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# device-clear-output

Generic Function, excl package

Arguments: stream

If the device connected to stream has functionality to clear any pending output, it is called. Otherwise, no action is taken.

Defined methods

- On class: simple-stream: returns `nil`.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# device-close

Generic Function, excl package

Arguments: stream abort

Called by close as its implementation. An around method first clears the output-buffer of the stream using either force-output (if abort is `nil`) or clear-output (if abort is `t`) The primary method then actually breaks the connection with the device, and the around method sets any external file or window handles or descriptors in the stream object to `nil`, to ensure that they are never used again due to this stream, and also marks the stream as closed, so that CL data-movement stream functions such as read-byte/read-char and write-byte/write-char cannot proceed on the now-closed stream.

device-close must always succeed (i.e. it must never return a failure code or call error), and it cannot take excessive time to perform its job. If it fails to break the connection within a clock tick or some reasonably small time, it gives up and returns with no further action. Leakage of file descriptor or window handles is possible in this case.

Defined methods

In addition to the described around method:

- On class: simple-stream: returns `t`.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# device-file-length

Generic Function, excl package

Arguments: stream

Returns the number of octets (8-bit bytes) in the argument stream if possible (i.e. if the stream represents a device which resembles a file).

Defined methods

- On class: simple-stream: returns `nil`.

- On class: direct-simple-stream: returns the length of the buffer.

- On class: string-simple-stream: returns the length of the string.

- On class: file-simple-stream: the file is queried for its size in octets.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# device-file-position

Generic Function, excl package

Arguments: stream

Returns a positive integer that is the current octet (8-bit byte) position of the device represented by the argument stream, or else `nil` if this position cannot be determined.

This generic function is setf'able. The position of the stream device is changed to reflect the value given, if possible. The value given may be either a positive integer designating the position from the start of the file, or else a negative integer, whose one's complement designates the position backwards from the end of the file. Thus, for example, -1 denotes the end of the file, -2 denotes the last octet from the end of file, -3 denotes 2 octets from the end of the file, etc.

Defined methods

These apply to device-file-position and its setf.

- On class: simple-stream: the current position in the buffer is returned or set.

- On class: string-simple-stream: the length of the string is returned or set. (On fill-pointer-output-simple-stream, the fill-pointer is used).

- On class: file-simple-stream: a seek operation is used to query or set the position.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# device-finish-record

Generic Function, excl package

Arguments: stream blocking action

Performs record-oriented operations on stream. Simple-streams have a record-end slot that normally has a `nil` value. When the slot is set to a numeric value, it is interpreted by the read or write operation as the location in the buffer of the record-end or break. device-finish-record is then called, and the return value is interpreted based on the action specified and the value of blocking. action is typically one of `:input`, `:output`, or `:prime-input` (see the discussion on "priming" in the second bulleted paragraph below). blocking is a boolean which specifies whether or not the method should block during its operation, or else return immediately.

The return value is either true, meaning success, or `nil`, meaning failure. The interpretation of the `nil` return depends on the value of the blocking argument; if `nil`, then device-finish-record failed to complete the requested task. If blocking was true, then a return of `nil` means an eof was encountered (if action was `:input` or `:prime-input`), or an error occurred (if action was `:output`).

Allegro CL offers calls to device-finish-record under the following circumstances:

- string-output-simple-stream: An xp-simple-stream is a subclass of string-output-stream, and thus has character orientation. The pretty printer sets the record-end slot of the xp-simple-stream to the value of *print-right-margin*. Then, when that many characters have been output, the device-finish-record method is called which makes formatting decisions about how and where the accumulated output will be sent to the base stream.

- dual-channel-simple-stream A socket-simple-stream that might do "chunking" sets the record-end slot to a true value while input chunking is occurring (output-chunking does not use record-orientation, but writes chunks out whenever the buffer becomes full or when force-output or finish-output is called). A special value indicates a "priming", and device-finish-record is called with `:prime-input` as action just before the first character is read. This call causes chunking to temporarily be suspended: bytes are read until the #\return #\linefeed combination, and the bytes read indicate the chunk length. The record-end slot is set based on the chunk length. When the chunk length is reached, device-finish-record is called with `:input` action, which reads bytes and expects a terminating #\return #\linefeed combination. If either of these calls to device-finish-record return `nil`, end-of-file processing is done.

There are no usable methods defined.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# device-open

Generic Function, excl package

Arguments: stream slot-names initargs

Number of required arguments changed in release 7.0. In release 6.2, this function had two required arguments, simple-stream and options. In 7.0, it has three. The initargs argument is essentially a new name for the old options argument. device-open now is similar to shared-initialize.

This generic function makes the connection between the stream structure and the actual device being opened, if appropriate, and completes the initialization of the stream structure adequately enough to perform operations on the stream. See below for device-open on string-streams.

device-open is called from an `:after` method on shared-initialize after the CLOS stream is created and initialized. device-open returns true if successful and `nil` otherwise. If unsuccessful, the shared-initialize after method will call device-close on the new stream with `:abort t`. Writers of methods on device-open must be aware that if they `call-next-method` and that returns `nil`, it means that the next-method has failed. The primary method must either install all of the control-character processing tables, external-formats, and instance flags (see section Control-character Processing) or it must call the next more general primary method to do so, modifying the stream to specialize it after such installations, as desired.

Allocation and/or installation of any buffers required for stream operation is also done by the device-open method which is at an appropriate specialization level for use of that buffer. If resourcing of buffers is desired, they may be passed in through make-instance/initialize-instance arguments, or previously installed buffers may be reused.

The device-open method must be prepared to recognize resource and change-class situations. If no filename is specified in the options list, and if no input-handle or output-handle is given, then the input-handle and output-handle slots should be examined; if non-`nil`, that means the stream is still open, and thus the operation being requested of device-open is a change-class. Also, a device-open method need not allocate a buffer every time it is called, but may instead reuse a buffer it finds in a stream, if it does not become a security issue.

The initargs argument is a list of keyword/value pairs. It is restified list of the initargs argument to the shared-initialize :after method (that list is passed to device-open unchanged). Acceptable keywords include the keyword arguments to cl:open (the filespec required argument to cl:open is turned into a physical pathname and passed in the options list paired with the keyword `:filename`). The Allegro CL implementation of cl:open has been extended with additional named keyword arguments and also has `&allow-other-keys` so any keyword may appear as the identifier in the options list processed by device-open. (See the discussion of the Allegro CL implementation of cl:open in implementation.html.)

Additional named keyword arguments include:

- `:class`: the class argument can determine what class to make an instance of, in the same way as in gray-streams.

- `:mapped`: if `:mapped t` is specified, and the file being opened is not a fifo or character-special file, then the file is opened using a mapped-file-simple-stream.

- `:fn-in` and `:fn-out`: these are preserved for compatibility, but are deprecated in favor of the better names, `:input-handle` and `:output-handle`.

- `:input-handle` and `:output-handle`: these allow the specification of an already-opened "device", which can either be an open file descriptor or a stream. If either of these options are used, then cl:open should not be called, but instead make-instance should be called with no `:filename` specified. If a handle is a stream, then the make-instance call is said to encapsulate the stream; the result of the make-instance call is the encapsulating stream, and the handle is the encapsulated stream (which itself may be an encapsulating stream).

The slot-names is provided to distinguish between calls to device-open from a new stream (via initialize-instance, a reused stream from a resource (via reinitialize-instance), or a changed class, and is precisely the same value that was given to the shared-initialize which called device-open. In short, if slot-names is the value `t`, then the operation being performed is an initialize-instance; if slot-names is a non-`nil` list, then a change-class is occurring, and if it is `nil`, then either a change-class or a initialize-instance is occurring.

Current unspecified device-open methods exist on all existing leaf stream classes (ones with no defined subclasses). Device writers must determine whether it is appropriate to use the existing version, or to write one.

device-open for string-streams

device-open methods for string-streams should be :before methods. There is a default primary method that simply returns `t` if the string-stream has been opened properly and returns `nil` otherwise. Users should ensure that they do not overwrite more-specific :before methods (that is, write a :before method for your own subclass but not for classes you have do not defined).

See streams.html for information on the simple-streams implementation in Allegro CL. See particularly these sections in that document: Device-open and From-scratch device-open.

# device-read

Generic Function, excl package

Arguments: stream buffer start end blocking

If buffer is `nil`, and start and end are not eql, then the appropriate buffer slot must be used as the buffer to read into, and the end argument (which will be `nil`) must be taken as if it were specified the number of octets in the buffer. Any manipulation of buffers, including replacement of the buffer slot with a new one of the same size, can be done before returning.

If read-octets is used to implement device-read, and if buffer is passed as `nil`, then read-octets will automatically provide the buffer.

An attempt is made to fill the buffer from start to end with data coming from the device. The number of octets (8-bit bytes) actually read is returned, or else an error or other exceptional situation encode in the following way:

- -1: EOF. This condition is latched into the stream until reset by some operation such as file-position.

- -2 Soft EOF. This value can be returned for a device that might read beyond an eof, such as a terminal (after typing a Control-D). The strategy processes the EOF, but does not leave the stream in that state; the next read will cause another device-read.

- -3: Special return value for a no-hang query. If the start and end arguments are eql and if blocking is nil, then a 0 return means no data will be read, and a -3 value means data would have been read.

- (- -10 errno): the value of the error return from the system operation. For example, -19 represents an errno value of 9, which is EBADF (bad file number) on most systems.

The blocking argument also allows asynchronous reads. If blocking is true, then the read waits until at least one byte can be read (or, if the scheduler is running, the thread waits until at least one byte can be read, allowing other threads to continue meanwhile). If blocking is `nil`, then the read transfers as much as it can immediately and returns the number of bytes read. See Blocking behavior in simple-streams in streams.html.

Note that there is no device-level listen operation. The higher-level streams API implements listen as a query to its buffer possibly followed by a device-read with blocking set to false. If there is no data on the stream, all is well, and the read returns with 0 bytes, allowing a listen operation to return with `nil`. But if there is data on the stream, then it will be read into the given buffer and the higher level operation must take care not to lose this data.

buffer (if not `nil`) must be a specialized simple-array of one dimension. It can be of any size and specialized element-type (its upgraded-element-type must not be `t`). If the element-type is not octet (8-bit byte, signed or unsigned) then the endianness order of bits or bytes is that of the natural order of the native machine. Thus, with an element-type of `(unsigned-byte 32)` on a little-endian machine, a read of the four bytes `#x12`, `#x34`, `#x56`, and `#x78` with start of 0 will be read into the element as the word `#x78563412`. The same byte stream read into a big-endian machine will form the word `#x12345678`.

Note that no checking is done to match the byte-count to element-widths; if three bytes only are read into a four-byte element, the fourth byte is left alone. It is up to the strategy-level programmer (see the end of section Simple-stream Description) to ensure that endianness is matched against the stream, and that data widths are received as expected.

Defined methods

- On classes: single-channel-simple-stream and dual-channel-simple-stream: for both methods, after checking for null buffer and end args, read-octets is called directly and the resulting values returned.

- On classes: null-simple-stream: nothing is called, and -1 is always returned.

- On classes: terminal-simple-stream: A return value of -1 (latching eof) is turned into -2 (non-latching eof).

Note that the supplied device-read and device-write functions do not generate errors themselves, but pass them back to the higher level for processing. This allows read-octets and write-octets to pass errors back as well, as the implementation of a higher level (encapsulating) device-read and device-write.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# device-write

Generic Function, excl package

Arguments: stream buffer start end blocking

device-write is called to transfer data to the device or to do a no-hang query on the device.

Data Transfer

If start and end are not eq, then an attempt is made to transfer data from the buffer (from start to end) to the device specified by stream.

If buffer is `nil`, then the appropriate buffer slot must be used as the buffer to write from. Any manipulation of buffers, including replacement of the buffer slot with a new one of the same size, can be done before returning.

buffer (if not `nil`) must be a specialized simple-array of one dimension. It can be of any size and specialized element-type (its upgraded-element-type must not be `t`). If the element-type is not octet (8-bit byte, signed or unsigned) then the endianness order of bits or bytes is that of the natural order of the native machine. Thus, with an element-type of `(unsigned-byte 32)` on a little-endian machine, a write of the value `#x12345678` will result in the byte stream `#x78`, `#x56`, `#x34`, `#x12`, whereas on a big-endian machine the resulting byte stream will be `#x12`, `#x34`, `#x56`, `#x78`.

Note that no checking is done to match byte-counts to element-widths. It is up to the strategy-level programmer (see the end of section Simple-stream Description) to ensure that endianness is matched against the stream, and that data widths are sent as expected.

The output-handle slot of stream can either be an operating-system file descriptor/handle, or another stream. If it is another stream, then device-write performs the equivalent of a write-vector on that stream, instead of getting the data from the operating system. Arguments and return values are adjusted to agree with the interfaces between device-write and write-vector.

The blocking argument allows asynchronous writes. If blocking is true, then the write waits until the first element of the buffer is written (or, if the scheduler is running, the thread waits until output can be continued, allowing other threads to continue meanwhile). Because device-write is a B/NB (blocking/non-blocking) function, when blocking blocking is true, the function blocks on the first element only, and does not block thereafter. See Blocking behavior in simple-streams in streams.html.

If blocking is `nil`, then the write transfers as much as it can immediately.

The number of octets (8-bit bytes) actually written is returned (so a positive return value indicates success). Errors and other exceptional situation are encoded as specified in the 'Return values' section below.

No-hand query

If the start and end arguments are eql and if blocking is nil, then the caller is requesting a no-hang query on the device. device-write should return 0 if no data can be written, and a -3 if data could have been written.

Return values

- 0: No data could be written. It is likely that the stream has become clogged with data, and is rejecting further attempts to write.

- -3: Special return value for a no-hang query. -3 means data could have been written.

- (- -10 errno): the value of the error return from the system operation. For example, -19 represents an errno value of 9, which is EBADF (bad file number) on most systems.

Defined methods

- On classes: single-channel-simple-stream and dual-channel-simple-stream: for both methods, after checking for null buffer, write-octets is called directly and the resulting values returned.

- On classes: null-simple-stream: nothing is called, and the entire request `(- end start)` is returned.

- On classes: socket-base-simple-stream: chunking is supported.

Note that the supplied device-read and device-write functions do not generate errors themselves, but pass them back to the higher level for processing. This allows read-octets and write-octets to pass errors back as well, as the implementation of a higher level (encapsulating) device-read and device-write.

See streams.html for information on the simple-streams implementation in Allegro CL. The older but still supported Gray streams implementation is described in gray-streams.html.

# digest-file

function, excl package

Arguments: md-name filespec return

You may need to evaluate `(require :digest)` to load the digest code before calling this function.

Using digest-init, digest-update, and digest-final, compute the hash on the contents of the file given by filespec.

name can be one of the symbols md2, md4, md5, sha1, sha224, sha256, sha384, sha512, and rmd160, specifying the type of hashing.

This function returns the value of digest-final on the implicitly created context. The return argument is passed to digest-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# digest-final

function, excl package

Arguments: context &key return

You may need to evaluate `(require :digest)` to load the digest code before calling this function.

Compute and return the hash from context, in a format determined by the return keyword argument. digest-init returns a context (and you specify the hashing type in that call).

return can be one of the following values:

- `:integer` (the default): the return value is an integer (typically a large integer) representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octet(s) containing only zeroes. Care should be taking when using this return type if you intend to further encode the signature (such as to a base64-encoded string). See the example below.

- `:usb8`: return an usb-8 array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (digest-init 'md5))
    #(1 35 69 103 137 171 205 239 254 220 ...)
    cl-user(5): (digest-update c "foo")
    cl-user(6): (digest-final c :return :usb8)
    #(172 189 24 219 76 194 248 92 237 239 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to DIGEST-FILE which calls
    ;;  DIGEST-FINAL and returns the value MD5-FINAL returns.
    ;;
    ;;  Here we get the md5 value in a shell:
    %  openssl dgst -md5 -hex cmp05-optdialog.jpg
    MD5(cmp05-optdialog.jpg)= 03c6f3f0ede5188ac49c30e11e7afa4e

    ;; Now we get it with DIGEST-FILE:
    cl-user(17): (digest-file 'md5 "~/cmp05-optdialog.jpg")
    5020706479262241505478555770059160142
    cl-user(18): (format t "~x" *)
    3c6f3f0ede5188ac49c30e11e7afa4e
    nil
    cl-user(19):

    ;; Note the hex values are the same but the leading 0 is not printed
    ;; by Lisp, which is dealing with the value as an integer. The leading
    ;; 0 is preserved when the :return is :hex:
    cl-user(21): (digest-file 'md5 "~/cmp05-optdialog.jpg" :return :hex)
    "03c6f3f0ede5188ac49c30e11e7afa4e"
    cl-user(22):

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# digest-init

function, excl package

Arguments: name

You may need to evaluate `(require :digest)` to load the digest code before calling this function.

Returns an initialized context for the hashing specified by name, used by the other digest functions.

name can be one of the symbols md2, md4, md5, sha1, sha224, sha256, sha384 sha512, and rmd160, specifying the type of hashing.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# digest-string

function, excl package

Arguments: name string start end external-format return foreign

You may need to evaluate `(require :digest)` to load the digest code before calling this function.

Using digest-init (which creates a context), digest-update (which updates the context with the argument string), and digest-final (which calculates the hash of the resulting context), this function computes the hash for string.

name can be one of the symbols md2, md4, md5, sha1, sha224, sha256, sha384, sha512, and rmd160, specifying the type of hashing.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context.

To use the entire string, specify 0 for start and `nil` (or `(length string)`).

You can use :default as the value of external-format to use to the default external format. These arguments, along with string, are passed to digest-update.

The format of the result, just as for digest-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See digest-final for information on these values and the corresponding formats of the returned value.

If foreign is non-`nil`, then string must (despite the argument name) be an integer address in foreign memory (such as what would be passed to sys:memref) and the bytes contained at that address are used as the input to the digest function.

    cl-user(4): (digest-string 'md5 "foo" 0 nil :default :integer nil)
    229609063533823256041787889330700985560
    cl-user(5): (digest-string 'md5 "foo" 0 nil :default :usb8 nil)
    #(172 189 24 219 76 194 248 92 237 239 ...)
    cl-user(6):

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# digest-update

function, excl package

Arguments: context data &key start end external-format foreign

You may need to evaluate `(require :digest)` to load the digest code before calling this function.

Add data to the running hashing computation in context (digest-init returns a context). data may be a string or an (unsigned-byte 8) vector or (if foreign is true) an integer.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

If foreign is non-`nil`, then data must be an integer address in foreign memory (such as what would be passed to sys:memref) and the bytes contained at that address are used as the input to the digest function.

This function returns no values, but side-effects context.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# directory-size

Function, excl package

Arguments: dirname &key roundup

Returns the size, in bytes, of all the files in dirname, which should name a directory, and all its subdirectories. The contents of all subdirectories of pathname are included in the total.

If roundup is given and true, its value should be a positive integer. The size of each file will be rounded up to be a multiple of that value and the sum of all the rounded values will be returned as the size. The default on Unix is `nil`. The default on Windows is 32000. On many Windows machines using a fat file system (and having a disk holding more than one gigabyte), the actual space used by a file is rounded up to be a multiple of 32k, whence the default value.

See also os-interface.html for general information on the interface between Allegro CL and the operating system. See section Filesystem manipulation functions in that document for information on file and directory information and manipulation functions in Allegro CL.

# discard-all-source-file-info

Function, excl package

Arguments:

This function removes all source file information previously recorded in this incarnation of Allegro CL. Users may wish to use this function before a call to dumplisp, if source file information will be incorrect when Lisp is restarted. Further, source file information can take up a lot of space. Discarding it makes space available for other uses.

See also source-file-recording.html for general information on source file recording in Allegro CL.

# discard-local-name-info

Function, excl package

Arguments: &optional scopes-only

Functions compiled with the compiler switches save-local-scopes-switch and/or save-local-scopes-switch true will store additional information to assist debugging. Calling this function will cause that information to be discarded allowing you to dump a smaller image with dumplisp. When scopes-only is `nil` (the default), this function will discard all name and scope information in the current image. When scopes-only is true, scope information is discarded but name information is kept. After calling this function, debugging becomes harder (of course) so this function is typically called just before calling dumplisp, after you have finished debugging.

See debugging.html for more information on debugging.

# double-float-p

Function, excl package

Arguments: object

Returns `t` if the argument is a double-float and returns `nil` otherwise.

See also single-float-p and fixnump.

# double-float-to-shorts

Function, excl package

Arguments: double-float

Returns four values, each 16-bit unsigned numbers that represent 16 bits of the double-float, starting from the highest significant 16 bits, and ending with the lowest significant 16 bits. No consing is done, except that the pseudo-resourced multiple-values-vector might be consed the first time after a scavenge. Each succeeding call will reuse the values vector normally.

See also single-float-to-shorts, shorts-to-single-float, and shorts-to-double-float.

# dribble-bug

Function, excl package

Arguments: &optional pathname

This function is an extension of the Common Lisp function dribble. dribble-bug called with the optional pathname argument calls print-system-state to print an informational header at the top of the dribble file (and also calls the functions on the list which is the value of *dribble-bug-hooks*). The header will contain information on, among other things, the lisp-implementation-type, lisp-implementation-version, machine-type, machine-version, software-type, software-version, short-site-name, the value of *features*, and all loaded patches.

If the optional argument is not provided, dribbling to the file is stopped and the file is closed. Note that nested dribbles are not supported, either with this function or dribble. Calling dribble or dribble-bug with a pathname argument while a dribble is in effect closes the current dribble before opening a new one.

See also *dribble-bug-hooks*.

# dribble-for-dxl-header

Function, excl package

Arguments: &optional pathname

This function returns no values but as a side effect writes a file which is appropriate as the dxl-header argument to dumplisp. This function is similar to dribble, and can be used in a similar manner to dribble, except for the extra manipulation of the output file upon close of the dribble. It is recommended that this function not be mixed with dribble, since dribble doesn't know about the requirements of the dxl-header format.

With a pathname argument, a dribble file is started with a file by that name and a #\1 character is written to the file. Dribbling will progress normally until this function is called without the pathname argument, at which time spaces are filled in to complete the dxl-header and the size character is written to the beginning of the file.

dxl-header Format

The dxl-header argument to dumplisp, when non-`nil`, must specify a file which is an even multiple of 8192 octets long, up to (* 9 8192) octets in all. Each octet should be a latin-1 character, and the first character in the file must be one of the characters in the range from #\1 to #\9. When the lisp is dumped to a .dxl and then in a Unix-like shell the head command is used, the first parts of the dxl-header are shown.

# dumplisp

Function, excl package

Arguments: &key name ignore-command-line-arguments suppress-allegro-cl-banner dxl-header

This function saves an image of the currently executing Common Lisp as an image file. This file (which usually has extension .dxl) is not executable, but is suitable as the image argument to the executable files such as mlisp or mlisp8 on Unix machines or mlisp.exe or mlisp8.exe on Windows (and alisp[.exe] or alisp8[.exe]). You can specify the name of the image file created with the name keyword argument. The name defaults to savedcl.dxl. Thus, calling in Lisp

    (dumplisp)

will produce an image file savedcl.dxl.

dumplisp will fail if there are too many oldspaces. The limit depends on a complex formula, but is around 2000. You can see how many oldspaces there are by calling `(room t)`. You can consolidate oldspaces with resize-areas. The error message when there are too many is Error: Too many regions. Consolidate oldspace with resize-areas and retry if you get this error.

This image can be started with the command line (use whichever of m/alisp or m/alisp8 was used to start the image that was dumped):

    UNIX 16-bit: mlisp -I <directory containing savedcl.dxl>/savedcl.dxl
    UNIX 8-bit: mlisp8 -I <directory containing savedcl.dxl>/savedcl.dxl

    WINDOWS 16-bit: mlisp.exe -I <directory containing savedcl.dxl>/savedcl.dxl
    WINDOWS 8bit: mlisp8.exe -I <directory containing savedcl.dxl>/savedcl.dxl

On Windows, .dxl is usually registered as an Allegro CL image file extension, so double-clicking on it in the File Explorer should also start Allegro CL with that image. Note too on Windows that if the image contains the IDE, then adding `-f ide:start-ide` to the command line will cause the IDE to be started automatically when the image starts.

The following table gives brief descriptions of the arguments. See the notes for more information on specific arguments and the warning that follow the notes. See dumplisp.html for more information on dumplisp.

- name

  - value should be a string naming a file (default "savedcl.dxl"). Image files must have an extension. The usual extension is dxl but any non-null extension will do.

  - side effect: the dumped image will have this name. If no directory is specified, the file will be written to the current working directory.

    See Warning below.

- ignore-command-line-arguments

  - value should be `t` or `nil` (default `nil`)

  - side effect: if true, command-line-arguments prefaced with a `-` (a dash) are ignored during startup and all such arguments are considered application arguments (see command-line-arguments and related functions). Arguments prefaced with a `+` (which are applicable to Windows only) are never ignored. See Command line arguments in startup.html for details of command-line arguments.

    See Note 2 below.

- suppress-allegro-cl-banner

  - value should be `t` or `nil` (default `nil`)

  - side effect: The Franz Inc copyright banner will not be printed on startup.

    See Note 3 below.

- virtual
  - *value should be `t` or `nil` (default `nil`)
  - side effect: See Virtual dumplisp: for very large images and pseudo-forks on Windows> for details. This argument is for Windows only. It allows dumping most data to a virtual file for use by additional Lisp processes, thus approximating a fork.
- dxl-header
  - value should be `nil` or a file designator (default `nil`)
  - side effect: if non-`nil`, the value should designate a file which is formatted properly to be a dxl file header. See the notes below for the requirements for such a file. The contents will be placed at the head of the resulting dxl file, and viewable with head or more or other appropriate operating system utilities.

Notes:

1. These arguments from earlier (than 5.0) Unix releases are no longer supported: checkpoint (if `t`, tried to restart actual computational state, no longer possible); standalone (the separate executable/image model means an image cannot be standalone).

2. See The emacs-lisp interface and dumped images in dumplisp.html for information on starting the emacs-lisp interface when ignore-command-line-arguments is true (the interface is usually started by a command-line argument).

3. When the* suppress-allegro-cl-banner* keyword argument is true, then the following warning is issued:

4. Requirements for a dxl header file: the file must be an even multiple of 8192 octets long, up to (* 9 8192) octets in all. Each octet should be a latin-1 character, and the first character in the file must be one of the characters in the range from #\1 to #\9. The function dribble-for-dxl-header will format a Lisp dribble in an appropriate manner to be a suitable dxl header file.

You are allowed to suppress (i.e., not display) the Franz Inc. supplied copyright banner in your application, if and only if you agree to display Franz Inc. copyright and proprietary notices wherever you display your own copyright or other proprietary notices.

Warning: This function depends on the current running Lisp image file to be present and readable (i.e. it cannot be read-protected) and not stripped. Therefore you cannot delete that file before running dumplisp and you cannot specify that file as the value of the name argument.

See also dumplisp.html, building-images.html, and delivery.html.

# ef-composee-ef

Function, excl package

Arguments: external-format

Returns the value in the `composee` slot of the argument external-format. A value of `nil` means external-format is not composed. See also ef-composer-ef and compose-external-formats.

See iacl.html.

# ef-composer-ef

Function, excl package

Arguments: external-format

Returns the value in the `composer` slot of the argument external-format. A value of `nil` means external-format is not composed. See also ef-composee-ef and compose-external-formats.

See iacl.html.

# ef-name

Function, excl package

Arguments: external-format

This function returns the name of the argument external-format.

Examples:

    (def-external-format :test)
    (ef-name (find-external-format :test)) -> :test

See iacl.html for more information on international character support in Allegro CL.

# ef-nicknames

Function, excl package

Arguments: external-format

This function returns the list of nicknames of the argument external-format.

Examples:

    (def-external-format :test :nicknames '(:testey :testich))
    (ef-nicknames (find-external-format :test)) -> (:testey :testich)

See iacl.html for more information on international character support in Allegro CL.

# ef-nulls

Function, excl package

Arguments: external-format

The argument must be an external-format object. This function returns the number of null (0) octets that must trail an external string represented using the argument external-format. For Franz Inc. supplied external-formats, the ef-nulls return value is 1 for 8-bit based external-formats; and 2 for 16-bit based external-formats (e.g., :fat and :unicode).

See def-external-format. See iacl.html for more information on international character support in Allegro CL.

# ef-width

Function, excl package

Arguments: external-format

This function returns the number of octets it takes to build a character in the argument external-format. It may have an integer value or the value `character`. The width slot of an external format is used to optimize listen techniques in a stream; by default listen requires at least ef-width octets to be available before returning true. Normally this means having to go through the process of building a character, but in simple formats, like latin1, availability of a single octet can allow a true return from listen.

See def-external-format. See iacl.html for more information on international character support in Allegro CL.

# encode-extended-time

Function, excl package

Arguments: second minute hour date month year &optional time-zone

This extension of encode-universal-time accepts years prior to 1900 and may (therefore) return negative numbers. When the year is 1900 or later, the value returned is the same as that returned by encode-universal-time.

Handling of two digit years

encode-universal-time treats two-digit years (like 04 or 99 or 55 -- one digit years are considered two digit years with the first digit 0) as the year ending in those digits nearest the current year (see encode-universal-time for the exact formula). In 2015, year 4 means 2004, year 99 means 1999, and year 55 means 2055. In 2050, 4 still means 2004, 55 still means 2055, but 99 means 2099.

encode-extended-time accepts any year, including one and two digit years from 0 to 99 (and from -99 to -1 but those are not legal year values for encode-universal-time). Therefore, one or two digit years are taken as absolute years, not relative to the current year.

Year 0 and calendar type

The standard calendar has positive years (referred to as Common Era or CE years) and negative years (refered to as Before Common Era or BCE years) but no year 0. Extended time allows for a year 0, and so you must subtract 1 from any non-positive year to get the correct BCE value. It also assumes that the Gregorian calandar extends back forever. (The Gregorian calendar is the modern calendar used more or less throughout the world, though many places also use other calendars, particularly when calculating religious dates.) In fact, it was adopted in 1582 CE and so dates prior to that year will not necessarily correspond to the dates found in documents and inscriptions prior to 1582 CE.

    ;; For values in the universal time range (after midnight, January 1,
    ;; 1900 GMT) ENCODE-UNIVERSAL-TIME and ENCODE-EXTENDED-TIME return
    ;; the same values so long as a 4 (or more) digit year is specified:
    cg-user(35): (encode-universal-time 0 0 10 15 4 2015 8)
    3638109600
    cg-user(36): (encode-extended-time 0 0 10 15 4 2015 8)
    3638109600

    ;; For values outside the universal time range, ENCODE-UNIVERSAL-TIME
    ;; errors and ENCODE-EXTENDED-TIME returns a negative value:
    cg-user(37): (encode-universal-time 0 0 10 15 4 1850 8)
    Error: Illegal year: 1850.
    [condition type: simple-error]
    cg-user(38): (encode-extended-time 0 0 10 15 4 1850 8)
    -1568786400

    ;; For two digit years, ENCODE-UNIVERSAL-TIME returns the value for
    ;; a year within 50 years of the current year, while
    ;; ENCODE-EXTENDED-TIME assumes the actual two-digit year and so
    ;; returns a negative value:
    cg-user(39): (encode-universal-time 0 0 10 15 4 15 8)
    3638109600
    cg-user(40): (encode-extended-time 0 0 10 15 4 15 8)
    -59475794400

    ;; ENCODE-EXTENDED-TIME accepts negative year. This is for 10:00 AM
    ;; March 15, 44 BCE. The ides of March. Caesar is being or is about
    ;; to be assassinated in Rome. (But see note in example on the
    ;; DECODE-EXTENDED-TIME page.)
    cg-user(41): (encode-extended-time 0 0 10 15 3 -43 -1)
    -61308802800
    cg-user(42):

See also decode-extended-time, string-to-universal-time, and universal-time-to-string.

# enough-pathname

Function, excl package

Arguments: pathname &optional defaults

Similar to enough-namestring except returns a pathname rather than a namestring.

Examples

    (enough-namestring "/foo/bar/baz.cl" "/foo/bar/")
     RETURNS "baz.cl"
    (enough-pathname "/foo/bar/baz.cl" "/foo/bar/")
     RETURNS #p"baz.cl"

See enough-namestring and pathnames.html.

# ensuring-compiled-body

macro, excl package

Arguments: &body body

This macro is like progn, in that is executes the forms in body sequentially, but when a ensuring-compiled-body form is encountered in interpreted code, it wraps the code body in a `lambda`, processes it with compile-lambda-expr-in-env, and funcalls the result.

Here is this macro being used by the Allegro CL implementation of cl:time, as an example of its use:

    (defmacro time (form)
      `(ensuring-compiled-body
        (excl::time-a-funcall #'excl::time-report *trace-output*
                        #'(lambda () ,form))))

See Compiling individual forms or groups of forms in compiling.html.

# eol-convention

Function, excl package

Arguments: stream

This function queries the stream's external-format to obtain information on the end-of-line convention being used. It returns two values: a symbol indicating the end-of-line convention and an external-format.

The first returned value is one of the following values:

- `:dos`: stream's external format is a composed external format with a DOS-style end-of-line convention (carriage-return linefeed at the end of each line).

- `:mac`: stream's external format is a composed external format with a Macintosh-style end-of-line convention (carriage-return but no linefeed at the end of each line).

- `:unix`: stream's external format is not a composed external format and has a UNIX-style end-of-line convention (linefeed but no carriage return).

- `:anynl-unix`: on input, any convention (dos-style carriage-return linefeed, unix-style linefeed and mac-style carriage-return) is correctly read and converted to a Lisp `#\newline`. On output, `#\newline`s are converted to linefeed (unix-style).

- `:anynl-dos`: on input, any convention (dos-style carriage-return linefeed, unix-style linefeed and mac-style carriage-return) is correctly read and converted to a Lisp `#\newline`. On output, `#\newline`s are converted to carriage-return linefeed (dos-style).

- `:anynl-mac`: on input, any convention (dos-style carriage-return linefeed, unix-style linefeed and mac-style carriage-return) is correctly read and converted to a Lisp `#\newline`. On output, `#\newline`s are converted to carriage-return (mac-style).

The nature of the second returned value depends on whether stream's external format is or is not a composed external format. If stream's external format is not a composed external format (i.e. the first returned value is `:unix`), stream's external format is returned as the second returned value. If stream's external format is a composed external format, the second returned value is the composee (which translates Lisp characters to octets) external format. This allows easy construction of a new composed external format based on stream's, if desired. Composed external formats are described in Composed External-Formats.

You can change the end-of-line convention using setf and this function. Specify one of the keywords specified above as the first return value or specify the keyword `:anynl`. When you specify `:anynl`, no change is made if the first return value is `:anynl-unix`, `:anynl-dos`, or `:anynl-mac`, and `:unix` is changed to `:anynl-unix`, `:dos` is changed to `:anynl-dos`, and `:mac` is changed to `:anynl-mac` (and the second returned value is changed appropriately).

The `:anynl` value allows you to have streams read files using any standard end of line convention while still writing files using the machine-appropriate convention. This makes importing files for input much easier.

Modifying the external format of a stream

The eol-convention of a stream may be modified if you explicitly set the external format of a stream and so you may have to reset the eol-convention to the desired value.

Examples

    [On Windows]
     (setq s (open "c:/autoexec.bat")) -> stream

     ;; The stream is currently set to read/write Ascii 13 followed by Ascii 10
     ;; as/for #\newline.
     (eol-convention s) -> :dos #<external-format ...>

     ;; Set the stream so that it reads/writes Ascii 13 as/for #\newline
     (setf (eol-convention s) :mac) -> :mac #<external-format ...>

     ;; Set the stream so that it reads/writes Ascii 10 as/for #\newline
     (setf (eol-convention s) :unix) -> :unix #<external-format ...>

     [On Unix]
     (setq s (open "/etc/passwd"))

     ;; The stream is currently set to read/write Ascii 10 as/for #\newline
     (eol-convention s) -> :unix #<external-format ...>

     ;; Set the stream so that it reads/writes Ascii 13 followed by
     ;; Ascii 10 as/for #\newline.
     (setf (eol-convention s) :dos) -> :dos #<external-format ...>

     ;; Set the stream so that it reads/writes Ascii 13 as/for #\newline
     (setf (eol-convention s) :mac) -> :mac #<external-format ...>

     ;; Set the stream so that it reads any standard end of line
     ;; and writes Ascii 13 for #\newline
     (setf (eol-convention s) :anynl-mac) -> :anynl-mac #<external-format ...>

     ;; Set the stream to the UNIX default
     (setf (eol-convention s) :unix)
     ;; Set the stream so that it reads any standard end of line
     ;; and writes Ascii 10 for #\newline
     (setf (eol-convention s) :anynl) -> :anynl-unix #<external-format ...>

See also #\newline discussion.

# errorset

Macro, excl package

Arguments: *form &optional announce catch-breaks

The expression form is evaluated and if no errors are signaled, then the first value returned by the macro will be `t` and the remaining values will be the values returned by form. If an error is signaled, then the single value `nil` is returned. If the value of the announce argument is true, then the error message associated with the error will be printed, otherwise, nothing is printed. The default value for announce is `nil`.

A call to break is not ignored (you do go into a break loop) unless catch-breaks is true, in which case a warning message is printed and `nil` is returned.

This macro predates the Common Lisp condition system. We recommend using the condition system in preference to this macro where possible. This macro is retained mostly for backward compatibility.

# euc-to-string

Function, excl package

Arguments: eucvector &key drop-last-null

This function is obsolete. Users are encouraged to use octets-to-string instead of excl:euc-to-string. The equivalence is as follows:

    (octets-to-string eucvector :end (if* drop-last-null
                    then (position 0 eucvector)
                    else (length eucvector))
            :external-format :euc)

This function converts an EUC vector (which must have type `(unsigned-byte 8 (*))` to a Lisp string. If the value of the drop-last-null keyword argument is `t` (the default), then if the last character in eucvector is a null character, it is not included in the Lisp string.

See iacl.html for information on character sets in Allegro CL.

# exceptional-floating-point-number-p

Function, excl package

Arguments: object

Returns true if object is a floating-point infinity or nan. Returns `nil` otherwise.

The actual value when true should not be depended upon, beyond its not being `nil`. The actual value may change in a new release or in an update without notice.

See also nanp and infinityp and the section on Floating-point infinities and NaNs, and floating-point underflow and overflow in implementation.html.

# exit

Function, excl package

Arguments: &optional code &key no-unwind quiet

This exits to the shell or OS, without querying the user, returning code to the program which invoked Common Lisp. code must be an integer whose range is determined by the Operating System, and hence the value may be truncated for large integers.

The keyword argument no-unwind defaults to `nil`. When it is `nil` exit causes each process to throw out of its current computation thereby executing all outstanding unwind-protect cleanup forms (see process-kill). If an error occurs during the execution of an unwind-protect cleanup form or the process becomes inactive, then exit could hang forever waiting for the process to die. exit prints the name of processes on which it is waiting. Processes which cause exit to hang indefinitely (because the error causes the process to enter a break level) can be killed manually from another window or editor buffer, or exit can be interrupted with C-c. Note, if exit is executed again after being interrupted, the unwind-protect which caused it to hang will likely not do so again, because execution will already have exited the offending unwind-protect; for this reason, exit could possibly be re-evaluated.

The keyword argument quiet defaults to `nil`. If it is specified true, information about what Lisp is doing as it exits, normally printed, is suppressed.

If no-unwind is true, then exit does not evaluate unwind-protect cleanup forms. Therefore, evaluating the form

    (exit 0 :no-unwind t)

should always cause Lisp to exit.

See also *exit-cleanup-forms* which is a list of forms to evaluated before exiting.

See How to exit Lisp in startup.html.

A non-zero code on Windows

For images started on Windows with default command-line arguments, a non-zero code will cause the Lisp console to remain alive. In this picture, we show an mlisp window after evaluating `(exit 12 :quiet t :no-unwind t)`:

There is no active prompt, but all exit messages are preserved. Note this happens even if the console is not visible and there is no apparent way to make it visible. (There is often no console visible if you are running Lisp as a service on Windows.) To ensure calling exit with a non-zero code in fact causes Lisp to fully exit on Windows, start the image with the +M option. See the table Command line arguments starting with a + [Windows only] in Command line arguments in startup.html for more information.

# explain-compiler-settings

Function, excl package

Arguments: &key speed safety space debug compilation-speed

This function causes an informational message to be printed to the terminal. The message describes compiler settings and their effect on code optimization. The value returned by each compiler switch when presented with the values of space, safety, speed, debug, and compilation-speed is also displayed. The keyword arguments default to the current settings in the environment.

See the section Examining the current settings and their effect in compiling.html.

# fasl-open

Function, excl package

Arguments: name &rest args

Returns a stream open to file named name. This function is the same as the following call to cl:open:

    (open *name* :element-type (unsigned-byte 8)
          :if-exists :supersede :direction :output *args*)

Thus it returns a stream suitable as the first argument to fasl-write. Note that fasl-write will not close an open stream passed to it so you must close streams opened by fasl-open explicitly. fasl-open cannot be used with fasl-read.

See The fasl reader/writer in miscellaneous.html for more information on this function, fasl-read and fasl-write.

# fasl-read

Function, excl package

Arguments: file

This function loads the data previously written to a file using fasl-write. The return value is a list of the data items written to the file. The list will have one element for each invocation of fasl-write used in creating the file. The data returned is independent of the value of *package* when fasl-read is called.

The file argument must be a filename specified as for load. Standard load search-list processing is done on this name to find a file to load (see Search lists in loading.html). The file that is loaded must have been written using fasl-write.

Version warning: a fasl file from one version of Allegro CL is usually unreadable in another

The fasl file format often changes in new releases and in general, fasl files written by a release will not be readable in a later release. Therefore, all data written to a fasl file should also be available in another readable format (such as a text file). The purpose of the fasl reader/writer is to allow data storage and retrieval in a single Allegro CL release on a single platform (fasl files written on one platform also may not be readable on another). Its advantage is that data does not have to be converted to its printed representation prior to being written (that conversion takes a significant amount of time for complex objects). Long term data storage should be in a generally readable format.

Floating-point numbers can be stored as octal values which can be read back exactly and are portable across versions and platforms. See single-float-to-shorts and double-float-to-shorts.

Application note

fasl-read and fasl-write require the compiler so they are not available in application images without the compiler.

See The fasl reader/writer in miscellaneous.html, and see fasl-write.

# fasl-write

Function, excl package

Arguments: data stream &optional fasl-circle compile-verbose

fasl-write writes coded data that can be loaded later to recreate a Lisp data value. The function's return value is unspecified. The coded data written to the file is independent of the value of *package* when fasl-write is called. The compiler must be in the image executing the fasl-write. A file written by fasl-write can be read by fasl-read.

The data argument specifies the data item to be written. It can be any Lisp value built from the following data types: cons cells, hashtables, symbols, numbers (integers, floats, ratios, complexes), characters, strings, structures, vectors and arrays (simple or non-simple, general or specialized), and functions.

The data cannot at this time include CLOS objects, streams, stacks, or c-allocated data (cstructs).

The value of the stream argument must be a string naming the file to be written or an open output stream with element-type (unsigned-byte 8) or one opened by fasl-open. If a string is supplied then a file with this name will be opened, with option `:if-exists` `:supersede`. If a stream is supplied, then fasl-write will put the coded form of the data argument in the stream without performing open or close operations. This allows writing several data values to a file so that all can be read later.

The fasl-circle argument specifies whether shared or circular structures should be handled. If this argument is passed and is `nil`, then fasl-write will perform no checking for circular or shared structure. If it is passed and is true, then checking will be done. If it is omitted, then the value of `comp::*fasl-circle*` determines whether checking is to be done, a true value of `comp::*fasl-circle*` forcing the check for shared/circular structure. Note that eq-ness of uninterned symbols within the data object is maintained even if the fasl-circle argument does not cause general checking for sharing. When the data object is subsequently read in, new instances of the uninterned symbols will be created, but only one new uninterned symbol will be created for each distinct uninterned symbol in the data.

Note that structure sharing cannot be maintained across separate calls to fasl-write.

Version warning: a fasl file from one version of Allegro CL is usually unreadable in another

The fasl file format often changes in new releases and in general, fasl files written by a release will not be readable in a later release. Therefore, all data written to a fasl file should also be available in another readable format (such as a text file). The purpose of the fasl reader/writer is to allow faster data storage and retrieval in a single Allegro CL release on a single platform (fasl files written on one platform also may not be readable on another). Long term data storage should be in a generally readable format.

Application note

fasl-read and fasl-write require the compiler so they are not available in application images without the compiler.

See The fasl reader/writer in miscellaneous.html for more information on fasl-read and fasl-write.

# fast-and-clean

macro, excl package

Arguments: &body body

This is a direct replacement for `(excl::fast (atomically ...))` when that was used to warn of a loss of expected efficiency (fast and atomically were not exported or documented). It will provide the same warnings and the same generated code that the old combination gave. The new macro exists to provide self-documentation of the intended use.

Lisp interrupts and gc requests are honored only at certain points in Lisp code. The compiler verifies that during the execution of body there are no checks for Lisp interrupts or gc requests. If the compiler detects that this assumption may be violated, an error is signaled at compile time. This form is similar in effect to with-delayed-interrupts, but no explicit interrupt or gc check is made; an interrupt or gc check will occur at the next function call or loop iteration.

The following well intentioned code does not work:

       (let (did-x did-y)
         (unwind-protect
            (progn
              (incf x)
              (setq did-x t)
              (incf y)
              (setq did-y t)
              (do-something-with-x-and-y))
           (when did-x (decf x))
           (when did-y (decf y))))

If an interrupt resulting in a throw should happen between the incf and setq, it could fail to decrement one of the values.

This will work correctly, but will involve some run-time overhead to suppress and check for interrupts.

       (let (did-x did-y)
         (unwind-protect
            (progn
              (with-delayed-interrupts
                (incf x)
            (setq did-x t)
                (incf y)
            (setq did-y t))
              (do-something-with-x-and-y))
           (with-delayed-interrupts
             (when did-x (decf x))
             (when did-y (decf y)))))

This works correctly with no overhead:

       (let (did-x did-y)
         (unwind-protect
            (progn
              (fast-and-clean
                ;; We add declarations to avoid any calling.
                (the fixnum (incf (the fixnum x)))
            (setq did-x t)
                (the fixnum (incf (the fixnum y)))
            (setq did-y t))
          (do-something-with-x-and-y))
           (fast-and-clean
             (when did-x (the fixnum (decf (the fixnum x))))
             (when did-y (the fixnum (decf (the fixnum y)))))))

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# featurep

Function, excl package

Arguments: feature-or-list-of-features

This function returns true if the argument correctly describes the state of the *features* list and `nil` if it does not. feature-or-list-of-features can be any atom or list acceptable to the reader macros #+ and #- (and so can include not, and and or and can contain sublists). Note that the `:version>=` extension used by Allegro CL is often useful (see Reader macros and cl:features in implementation.html). The Allegro CL style is for features to be keywords. If the argument is an atom, the subsequence of *features* starting at that feature is returned if it is present and `nil` if it is not.

Examples:

    (excl:featurep :gsgc) -> (:gsgc :clos ...)
    (excl:featurep :foo) -> nil
    (excl:featurep '(and (or :unix :foo))) -> t

# file-access-date

Function, excl package

Arguments: path

Returns (or sets with setf) the time of last access to the file named by path (which must be a pathname object or a string naming a path). An access is a read or a write of the file. The time is returned as a universal time value. The functions universal-to-unix-time and unix-to-universal-time are useful in converting between universal time (the number of seconds since midnight 1/1/1900) and UNIX time (the number of seconds since midnight 1/1/1970).

This function causes the `:osi` module to be loaded. See The Operating System Interface (OSI) module in os-interface.html. Also see file-write-date.

# file-archive-p

Function, excl package

Arguments: pathname-or-string

In earlier releases, this function was exported from the `aclwin` package. Now its home package is `excl`, though it is still exported from `aclwin` for compatibility.

Returns whether this existing file or directory is an archive. Applications use this flag to mark files for backup or removal. Errors if pathname-or-string does not name an existing file or directory.

# file-attributes

Function, excl package

Arguments: pathname-or-string

In earlier releases, this function was exported from the `aclwin` package. Now its home package is `excl`, though it is still exported from `aclwin` for compatibility.

If pathname-or-string names an existing file or directory, returns the values `t`, and the values returned by file-read-only-p, file-hidden-p, file-system-p, file-directory-p, file-archive-p, file-normal-p, and file-temporary-p. Otherwise returns `nil`.

# file-character-position

generic-function, excl package

Arguments: simple-stream

This generic function tries to determine the character position of its simple-stream argument, similar to stream-line-column which tries to determine the character number from the beginning of a line. The value returned is a non-negative integer or `nil`.

`nil` means that the value cannot be determined. This can happen, for example, if bytes rather than characters have been read from simple-stream or the file-position has been set. Unlike stream-line-column, which can re-synchronize itself after reading a newline, file-character-position cannot; it can only re-synchronize itself when the file-position starts at zero and only characters are read.

# file-contents

Function, excl package

Arguments: filespec &rest open-arguments

This function returns a vector containing the contents of the file specified by filespec. filespec may be a pathname, a string naming a file, or a stream open to a file.

The open-arguments arguments are the same as the arguments to cl:open, except the direction keyword argument is ignored and the if-does-not-exist keyword argument defaults unconditionally to `nil` (recall that in calls to cl:open, the default for if-does-not-exist depends on the values of other arguments).

The element-type argument to cl:open specifies the type of vector that will be created (which will be upgraded-array-element-type applied to the specified element-type). If element-type is not specified, it defaults to `character` and the result is a string. For a byte array containing the file contents, specify `(unsigned-byte 8)`. Basically, the function is intended for element-types `character` and `(unsigned-byte 8)`. Specifying other element types will work but may produce an unspecialized array (element-type t) which would not be suitable as data when setf'ing this function.

If file-contents is being called to simply hold the contents of a file, for example for later writing out, then element-type should be `(unsigned-byte 8)` rather than `character`. Using `character` involves an external-format overhead, and you have to be sure to specify the same external-format when writing the file as was used when reading the file. `(unsigned-byte 8)` avoids both problems. Note further when using `character`: if you don't specify an external-format (as the value of the external-format to cl:open included among open-arguments) when calling file-contents, then the default external-format (which comes from the current *locale* setting) may not correctly represent all characters.

The behavior if the file specified by filespec does not exist is determined by the if-does-not-exist argument (to cl:open and thus to this function). For this function, that argument defaults to `nil` so `nil` is returned if the file does not exist and if-does-not-exist is unspecified.

This function is setf'able. The setf function has argument list

Arguments: vector pathname &rest open-arguments

The standard setf form is, of course:

    (setf (file-contents pathname) vector)

The setf function also accepts keyword/value pairs suitable to be passed to the function cl:open, but direction and element-type are not accepted. The element-type passed to cl:open is the array-element-type of vector. Warning: if the element-type of the vector is not suitable as an element-type for cl:open, the call to cl:open will fail. `t` is not suitable as an element-type to cl:open. `character` and `(unsigned-byte 8)` are both, of course, suitable.

# file-directory-p

Function, excl package

Arguments: pathname &key (follow-symbolic-links t)

Returns `t` if pathname names a directory and `nil` if it names a file. `nil` is also returned if pathname does not exist.

The behavior when the pathname argument names a symbolic link depends on the follow-symbolic-links argument. When true (the default), symbolic links are followed and `t` or `nil` is returned as the resolved link is or is not a directory. When follow-symbolic-links is `nil` and pathname names a symbolic link, `nil` is returned regardless of what the link resolves to (since pathname is a symbolic link, not a directory).

## Symbolic link example

    ;; Suppose we have:
    $ ls -ld foo tmp
    lrwxrwxrwx  1 ueer ftp    3 Feb  4 14:48 foo -< tmp/
    drwxr-xr-x. 7 user ftp 4096 Feb  1 12:47 tmp/
    $

    ;; In Lisp we have:
    ;;
    cl-user(3): (file-directory-p "foo" :follow-symbolic-links nil)
    nil
    cl-user(4): (file-directory-p "foo" :follow-symbolic-links t)
    t
    ;; :follow-symbolic-links defaults to t:
    cl-user(5): (file-directory-p "foo")
    t

# file-hidden-p

Function, excl package

Arguments: pathname-or-string

In earlier releases, this function was exported from the `aclwin` package. Now its home package is `excl`, though it is still exported from `aclwin` for compatibility.

Returns whether this existing file or directory should be excluded from an ordinary directory listing. The CL function directory will still include hidden files. Errors if pathname-or-string does not name an existing file or directory.

# file-normal-p

Function, excl package

Arguments: pathname-or-string

In earlier releases, this function was exported from the `aclwin` package. Now its home package is `excl`, though it is still exported from `aclwin` for compatibility.

Returns whether this existing file or directory is neither a read-only, hidden, system, temporary, nor archive file nor a directory. Errors if pathname-or-string does not name an existing file or directory.

# file-older-p

Function, excl package

Arguments: file-1 file-2

If file-1 and file-2 both exist, and if file-1 is older than file-2, this function returns `t`. Otherwise, it returns `nil`. It is not an error if one or both of the argument files do not exist: `nil` is simply returned in that case.

# file-read-only-p

Function, excl package

Arguments: pathname-or-string

In earlier releases, this function was exported from the `aclwin` package. Now its home package is `excl`, though it is still exported from `aclwin` for compatibility.

Returns whether applications are not allowed to write to or delete this existing file or directory. Errors if pathname-or-string does not name an existing file or directory.

# file-system-p

Function, excl package

Arguments: pathname-or-string

In earlier releases, this function was exported from the `aclwin` package. Now its home package is `excl`, though it is still exported from `aclwin` for compatibility.

Returns whether this existing file or directory is part of, or is used exclusively by, the operating system. Errors if pathname-or-string does not name an existing file or directory.

# file-temporary-p

Function, excl package

Arguments: pathname-or-string

In earlier releases, this function was exported from the `aclwin` package. Now its home package is `excl`, though it is still exported from `aclwin` for compatibility.

Returns whether this existing file or directory is being used for temporary storage. Errors if pathname-or-string does not name an existing file or directory.

# find-composed-external-format

Function, excl package

Arguments: external-format1 external-format2

external-format1 should be either a macro-based composing external-format or an encapsulated-based composing external-format. The function returns the composition of external-format1 with external-format2.

If external-format1 is a macro-based composing external-format, then if external-format2 is in runtime mode (i.e., its defining macros have been removed), an attempt is made to reload external-format2's original definition through the find-external-format autoload mechanism in order to complete the composition. If the autoload fails, then the function signals an error.

See also compose-external-formats. See iacl.html for more information on international character support in Allegro CL.

# find-external-format

Function, excl package

Arguments: name &key (errorp t) (load-prebuilt t) try-variant verbose

name should be either a symbol naming an external-format or a list of (possibly nested) external-format names. This function returns the external format object whose name or one of whose nicknames is name. If no such external-format exists, then an attempt is made to autoload the external-format by performing the following:

    (ignore-errors (require :ef-[name]))

where `[name]` is name.

When name is `:default`, find-external-format returns the external-format associated with *locale* (the current locale, see External formats and locales in iacl.html).

If the attempt to autoload fails, the behavior is controlled by the errorp keyword argument. If its value is true (which is the default), then if the attempt to autoload fails, an error, of condition type no-external-format-error, is signaled. If errorp is false, then find-external-format returns `nil` if the attempt to autoload fails.

If the value of the load-prebuilt is true (which is the default), then if an external-format matching name is located and/or successfully loaded, find-external-format will also autoload Allegro CL system code corresponding to the external-format. Such code is referred to as prefilled-ef-template code (see generate-filled-ef-templates), and its inclusion in the lisp eliminates the need for the external-format convertors. If the prefilled-ef-template code is successfully loaded by find-external-format, then find-external-format calls switch-ef-to-runtime on the external-format to discard the external-format's convertor macros as well as structures needed by the convertors.

If the value of the try-variant is true (the default is `nil`), then if find-external-format is unable to find an external-format that exactly matches the passed in name argument, or if find-external-format is unable to find an external-format whose nickname includes the specified name argument, then it will try variants on the specified name argument. See the example below. Note that we do not document the rules for try-variant and updates and/or patches may change them.

verbose binds *load-verbose* and defaults to `t`. When an external-format is switched to runtime mode a message is printed or not based on this variable.

Examples:

    (pushnew ':new-utf8-nickname
             (ef-nicknames (find-external-format ':utf-8)))
    (eq (find-external-format :utf-8)
        (find-external-format :new-utf8-nickname)) --> t

Here is an example using the try-variant argument.

    ;; This example assumes that only those external-formats
    ;; included with the release are available

    (find-external-format :iso-8859_1 :try-variant nil :errorp nil)
    -> nil
    ;; returns false when :iso-8859_1 doesn't match an existing or
    ;; autoloadable external-format. But

    (find-external-format :iso-8859_1 :try-variant t)
    -> <the iso8859-1 external-format>
    ;; returns the iso8859-1 external-format since
    ;; find-external-format tries some known variants to produce
    ;; possible matching external-format names. Note that you may
    ;; see a different external format identifier.

See iacl.html for more information on international character support in Allegro CL. See particularly External-Format Overview and Retrieving Existing External-Formats in that document.

# find-locale

Function, excl package

Arguments: name

name can be a locale or a string naming a locale or a symbol (in which case, the symbol-name is used) or a locale. If name is a locale, then name is returned.

If name is a string designator, then this function looks through all locales returned by all-locales to find a locale whose locale-name matches (i.e., is equalp to) name. If one such locale is found, it is returned.

If no such locale is found, then if the name includes a charset specification (i.e., has a period followed by a charset name), then the charset specification is passed to find-external-format and a base-locale is retrieved by calling find-locale recursively on name with the charset specification stripped. If both the charset specification names an external-format and the base-locale is a valid locale, then this function creates a new locale using all the slots of base-locale except for the external-format slot, which is set to the external-format corresponding to the specified charset.

If name does not specify a charset and it does not name an existing locale in Lisp, then this function searches the directory specified by *locales-dir* for a file with name's pathname-name and calls load-localedef on that pathname. If no such file exists with name's pathname-name, then a file in that directory whose name's prefix matches name may be selected. This search is case-sensitive. In this way, Allegro CL autoloads locale definitions.

If no locale or suitable file is found, `nil` is returned.

Examples:

    (find-locale "pl")
      -> #<locale "pl_PL" [(:e-crlf :iso8859-2-base)] @ #x204de7ca>
    (find-locale "en_US")
      -> #<locale "en_US" [(:e-crlf :latin1-base)] @ #x204e5812>
    (locale-external-format (find-locale "en_US.iso8859-1"))
      -> #<external-format (:e-crlf :latin1-base) @ #x20096d02>
    (locale-external-format (find-locale "en_US.shiftjis"))
      -> #<external-format (:e-crlf :shiftjis-base) @ #x2053dde2>

General information on international character set support in Allegro CL is in iacl.html. See particularly External formats and locales in that document.

# find-system

Function, excl package

Arguments: system-name &optional errorp

This function returns the system object associated with the name system-name.

If errorp is supplied and is `t`, then an error is signalled if no system named system-name exists. If errorp is not supplied or is `nil`, then `nil` is returned if no system named system-name exists.

    USER(18): (defsystem :my-serial-sys ()

    (:serial "my1" "my2"))
    MY-SERIAL-SYS
    USER(19): (find-system :my-serial-sys)
    #<DEFSYSTEM:DEFAULT-SYSTEM "MY-SERIAL-SYS" @ #x6b5b4e>
    USER(20):

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# fixnump

Function, excl package

Arguments: x

Returns `t` if the argument is a fixnum and returns `nil` otherwise.

    cl-user(2): (fixnump 1)  ;; 1 is a fixnum is any Common Lisp
    t
    cl-user(3): (fixnump most-positive-fixnum) ;; defined to be a fixnum
    t
    cl-user(4): (fixnump (1+ most-positive-fixnum))
      ;; defined not to be a fixnum
    nil
    cl-user(5): (fixnump 1.0) ;; floats are not fixnums
    nil
    cl-user(6): (fixnump t) ;; works (returning NIL) for
                            ;; values that are not numbers
    nil
    cl-user(7):

See also single-float-p and double-float-p.

# format-arg-count-stats

Function, excl package

Arguments: &optional action path tag

This function uses the value of *format-arg-count-stats* to report on format string compilations. The value of that variable should be a list of six fixnums and this function returns a list based on those values (and returns `nil` if *format-arg-count-stats* is not a list of six fixnums).

The exact behavior depends on the value of action:

- action is omitted or any value other than `:report` or `:reset`: return the list of six fixnums that is the value of *format-arg-count-stats* (return `nil` if *format-arg-count-stats* is not a list of six fixnums).

- action is `:report`: return a list of the form

      (:format-arg-stats :all N1 :missing N2 :equal N3 :extra N4 :complex N5 :error N6)

  where the Ni are the six fixnums in the list that is the value of *format-arg-count-stats*. (Return `nil` if *format-arg-count-stats* is not a list of six fixnums.) See below for an interpretation of the values.

- action is `:reset`: behavior is the same as for `:report` but additionally the value of *format-arg-count-stats* is set to (list 0 0 0 0 0 0). Again return `nil` if *format-arg-count-stats* is not a list of six fixnums but reset the value of *format-arg-count-stats* in that case as well.

The six value are:

1. (`:all`): the number of format forms examined (should equal the sum of remaining values).

2. (`:missing`): the number of format forms with insufficient arguments (N needed, fewer than N supplied).

3. (`:equal`): the number of format forms with just as many arguments supplied as needed.

4. (`:extra`): the number of format forms with more arguments supplied than needed.

5. (`:complex`): the number of format forms that are too complex to analyse.

6. (`:error`): the number of format forms that contain a syntax error.

Statistics about compilation of format forms are collected when compilation is done so that the comp:verify-format-argument-count-switch compiler switch has the value `t`, 1, 2, 3, or 4. If that switch has the value `nil` or 0 when the compilation is done, no statistics are kept.

The path and tag arguments

If the path argument names an existing file, one or two line will be appended to the files. If *compile-file-pathname* is non-`nil`, its value and the value of tag will be written to the first line and the list with labels will be written as the second line. If *compile-file-pathname* is `nil`, just one line will be written, the list with labels.

path can also be a stream suitable for writing to.

See Checking format forms during compilation in miscellaneous.html for more information.

# free

Function, excl package

Arguments: address

Gives the object allocated by malloc back to the system. free should not be called with an address which was not directly generated by excl:malloc or else generated from translating an address generated by the C malloc() function, and it should not be called with an address which represents an already-freed object.

Note on backward compatibility

In releases prior to 7.0, the symbols excl::malloc and excl::free named functions that were different from the functions named by the now exported symbols excl:malloc and excl:free. The old versions of excl::malloc and excl::free are equivalent to aclmalloc and aclfree. If any code from Allegro CL 6.2 calls excl::malloc or excl::free, those calls should be changed to calls to aclmalloc and aclfree.

Note on various Allegro CL malloc and free functions

The space allocated by excl:malloc and its C counterpart malloc() (described here collectively as "malloc") is different than the space allocated by excl:aclmalloc and the C aclmalloc() (described collectively as "aclmalloc"). Malloc allocates in space defined and maintained by the system, in whatever manner the system defines. Some operating systems allow the linking in of alternate versions of malloc() and its cohorts (usually including free(), calloc(), realloc(), and others), giving some flexibility in debugging malloc bugs (but of course this need arises much less often in Lisp programming). The aclmalloc functionalities are part of the Allegro CL library and allocate from space usually known as Aclmalloc heap space. aclmalloc is useful for allocating objects which should survive the rebirth of a dumped lisp.

The free and aclfree functionalities must always match objects to free with the mallocs of the same kind; i.e. one should never free an aclmalloc'd object, nor should one call an aclfree function on an object created with malloc. Note that one can mix aclmalloc/aclfree with aclmalloc-aligned/aclfree-aligned, but only after proper conversions are done; see ff:address-to-aligned and ff:aligned-to-address.

# fspec-first

Function, excl package

Arguments: fspec

Function specs in Allegro CL have internal and external representations. The external representation is a list but the internal representation is more complicated. This function returns the first element of the function spec argument regardless of whether the representation is internal or external.

See the section Function specs in implementation.html, and fspec-second, and fspec-third.

# fspec-second

Function, excl package

Arguments: fspec

Function specs in Allegro CL have internal and external representations. The external representation is a list but the internal representation is more complicated. This function returns the second element of the function spec argument regardless of whether the representation is internal or external.

See the section Function specs in implementation.html, and fspec-first, and fspec-third.

# fspec-third

Function, excl package

Arguments: fspec

Function specs in Allegro CL have internal and external representations. The external representation is a list but the internal representation is more complicated. This function returns the third element of the function spec argument if there is one (returns `nil` if there is not) regardless of whether the representation is internal or external.

See implementation.html, particularly section Function specs and also fspec-first, and fspec-second.

# ftrace

Function, excl package

Arguments: function-spec &key condition break-before break-after inside not-inside print-before print-after show-stack

Starts tracing function-spec, which can be a function name (such as a symbol naming a function) or a function object (such as returned by function applied to a symbol naming a function). The related macro trace and top-level command :trace do not accept function objects as arguments.

Thus,

    (ftrace #'foo)

starts tracing of the function object associated with `foo`. See also funtrace. See The tracer and Tracing function objects in debugging.html.

The various keyword arguments (condition, break-before, break-after, inside, not-inside, print-before, print-after) are a subset of those accepted by the :trace top-level command and have the same effect. See that page for details.

The :trace top-level command also accepts the keyword arguments break-all and print-all, which are not accepted by ftrace. To achieve the effect of specifying either of those, specify both the associated before and after arguments as true. Thus, to get the effect of `:print-all t` passed to :trace, specify `:print-before t :print-after t` to ftrace; similarly specify `:break-before t :break-after t` in place of `:break-all t`.

# funcall-stm-handler-2

Macro, excl package

Arguments: slot-name arg1 stream &rest args

You must load the `:iodefs` module to use this macro. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.)

This macro is only valid within a with-stream-class form. The slot-name argument names a slot in the stream which is accessed very quickly. It is expected to contain a function object, which is funcall'ed along with arg1, the stream and the other args. The macro returns whatever values the function returns. This macro is useful for write-like operations, where the stream is the second argument of the function.

You must load the `:iodefs` module to use this macro. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This macro is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# funcall-stm-handler

Macro, excl package

Arguments: slot-name stream &rest args

This macro is only valid within a with-stream-class form. The slot-name argument names a slot in the stream which is accessed very quickly. It is expected to contain a function object, which is funcall'ed along with the stream and the other args. The macro returns whatever values the function returns. This macro is useful for read-like operations, where the stream is the first argument of the function.

You must load the `:iodefs` module to use this macro. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This macro is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# function-name-p

Function, excl package

Arguments: spec

This function returns true if spec is a suitable function name (whether or not it actually names an operator) and returns `nil` otherwise. function-name-p thus returns true when spec is a symbol and when spec is a list of the form `(setf symbol)`. According to the ANS, symbols and lists of that type are the only valid function names.

Allegro CL, however, permits additional lists, defined with def-function-spec-handler, to name functions. If spec is a proper (Allegro CL) function spec, that is one whose fspec-first is a proper function spec name (one defined by def-function-spec-handler) and for which a `:validate` call returns true, function-name-p returns true.

function-name-p has been added because the behavior of the Common Lisp function fboundp has been brought into conformance (with the exception noted). In earlier releases of Allegro CL, fboundp would return `nil` when given an argument which was not a valid function name. Thus, for example, `(fboundp 2)` returned `nil`. However, the ANS requires that fboundp signal an error if passed an argument which is not a valid function name, and return `nil` only for valid function names which do not, in fact, name an operator. This function allows you to modify potentially improper calls to fboundp to avoid errors in 7.0 which would not have been signaled in earlier releases. A call to fboundp can be modified as follows:

    (if (function-name-p spec) (fboundp spec))
    ;; will behave in Allegro CL 7.0 just as
    (fboundp spec)
    ;; did in earlier releases.

The ANS seems to forbid function names other than symbols and lists of the form `(setf symbol)`. Allegro CL allows additional lists, specified by def-function-spec-handler. fboundp does not signal an error when passed a valid Allegro CL function spec, even if it is not an ANS function spec (and thus fboundp is arguably non-conformant).

# funtrace

Function, excl package

Arguments: function-spec

Stops tracing of function-spec, which can be a function name (such as a symbol naming a function) or a function object (such as returned by function applied to a symbol naming a function). The related macro untrace and top-level command :untrace do not accept function objects as arguments.

Thus,

    (funtrace #'foo)

stops tracing of the function object associated with `foo`. See also ftrace. See The tracer and Tracing function objects in debugging.html.

# funwrap

Function, excl package

Arguments: primary-function indicator

Returns the primary function object, after removing the indicated fwrapper. Note that it is not an error to funwrap a primary-function that is not fwrapped, nor is it an error to specify an indicator on which there is no fwrapper; such requests are silently ignored. It is, however, necessary that the primary-function be either a symbol fbound to a function object or else a function object itself.

See fwrappers-and-advice.html for information of fwrapping functions (and on the older, deprecated advice facility).

# fwrap-order

Function, excl package

Arguments: primary-function &key outer inner

Returns the fwrapper property list, after possibly modifying the ordering of the indicated fwrappers. If either or both of outer or inner are specified, then they should be indicators for which the primary-function has an fwrapper. These indicator/fwrapper pairs are moved from the order they are currently in to either the outermost or innermost position depending on which keyword was selected. Both outer and inner may be selected in the same call, but they must not refer to the same indicator.

There is no way to specify the order in one action, but repeated calls to fwrap-order can result in any desired order.

Note: The order of fwrappers is determined before the point of call to the primary function. The behavior is not defined (as to the number and ordering of fwrappers called) if the order is changed while the fwrappers are being executed.

See fwrappers-and-advice.html for information of fwrapping functions (and on the older, deprecated advice facility).

# fwrap

Function, excl package

Arguments: primary-function indicator fwrap-function

Returns the primary function object, after giving it an indicated fwrapper. Arguments primary-function and fwrap-function can each either be a function-spec or the actual function object. indicator may be any object for which eq comparisons are appropriate, as if with getf. Typically this might be a symbol.

The ordering of fwrapped functions is specified as follows: If an fwrapper of the same indicator was present on this primary-function before the call, then the order is not changed; the fwrap call simply replaces that fwrapper with the specified fwrap-function wherever it was previously. If no fwrapper of the same indicator yet existed on this primary-function, then a new fwrapper is established as the outermost fwrapper, i.e. the one which will be called before any others.

The ordering of the fwrappers can be manipulated by using fwrap-order.

Whenever the primary-function is described using describe, all fwrappers wrapped around the primary-function are listed in their outermost to innermost order.

See fwrappers-and-advice.html for information of fwrapping functions (and on the older, deprecated advice facility).

# gb-18030-transcoding-error-char

Function, excl package

Arguments: &optional char-or-code

Release 10.1 and later only. This function queries or modifies the action taken when the `:gb18030` external format encounters a transcoding error, i.e. on output a Unicode character does not have a corresponding GB-18030 encoding or on input an invalid sequence of octets is detected (every valid GB-18030 code sequence has a Unicode equivalent).

If the argument is omitted or `nil`, return the current error character, i.e. the character that is inserted in the input or output stream instead of the invalid source.

If the argument is a character with a code in the single octet range, set the error character to the argument and return the same value.

If the argument is an integer that denotes a valid single-octet Unicode character, set the error character to that character and return it.

Otherwise signal a type error.

See Strict external formats which do not allow improper characters in iacl.html for more information on the `:utf-8s` external format, international characters and external formats in general.

# gc-after-c-hooks

Function, excl package

Arguments:

Returns a list whose entries each represent a C (or C-compatible) function to call after garbage collections of any kind. The typical declaration of the C function can be

    int myafterhook(void);

The list entry itself must be an (unsigned-byte 32) array of at least 1 entry, and its first entry must be the address of the C function.

setf can be used to store into the list.

A typical usage of this feature is

    (let ((myaddr (ff:get-entry-point "myafterhook")))
     (push (make-array 1 :element-type '(unsigned-byte 32)
                         :initial-element myaddr)
           (excl:gc-after-c-hooks)))

No gc hooks are saved across dumplisps. All applications are responsible for re-establishing their own gc-after-c-hooks.

See also gc.html for general information on garbage collection in Allegro CL.

# gc-before-c-hooks

Function, excl package

Arguments:

Returns a list whose entries each represent a C (or C-compatible) function to call before garbage collections of any kind. The typical declaration of the C function can be

    int mybeforehook(int gctype);

where gctype is passed in as 0 if the current gc is a scavenge and 1 if a global-gc.

The list entry itself is typically an (unsigned-byte 32) array, for 32-bit Lisps, or (unsigned-byte 64) or (signed-byte 64) array, for 64-bit Lisps. The array must have at least 1 entry, and its first entry must be the address of the C function. (signed-byte 32) will also work on 32-bit Lisps if the address is small enough or wrapped, if in the upper half of memory. There is no restriction on using a (signed-byte 64) array on a 64-bit Lisp.

setf can be used to store into the list.

A typical usage of this feature is

    ;;  This example is for 32-bit Lisps as it uses (unsigned-byte 32)
    ;;  arrays. For 64-bit Lisps, you can use (unsigned-byte 64) arrays
    (let ((myaddr (ff:get-entry-point "mybeforehook")))
     (push (make-array 1 :element-type '(unsigned-byte 32)
                         :initial-element myaddr)
           (excl:gc-before-c-hooks)))

No gc hooks are saved across dumplisps. All applications are responsible for re-establishing their own gc-before-c-hooks.

See also gc.html for general information on garbage collection in Allegro CL.

Warning: No before hook should ever call back into lisp. The fact that during the hook call a gc is about to begin means that most likely there is no space in lisp heap. Also, it should never be assumed that the callback will not require lisp heap, even if the lisp function itself does not cons. A program whose before-hook calls into lisp may not fail the majority of the time, but it is likely to fail at some inopportune time with disastrous results.

# gc

Function, excl package

Arguments: &optional mode (error t)

This function can be used to trigger a scavenge or global gc and to toggle some gsgc switches. The behavior depends on the mode argument. Possible values for mode and their effects are shown in the table below.

gc returns no values.

If mode is not one of the items in the table below, the system signals an error when error is true (the default) or prints a message that the mode is unknown but does not signal an error when error is `nil`. Thus:

    (gc :foo t)
    -> ERROR: Unknown option to gc: :foo

    (gc :foo nil)
    -> Returns nothing, does nothing, prints:
    Unknown option to gc: :foo

See also gc.html for general information on garbage collection in Allegro CL.

Value of mode:

- `nil`: Perform a scavenge. This is the default.
- `t`: Perform a global garbage collection.
- `:mark-for-tenure`: Mark all surviving objects so that they are tenured as soon as convenient and perform a scavenge. Some or all of these objects may be tenured during the current scavenge and some (perhaps all) may be tenured during a later scavenge. (Objects with lispval-storage-type) `:panified` are never tenured and are thus unaffected.)
- `:tenure`: Perform a scavenge and tenure all surviving objects. All will be tenured when the call to gc completes (contrast with `:mark-for-tenure`, where some surviving objects may not be tenured after the call completes). `(gc :tenure)` will likely take appreciably more time than `(gc :mark-for-tenure)`. (Objects with lispval-storage-type `:panified` are never tenured and are thus unaffected.)
- `:show`: Print the names and current values of gc switches and parameters. This argument does not trigger a scavenge or global gc.
- `:room`: Equivalent to `(room t)`. This argument does not trigger a scavenge or global gc.
- `:print`: Toggles whether messages are printed when a gc occurs. This argument does not trigger a scavenge or global gc.
- `:help`: Prints the list of acceptable values for the type argument. This argument does not trigger a scavenge or global gc.

# gen-sym

function, excl package

Arguments: x

This function is identical to cl:gensym except that a symbol is accepted as its optional argument (as well as the standard string or integer), in which case the symbol-name is used. This is useful for programs that are intended for use in either ansi or modern lisps, where it is desired to print any gensyms without requiring escapes. See case.html for information on ANSI and modern case modes.

# generate-application

Function, excl package

Arguments: application-name destination-directory input-files &rest rest &key allow-existing-directory application-files application-administration application-type copy-shared-libraries copy-file-function debug icon-file demo image-only pure-files purify runtime-bundle include-locales file-version-info [build-lisp-image keyword arguments...] [dumplisp ignore-command-line-arguments keyword argument]

See delivery.html for a complete description of the issues and functionality associated with this function. Note that this function is only available in Enterprise versions of Allegro CL.

This function writes a collection of files to destination-directory. In theory, all the files needed to deliver an application will be in that directory when generate-application completes (but you should test that carefully).

Note that this function calls build-lisp-image and like build-lisp-image, this function does not inherit from the currently running image (except for the defaults for certain arguments).

Note on including SSL in the application. A generated application that includes the `:ssl` module will link at run time to the OpenSSL version determined by the same logic used when `(require :ssl)` is called initially. In other words, the same environment variables and Lisp variables will affect the behavior. See The Allegro CL SSL API in socket.html.

The required arguments:

- application-name: the name of the application (i.e., `"myapp"`). When coerced to a pathname, this name should not have a directory or type. It is used to create the name of the executable or .dll or .so or .sl (whichever is appropriate for the platform) and ancillary files.

- destination-directory: the name of a non-existent directory. It is the directory used to create the output files. See image-only keyword argument below.

- input-files: the list of Lisp (.fasl or .cl) files to be loaded, strings or pathnames. Symbols are allowed and signify modules to be loaded with require. These files are loaded after sys:custom.cl is loaded. Note that this argument supersedes the build-lisp-image argument `:lisp-files`. That argument is ignored even if specified to generate-application. The section Use of custom.cl in building-images.html has information on when sys:custom.cl is loaded when an image is built.

The keyword arguments:

- `:allow-existing-directory`: allow destination-directory to exist. If the value of this keyword argument is `nil` and the directory exists, then an error is signaled.

- `:application-files`: files which should merely be copied to the destination directory.

- `:application-administration`: allows the specification of various application administrative tasks. The form of the value of this keyword is

        ` (type-keyword ...)  `

  or

        `((type-keyword ...) (type-keyword ...) ...)`

        `(type-keyword ...) can be:

        `(:resource-command-line "...command line arguments...")`

  This creates a lisprc in the destination directory which sets the default command line arguments to ...command line arguments.... See the Resources section in delivery.html for more information.

        `([:shortcut | :batch-file] filename ...command line arguments...) [Windows only]`

  This creates either a batch file or a shortcut named filename that will initialize the application. For a shortcut, the filename must have type "lnk" (the letter L, the letter N, the letter K). command line arguments are the arguments to application-name.exe. The filename argument should actually be a format control string given one argument, the name of the application. It is used like this: `(format nil *filename* *application-name*)`. This allows the customization of the generated filename based on information generate-application has already been given.

  One use of this is for OLE registration. For example: `'(:shortcut "One-time registration of ~a.lnk" "-register")`

  If the given `application-name` was "foo" this would create a shortcut named One-time registration of foo with the following command line:

        `foo.exe -- -register`

  An error is signaled if application-type is not `:exe`.

- `:application-type`: valid values: `:exe`, `:ole-in-proc-server`, or `:dll`. If `:exe` is used, then an executable file named application-name.exe (on Windows) and application-name (on UNIX) is created.

  If `:dll`, then the application will be used as a dll and no executable file is created. The dll used is the Allegro CL shared library, and the application itself will live in the newly created .dxl file. The Allegro CL shared library is used to initialize the Allegro CL runtime system, which loads the user's app in the .dxl file. See dll.html.

  If `:ole-in-proc-seqrver`, a file is created in the destination directory called application-name.dll. See the OLE samples in ole/samples/sample05/ and ole/samples/sample06/.

- `:autoload-warning`: when true, the file autoloads.out is created that contains the functions, macros and methods that could possibly be autoloaded. Defaults to `t`.

- `:build-executable`: this is a build-lisp-image keyword argument but is also used by generate-application if a value is supplied. The value must name a Lisp executable file (such as mlisp on Unix or mlisp.exe on Windows -- those are the defaults). It is used by build-lisp-image to start the Lisp process that builds the image. Unless image-only is true, generate-application copies a Lisp executable to the application directory. The executable specified as the value of this argument is the one copied.

- `:copy-shared-libraries`: if true, then copy shared objects/libraries that have been loaded with the Common Lisp function load by the time the image is dumped. The value of this keyword argument can also be a lambda expression (you cannot use the function special form, the value must be a list), accepting one argument, that is a predicate which determines if the loaded shared objects should be copied. The one argument is the pathname of the shared object file (the original pathname given to load). The predicate should return `t` if the shared object is to be copied, and `nil` if it is to be ignored by shared-library copying process. The predicate can also return a relative pathname, which will be used as the name of the copied shared library relative to the destination-directory. Note: shared libraries may be specified without a directory path and found using Operating System tools (such as LD_LIBRARY_PATH or PATH), as described in section Load foreign code with cl:load in the foreign-functions.html document. However, the shared library copying functionality will not use Operating System tools to find shared libraries. If a shared library is specified without a directory path and is not in the current directory, it will not be found.

  For shared objects that are copied, the image that is created will load them from the destination directory upon startup. That is, in the image built by generate-application, the name of the shared libraries loaded on startup will be sys:[name], for each [name] copied by generate-application.

- `:copy-file-function`: This function will be used to copy files to the destination directory. The default value is copy-file and that function is likely sufficient for most purposes. However, another function can be used if that is insufficient. This function will be called by the image that calls generate-application (not the image that builds the image).

- `:debug`: more information will be printed about progress as an aid to debugging.

- `:demo`: You must be licensed to produce demos (demonstration applications) to specify a non-`nil` value for this argument. If you are licensed, there is a maximum number of days that a demo will work specified in your license. The value of this argument, if specified and non-`nil`, should be an integer less than or equal the maximum number of days that a demo is allowed to work. The application license written to the application directory will then be valid for that number of days. Contact your Franz Inc. Account Manager (send email to info@franz.com if you do not know who your Account Manager is) for information on the demo license.

- `:image-only`: just build for the image, and possibly the .pll file.

- `:lisp-files`: this build-lisp-image keyword argument is ignored by generate-application. The list of files specified as the value of the required input-files argument is used instead.

- `:pure-files`: a list of .cvs and .str files to be put into the application's .pll file. See Creating and using pll files in miscellaneous.html.

- `:purify`: do automatic purification of Lisp and the application. This means all the strings and code vectors will be put into a .pll file. If you choose this option, do not also specify a value for pure-files.

- `:runtime-bundle`: if true (the default) a bundle file named files.bu will be placed in the application directory. This file contains the modules allowable in a runtime image. This means that such modules need not be loading into the application image during the application build.

- `:include-locales`: if true (the default) the copy-file-function is used to copy the locales/ subdirectory and its contents of the Allegro directory to the application directory being created. Note that the size of the locales/ subdirectory is about 2 Mbytes. You may wish to save space in your application by specifying a copy-file-function that copies only the locales that will actually be needed. See Retrieving Existing External-Formats and Locales in applications in iacl.html.

- `:file-version-info` (Windows only): set values of the application VERSIONINFO (the executable is the .exe file copied to the application directory). The value, of this argument, if specified, should be a list of keyword/string pairs, where the keywords appear in the list returned by file-version-info and the associated value in that list is a cons. See Setting the VERSIONINFO of the application executable on Windows in delivery.html. The following a an example of using this argument:

      :file-version-info '(:company-name "Foo Inc"
                           :product-name "Foo Bar"
                           :legal-copyright "Copyright (C) 2009 Foo, Inc."
                           :product-version "1.0.0.0"))

- `:runtime`: the value defaults to `:standard` and must be either `:standard`, `:dynamic` or `:partners`. See runtime.html.

- build-lisp-image keyword args: generate-application accepts and passes through to build-lisp-image all of build-lisp-image's keyword arguments except for `:lisp-files`. The required input-files argument is used to specify files to be loaded. `:lisp-files`, even if specified, is ignored.

- dumplisp `:ignore-command-line-arguments` keyword arg: generate-application accepts and passes through to dumplisp the `:ignore-command-line-arguments` keyword argument. When true, the resulting image will ignore command-line arguments prefixed by a dash (`-`). Command-line arguments prefixed by a `+` (used on Windows only) are never ignored. See Command line arguments in startup.html for details of command-line arguments.

The function generate-executable is a wrapper for generate-application, producing an application whose input is the command-line arguments. It can be used either as a quick way to create an application, or as an example of using generate-application. The source for generate-executable can be found in the file [allegro cl dir]/src/genexe.cl.

See delivery.html for a complete description of this function.

# generate-executable

Function, excl package

Arguments: name input-files &rest rest

Please note that this function is only available in images licensed for creating runtime images. All Enterprise and above customers are so licensed.

This function is a wrapper for generate-application, producing an application directory containing an application executable/image and other necessary files.

name should be a string naming the application. A directory will be created with that name (with path merged with default-pathname-defaults) for the application files (that directory must not already exist). The image file and the executable will have filename name.

input-files should be a list of files to be loaded into the application. input-files corresponds to the input-files (third required) argument to generate-application. Modules can be specified with keywords which are suitable as arguments to require. (Thus, placing `:sock` on the list causes the Socket module sock.fasl to be loaded; placing `:foreign-functions` on the list causes the Foreign Functions module, foreign-functions.fasl, to be loaded, and so on.)

One of the input-files should define a function named by the symbol `user::main`. This function should accept any number of arguments (that is, its argument list should be `(&rest rest)`) and initiate whatever computation is to be done by the application.

When the application starts up, all the command-line arguments (including the executable name but not the -I or the image name) are collected (as a list of strings) and user::main is called with those strings as arguments, as with the form

    (apply 'user::main [list of command-line argument strings])

The rest arguments should be keyword/value pairs where the keyword names a keyword argument to generate-application.

generate-executable processes its arguments and calls generate-application with a bunch or keyword arguments specified. See the source for the function in the file [allegro cl dir]/src/genexe.cl for information on what keyword arguments are specified and what values are given to them. We discuss some keyword arguments in the notes below.

A note about modules

Allegro CL images do not contain all modules by default. Instead, modules (for functionality like foreign functions, contained in the `:foreign-functions` module, and sockets, contained in the `:sock` module) are loaded when needed. The loading may be automatic (see Autoloading in implementation.html) or may need an explict call to require.

But the important fact to consider when building an application is that modules will not be available in an application unless the module is loaded during the application build or the `:runtime-bundle` keyword argument is specified true in the call to generate-application and thus in the call to generate-executable.

See Including all desired modules in delivery.html. Also, generate-executable generates a file autoloads.out which tells you what modules might be autoloaded in your application (that is, which autoloadable modules are associated with functions in your application) and you can decide whether it is necessary to include the module.

Command-line arguments

The ignore-command-line-arguments keyword argument to generate-application is specified true in the call to generate-executable unless you specify `:ignore-command-line-arguments nil` in the rest. (ignore-command-line-arguments is actually an argument to dumplisp. generate-application accepts it (and all dumplisp arguments) and simply passes it through.)

The command-line arguments that are ignored are the ones prefaced by a `-` (i.e., a dash) specified in Command line arguments in startup.html. Arguments prefaced by a `+` (which are for Windows only) are never ignored. Note: if you specify `:ignore-command-line-arguments nil`, then the `-` prefaced command-line arguments specified to the executable will not be passed to the main function as described. Instead, your main function must access the arguments itself using functions like command-line-arguments.

Calling generate-executable when the directory name exists

generate-executable passes `nil` as the value of the allow-existing-directory keyword argument to generate-application. This means if generate-executable is called with name naming a directory that exists (as would happen, for example, if generate-executable is called twice with the same name without removing the application directory between the calls), a continuable error will be signaled because the directory exists. One restart instructs the system to remove the directory and continue. Aborting and removing or renaming the directory and changing the name so it does not name an existing directory are other options.

Example

Here is an example using generate-executable:

    ;; If foo.cl contains:

    (in-package :user)

    (defun main (&rest args)
      (format t "args: ~s~%" args)
      (force output)
      ;; we sleep for a bit so the args can be seen when
      ;; a window which disappears is used.
      (sleep 5)
      (format t "slept 5 seconds.~%")
      (when (string= "foo" (second args))
        (error "foo!")))

    ;; and then the application can be built with this:

    cl-user(7): :cf foo.cl
    ;;; Compiling file foo.cl
    ;;; Writing fasl file foo.fasl
    ;;; Fasl write complete
    cl-user(8): (generate-executable "foo" '("foo.fasl"))
    ;;; Compiling file /net/killer/tmp/fooa52fe1e.cl
    ;;; Writing fasl file /net/killer/tmp/fooa52fe1e.fasl
    ;;; Fasl write complete
    Initial generation spread = 1
    Allocated 10492920 bytes for old space
    Allocated 5242880 bytes for new space
    ...
    cl-user(9):

    ;; Example run:

    % foo/foo 1 2 3
    args: ("foo/foo" "1" "2" "3")
    % echo $status
    0
    % foo/foo foo 1 2 3
    args: ("foo/foo" "foo" "1" "2" "3")
    foo!
    % echo $status
    1
    %

See generate-application, building-images.html and delivery.html.

# generate-filled-ef-templates

Function, excl package

Arguments: &key external-formats directory (force t)

external-formats should be a list of external-formats. It defaults to the list returned by all-external-formats. directory should be a pathname. It defaults to the value of *default-pathname-defaults*.

When force is true (the default), templates will be rebuilt. That does require the compiler and writable access to sys:. So if there is no compiler or write permission is not available, the argument must be specified `nil` or an error will be signaled.

This function uses compile-file to generate fasl files which, when loaded into Lisp, fill code external-format specific templates used for Allegro CL system code. This function allows users defining their own external-formats to "pre-build" the filled-templates so that, when a filled-template is needed at runtime, the corresponding external-format's filled-templates fasl file can simply be loaded. Allegro CL autoloads this file when needed using require.

If the fasl file does not exist, the template being filled may get built using the Lisp compiler. Thus, the main advantage of using a pre-built filled-ef-templates file is that the compiler is not needed at runtime.

The external-formats argument names the external-formats for which the fasl files are built.

The directory argument names the location where the fasl files are to be created.

The force argument causes the fasl files to be regenerated if they exist. Note that if the fasl file corresponding to an external-format exists and is found to be out of date, it will be regenerated regardless of the value of force.

See iacl.html for more information on international character support in Allegro CL.

# generate-rsa-keys

Function, excl package

Arguments: &key verbose

Generate a pair of RSA keys and return a list of two items: the public key and the private key.

If verbose it true (the default) then generate-rsa-keys will print diagnostic information as it generates the keys. This function generates very large numbers and tries to find prime numbers near those numbers. This can take a long time (perhaps 15 minutes on a slow processor if finding a prime number proves difficult).

The crucial part of generating an RSA key is computing two large prime numbers. Testing whether a number is prime is done in a probabilistic manner. This means that we can't say with 100% certainty that we've found prime numbers and if the key is generated with non-prime numbers then the RSA algorithm will fail to encrypt or decrypt certain values.
A mitigating factor is that all RSA key generators use this probabilistic prime number test and one never hears of cases where it failed.

The resulting modulus value is approximately 1024 bits long.

See rsa-encrypt and rsa-decrypt.

See Support for RSA encryption in miscellaneous.html for information on RSA encryption and RSA encryption support in Allegro CL. There are examples of RSA encryption and decryption in that section. Support for encryption in the same document discusses encryption support in Allegro CL in general.

# get-atomic-modify-expansion

Function, excl package

Arguments: place-form environment safe

This function is called by the atomic-modify macro expanders to find out how to treat place-form. It returns six values:

1. list of generated symbols for subform bindings

2. list of subforms to be bound to the variables in first value

3. generated symbol for variable to get old value from place

4. generated symbol for variable to be set to new value for place

5. conditional atomic write form (will be `nil` if we can't handle this place form atomically)

6. read form

The arguments are:

- place-form: a form designating a place to be read and updated

- environment: a compiler environment or nil

- safe: a boolean; non-nil means we know somehow that the place-form value cannot have changed since we read it, so the conditional-store form can be simplified to an unconditional setf. This is very rarely used.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# get-executable-handle

Function, excl package

Arguments:

Returns the handle of the running Allegro CL. This might be most easily described as the "handle of main()". It is not appropriate in some operating systems, and is thus 0, but in other systems where appropriate, the value can be used in the symbol-lookup functions in a similar manner to the get-shared-library-handle.

See Delaying linking the Allegro CL shared-library until runtime in foreign-functions.html.

# get-fixed-index-assignments

Generic Function, excl package

Arguments: metaclass direct-supers class-name

Release 10.1 and later only. If one value is returned or if the second (map) value is `nil`, then the first slot will be assigned the first returned value, and subsequent slots will be assigned using a simple increment by 1 for each unassigned slot. Note that if a slot in the class being defined is given a fixed-index option, then no assignment is added to that slot, and the increment for the next slot will start from there. If a second value is returned, then it must be a vector of index assignments which will be used to assign fixed-index values to as yet unassigned slots, starting with the second unassigned slot (the first unassigned slot will be assigned based on the first value returned from this generic function). The index values in the map may be in any order - they need not be in ascending order - but they must not conflict with any other fixed-index assignments either in the class being defined or in the superclasses.

The default method

    (method excl:get-fixed-index-assignments (fixed-index-class t t)

This method returns one value: the first index to use which is guaranteed not to conflict with any index values specified by either the class to be defined or any of its superclasses. This style of index assignment could be thought of as an append style; a method on a subclass of fixed-index-class could return a fill style or a hybrid style which could be implemented by returning a map of all of the currently used indexes in the class or its superclasses.

# get-objects

Function, excl package

Arguments: code &key (old t) (new t) weak

The weak keyword argument was added in release 11.0.

This function takes one required argument and three keyword arguments. It returns a heapwalker vector, which is defined below. If weak is true the returned heapwalker array is a weak heapwalker vector rather than a regular heapwalker vector (see the fuller argument description below). Its return value is suitable as the required argument to the related function get-references. Here is more about the arguments:

- code: this argument, which is required, should be a type code, which is a positive integer. Type code are shown in the output of (room t) and also in the output of print-type-counts. See below for an example.

- `:new`: this keyword argument, if true (the default), causes newspace to be searched for objects with the desired type code.

- `:old`: this keyword argument, if true (the default), causes oldspace to be searched for objects with the desired type code.

- `:weak`: default is `nil`. This argument was added in release 11.0. If specified true, causes the returned heapwalk vector to be a weak vector (see Weak vectors, finalizations, static arrays, etc. for more information on weak vectors). This allows the (weak) vector to be useful input to gcpath:find-gc-path without thwarting the finding of the path due to overshadowing by the reference in the heapwalker array.

Since both new and old default to true, if neither is specified, both old and new space will be searched.

Here is a (slightly truncated) output of `(room t)`:

    cl-user(2): (room t)
    area area  address(bytes)        cons         other bytes
      #  type                   8 bytes each
                                 (free:used)      (free:used)
         Top #x20d7a000
         New #x20994000(4087808)   916:15225     843936:3035024
         New #x205ae000(4087808)    -----            -----
       0 Old #x20000aa0(5952864)   711:78771    2098888:3209704
    Root pages: 126
      Lisp heap:    #x20000000  pos: #x20d7a000 resrve: #x20fa0000
    Aclmalloc heap: #xa0000000  pos: #xa0048000 resrve: #xa00fa000
     Pure space:    #x1f8ec000  end: #x1ffff888

    code   type                                 items     bytes
    126: (simple-array (unsigned-byte 16))       10767   2153400 31.4%
    112: (simple-array t)                         8891   1445976 21.1%
      1: cons                                    93996    751968 11.0%
      7: symbol                                  20360    651520  9.5%
      8: function                                 9681    602864  8.8%
    133: sv-vector                               20549    340840  5.0%
    120: (simple-array fixnum)                     259    270272  3.9%
    119: (simple-array code)                       367    192064  2.8%
    117: (simple-array character)                 2396    148960  2.2%
    125: (simple-array (unsigned-byte 8))           19     98720  1.4%
     12: standard-instance                        3900     62400  0.9%
      9: closure                                  2897     50432  0.7%
     15: structure                                1159     47856  0.7%
    127: (simple-array (unsigned-byte 32))          11     12744  0.2%
    [...]

     total bytes = 6856032
    aclmalloc arena:
    [...]

The type codes are given in the first column: 112 for (simple-array t (*)), 117 for strings (also known as `(simple-array character)`), and 127 for `(simple-array (unsigned-byte 32))`. We use 127 in the example below.

get-objects returns a heapwalk vector, which is a simple vector of type t whose first element is the number of objects of the specified type which were found, whose next elements are the objects found, and whose last elements are unspecified (the vector is made somewhat bigger than is necessary). Here is an example where we find objects of typecode 127, which is the code for `(simple-array (unsigned-byte 32))`.:

    cl-user(3): (get-objects 127)
    #(11 #(255 65535 16777215 4294967295) #(32 8224 2105376 538976288)
      #(3960924350 2165561044 562617442 2270225120 1264129478 758582028 172407450
        2782512936 595962478 1609675396 ...)
      #(0 2567483615)
      #(546914304 4087808 916 15225 529448960 536869000 553254912 536870912 843936
        3035024 ...)
      #(3960924350 2165561044 562617442 2270225120 1264129478 758582028 172407450
        2782512936 595962478 1609675396 ...)
      #(3960924350 2165561044 562617442 2270225120 1264129478 758582028 172407450
        2782512936 595962478 1609675396 ...)
      #(200235464 1375865383 2472949741 3729159793 443451277 421802134 4188904507
        2175392005 408067652 1254986169 ...)
      #(3960924350 2165561044 562617442 2270225120 1264129478 758582028 172407450
        2782512936 595962478 1609675396 ...)
      ...)
    cl-user(4): (length *)
    31
    cl-user(5):

The result is a heapwalk vector. The first element is 11, the number of objects of the type of interest. Then those eleven objects. Then some extra elements (19 extra in this case, for a total vector size of 31).

The objects in the heapwalk vector returned by get-objects (that is, the elements with indices 1 through (+ 1 (aref hwvec 0)), where hwvec is the heapwalk vector) are suitable as the required argument to get-references.

See Heap walkers in Allegro CL for more information.

# get-output-stream-buffer

Function, excl package

Arguments: stream &optional detach

Returns two values: the current value out of the output stream buffer for stream and the number of elements written to that buffer. If detach is true, the stream's buffer itself is removed and returned unchanged, and the stream is disabled, otherwise (by default) an `(unsigned-byte 8)` vector is made which is just large enough to hold the current contents of the stream, and the contents are transferred. Also when detach is `nil`, the stream is left in a state where it is empty and ready to accept further output to it.

See streams.html for information on the stream implementation in Allegro CL.

# get-references

Function, excl package

Arguments: object &optional include-stacks

This function accepts an object and returns a heapwalker vector filled with all objects in the lisp heap or in lispstatic space which point directly to the given object. Objects are usually found using get-objects.

A heapwalk vector is a simple vector of type t whose first element is the number of objects of which were found, whose next elements are the objects found, and whose last elements are unspecified (the vector is made somewhat bigger than is necessary). Thus suppose 32 objects referencing object were found. The returned vector will have 32 as its first element, then elements 1 through 33 will be those 32 objects. The vector may have length larger than 33, and the remaining elements, if any, are unspecified.

Note that compound structures might not point to the object directly; for example, if a list has an element within it, the first call to get-references will return only the cons cell whose car is that object; you would have to repeat the get-references on that cons cell to find the cons whose cdr points to it, and so on backward through the list until you find a recognizable structure, symbol, or function that points to the head of the list.

If you call this function interactively then the special variable * tends to show up in the results quite often, because it is changing every time to point to the heapwalker vector result. On the other hand, the result is pretty printed in the listener, and usually you can see the first value in the most recent result. A useful paradigm once you have called get-references the first time is

     (excl::get-references (aref * 1))

which can be repeated to chain backwards through the oldest link to the original object, though sometimes you might want to index a different item, depending on what looks interesting. You may also have to scroll back up the screen, so be sure to do this in a window that can scroll quite a bit (such as an emacs buffer), since the heapwalker vectors will tend to get long after a few iterations.

Note the following:

- Do a (gc t) -- that is, a global gc -- before you start using this tool. Heapwalkers don't care if an object is dead or not, so it may be that you are grabbing objects from the heap which would have otherwise been collected because it was dead.

- *, **, and *** are assigned results from previous invocations of get-references, so it is likely that one of them will be in the next result vector.

The include-stacks argument

The include-stacks argument expands the search for stack objects, providing reasonable results for stack locations. Under the normal rules of get-references, an object seen in a stack location would result in the stack itself being seen in the heapwalker results vector. But because stacks are hard to identify, depending on whether the scheduler is turned on, and also depending on whether virtual threads, os-threads, or smp is impemented, and so the include-stacks options choose to look at stacks on a per-frame basis. Frames are identified by frame-descriptor structs, and are unique per thread. A frame-descriptor might be valid (because its invocation is still dynamically in scope), or invalid (because its execution has terminated). If the frame-descriptor is valid, it can be queried by one of the debugger-api functions (see debugger-api.html, or simply by performing debugger commands such as :zoom and :local when the frame-descriptor is found.

Whenever a frame-descriptor is seen in a results vector due to the include-stacks argument options, it may be necessary to use the new :r option to the :local command to see the raw data - a much expanded view that includes slots of stack-allocated objects. Note that there is no distinction made between a frame-descriptor whose frame has a slot with the object in it and a frame-descriptor which as a lisp struct actually references the object.

The possible values for include-stacks are:

- `t`: besides heap objects which reference the object argument, any frame which holds the object will have its frame-desriptor added to the result vector.

- `:only`: same as `t`, but only those objects which are on the stack and not referenced in the heap will be captured. This is slightly different than other get-references results; the object argument is ignored, and all objects meeting the criterion are placed into the result vector (and not any objects that reference those objects). This might provide a set of objects from which to initiate further get-references calls. This option reveals any truly transient data, but beware: when a result vector has captured such an object it is no longer transient, since it is now also referenced by a lisp object (the now-older results vector).

- `:all`: same as `:only`, but an object meets the criterion even if it is referenced by a heap object. The only criterion for an object to be in the results vector with `:all` is that it be referenced on a stack somewhere.

- `nil` (the default): stacks are not searched at all - only the heap is searched.

See Heap walkers in Allegro CL for more information.

# get-shared-library-handle

Function, excl package

Arguments:

Returns the handle of the Allegro CL shared-library, as passed in to lisp_init (see main.html). If the shared-library was not dynamically-loaded, but statically linked, then the value is 0. A non-zero handle is an integer that can be passed to the operating-system's preferred dynamic-loading system to lookup symbol addresses. See also get-executable-handle and get-shared-library-name.

See Delaying linking the Allegro CL shared-library until runtime in foreign-functions.html.

# get-shared-library-name

Function, excl package

Arguments:

Returns the name of the Allegro CL shared-library (a so/sl/dll/dylib/etc. file).

Here is an example. Note that the name differs on different machines so you may not see this exact name. See also get-shared-library-handle.

    cl-user(103): (get-shared-library-name)
    "libacli61pf4.so"

See Creating Shared Objects that refer to Allegro CL Functionality in foreign-functions.html.

# gf-discriminator-cache

Function, excl package

Arguments: generic-function &optional print

If the print argument is given and true, then no values are returned, and the function is run for side-effect. If print is false or absent them a representation of the cache is returned.

See Appendix: Effective-method selection in Allegro CL CLOS and Associated Optimizations in implementation.html for more information on this function.

# gf-discriminator-type

Function, excl package

Arguments: generic-function

Release 10.1 and later only. Returns the type of the discriminator currently installed in the generic-function. The type can be any of the kinds of discriminatos listed in Generic Function Discriminators in implementation.html, or it can be `excl::redeffed-initial`, which means that the generic-function has not yet been called and so no discriminator function has been created.

See Appendix: Effective-method selection in Allegro CL CLOS and Associated Optimizations in implementation.html for more information on this function.

# gf-discriminator-value

Function, excl package

Arguments: generic-function

Release 10.1 and later only. Returns the value (defined below) for the generic-function, if it exists and is unique. For discriminators which treat the generic-function as a slot accessor, the value is the slot's index into the slot vector (a fixnum). For the checking style discriminator, the value is the effective-method which has only ever been used in calls to this generic-function. Some discriminators do not have a single value stored, but instead the value calculated by the discrminator is either an index or an effective-method stored as part of the cache line held for the discriminator. In this case the value returned by gf-discriminator-value is `nil`.

See Appendix: Effective-method selection in Allegro CL CLOS and Associated Optimizations in implementation.html for more information on this function.

# gf-discriminator

Function, excl package

Arguments: generic-function

Release 10.1 and later only. Returns the discriminator (a function) that is currently installed in the generic-function. The discriminator is also called the funcallable-instance-function `(or fin-fun)` by the MOP.

See Appendix: Effective-method selection in Allegro CL CLOS and Associated Optimizations in implementation.html for more information on this function.

# globalq

Macro, excl package

Arguments: symbol

Because `(system:global-symbol-value 'xxx)` is such a common place for shared data operations, we've introduced a macro to make the source a little easier to read and write. `(globalq x)` is a macro form that expands to `(system:global-symbol-value 'x)` for any symbol `x`.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# ha_descriptor

Function, excl package

Arguments: hash-table

Returns the descriptor component of hash-table. No checking is done that hash-table is in fact a hash-table.

This function is setf'able, and also has a compiler-macro which compiles to very efficient code (i.e. one instruction). Note that neither this function nor its compilation is safe and should be treated with care.

See make-hash-table extensions in implementation.html and Creating user-defined hash-table implementations in miscellaneous.html for more information.

# ha_instance

Function, excl package

Arguments: hash-table

Returns the instance component of hash-table. No checking is done that hash-table is in fact a hash-table.

This function is setf'able, and also has a compiler-macro which compiles to very efficient code (i.e. one instruction). Note that neither this function nor its compilation is safe and should be treated with care.

See make-hash-table extensions in implementation.html and Creating user-defined hash-table implementations in miscellaneous.html for more information.

# hash-primify

Function, excl package

Arguments: int

Returns a positive fixnum suitable for a hash-table size greater than or equal to int, which should be a fixnum. With all fixnums below the limit, the value returned will be a prime number. The value is returned from a table, so the calculation is fast. For fixnums above the limit, the value returned is at least not divisible by 2, 3, 5, or 7. Results lose accuracy as they approach most-positive-fixnum.

Limits:

Limits are approximate, and may change in the future. Currently:

- For 32-bit Lisps, the limit is a fixnum between `(/ most-positive-fixnum 2)` and most-positive-fixnum.

- For 64-bit Lisps, the limit is a fixnum between `(expt 2 47)` and `(expt 2 48)`.

Granularity:

Not all prime numbers are returned. The prime number table is populated with an approximately 2% increment, so the difference between one result and the next possible result (for values of int under the limit) are approximately 2% apart:

    cl-user(1): (excl:hash-primify 100000000)
    100121387
    cl-user(2): (excl:hash-primify (1+ *))
    102123817
    cl-user(3): (float (/ * **))
    1.02
    cl-user(4):

There may be other prime numbers not returned by this function; but because it is the goal of this function to quickly return a size suitable for efficient hash-table operation, populating all primes is not necessary.

# hash-table-hash-function

Function, excl package

Arguments: hashtable

Returns the hash function used by the hashtable specified by the argument. The hash function can be specified when the hashtable is created by make-hash-table. This is an extension to standard CL in Allegro CL. See cl:make-hash-table in implementation.html for details.

# hash-table-values

Function, excl package

Arguments: hashtable

Returns the value of the `values` slot in the hashtable specified by the argument. `values` can be `t`, `nil`, or `:weak`. This is an extension to standard CL. See cl:make-hash-table in implementation.html for details.

# hash-table-weak-keys

Function, excl package

Arguments: hashtable

Returns a list of weak keys in the hashtable specified by the argument. Weak keys can be specified (as an extension to standard CL) by make-hash-table in Allegro CL. See cl:make-hash-table in implementation.html.

# hex-string-to-integer

Function, excl package

Arguments: string &optional (start 0) end

Returns a number which is the conversion of string, which should be a string of hexadecimal digits, such as in a MD5 signature. This function is more efficient than parse-integer. md5-string and other md5 functions and other functions that do similar hashing and return hashing digests can return hex strings.

For example:

    (hex-string-to-integer "deadbeef") => 3735928559

See integer-to-hex-string, which is the inverse of this function, and MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also usb8-array-to-hex-string and hex-string-to-integer.

# hex-string-to-usb8-array

Function, excl package

Arguments: string &key start end

This function converts the portion of string delimited by start and end (defaults: beginning and end of the string) to an array of (unsigned-byte 8). Example:

    (hex-string-to-usb8-array "01020304") ==> #(1 2 3 4)

This function is useful with encryption routines. See, for example, Support for Blowfish encryption in miscellaneous.html. Support for encryption in the same document discusses encryption support in Allegro CL in general.

See also usb8-array-to-hex-string, hex-string-to-integer and integer-to-hex-string.

# hmac-final

Function, excl package

Arguments: context &key return

Finalize and return the HMAC hash from context, in a format determined by the return keyword argument.

The `:return` keyword can have one of the following values:

- `:integer` (the default): the return value is an integer (typically a large integer) representing the digest.

- `:usb8`: return a usb-8 array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-final.

# hmac-init

Function, excl package

Arguments: digest-name key &key external-format

The digest-name argument determines the digest algorithm. Supported digests are :md5, :sha1, :sha224, :sha256, :sha384, and :sha512.

hmac-init prepares and returns a context for use in subsequent calls to hmac-update and hmac-final. The context is initialized according to the key argument. key can be a string or (unsigned-byte 8) array. If key is a string, it is internally converted to an (unsigned-byte 8) array according to the external-format keyword argument (or the default external format, if the keyword argument is not supplied).

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-md5-final

Function, excl package

Arguments: context &key return

This function, while still supported, is out of date. See the new hmac-init, hmac-string, hmac-update, and hmac-final which handle additional digest algorithms.

Compute and return the HMAC-MD5 checksum from context, an integer of length 128 or less. hmac-md5-init returns a context, in a format determined by the return keyword argument.

The `:return` keyword can have one of the following values:

- `:integer` (the default): the return value is an integer (typically a large integer) representing the digest.

- `:usb8`: return a usb-8 array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-final.

# hmac-md5-init

Function, excl package

Arguments: key &key external-format

This function, while still supported, is out of date. See the new hmac-init, hmac-string, hmac-update, and hmac-final which handle additional digest algorithms.

hmac-md5-init prepares and returns a context for use in subsequent calls to hmac-md5-update and hmac-md5-final. The context is initialized according to the key argument. key can be a string or (unsigned-byte 8) array (i.e (unsigned-byte 8) array). If key is a string, it is internally converted to an (unsigned-byte 8) array according to the external-format keyword argument (or the default external format, if the keyword argument is not supplied).

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-md5-string

Function, excl package

Arguments: key string &key external-format return

This function, while still supported, is out of date. See the new hmac-init, hmac-string, hmac-update, and hmac-final which handle additional digest algorithms.

hmac-md5-string returns the hash value of string, given key. 'key' can be a string or usb8 array (i.e (unsigned-byte 8) array). If it is a string, it will be internally converted to a usb8 array according to the external-format keyword argument (or the default external format if the keyword argument is not supplied).

return determines the form in which the hash value will be returned. See the documentation for hmac-md5-final for details.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-md5-update

Function, excl package

Arguments: context data &key start end external-format

This function, while still supported, is out of date. See the new hmac-init, hmac-string, hmac-update, and hmac-final which handle additional digest algorithms.

Add data to the running HMAC-MD5 computation in context (hmac-md5-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

This function returns no values, but side-effects context.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-sha1-final

Function, excl package

Arguments: context &key return

This function, while still supported, is out of date. See the new hmac-init, hmac-string, hmac-update, and hmac-final which handle additional digest algorithms.

Compute and return the HMAC-SHA1 checksum from context, an integer of length 128 or less. hmac-sha1-init returns a context, in a format determined by the return keyword argument.

The `:return` keyword can have one of the following values:

- `:integer` (the default): the return value is an integer (typically a large integer) representing the digest.

- `:usb8`: return a usb-8 array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-sha1-init

Function, excl package

Arguments: key &key external-format

This function, while still supported, is out of date. See the new hmac-init, hmac-string, hmac-update, and hmac-final which handle additional digest algorithms.

hmac-sha1-init prepares and returns a context for use in subsequent calls to hmac-sha1-update and hmac-sha1-final. The context is initialized according to the key argument. key can be a string or usb8 array (i.e (unsigned-byte 8) array). If key is a string, it is internally converted to an usb8 array according to the external-format keyword argument (or the default external format, if the keyword argument is not supplied).

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-sha1-string

Function, excl package

Arguments: key string &key external-format return

This function, while still supported, is out of date. See the new hmac-init, hmac-string, hmac-update, and hmac-final which handle additional digest algorithms.

hmac-sha1-string returns the hash value of string, given key. 'key' can be a string or usb8 array (i.e (unsigned-byte 8) array). If it is a string, it will be internally converted to an usb8 array according to the external-format keyword argument (or the default external format if the keyword argument is not supplied).

return determines the form in which the hash value will be returned. See the documentation for hmac-sha1-final for details.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-sha1-update

Function, excl package

Arguments: context data &key start end external-format

This function, while still supported, is out of date. See the new hmac-init, hmac-string, hmac-update, and hmac-final which handle additional digest algorithms.

Add data to the running HMAC-SHA1 computation in context (hmac-sha1-init returns a context). data may be a string or an usb8 (i.e (unsigned-byte 8)) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

This function returns no values, but side-effects context.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-string

Function, excl package

Arguments: digest-name key string &key (external-format :default) (return :integer)

The digest-name argument determines the digest algorithm. Supported digests are :md5, :sha1, :sha224, :sha256, :sha384, and :sha512.

hmac-string returns the hash value of string, given key. 'key' can be a string or usb8 array (i.e (unsigned-byte 8) array). If it is a string, it will be internally converted to a usb8 array according to the external-format keyword argument (or the default external format if the keyword argument is not supplied).

return determines the form in which the hash value will be returned. See the documentation for hmac-final for details.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# hmac-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running HMAC digest computation in context (hmac-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external message digest of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

This function returns no values, but side-effects context.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# ics-target-case

Macro, excl package

Arguments: &body clauses

This special operator is only relevant for people who are using International Allegro CL (which supports extended character sets). See iacl.html.

Sometimes it is necessary to conditionalize your code depending on whether it will be running on an ICS-capable system. ics-target-case provides this conditionalization, causing the compiler to compile the containing form in both modes. It can be used both at top level of a file compilation and inside a function body. Simple examples:

    (excl:ics-target-case
     (:-ics (defvar banner "Regular Allegro"))
     (:+ics (defvar banner "ICS-Capable Allegro")))

    (defun string-size-in-bytes (string)
     (* 8
     (ceiling (+ 5
                (excl:ics-target-case
                    (:-ics (length string))
                    (:+ics (* 2 (length string)))))
                 8)))

Two alternate versions of both the defvar and the function will be file-compiled, and the correct version selected at fasl load time. In each of the examples, the ics-target-case form could have been wrapped around a different boundary in the code with equivalent effect, for example:

    (defvar banner (excl:ics-target-case
    (:-ics "Regular Allegro")
    (:+ics "ICS-Capable Allegro")))

See also iacl.html for general information on international character set support in Allegro CL.

# if*

Macro, excl package

Arguments: (test-form {then then-form+ | thenret} {elseif else-test-form {then else-then-form+ | thenret}}* [else else-form+])

This form consists of a series of clauses introduced by the symbols `then`, `elseif`, `else`, and `thenret`. First the predicate test-form is evaluated. If it is true, the then-forms are evaluated, and the value of the last such form is returned. If test-form evaluates to `nil`, any remaining clauses are processed. If no clauses remain, if* returns `nil`.

When a `thenret` clause is encountered no further evaluation takes place, and the value of the most recently evaluated test-form is returned.

When an `elseif` clause is encountered, the predicate else-test-form is evaluated. If it is true, the else-then-forms are evaluated, and the value of the last such form is returned; otherwise any remaining clauses are processed. If no clauses remain, if* returns `nil`. And lastly, when an `else` clause is encountered, the else-forms are evaluated, and the value of the last such form is returned.

Examples

    ;; The basic format of a IF* expression is:
    ;;
    ;; (if* [test] then [do this 1] [do this 2] else [do other 1] [do other 2])
    ;;
    ;; When [test] is true, the forms after the THEN are evaluated and the
    ;; result of the last returned; if [test] if false, the forms after the
    ;; ELSE are evaluated and the result of the last is returned.

    ;; So:

    cl-user(18): (if* (> 3 2) then "three is bigger" 3
                         else "three is smaller" 2)
    3
    ;;  Your do not need an ELSE form:
    cl-user(19): (if* (> 3 2) then "three is bigger" 3)
    3
    cl-user(19): (if* (> 2 3) then "two is bigger" 2)
    nil

    ;; You can have multiple fors after THEN or ELSE:
    cl-user(21): (defun foo (x) (if* x then (setq y 2) (print x)
                                     else (setq y -2) "no"))
    foo
    cl-user(22): (foo 2)

    2
    2
    cl-user(23): (foo "hello")

    "hello"
    "hello"
    cl-user(24): (foo nil)
    "no"
    cl-user(25):

    ;; There are two more special symbols: THENRET and ELSEIF.

    ;; THENRET says when the test is true just return the value of the test
    ;; form just evaluated:

    cl-user(25): (if* (+ 4 5) thenret)
    9
    cl-user(26):

    ;; ELSEIF introduces a new test, so you can have compound tests:

    cl-user(27): (setq score 77)
    77
    cl-user(28): (if* (< score 60) then "F"
                         elseif (< score 70) then "D"
                 elseif (< score 80) then "C"
                         elseif (< score 90) then "B"
                         else "A")
    "C"
    cl-user(29): (setq score 55)
    55
    cl-user(30): (if* (< score 60) then "F"
                         elseif (< score 70) then "D"
                 elseif (< score 80) then "C"
                         elseif (< score 90) then "B"
                         else "A")
    "F"
    cl-user(31): (setq score 92)
    92
    cl-user(32): (if* (< score 60) then "F"
                         elseif (< score 70) then "D"
                 elseif (< score 80) then "C"
                         elseif (< score 90) then "B"
                         else "A")
    "A"
    cl-user(33):

# in-case-mode

macro, excl package

Arguments: mode

This macro is designed to assist users who work in one case mode who need to use compiled files written for another mode. Case modes in Allegro CL are described in case.html.

What in-case-mode does is complicated. It is designed as part of a more complex system to support interoperability among modes, but at the moment it is only supported for dealing with the issue of loading files compiled in one mode into a Lisp running in another mode. We give a suggested recipe for loading files compiled in a case mode different from the case mode you are using. This recipe involves using an auxiliary file. We discuss using in-case-mode directly as well, but we recommend using the procedure we describe.

Except when using in-case-mode as described here, trying to load an ANSI-Lisp compiled file into a modern Lisp signals an error. Trying to load a modern-Lisp compiled file into an ANSI Lisp does not signal an error but may nonetheless result in problems.

The value of the mode argument (which is not evaluated) should be either `:local` (corresponding to modern mode) or `:common` (corresponding to ANSI mode).

If you are running a modern mode Lisp (mlisp or equivalent), you should load an ANSI-mode compiled file foo.fasl by writing an auxilliary file aux.cl with the following contents:

    (in-case-mode :common)
    (load "foo.fasl")

If you are running an ANSI mode Lisp (alisp or equivalent), you should load a modern-mode compiled file foo.fasl by writing an auxilliary file aux.cl with the following contents:

    (in-case-mode :local)
    (load "foo.fasl")

You use auxiliary files because load binds relevant variables (such as *readtable* and *case-translation*) which are affected by in-case-mode so when the loading is complete, the values of those variables in the Lisp calling load are unchanged. The auxiliary file can thus be used in any Lisp, ANSI or modern. It need not but can be compiled.

Multiple files can be loading with a single auxiliary file.

You may want to set *ignore-package-name-case* to true when loading files compiled in a different mode.

Restrictions

This method for loading files compiled in another mode does not work in all cases. Specifically, it will not work when:

- You have modified the current readtable (the value of *readtable* to affect its handling of case.

- You are using functionality in modules which do not support in-case-mode, such as the winapi module.

- You are intending for behaviors of intern, make-symbol, find-symbol, and symbol-name to be consistent across in-case-mode invocations of opposite modes. See below for more information on this point.

We recommend loading files compiled in another mode early in a Lisp session.

What in-case-mode does

When in-case-mode is called with mode having the same value as the current value of *case-translation*, nothing is done. When it is called with mode having a different value as the current value of *case-translation*, the following occurs:

- The value of *case-translation* is set to the new mode.

- If the current value of *readtable* (in the current thread) is the same as `(global-symbol-value *readtable*)`, the value of `*readtable*` is set to the result of `(copy-readtable nil)`. (The internal readtable cannot be changed, but copies can be, so this step ensure the value is a copy.)

- The internal Lisp readtable is changed (if mode is `:common`, to an upcasing readtable, if `:local` to a case-sensitive readtable).

- The printer is modified to print according to the mode.

**When the case-translation-gravity is different from the value of case-translation **

When Lisp starts, the value returned by case-translation-gravity and the value of *case-translation* are the same. When you change the mode with in-case-mode, the value of *case-translation* and the value returned by case-translation-gravity are different (the function is unchanged, the value of the variable changes).

When the value returned by the function is different from the value of the variable, the behavior of the functions intern, make-symbol, find-symbol, and symbol-name are changed so that effectively:

- When a string is passed to intern, its case is reversed before being stored (so if the string is "aaa", it is stored as "AAA" and if the string is "AAA", it is stored as "aaa"). Also an alternative name is stored which is the unmodified name. If the string is mixed case, it is not modified and no alternative name is stored. If the reader was involved in creating the string, it is passed to intern after the readtable case etc. is applied.

- When a symbol name is printed or searched for, its alternative name, if there is one, is used. Otherwise the symbol name is used.

Now, in a fasl file compiled in alisp and not using the mixed case names mentioned above, all symbols are named with uppercase letters (because the reader upcased the letters when the symbol name was read). Therefore, when in an mlisp in :common mode, that fasl file is read, the symbol names are stored downcased but (while the mode is :common) referenced upcased. If the symbol AAA is encountered, its name is stored as "aaa" and it is given an alternative name "AAA" which is also stored. If the symbol CAR is encountered, the system checks for "car" and finds the Common Lisp symbol of that name. An alternative name "CAR" is created and stored for that symbol. (We will discuss what we mean by "stored" below.)

When the mode is changed back to :local, the symbol names are still stored downcased and because case-translation-gravity and the value of *case-translation* are the same, the alternative names are no longer used.

Using in-case-mode in individual files

We recommend using in-case-mode in an auxiliary file as described, but you can place an in-case-mode form at the top of a source file (it must be the very first form, even before the in-package form). That produces a file that can be generally loaded into any Lisp without using an auxiliary file.

Using in-case-mode at the top-level

You can also evaluate `(in-case-mode <mode>)` at the top level and then call load to load fasl files as we suggest doing with an auxiliary file. You should change the mode back after the files are loaded.

Some lower level details

Symbol objects have a normal symbol name location and an alternative symbol name location (the exact details of where these are stored and how they are accessed do not concern us here). When a string is interned by intern, the string is treated as follows. If the case-translation-gravity and the value of *case-translation* are the same, the name is stored as passed and nothing is stored in the alternative name location. If the values are different and the string is not mixed case, the string case is inverted ("AAA" to "aaa" and "aaa" to "AAA") and stored in the normal name location, and the unmodified name is stored in the alternative name location.

When the values are different, the functions symbol-name and find-symbol use the alternate name (when there is one) instead of the normal name.

# incf-atomic

macro, excl package

Arguments: place &optional (increment-form 1)

This macro acts like incf with the same arguments except that the update is atomic with respect to any other processes looking at the same place. That is, if several processes simultaneously try to incf-atomic (or decf-atomic) the same location, all operations occur sequentially in some unspecified order. As a result, the final value will be what is expected. (If you just used incf's and decf's, the first incf could read the value and while it is calculating the increment, another incf could run, and then the initial incf could store its result effectively cancelling the action of the second incf.)

Note on the place argument: not all places legal as the first argument of setf can be used as the place argument to this macro. The list of allowable places can be found in Atomic read-modify-write primitives in smp.html.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# infinityp

Function, excl package

Arguments: object

Returns true if object is a floating-point infinity. Returns `nil` otherwise.

The actual value when true should not be depended upon, beyond its not being `nil`. The actual value may change in a new release or in an update without notice.

See also exceptional-floating-point-number-p and infinityp and the section on Floating-point infinities and NaNs, and floating-point underflow and overflow in implementation.html.

# install-dual-channel-character-strategy

Function, excl package

Arguments: stream format

In earlier releases, the symbol naming this function was `dual-channel-install-ef-methods`. That symbol is no longer exported. Use this new name instead.

You must load the `:iodefs` module to use this function. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.)

This function is called for its side-effects. Its return value is unspecified. This function installs character handlers into the stream that are appropriate for dual-channel streams, and also sets the external-format state slots to nil. The selection of which external-format handlers are used is based on the format argument; the external-format is looked up (possibly causing autoloading, compilation of the templates, and/or loading of pre-built external-formats).

You must load the `:iodefs` module to use this function. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# install-single-channel-character-strategy

Function, excl package

Arguments: stream format access

In earlier releases, the symbol naming this function was `single-channel-install-ef-methods`. That symbol is no longer exported. Use this new name instead.

This function is called for its side-effects. Its return value is unspecified. This function installs character handlers into the stream that are appropriate for single-channel streams, and also sets the external-format state slots to `nil`. The selection of which external-format handlers are used is based on the format; the external-format is looked up (possibly causing autoloading, compilation of the templates, and/or loading of pre-built external-formats).

Normally, access should be specified as `nil`. If specified as either the symbol `excl::buffer` or the smbol `excl::mapped`, installation of special buffer-oriented or mapped templates will be done. Note however, that these options are not exported and thus not documented, and should not be counted on remaining unchanged in future versions of Allegro CL.

You must load the `:iodefs` module to use this function. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# install-string-character-strategy

Function, excl package

Arguments: stream

Use of this function is deprecated in favor of install-string-input-character-strategy and install-string-output-character-strategy, which specialize strategy on input or output.

In earlier releases, the symbol naming this function was string-install-ef-methods. That symbol is no longer exported. Use this new name instead.

This function is called for its side-effects. Its return value is unspecified. This function installs character handlers into the stream that are appropriate for string-streams, and also sets the external-format state slots to `nil`. (If more specific methods for character handling have already been installed, they will not be overwritten. This allows device-open :before methods from more-specific string streams to install strategy functions that will stick. For example, if a device-open :before method stores the j-read-char function of its choosing, then subsequent calls to install-string-character-strategy by less-specific device-open before methods will result in the `excl::j-read-char` slot being left alone, but other slots being initialized to their appropriate default values.)

You must load the `:iodefs` module to use this function. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# install-string-input-character-strategy

Function, excl package

Arguments: stream

In earlier releases, the symbol naming this function was string-install-ef-methods. That symbol is no longer exported. Use this new name instead.

This function is called for its side-effects. Its return value is unspecified. This function installs input character handlers into the stream that are appropriate for string-streams, and also sets the external-format state slots to `nil`.

You must load the `:iodefs` module to use this function. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See also install-string-output-character-strategy. That function and this one replace the older install-string-character-strategy. See streams.html for information on the simple-streams implementation in Allegro CL.

# install-string-output-character-strategy

Function, excl package

Arguments: stream

This function is called for its side-effects. Its return value is unspecified. This function installs output character handlers into the stream that are appropriate for string-streams, and also sets the external-format state slots to `nil`.

You must load the `:iodefs` module to use this function. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See also install-string-input-character-strategy. That function and this one replace the older install-string-character-strategy. See streams.html for information on the simple-streams implementation in Allegro CL.

# instancep

Function, excl package

Arguments: object

Returns true if object is a flavors instance (not anything to do with CLOS or CLOS instances) and returns `nil` otherwise. See flavors.html. Flavors is an obsolete object-oriented system maintained for backward compatibility.

# integer-to-base64-string

Function, excl package

Arguments: integer &optional (column 52)

Takes the integer specified by the integer, assumes it is a base64 encoding, and converts it to a base64 string. If column is non-`nil`, its value must be a positive integer and newlines are inserted in the string each time that number of characters is output. If column is `nil`, no newlines are inserted.

The function base64-string-to-integer converts a base64 string (the output of this function) back to an integer.

Here is an example:

    cl-user(2): (integer-to-base64-string #xfeedfacefeedface)
    "/u36zv7t+s4="
    cl-user(3): (base64-string-to-integer "/u36zv7t+s4=")
    18369614222061337294
    cl-user(4): (format t "~x" *)
    feedfacefeedface
    nil
    cl-user(5):

See Base64 Support in miscellaneous.html for information on Base64 and Base64 support in Allegro CL.

# integer-to-hex-string

Function, excl package

Arguments: &body integer

Converts integer to a hexadecimal string. This function is designed to be very efficient.

See hex-string-to-integer, which is the inverse of this function, and MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also usb8-array-to-hex-string and hex-string-to-integer.

# interpreted-function-p

Function, excl package

Arguments: x

Returns true if the argument is an interpreted function object and returns `nil` otherwise (in particular when the argument is a compiled function object or, of course, not a function at all). Returns `nil` when the argument is a symbol, even a symbol naming an interpreted function.

# invalid-fd-close-on-fork-limit

Function, excl package

Arguments: value

Release 10.1 and later only. When Lisp starts a subordinate process using run-shell-command it generally closes all open file descriptors in the new process except stdin, stdout and stderr. It does this by cycling through the set of legal file descriptors trying to close each one. The overhead is generally insignificant given the low frequency and heavy cost of the operation as a whole.

However, this action (which can involve a sequence of 65000 or so system calls) can confuse some performance analysis tasks, particularly those involving strace. This function allows an application to limit the number of invalid-fd error returns accepted on closes of sequential fds during this operation. If that number of calls to close on sequentially increasing fds all return EBADF (bad file descriptor), the close loop terminates early, on the reasonable expectation that there are no more open fds.

The initial limit is a number big enough that it does not come into effect, so that the normal behavior is to attempt to close all fds after the three standard ones. invalid-fd-close-on-fork-limit allows inspection and modification of the limit.

The single argument to invalid-fd-close-on-fork-limit can have the following values:

- `nil`: invalid-fd-close-on-fork-limit returns the current limit without modifying anything.

- `t`: invalid-fd-close-on-fork-limit returns the maximum legal limit value, again without modifying the limit.

- an integer: any integer value >= to 1 and <= the maximum legal limit resets the limit to this value. The previous limit is returned.

Any other argument value, including integers less than 1 or greater than the maximum limit, cause an error to be signaled.

# lasting-cons

Function, excl package

Arguments: car cdr

Returns a newly-allocated cons of car and cdr, allocated in old-space. lasting-cons behaves exactly like cons except that the returned cons cell has already been tenured. This bypasses the overhead of copying the cons cell several times in subsequent scavenges before it becomes tenured due to longevity, and can be useful when constructing lists that are known to be permanent.

If there is not enough old space available to do the allocation immediately then newspace will be moved to make room to expand oldspace. This does not involve a global gc or a scavenge, but it does require updating all pointers to newspace to reflect the shift. This is done by scanning all stack frames, all of newspace and all oldspace pages that have been marked as holding pointers to newspace.

Note: lasting-cons is available as a patch in ACL 10.1 (Jan 2025) and 11.0 (Feb 2025). On ACL 10.1 Solaris this feature is not available.

## See also lasting-list, lasting-list*, lasting-push.

# lasting-list

Function, excl package

Arguments: &rest args

Returns a newly-allocated list whose elements are the arguments. All cons cells of the list are allocated in old-space (but cons cells within the arguments are not automatically tenured). Called with no arguments, lasting-list returns nil. lasting-list behaves exactly like list except that the newly-allocated cons cells have already been tenured. This bypasses the overhead of copying the cons cells several times in subsequent scavenges before they become tenured due to longevity, and can be useful when constructing lists that are known to be permanent.

If there is not enough old space available to do the allocation immediately then newspace will be moved to make room to expand oldspace. This does not involve a global gc or a scavenge, but it does require updating all pointers to newspace to reflect the shift. This is done by scanning all stack frames, all of newspace and all oldspace pages that have been marked as holding pointers to newspace.

Note: lasting-list is available as a patch in ACL 10.1 (Jan 2025) and 11.0 (Feb 2025). On ACL 10.1 Solaris this feature is not available.

## See also lasting-cons, lasting-list*, lasting-push.

# lasting-list*

Function, excl package

Arguments: arg1 &rest more-args

With exactly one argument, lasting_list* returns that argument. With more than one argument lasting-list* Returns a newly-allocated tenured chain of cdr-linked cons cells whose cars are the arguments before the last one. The last cons cell has the last argument as its cdr. lasting-list* behaves exactly like list* except that the newly-allocated cons cells of the returned list have already been tenured. This bypasses the overhead of copying the cons cells several times in subsequent scavenges before they become tenured due to longevity, and can be useful when constructing lists that are known to be permanent.

If there is not enough old space available to do the allocation immediately then newspace will be moved to make room to expand oldspace. This does not involve a global gc or a scavenge, but it does require updating all pointers to newspace to reflect the shift. This is done by scanning all stack frames, all of newspace and all oldspace pages that have been marked as holding pointers to newspace.

Note: lasting-list* is available as a patch in ACL 10.1 (Jan 2025) and 11.0 (Feb 2025). On ACL 10.1 Solaris this feature is not available.

## See also lasting-cons, lasting-list, lasting-push.

# lasting-push

Macro, excl package

Arguments: value place

value is a form that will be evaluated. place is a place appropriate for setf. This allocates and returns a tenured cons cell whose car is the result of evaluating the value form and whose cdr is the value accessed from place, and stores the result in place. lasting-push behaves exactly like push except that the returned cons cell has already been tenured. This bypasses the overhead of copying the cons cell several times in subsequent scavenges before it becomes tenured due to longevity, and can be useful when constructing lists that are known to be permanent.

If there is not enough old space available to do the allocation immediately then newspace will be moved to make room to expand oldspace. This does not involve a global gc or a scavenge, but it does require updating all pointers to newspace to reflect the shift. This is done by scanning all stack frames, all of newspace and all oldspace pages that have been marked as holding pointers to newspace.

Note: lasting-push is available as a patch in ACL 10.1 (Jan 2025) and 11.0 (Feb 2025). On ACL 10.1 Solaris this feature is not available.

## See also lasting-cons, lasting-list, lasting-list*

# lisp-to-bat-file

Function, excl package

Arguments: lisp-file bat-file &key (executable "sys:mlisp.exe") (image "sys:mlisp.dxl") (pause t) if-exists

This function creates a bat file which (on Windows) will execute the contents of lisp-file. The bat-file argument specifies the name of the bat file. It does this by wrapping around the Lisp code commands from the Windows command shell (cmd.exe), and using the new arguments to Allegro CL, --bat and --bat-pause. (See Command line arguments in startup.html for a list of command-line arguments accepted by Allegro CL.)

bat files are only supported on Windows. This function exists and works on UNIX platforms but only for creating bat files that will be used on Windows with Allegro CL on Windows. Similar functionality, running Lisp from a shell script, is supported on UNIX (but not on Windows, where shell scripts are not supported). See Starting on UNIX using a shell script in startup.html for details of using a shell script on UNIX to run Lisp.

The executable keyword argument must specify a exe file. There are effectively four exe files on Windows: mlisp.exe and buildi.exe, and mlisp8.exe and build.exe. The first pair use international characters (16-bits per character) while the second pair use 8-bit charcaters. build.exe and buildi.exe run console apps on Windows (note the warning about multiprocessing and console apps below). (Executables with other names are copies of one or another of those four -- alisp8.exe, for example, is a copy of mlisp8.exe.)

The image keyword argument must specify an image file (with type dxl). Examples of existing image files include mlisp.dxl and mlisp8.dxl. allegro.dxl is the image file for the IDE. While you can call that image in a bat file, it is necessarily interactive so it is hard to see why doing so would be practical.

The specified executable and image files must be compatible, that is they must use the same character sizes. The table below shows compatible executables and images among those supplied with the distribution.

The pause keyword argument indicates if a pause at the end of the script is desired. (By pause, we mean the script will execute and then Lisp will not exit until the user hits the Enter key. This allows the user to examine information which may be displayed. If there is no pause, it is likely the user will not be able to see anything displayed before Lisp exits.) For console apps pause should be `nil`, but for Windows apps `t` is a good value for, as we said, seeing the results of the script before Lisp exits. (If pause is specified true, the --bat-pause command-line argument is used. If pause is `nil`, --bat is used.

The value of the if-exists keyword argument is passed to cl:open when creating bat-file.

Table of compatible predefined images

The supplied executables in the first column are compatible with the images in the second column. (Often an executable is compatible with more images: the only important feature is character size. We list them this way for ease of specifying arguments.) I18n is an abbreviation for Internationalization. If the I18n is `t`, international characters are supported.

executable | images | type | i18n?
--- | --- | --- | ---
`build.exe` | `mlisp8.dxl`, `alisp8.dxl` | console | no
`buildi.exe` | `mlisp.dxl`, `alisp.dxl` | console | yes
`mlisp.exe` | `mlisp.dxl` | window | yes
`alisp.exe` | `alisp.dxl` | window | yes
`mlisp8.exe` | `mlisp8.dxl` | window | no
`alisp8.exe` | `alisp8.dxl` | window | no

Warning about Console Apps and multiprocessing

Console apps may not work properly when they use multiprocessing. If you intend to use multiple processes, you should use a Windows app.

#### More information and an example

This Tech Corner entry talks about the bat file feature and gives an example.

# lispval-other-to-address

Function, excl package

Arguments: static-array

Allegro CL supports static arrays, where the array is stored in malloc space, which is never moved and untouched by the garbage collector. Such arrays are created with make-array using the Allegro-CL-specific allocation keyword argument, as described in the description of make-array in implementation.html. See also Static arrays in gc.html.

This function is useful for freeing a static array (recall, it will not be garbage collected). When called with a static array as its argument, it returns an integer suitable to be the argument to aclfree. The array will be freed when aclfree is called with that integer as its argument. Be sure not to try to access the array after it has been freed in that way, as doing so will return meaningless values. Even worse is storing in this now invalid array. Doing that may overwrite data now used by something else, with potentially disastrous results.

The value returned by this function is not suitable for accessing array values

Do not use the value returned by this function to access elements of the array. Even though the array is not moved once it is created (so the value remains valid regardless of garbage collections), it points to the array header, not the array data. While in theory you could figure out where the data starts given the header location, there is no guarantee that offset will not be changed in some update. Further, changing the array from static allocation to (say) heap allocation will invalidate any accessing code.

Instead you should associate a foreign type to the array (see ftype.html) and use with fslot-value-typed and ff:fslot-address-typed.

# lispval-to-address

Function, excl package

Arguments: lispval

Returns an integer which represents the precise bit pattern representing lispval. The pattern includes the tag of the object, as well as either:

- the immediate data in the rest of the word

- the address of the object, as offset by the tag, and, depending upon the architecture, an additional offset which is always a multiple of 8 bytes (on 32-bit machines) or 16 bytes (on 64-bit machines). This extra offset can be seen in the [allegro-directory]/misc/lisp.h file as the macro TagOffset.

The integer returned by this function is the same value as is seen when print-unreadable-object uses the `:identity` option.

Users have occasionally been told about an internal function `excl::pointer-to-address`. lispval-to-address function is essentially an exported (and documented and supported) version of `excl::pointer-to-address`. Users who have code which refers to `excl::pointer-to-address` should replace it so lispval-to-address is called.

See also lispval-to-aligned-malloc-address.

# lispval-to-aligned-malloc-address

Function, excl package

Arguments: object

This function returns a fixnum which represents the beginning of the object. If the object had been allocated using aclmalloc or aclmalloc-aligned, then aclfree-aligned may be called with this value.

See also lispval-to-address.

# list-assert-enables-set

Function, excl package

Arguments:

Returns the list of names of assert-enables which are set (or enabled). If no assert-enables are set then `nil` is returned.

See Conditionalizing assert calls in miscellaneous.html for more information.

# list-hash-table-implementations

Function, excl package

Arguments:

Returns the list of names of all hash-table implementations currently known to the lisp. The symbol :acl (representing the Allegro CL implementation) and the symbol :unsafe-clrhash (representing a fast but unsafe for multiple threads version) will always be in that list. New entries are placed in the list with def-hash-table-implementation.

See make-hash-table extensions in implementation.html and Creating user-defined hash-table implementations in miscellaneous.html for more information.

# list-assert-enables

Function, excl package

Arguments:

Returns the current list of names of assert-enables. The first 6 such assert-enables are reserved by Allegro CL and should not be used or modified by users.

See Conditionalizing assert calls in miscellaneous.html for more information.

# list-to-delimited-string

Function, excl package

Arguments: list delimiter-string-or-char

This function formats a list of objects into a single string, with delimiter-char-or-string inserted between the objects. The print representation of the objects is used in the resulting string. See delimited-string-to-list.

Examples:

    (list-to-delimited-string '("one" "two" "three") #\space)

    -> "one two three"
    (list-to-delimited-string '(:foo :bar) ", ")

    -> "FOO, BAR"

# load-application

Macro, excl package

Arguments: form &key global-gc generation-spread xref-info source-file-info devel

This macro evaluates form with specific settings of certain global variables and specified gc behavior. form can be any single form whose evaluation causes load to be called. The simplest examples are direct calls to load or require, e.g.:

    (load "foo.fasl" :libfasl t)

The global-gc keyword argument specifies whether a global gc will be performed after the form is evaluated. Its value should be a boolean and defaults to t.

The generation-spread keyword argument specifies the value of the :generation-spread gsgc-switch while form is evaluated (see Gsgc switches in gc.html for information on that gsgc switch). Its default value is 0, which means that all live objects will be tenured at the next scavenge. That is usually the recommended behavior although a value of 1 might be appropriate if many evaluations that generate garbage are done during the load.

The xref-info, source-file-info, and devel keyword arguments control loading of source-file info and cross-reference info while form is evaluated.

If xref-info is specified, the value of *load-xref-info* will be bound to that value. If source-file-info is specified, *load-source-file-info* will be bound to that value. Both arguments default to `nil`. However, if a value is specified for devel, that both *load-xref-info* and *load-source-file-info* are bound to that value (and the xref-info and source-file-info arguments are ignored). Note that the associated variables *record-xref-info* and *record-source-file-info* are unaffected by this macro (they come into play at compile time).

See loading.html for general information on loading.

# load-compiled

Function, excl package

Arguments: filename &rest keys

Compiles and loads the file specified by the filename argument. This function takes a filename and any number of keys that are appropriate for cl:compile-file.

This function is obsolete. When originally implemented, it did not produce a fasl file (for reasons associated with licensing) but now it does. User should use compile-file and load, or compile-file with the load-after-compile (Allegro CL-specific) keyword argument in preference to this function. See the description of the compile-file implementation in compiling.html for details of additional arguments to compile-file.

# load-localedef

Function, excl package

Arguments: pathname &optional name

This function loads locale information from a localedef source file. pathname specifies the source file and the optional name specifies the name of the locale. If name is not provided, it defaults to the pathname-name of pathname. The new locale is returned, but it is accessible using find-locale and the name anytime after load-localedef completes.

Several localedef source files are included with Allegro CL. These definitions come from the IBM Universal Locales project. They can be found in the directory specified by *locales-dir*.

The localedef file does not include external-format information. After load-localedef parses the input file and creates the appropriate attribute/value pairings, the external-format is determined by looking to see if a charset is specified in the locale name (using the ".[charset]" specification). If the name does not specify the external-format, then Allegro CL uses a [language -> external-format] table which is kept in Lisp.

See Localization support in Allegro CL in iacl.html.

# load-system

Generic Function, excl package

Arguments: system &key interpreted compile no-warn reload silent simulate include-components module-keys

This generic function loads system into the current environment. This function returns `t` if any actions are necessary to bring system up-to-date. If no actions are necessary, then this function returns `nil`.

The value of the interpreted keyword argument can be `t` or `:interpreted :compile :no-warn :reload :silent :simulate :include-components :module-keys`. The default value is `nil`. `t` means to load the source file of each module rather than the product file.

The value of the compile keyword argument can be `t` or `nil`. The default value is `nil`. `t` means to compile the source file before loading the product file. If the value of the :interpreted keyword argument is true, the value of the :compile argument is ignored.

The value of the no-warn keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means do not print warnings of any kind when loading a system.

The value of the reload keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means reload all the files even if the most up-to-date version has been previously loaded.

The value of the silent keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means do not print anything while performing the operation. A true value of simulate overrides `:silent t`. If the value of this keyword argument is `t`, then the functionality is similar to the Unix command make -s.

The value of the simulate keyword argument can be `t` or `nil`. `t` means print the list of actions that would be taken if the operations were to be performed at this time, but do not actually perform the operations. If the value of this keyword argument is `t`, then the functionality is similar to make -n.

The value of the include-components keyword argument can be `t` or `nil`. The default value is `t`, which means perform a load-system operation on all component systems of system. A value of `nil` means ignore component systems.

The value of the module-keys keyword should be a list of keywords and arguments to be passed as a keyword list to the load-module-action method for each module-group.

Although the home package of the symbol naimg this operator is the excl package, it is also exported from the defsystem package.

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# locale-abday

Function, excl package

Arguments: locale

Returns the value of the `abday` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "abday" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-abmon

Function, excl package

Arguments: locale

Returns the value of the `abmon` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "abmon" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-am-pm

Function, excl package

Arguments: locale

Returns the value of the `am_pm` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "am_pm" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-attribute

Function, excl package

Arguments: locale attribute &key category

The attribute and category arguments to locale-attribute are string designators. The lookup is first done using a case-sensitive search. If the attribute cannot be found, then the search is retried using a case-insensitive search.

A call to (locale-attribute x-locale x-attr) returns the value for x-attr in locale x-locale. Since attribute names are unique among all categories, it is not necessary to supply the category, but the :category keyword argument limits the attribute search to the specified category. This may help speed up the attribute's search. If the attribute can not be found, then locale-attribute returns the keyword :unspecified. It is an error to specify a category for which the attribute is not defined.

Note that locale-attribute is a general attribute accessor. Many attributes have their own specific accessors (which have more Lisp-like names). Thus:

    (locale-attribute locale "int_curr_symbol" :category "LC_MONETARY")
     == (locale-int-curr-symbol locale)

See Localization support in Allegro CL in iacl.html.

# locale-currency-symbol

Function, excl package

Arguments: locale

Returns the value of the `currency_symbol` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "currency_symbol" :category "LC_MONETARY"))

See Localization support in Allegro CL in iacl.html.

# locale-d-fmt

Function, excl package

Arguments: locale

Returns the value of the `d_fmt` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "d_fmt" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-d-t-fmt

Function, excl package

Arguments: locale

Returns the value of the `d_t_fmt` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "d_t_fmt" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-day

Function, excl package

Arguments: locale

Returns the value of the `day` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "day" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-decimal-point

Function, excl package

Arguments: locale

Returns the value of the `decimal_point` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "decimal_point" :category "LC_NUMERIC")

See Localization support in Allegro CL in iacl.html.

# locale-external-format

Function, excl package

Arguments: locale

This function returns the external-format associated with locale.

Example:

    (locale-external-format (find-locale "POSIX"))
            -> #<external-format :latin1-base>

See iacl.html for more information on international character support in Allegro CL.

# locale-format-monetary

Function, excl package

Arguments: stream value use-int-symbol suppress-dp &optional (locale *locale*)

The arguments are:

- stream is a stream.

- value is a number.

- use-int-symbol is a boolean.

- suppress-dp is a boolean.

- locale is a locale.

This function outputs value to stream as a monetary amount appropriate to the specified locale.

If use-int-symbol is true, then the locale's international currency symbol (locale-int-curr-symbol) is used, otherwise the locale's currency-symbol (locale-currency-symbol) value is used.

If suppress-dp is true, then the decimal-point is not displayed if the locale's appropriate monetary fractional digits specification is zero. Note: It is an error for value to be a non-integer when being displayed with a locale where the fractional digits specification is zero.

The function locale-format-monetary can be invoked using the format ~/ directive. The locale argument can be supplied using format's ~v construct. The use-int-symbol argument is specified using the colon modifier. The suppress-dp argument is specified using the at-sign modifer.

**Examples: **

    ;; [assuming *locale* is (find-locale "en_US")]

    (locale-format-monetary *terminal-io* 1045.67 nil nil)
      prints `$1,045.67'

    (locale-format-monetary *terminal-io* 1045.67 t nil)
      prints `USD 1,045.67'

    (locale-format-monetary *terminal-io* 1045.67 t nil :fr_FR)
      prints `FRF 1 045,6700'

    (format t "~v/locale-format-monetary/" :en_US 1045.67)
      prints `$1,045.67'

    (format t "~v/locale-format-monetary/" :fr_FR 1045.67)
      prints `F1 045,6700'

    (format t "~v:/locale-format-monetary/" :fr_FR 1045.67)
      prints `FRF 1 045,6700'

    (format t "~v:/locale-format-monetary/" :ja_JP 1045)
      prints `JPY 1,045.'

    (format t "~v@:/locale-format-monetary/" :ja_JP 1045)
      prints `JPY 1,045'

See Localization support in Allegro CL in iacl.html.

# locale-format-number

Function, excl package

Arguments: stream value suppress-ts suppress-dp &optional (locale *locale*)

Arguments:

- stream is a stream.

- value is a number.

- suppress-ts is a boolean.

- suppress-dp is a boolean.

- locale is a locale.

This function outputs value to stream in the locale appropriate numeric format.

If suppress-ts is specified true, then the thousands-separator character is not used.

If suppress-dp is specified true, then the decimal-point character is not used if value is an integer.

The function locale-format-number can be invoked using the format ~/ directive. The locale argument can be supplied using format's ~v construct. The suppress-ts argument is specified using the colon modifier. The suppress-dp argument is specified using the at-sign modifier.

**Examples: **

    ;; [assuming *locale* is (find-locale "en_US")]

    (locale-format-number *terminal-io* 12345 nil nil)
      prints 12,345

    (format t "~/locale-format-number/" 12345.67)
      prints 12,345.67

    (format t "~v/locale-format-number/" :fr_FR 12345.67)
      prints 12 345,67

    (format t "~v/locale-format-number/" :fr_FR 12345)
      prints 12 345,

    (format t "~v:/locale-format-number/" :fr_FR 12345)
      prints 12345,

    (format t "~v@/locale-format-number/" :fr_FR 12345)
      prints 12 345

See Localization support in Allegro CL in iacl.html. See also iacl.html for general information on locales in Allegro CL.

# locale-format-time

Function, excl package

Arguments: stream date-time show-date show-time &optional (locale *locale*) fmt

Release 10.1 and later only.

Argument description:

- stream is a stream.

- date-time is a universal-time (see get-universal-time) or a date-time object (see date-time).

- show-date is a boolean.

- show-time is a boolean.

- locale is a locale.

- fmt is a keyword, string, or a list.

This function outputs to the stream a locale appropriate representation of the time specified by date-time. The output format can be specified as a string following the XPG4 strftime() format (see below). If fmt is non-`nil`, then the date and time booleans are ignored. Otherwise, if fmt is `nil`, then the date and time booleans determine the format based on the following table:

show-date | show-time | fmt control
--- | --- | ---
false | false | ([locale-t-fmt-ampm]#locale-t-fmt-ampm) locale)
false | true | (locale-t-fmt locale)
true | false | (locale-d-fmt locale)
true | true | (locale-d-t-fmt locale)

The function locale-format-time can be invoked using the format ~/ directive. The locale argument can be supplied using format's ~v prefix argument. The fmt argument can be supplied as the second prefix argument. The show-date argument is specified using the colon modifier. The show-time argument is specified using the at-sign modifier.

The LC_TIME category defines display formats using conversion specifications which are also defined in the category. The conversion specifications consist of a '%' followed by one or two letters. The formats are intended for the XPG4 strftime() function.

The locale-format-time function outputs the date/time as specified by the format string in the same way as strftime(). In addition to the field descriptor definitions, the locale-format-time function will interpret the following C escape sequences as follows:

     \\ insert #\\
     \a insert #\bell
     \b insert #\backspace
     \f insert #\page
     \n insert #\linefeed
     \r insert #\return
     \t insert #\tab
     \v insert #\vt

These are the field descriptor definitions:

      %%      same as %
      %a      locale's abbreviated weekday name
      %A      locale's full weekday name
      %b      locale's abbreviated month name (equivalent to %h)
      %B      locale's full month name
      %c      locale's appropriate date and time representation
      %C      century number (the year divided by  100  and  truncated
              to  an  integer  as a decimal number [1,99]);
              single digits are preceded by 0
      %d      day of month [1,31]; single digits are preceded by 0
      %D      date as %m/%d/%y
      %e      day of month [1,31]; single digits are preceded by a
              space
      %F      equivalent to %Y-%m-%d
      %G      The ISO 8601 year with century as a decimal number.
              The 4-digit year corresponding to the ISO week number
              (see %V).  This has the same format and value as %y,
              except that if the ISO week number belongs to the
              previous or next year, that year is used instead.
      %g      Like %G, but without century, i.e., with a 2-digit year (00-99)
      %h      locale's abbreviated month name (equivalent to %b)
      %H      hour (24-hour clock) [0,23]; single digits are preceded
              by 0
      %I      hour (12-hour clock) [1,12]; single digits are preceded
              by 0
      %j      day number of year [001,366];
      %k      hour (24-hour clock) [0,23]; single digits are
              preceded by a blank
      %l      hour (12-hour clock) [1,12]; single digits are
              preceded by a blank
      %m      month number [1,12]; single digits are preceded by 0
      %M      minute [00,59]; single digits are preceded by 0
      %n      insert a newline
      %p      locale's equivalent of either a.m. or p.m
              (case unspecified).
      %P      like %p but case specified to be lowercase
      %r      appropriate time  representation  in  12-hour  clock
              format with %p
      %R      time as %H:%M
      %S      seconds [00,61]
      %t      insert a tab
      %T      time as %H:%M:%S
      %u      weekday as a decimal number [1,7], with 1 representing
              Monday
      %V      week number of the year as a decimal number [01,53],
              with  Monday  as  the first day of the week.  If the
              week containing 1 January has four or more  days  in
              the  new  year, then it is considered week 1;
              otherwise, it is week 53 of the previous  year,  and
              the next week is week 1.
      %w      weekday as a decimal number [0,6], with 0
              representing Sunday. See also %u.
      %x      locale's appropriate date representation
      %X      locale's appropriate time representation
      %y      year within century [00,99]
      %Y      year, including the century (for example 1993)
      %z      time zone name or abbreviation, or no  bytes  if  no
              time zone information exists

Modified Conversion Specifications

Some conversion specifications can be modified by the E and O modifiers to indicate that an alternate format or specification should be used rather than the one normally used by the unmodified conversion specification. If the alternate format or specification does not exist in the current locale, the behavior will be as if the unmodified specification were used.

      %Ec     locale's  alternate  appropriate   date   and   time
          representation
      %EC     name of the  base  year  (period)  in  the  locale's
          alternate representation
      %Ex     locale's alternate date representation
      %EX     locale's alternate time representation
      %Ey     offset from %EC (year only) in the  locale's
              alternate representation
      %EY     full alternate year representation
      %Od     day  of  the  month  using  the  locale's  alternate
          numeric symbols
      %Oe     same as %Od
      %OH     hour (24-hour clock) using  the  locale's  alternate
          numeric symbols
      %OI     hour (12-hour clock) using  the  locale's  alternate
          numeric symbols
      %Om     month using the locale's alternate numeric symbols
      %OM     minutes using the locale's alternate numeric symbols
      %OS     seconds using the locale's alternate numeric symbols
      %Ow     number of the weekday (Sunday=0) using the  locale's
          alternate numeric symbols
      %Oy     year (offset from  %C)  in  the  locale's  alternate
          representation  and  using  the  locale's  alternate
          numeric symbols

#### The fmt argument

The fmt argument can be a string, as specified above; the symbol `:secondf`, `:minutef`, or `:hourf`; a list where each element is either a string or one of the keywords just specified, or a list where the first element of the inner list is either `:secondf`, `:minutef`, or `:hourf` and the second element is an integer specifying the number of fractional digits to be displayed, or a list where the first element is `:expanded`, the second element is an integer specifying the number of year digits to be displayed (along with a preceeding #+ or #- sign), followed by a fmt that displays a year (such as "%G").

**Example: **

    ;;  [assuming *locale* is (find-locale "en_US")]

    (format t "~/locale-format-time/" 3192624000)
      prints `08:00:00 AM '

    (format t "~:/locale-format-time/" 3192624000)
      prints `Saturday, March 03, 2001'

    (format t "~@/locale-format-time/" 3192624000)
      prints `08:00:00  '

    (format t "~:@/locale-format-time/" 3192624000)
      prints `Saturday, March 03, 2001 08:00:00 AM '

    (format t "~v:@/locale-format-time/" :fr_FR 3192624000)
      prints `samedi 03 mars 2001 08 h 00 '

    (format t "~v,v:@/locale-format-time/" :fr_FR "%A" 3192624000)
      prints `samedi'

    (format t "~,v:@/locale-format-time/" "%A" 3192624000)
      prints `Saturday'

    ;;  The following examples use date-time representations:

    (format t "~,v/locale-format-time/"
            '(:expanded 3 "%G") (date-time "19850412"))
      prints `+0001985'

    ;;  The date-time which is the value of D is used in the
    ;;  examples below.
    (setq d (date-time "19850412T23:20:50,46"))

    (format t "~,v/locale-format-time/" '((:secondf 1)) d)
      prints `5'  ;; rounds up to fit the number of digits specified

    (format t "~,v/locale-format-time/" '((:secondf 2)) d)
      prints `46'

    (format t "~,v/locale-format-time/" '((:secondf 3)) d)
      prints `460'

    (format t "~,v/locale-format-time/" '("%H," (:hourf 3)) d)
      prints `23,345'

See Localization support in Allegro CL in iacl.html.

# locale-frac-digits

Function, excl package

Arguments: locale

Returns the value of the `frac_digits` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "frac_digits" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html.

# locale-grouping

Function, excl package

Arguments: locale

Returns the value of the `grouping` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "grouping" :category "LC_NUMERIC")

See Localization support in Allegro CL in iacl.html.

# locale-int-curr-symbol

Function, excl package

Arguments: locale

Returns the value of the `int_curr_symbol` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "int_curr_symbol" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html.

# locale-int-frac-digits

Function, excl package

Arguments: locale

Returns the value of the `int_frac_digits` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute

    (locale-attribute locale "int_frac_digits" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html. See also iacl.html for general information on locales in Allegro CL.

# locale-mon-decimal-point

Function, excl package

Arguments: locale

Returns the value of the `mon_decimal_point` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "mon_decimal_point" :category "LC_MONETARY"))

See Localization support in Allegro CL in iacl.html.

# locale-mon-grouping

Function, excl package

Arguments: locale

Returns the value of the `mon_grouping` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "mon_grouping" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html.

# locale-mon-thousands-sep

Function, excl package

Arguments: locale

Returns the value of the `mon_thousands_sep` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "mon_thousands_sep" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html.

# locale-mon

Function, excl package

Arguments: locale

Returns the value of the `mon` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "mon" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-n-cs-precedes

Function, excl package

Arguments: locale

Returns true or `nil` as the value of the `n_cs_precedes` attribute of locale is 1 or 0. The value returned is the same as returned by the following form (see locale-attribute):

    (eql 1
        (locale-attribute locale "n_cs_precedes" :category "LC_MONETARY"))

See Localization support in Allegro CL in iacl.html.

# locale-n-sep-by-space

Function, excl package

Arguments: locale

Returns true or `nil` as the value of the `n_sep_by_space` attribute of locale is 1 or 0. The value returned is the same as returned by the following form (see locale-attribute):

    (eql 1
        (locale-attribute locale "n_sep_by_space" :category "LC_MONETARY"))

See Localization support in Allegro CL in iacl.html.

# locale-n-sign-posn

Function, excl package

Arguments: locale

Returns the value of the `n_sign_posn` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "n_sign_posn" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html.

# locale-name

Function, excl package

Arguments: locale

This function returns the name of locale.

See iacl.html for more information on international character support in Allegro CL.

# locale-negative-sign

Function, excl package

Arguments: locale

Returns the value of the `negative_sign` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "negative_sign" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html.

# locale-p-cs-precedes

Function, excl package

Arguments: locale

Returns true or `nil` as the value of the `p_cs_precedes` attribute of locale is 1 or 0. The value returned is the same as returned by the following form (see locale-attribute):

    (eql 1
        (locale-attribute locale "p_cs_precedes" :category "LC_MONETARY"))

See Localization support in Allegro CL in iacl.html.

# locale-p-sep-by-space

Function, excl package

Arguments: locale

Returns true or `nil` as the value of the `p_sep_by_space` attribute of locale is 1 or 0. The value returned is the same as returned by the following form (see locale-attribute):

    (eql 1
        (locale-attribute locale "p_sep_by_space" :category "LC_MONETARY"))

See Localization support in Allegro CL in iacl.html.

# locale-p-sign-posn

Function, excl package

Arguments: locale

Returns the value of the `p_sign_posn` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "p_sign_posn" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html.

# locale-parse-number

Function, excl package

Arguments: string &key (locale *locale*) (start 0) end*

Arguments:

- string is a string.

- `:locale` is a locale.

- `:start` is a bounding index designator of string. The default is 0.

- `:end` is a bounding index designator of string. The default is `nil`.

locale-parse-number parses the number in string, with bounds designated by start/end, assuming that the number is in locale's format (i.e., follows locale's thousands separator and decimal point rules).

It is an error for the boundary designated by start/end in the string not to consist entirely of the representation of the number, possibly surrounded on either side by whitespace characters.

The first value returned is the number that was parsed. The type is that of *read-default-float-format*.

The second value returned is the index into the string of the delimiter that terminated the parse, or the upper bounding index of the substring if the parse terminated at the end of the substring.

Example:

    (locale-parse-number "1.234,56" :locale :de_DE)
      ==> values 1234.56 7

See Localization support in Allegro CL in iacl.html.

# locale-positive-sign

Function, excl package

Arguments: locale

Returns the value of the `positive_sign` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "positive_sign" :category "LC_MONETARY")

See Localization support in Allegro CL in iacl.html.

# locale-print-monetary

Function, excl package

Arguments: value &key (stream *terminal-io*) (use-int-symbol nil) (suppress-dp nil) (locale *locale*)*

This function provides a shorthand way to call to locale-format-monetary. This function takes only one required argument (compared to four for locale-format-monetary) and supplies defaults for the rest. A call to locale-print-monetary is equivalent to (but not necessarily implemented as) the following.

    (locale-format-monetary stream value use-int-symbol suppress-dp locale)

See Localization support in Allegro CL in iacl.html.

# locale-print-number

Function, excl package

Arguments: value &key (stream *terminal-io*) (suppress-ts nil) (suppress-dp nil) (locale *locale*)

This function provides a shorthand way to call to locale-format-number. This function takes only one required argument (compared to four for locale-format-number) and supplies defaults for the rest. A call to locale-print-number is equivalent to (but not necessarily implemented as) the following.

    (locale-format-number stream value suppress-ts suppress-dp locale)

See Localization support in Allegro CL in iacl.html.

# locale-print-time

Function, excl package

Arguments: date-time &key (stream *terminal-io*) (show-date nil) (show-time nil) (fmt nil) (locale *locale*)

This function provides a shorthand way to call to locale-format-time. This function takes only one required argument (compared to four for locale-format-time) and supplies defaults for the rest. A call to locale-print-time is equivalent to (but not necessarily implemented as) the following.

    (locale-format-time stream datetime show-date show-time locale fmt)

See Localization support in Allegro CL in iacl.html.

# locale-t-fmt-ampm

Function, excl package

Arguments: locale

Returns the value of the `t_fmt_ampm` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "t_fmt_ampm" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-t-fmt

Function, excl package

Arguments: locale

Returns the value of the `t_fmt` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "t_fmt" :category "LC_TIME")

See Localization support in Allegro CL in iacl.html.

# locale-thousands-sep

Function, excl package

Arguments: locale

Returns the value of the `thousands_sep` attribute of locale. The value returned is the same as returned by the following form (see locale-attribute):

    (locale-attribute locale "thousands_sep" :category "LC_NUMERIC")

See Localization support in Allegro CL in iacl.html.

# logical-pathname-translations-database-pathnames

Function, excl package

Arguments: **

Returns a list of pathnames or strings naming files to be searched for translations of logical-pathname hosts. Initially, this function returns the list

    ("sys:hosts.cl")

This function is setf'able so standard operators such as push or pushnew may be used to add additional entries to the list. For example, to add "~/myhosts" to the list, evaluate:

    (pushnew "~/myhosts"
      (excl:logical-pathname-translations-database-pathnames))

logical-pathname-translations-database-pathnames will now return

    ("~/myhosts" "sys:hosts.cl")

So long as the elements of the list can be coerced to pathnames, the searching done by load-logical-pathname-translations is well protected against errors. In particular, it is not an error if a pathname identifies a file (or a directory) that does not exist. Nor will specifying a file with a logical host for which no translation is known cause a problem. Users might consider adding a file such as "~/myhosts" prior to a call to dumplisp so that they can easily provide translations to the restarted image during startup (before the first prompt). Translations can be added using sys:hosts.cl, but many users cannot modify that file, since it is shared by all Lisp users.

The format of the file is:

    host {translation}+

where host is a string naming a logical host (i.e., "src") and translation is a list which specifies the translation (i.e., a list of the source and target, such as (list ";." "sys:;.")). translation is evaluated.

See Details of cl:load-logical-pathname-translations in pathnames.html.

# make-buffer-input-stream

Function, excl package

Arguments: buffer &optional start end external-format

Returns a buffer-input-simple-stream. buffer may be a simple-vector, or it can have a fill-pointer. start defaults to 0, and end defaults to nil, in which case the current length of buffer is used as the end. The external-format argument should be the name of an external-format, or `:default` will cause it to be looked up in the locale.

Reading can then proceed from the stream, until the end location is reached, at which time eof processing takes place. file-position can be used to read and set the location, but must not set the location beyond the end.

See streams.html for information on the simple-streams implementation in Allegro CL.

# make-buffer-output-stream

Function, excl package

Arguments: buffer &optional external-format

Returns a buffer-output-simple-stream. buffer must be a simple-vector (that is, a vector that is not adjustable, not displaced, and does not have a fill-pointer). The external-format argument should be the name of an external-format, or `:default` will cause it to be looked up in the locale.

Writing can be done on the stream, and file-position can be used to read and set the location, but not past the end of the buffer. A read past the end of the buffer causes an error.

See streams.html for information on the simple-streams implementation in Allegro CL.

# make-control-table

Function, excl package

Arguments: &rest inits

A control table suitable for control-character processing is returned. The inits are character/function pairs; if the character is a control-character, the function object is stored in that character's location in the table.

Example:

    (defvar *std-control-out-table*
      (make-control-table
               #\newline
               #'std-newline-out-handler
               #\tab
               #'std-tab-out-handler))

See streams.html for information on the simple-streams implementation in Allegro CL.

# make-directory

Function, excl package

Arguments: pathname &optional mode

Creates a new directory specified by pathname. mode defaults to #o755 (i.e. the octal number 755). mode is ignored on Windows.

See also os-interface.html for general information on the interface between Allegro CL and the operating system. See section Filesystem manipulation functions in that document for information on file and directory information and manipulation functions in Allegro CL.

# make-escaped-string

Function, excl package

Arguments: string &key (escape #%) (passed #'alphanumericp) escaped

If the argument string does not contain any characters that need to be escaped (as described below), then the value returned is the input argument string.

Otherwise, this function returns a new string in which some characters are replaces with the character triples `%hh` where `%` is the escape character (as specified by the escape keyword argument) and hh is the two-digit hexadecimal representation of the character code.

This function only handles characters with a char-code values under 256 (255 is the largest value that can be represented by a two-digit hex value).

Strings of this form are useful as companion arguments to the -ee command line argument. (See Command line argumentsand Further description of the -e and -ee command-line arguments, both in startup.html.)

A character is replaced with the escaped sequence if any of the following is true:

- it is the escape character (default %)

- it satisfies the escaped argument (default `nil`, meaning no test)

- it fails the passed argument (default #'alphanumericp)

The escaped and passed arguments may be

- a single character; this case is satisfied only by an eql character

- a sequence of characters; this case is satisfied by any character that appears in the argument

- `nil`; this case is never satisfied (the default for escaped is `nil`, so in the default no characters are converted because of the value of escaped)

- `t` or `:all`; this case is satisfied by any character

- a predicate; this case is satisfied if the predicate returns `nil` when applied to the character (the default for passed is #'alphanumericp, so all numbers and letters except the value os escape but no other characters pass)

For example, suppose you want to evaluate the form (foo:bar #\a "efg") on startup. Constructing the correct comapnion argument to -e is difficult (we won't even try). But we can find the escaped string with this function (not we double the backslash and escape the double-quotes):

    cl-user(34): (make-escaped-string "(foo:bar #\\a \"efg\")")
    "%28foo%3abar%20%23%5ca%20%22efg%22%29"
    cl-user(35):

And use -ee %28foo%3abar%20%23%5ca%20%22efg%22%29.

The argument -ee %28foo%3abar%20%23%5ca%20%22efg%22%29, while obscure, conveys the desired expression with no trouble at all (and it can be decoded by hand if necessary).

# make-function-input-stream

Function, excl package

Arguments: function &rest args

Release 10.1 and later only. make-function-input-stream creates and returns an input stream that is populated by function. function is invoked in a new Lisp process with one or more arguments (function will be passed the same number of arguments as make-function-input-stream was passed). The first argument is an output stream to which function should write. The data written by function will be available for reading on the input stream which make-function-input-stream returns. The remaining arguments passed to function are the remaining arguments that were passed to make-function-input-stream. When function terminates (either normally or abnormally), the output stream is closed.

See also with-function-input-stream.

Example

    cl-user(34): (defun filler (writeto count)
                    (dotimes (n count)
                       (write-byte n writeto))
                    (close writeto))
    filler
    cl-user(35): (setq instream (make-function-input-stream #'filler 3))
    #<pipe-stream  @ #x10005170752>
    cl-user(36): (read-byte instream nil instream)
    0
    cl-user(37): (read-byte instream nil instream)
    1
    cl-user(38): (read-byte instream nil instream)
    2
    cl-user(39): (read-byte instream nil instream)
    #<pipe-stream  @ #x10005170752>  ;; EOF reached
    cl-user(40): (close instream)
    t
    cl-user(41):

# make-pipe-stream

Function, excl package

Arguments:

make-pipe-stream creates and returns (as multiple values) a pair of bidirectional streams. For the purpose of discussion we'll call the first stream A and the second stream B. Data written to stream A will be readable on stream B. Likewise, data written to stream B will be readable on stream A. Contrast this with pipe where one stream is specifically the input stream and one stream is specifically the output stream.

Note: When it is time to flush the buffer for the stream being used as the output stream, the process flushing the output buffer will block until the other end of the pipe is read by another process. Example 1 below shows how a separate process should be used to read the stream. Example 2 shows Lisp blocking if this is not done correctly.

Pipe streams are not particularly useful by themselves. They are provided as a building block for inter-process communication within the lisp.

See also: make-function-input-stream (which uses pipe streams), and with-function-input-stream.

Example 1

    ;;  We create the streams and then start a separate process to
    ;;  read data written to one of the streams.
    cl-user(1): (multiple-value-setq (one two) (make-pipe-stream))
    #<pipe-stream  @ #x10963301>

    cl-user(2): (mp:process-run-function "reader"
                   (lambda (s) (format t "Reader got: ~a~%" (read-line s))) two)
    #<multiprocessing:process reader(3) @ #x109704a1>
    cl-user(3): (write-line "hello there" one)
    "hello there"
    cl-user(4): (finish-output one)
    Reader got: hello there
    nil

Example 2

    ;;  In this example (which shows the WRONG thing to do), we create
    ;;  the pipe streams and start writing to one without arranging
    ;;  for the material to be read. Lisp then hangs because it is
    ;;  waiting for the material to be read, but there is nothing to
    ;;  read it.
    ;;
    ;;  We include this example because (in our experience) this is
    ;;  a common mistake made by programmers when they first use
    ;;  MAKE-PIPE-STREAM. In Example 1 above, we do arrange for
    ;;  reading what is written to a pipe stream
    ;;
    cl-user(1): (multiple-value-setq (one two) (make-pipe-stream))
    #<pipe-stream  @ #x10963301>

    cl-user(2): (write-line "hello" one)
    "hello"

    cl-user(3): (finish-output one)

    ;;  The Lisp will now block until the data is read from stream TWO.
    ;;  In this case it will block forever because there is no process
    ;;  ready to read. Interrupt Lisp (typically with Control-C's on
    ;;  Unix, and with the Pause/Break or with the Console Window on
    ;;  Windows) to gain back control.

# malloc

Function, excl package

Arguments: size

Returns an integer representing the address of an object in system space allocated by this call. If no space is available, 0 is returned.

Note on backward compatibility

In releases prior to 7.0, the symbols excl::malloc and excl::free named functions that were different from the functions named by the now exported symbols excl:malloc and excl:free. The old versions of excl::malloc and excl::free are equivalent to aclmalloc and aclfree. If any code from Allegro CL 6.2 calls excl::malloc or excl::free, those calls should be changed to calls to aclmalloc and aclfree.

Note on various Allegro CL malloc and free functions

The space allocated by excl:malloc and its C counterpart malloc() (described here collectively as "malloc") is different than the space allocated by excl:aclmalloc and the C aclmalloc() (described collectively as "aclmalloc"). Malloc allocates in space defined and maintained by the system, in whatever manner the system defines. Some operating systems allow the linking in of alternate versions of malloc() and its cohorts (usually including free(), calloc(), realloc(), and others), giving some flexibility in debugging malloc bugs (but of course this need arises much less often in Lisp programming). The aclmalloc functionalities are part of the Allegro CL library and allocate from space usually known as Aclmalloc heap space. aclmalloc is useful for allocating objects which should survive the rebirth of a dumped lisp.

The free and aclfree functionalities must always match objects to free with the mallocs of the same kind; i.e. one should never free an aclmalloc'd object, nor should one call an aclfree function on an object created with malloc. Note that one can mix aclmalloc/aclfree with aclmalloc-aligned/aclfree-aligned, but only after proper conversions are done; see ff:address-to-aligned and ff:ff:aligned-to-address.

# map-over-directory

Function, excl package

Arguments: function directory &key *filter prune-directories include-directories (recurse t) (file-type :pathname) (follow-symbolic-links t) relative

#### Documentation Note

> In earlier releases, this documentation did not make clear that when the include-directories keyword argument is specified non-`nil`, the argument directory would be one of the objects mapped over. Also, an error in the implementation (now fixed) meant that function was (incorrectly) not applied to directory when include-directories was non-`nil` and file-type was `:string`.

This function can be used to walk a directory structure rooted at directory. function is applied to each file in the directory. directory can contain wildcards. This function is called for the side effects of applying function to files (and optionally directories) in directory. No useful value is returned.

If filter is non-`nil`, then its value should be a function used to filter out candidate files and directories. The filter function takes one argument, a pathname, and returns a true value if function should be called on this file. It does not prevent recursion if the pathname is a directory.

The argument file-type controls whether a pathname object or a namestring is passed to function. The allowable values are `:pathname` (the default) and `:string`. If the directory of interest is very large, specifying `:string` (and ensuring that function works as desired with a string argument) may significantly reduce consing (i.e. generation of garbage).

If include-directories is true, then function also gets called on directories, including the argument directory.

If recurse is true (the default), then map-over-directory descends into subdirectories and maps over the files (or files and directories) in them. Note that this argument and include-directories are disjoint. This argument controls whether the contents of subdirectories are mapped over. include-directories controls whether directories are passed to function or not.

prune-directories, if specified, must be a list of strings naming directories with no punctuation (i.e. no slashes) or a predicate function object (not a function name, i.e. a symbol or function spec) accepting one argument of the type specified by file-type. If the value is a list, any directory encountered during the operation whose name is on the list will be ignored (neither it nor its contents nor its subdirectories will be mapped over). If the value is a predicate function, a directory for which the predicate returns true will be ignored. For example, suppose subdirectories foo and bar each have a subdirectory CVS. Then either

    :prune-directories '("CVS")

or

    :prune-directories '(lambda (string)
                          (if (string= "CVS" string) t))

will cause foo/CVS and bar/CVS both to be ignored (the second example assumes file-type is :string). There is no way to have foo/CVS considered and bar/CVS ignored with this argument.

The follow-symbolic-links argument determines what is done when a symbol link to a directory is encountered. If follow-symbolic-links is true, then the link is followed and all elements of the directory are acted upon. If follow-symbolic-links is `nil`, then the symbolic link is treated as a file, and passed to the function, but the files in the directory are not. This argument provides more control over the behavior of this function, which might be important when the function does something like deleting files. The default is `t`, which preserves the behavior of earlier releases.

The follow-symbolic-links argument is ignored on Windows, where there are no symbolic links.

The relative argument, if true, causes the pathnames passed to function to be relative to the directory argument, rather than absolute. For example suppose the directory /usr/mydir/foo.d/ contains three files, foo1, foo2, and foo3, then we have the following behavior:

    cl-user(2): (map-over-directory
             (lambda (p) (print p))
             "/usr/mydir/foo.d/")

    #P"/usr/mydir/foo.d/foo2"
    #P"/usr/mydir/foo.d/foo1"
    #P"/usr/mydir/foo.d/foo3"
    nil
    cl-user(3): (map-over-directory
             (lambda (p) (print p))
             "/usr/mydir/foo.d/"
             :relative t)

    #P"foo2"
    #P"foo1"
    #P"foo3"
    nil
    cl-user(4):

# map-system

Generic Function, excl package

Arguments: system fun &key silent simulate include-components module-keys

This generic function maps function over each module-group in system. fun should be a function that takes one argument which will be a module-group. The default method returns `nil`, but is called for its side effects.

The value of the silent keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means do not print anything while performing the operation. A true value of simulate overrides silent `t`. If the value of this keyword argument is `t`, then the functionality is similar to make -s.

The value of the simulate keyword argument can be t or `nil`. `t` means print the list of actions that would be taken if the operations were to be performed at this time, but do not actually perform the operations. If the value of this keyword argument is `t`, then the functionality is similar to make -n.

The value of the include-components keyword argument can be `t` or `nil`. The default value is `t`, which means perform a map-system operation on all component systems of system. A value of `nil` means ignore component systems.

The value of the module-keys keyword should be a list of keywords and arguments to be passed as a keyword list to the map-module-action method for each module-group.

In this example, we pretty print each module in a system.

    USER(9): (defsystem :my-serial-sys ()
                        (:serial "my1" "my2"))
    :MY-SERIAL-SYS
    USER(10): (map-system :my-serial-sys
                 '(lambda (module) (pprint module)))
    #<DEFSYSTEM:LISP-MODULE "my1" @ #x68c9a6>
    #<DEFSYSTEM:LISP-MODULE "my2" @ #x69197e>
    NIL
    USER(11):

Although the home package of the symbol naimg this operator is the excl package, it is also exported from the defsystem package.

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# mapped-file-simple-stream-buffer

Generic Function, excl package

Arguments: stream

Returns the buffer that has been established by the opening of the stream, which must be a subclass of mapped-file-simple-stream. This buffer will always be an aligned pointer. It is a reader only, and is thus not setf'able.

Example

This example uses sys:memref.

    ;; We have a file named xxx which contains a single line of text:
    ;;
    cl-user(1): (shell "cat xxx")
    abcdefgxxxxxxxxx
    0
    cl-user(2): (setq xxx (open "xxx" :mapped t))
    #<mapped-file-simple-stream #P"xxx" mapped for input pos 0 @
      #x10003b83772>
    cl-user(3): (setq buf (mapped-file-simple-stream-buffer xxx))
    17461927465472
    cl-user(4): (code-char (sys:memref buf 0 0 :unsigned-byte))
    #\a
    cl-user(5): (code-char (sys:memref buf 0 3 :unsigned-byte))
    #\d
    cl-user(6): (code-char (sys:memref buf 0 10 :unsigned-byte))
    #\x
    cl-user(7):

# match-re

Function, excl package

Arguments: regexp input &key return case-fold single-line multiple-lines ignore-whitespace start end back-end start-unbounded end-unbounded

regexp must be a string specifying a regular expression, or a compiled regular expression (an object returned by compile-re). This function tries to match the string input with the regexp. If they do not match, `nil` is returned as the single returned value. If they match, `t` is returned as a first value, and the match result of the whole, submatch 1, submatch 2, ... are returned as the other values.

The way of returning match result can be specified by the return keyword argument. If it is `:string` (the default), substrings of input are returned. If it is `:index`, a cons of start and end index within input is returned for each match.

The keyword arguments start and end limit the region of input, as do start-unbounded and end-unbounded. The arguments (only one of start and start-unbounded and of end and end-unbounded should be specified in a call) differ in the handling of BOS (Beginning of String) and EOS markers. `(match-re "^abc" " abc def" :start 1)` returns true since `:start 1` means treat the string as starting at position 1 and so the BOS condition is satisfied, when `(match-re "^abc" " abc def" :start-unbounded 1)` returns nil since even though comparisons are only done in the substring, the true start of the string is remembered and 'abc', though at the beginning of the substring is not at the true beginning of the string. See the additional examples below.

The keyword arguments case-fold and back-end are passed to the compile-re function, when a string is given as the value of regexp. They are ignored when regexp is a compiled regular expression. The default value of back-end is `regexp:vm`.

When applicable, `:case-fold nil` means case-sensitive, `:case-fold t` means case-insensitive (see examples below).

A compiler-macro is defined for this function. If regexp is a literal string, compile-re is called at compilation time, so you do not need to pay the cost of regexp compilation at run-time.

Example

    cl-user(4): (match-re "^[A-E]" "Boo")
    t
    "B"
    cl-user(5): (match-re "i.*s" "mississippi")
    t
    "ississ"                ; the greedy version
    cl-user(6): (match-re "i.*?s" "mississippi")
    t
    "is"                    ; the non-greedy version
    cl-user(7):

    ;; The :CASE-FOLD argument (default is NIL so case-sensitive):
    cl-user(57): (match-re "Foo" "FOO")
    nil
    cl-user(58): (match-re "Foo" "FOO" :case-fold nil)
    nil
    cl-user(59): (match-re "Foo" "FOO" :case-fold t)
    t
    "FOO"

    ;; Here we use the new START-UNBOUNDED argument. With START,
    ;; a regexp with a BOS marker finds a match if the text is at the
    ;; beginning of the specified substring. With START-UNBOUNDED,
    ;; it does not find a match:

    cl-user(152): (match-re "^abc" "abc def")
    t
    "abc"
    cl-user(153): (match-re "^abc" " abc def")
    nil
    cl-user(154): (match-re "^abc" " abc def" :start 1)
    t
    "abc"
    cl-user(155): (match-re "^abc" " abc def" :start-unbounded 1)
    nil

    ;; Similarly with END-UNBOUNDED:

    cl-user(157): (match-re "def$" "abc def ")
    nil
    cl-user(158): (match-re "def$" "abc def " :end 7)
    t
    "def"
    cl-user(159): (match-re "def$" "abc def " :end-unbounded 7)
    nil

See The new regexp2 module in regexp.html for further information on this function and the regexp2 module.

# match-regexp

Function, excl package

Arguments: string-or-regexp string-to-match &key newlines-special case-fold return start end shortest

The string-or-regexp argument is a regular expression object (the result of compile-regexp) or it is a string (in which case it will be compiled into a regular expression object). The string-to-match is a string to match against the regular expression. This function will attempt to match the regular expression against the string-to-match starting at the first character of the string-to-match, and if that fails it will look inside the string-to-match for a match (unless the regular expression begins with a caret).

The keyword arguments are:

- `:newlines-special`: If true (default is true) then a newline will not match the . (i.e. a period) regular expression. This is useful to prevent multiline matches.

- `:case-fold`: If true then the string-to-match is effectively mapped to lower case before doing the match. Thus lower case characters in the regular expression match either case and upper case characters match only upper case characters.

- `:return`: The return value from a failed match is `nil`. If the value of return is `:string` then the return value from a successful match are multiple values. The first value is `t`. The second value is the substring of the string-to-match that matched the regular expression. The third value (if any) is the substring that matched group 1. The fourth value is the substring that matched group 2. And so on. If you use the `\|` form, then some groups may have no associated match in which case `nil` will be returned as that value. In highly nested `\|` forms, a group may return a match string when in the final match that group had no match.

  If the value of return is `:index` then it is just like `:string` except that instead of the strings being returned, a cons is returned giving the start and end indices in the original string-to-match of the match. The end index is one greater than the last character in the substring.

  If the value of return is `nil` then the one value `t` is returned when the match succeeds.

- `:start`: The first character in the string-to-match to match against.

- `:end`: One past the last character in the string-to-match to match against.

- `:shortest`: This makes match-regexp return the shortest rather than the longest match. One motivation for this is parsing HTML. Suppose you want to search for the next item in italics, which in HTML looks like `<i>foo</i>`.
  The following example shows the difference:

      cl-user(1): (setq string "<i>foo</i> and <i>bar</i>")
      "<i>foo</i> and <i>bar</i>"
      cl-user(2): (match-regexp "<i>.*</i>" string)
      t
      "<i>foo</i> and <i>bar</i>"
      cl-user(3): (match-regexp "<i>.*</i>" string :shortest t)
      t
      "<i>foo</i>"
      cl-user(4):

Compilation note: there is a compiler macro defined for match-regexp that will handle in a special way match-regexp calls where the first argument is a constant string. That is, this form `(match-regexp "foo" x)` will compile to code that will arrange to call compile-regexp on the string when the code is fasl'ed in. Since the cost of compile-regexp is high, this saves a lot of time.

Use of this function is deprecated and it is maintained for backward compatibility only. See regexp.html for information on the newer regular expression compiler in Allegro CL. You should use the functionality described there instead of this function is new code.

# mb-to-native

Function, excl package

Arguments: vector8 &key address (length (position 0 vector8))

This function was, in release 6.0, renamed octets-to-native. `mb-to-native` is retained as a name for this function for backward compatibility. Please use the new name in new code. See the description of octets-to-native.

See also iacl.html for general information on international character set support in Allegro CL and see native-to-octets.

# mb-to-string

Function, excl package

Arguments: mb-vector &key string (start 0) (end (or (position 0 mb-vector :start start) (length mb-vector))) make-string? (*external-format& :default)

mb-to-string is the pre-Release-6.0 name of the function octets-to-string. Please see the description of octets-to-string for details. mb-to-string is preserved as a name for that function for backward compatibility.

# md4-file

Function, excl package

Arguments: filespec &key return

Using md4-init, md4-update, and md4-final, compute the MD4 hash on the contents of the file given by filespec. Returns the value of md4-final on the implicitly created context. The return argument is passed to md4-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-file.

# md4-final

Function, excl package

Arguments: context &key return

Finalize and return the MD4 hash from context in a format determined by the return keyword argument.

The `:return` keyword can have one of the following values:

- `:integer` (the default): the return value is an integer of up to 128 bits representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octets containing only zeroes. Care should be taking when using this return type if you intend to further encode the signature (such as to a base64-encoded string). See the example below.

- `:usb8`: return an (unsigned-byte 8) array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (md4-init))
    #S(excl::md-context :ctx 24752192 :size 16)
    cl-user(5): (md4-update c "foo")
    cl-user(6): (md4-final c :return :usb8)
    #(10 198 112 12 73 29 112 251 134 80 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to MD4-FILE which calls
    ;;  MD4-FINAL and returns the value MD4-FINAL returns.
    ;;
    ;;  Here we get the md4 value in a shell:
    % openssl dgst -md4 -hex image-lubm-report.jpg
    MD4(image-lubm-report.jpg)= fafa002127c737695df8449a51cbecb5

    ;; Now we get it with MD4-FILE:
    cl-user(7): (md4-file "~/image-lubm-report.jpg")
    333605075787702791398779221664703704245
    cl-user(8): (format t "~x" *)
    fafa002127c737695df8449a51cbecb5
    nil
    cl-user(9):

    ;; Note the hex values are the same but if there is a leading 0
    ;; it is not printed by Lisp, which is dealing with the value
    ;; as an integer. The leading 0 is preserved when the :return is :hex.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-final.

# md4-init

Function, excl package

Arguments:

Returns an initialized MD4 context, used by the other MD4 functions.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-init.

# md4-string

Function, excl package

Arguments: string &key start end external-format return

Using md4-init (which creates a context), md4-update (which updates the context with the argument string), and md4-final (which finalizes the hash), this function computes the MD4 hash for string.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context. start defaults to 0, end defaults to the length of string, and external-format defaults to the default external format. These arguments, along with string, are passed to md4-update.

The format of the result, just as for md4-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See md4-final for information on these values and the corresponding formats of the returned value.

    cl-user(18): (md4-string "foo")
    14322627339080611868330898629662467250
    cl-user(19): (md4-string "foo" :return :usb8)
    #(10 198 112 12 73 29 112 251 134 80 ...)
    cl-user(20):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-string.

# md4-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running MD4 computation in context (md4-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

Earlier versions of md4-update had two required and one optional argument, len, specifying the number of characters of the argument string to use (that is, start was hardwired to 0 and the optional argument specified a value for end). This argument style is still accepted, though with a warning. Note len refers to the number of characters, not the number of bytes in the external hashing.

This function returns no values, but side-effects context.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-update.

# md5-file

Function, excl package

Arguments: filespec &key return

Using md5-init, md5-update, and md5-final, compute the MD5 hash on the contents of the file given by filespec. Returns the value of md5-final on the implicitly created context. The return argument is passed to md5-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-file.

# md5-final

Function, excl package

Arguments: context &key return

Finalize and return the MD5 hash from context in a format determined by the return keyword argument.

return can be one of the following values:

- `:integer` (the default): the return value is an integer of up to 128 bits representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octets containing only zeroes. Care should be taking when using this return type if you intend to further encode the signature (such as to a base64-encoded string). See the example below.

- `:usb8`: return an (unsigned-byte 8) array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (md5-init))
    #(1 35 69 103 137 171 205 239 254 220 ...)
    cl-user(5): (md5-update c "foo")
    cl-user(6): (md5-final c :return :usb8)
    #(172 189 24 219 76 194 248 92 237 239 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to MD5-FILE which calls
    ;;  MD5-FINAL and returns the value MD5-FINAL returns.
    ;;
    ;;  Here we get the md5 value in a shell:
    %  openssl dgst -md5 -hex cmp05-optdialog.jpg
    MD5(cmp05-optdialog.jpg)= 03c6f3f0ede5188ac49c30e11e7afa4e

    ;; Now we get it with MD5-FILE:
    cl-user(17): (md5-file "~/cmp05-optdialog.jpg")
    5020706479262241505478555770059160142
    cl-user(18): (format t "~x" *)
    3c6f3f0ede5188ac49c30e11e7afa4e
    nil
    cl-user(19):

    ;; Note the hex values are the same but the leading 0 is not printed
    ;; by Lisp, which is dealing with the value as an integer. The leading
    ;; 0 is preserved when the :return is :hex:
    cl-user(21): (md5-file "~/cmp05-optdialog.jpg" :return :hex)
    "03c6f3f0ede5188ac49c30e11e7afa4e"
    cl-user(22):

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-final.

# md5-init

Function, excl package

Arguments:

Returns an initialized MD5 context, used by the other MD5 functions.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-init.

# md5-string

Function, excl package

Arguments: string &key start end external-format return

Using md5-init (which creates a context), md5-update (which updates the context with the argument string), and md5-final (which finalizes the hash), this function computes the MD5 hash for string.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context. start defaults to 0, end defaults to the length of string, and external-format defaults to the default external format. These arguments, along with string, are passed to md5-update.

The format of the result, just as for md5-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See md5-final for information on these values and the corresponding formats of the returned value.

    cl-user(4): (md5-string "foo")  ;; default return format :integer
    229609063533823256041787889330700985560
    cl-user(5): (md5-string "foo" :return :usb8)
    #(172 189 24 219 76 194 248 92 237 239 ...)
    cl-user(6):

An earlier version of md5-string only accepted the single keyword argument `:usb8-result` (which, when specified true, produced a result equivalent to specifying ':return :usb8'). That keyword argument is no longer supported.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-string.

# md5-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running MD5 computation in context (md5-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

Earlier versions of md5-update had two required and one optional argument, len, specifying the number of characters of the argument string to use (that is, start was hardwired to 0 and the optional argument specified a value for end). This argument style is still accepted, though with a warning. Note len refers to the number of characters, not the number of bytes in the external hashing.

This function returns no values, but side-effects context.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-update.

# merge-locale-categories

Function, excl package

Arguments: &rest args &key (locale *locale*) (external-format (locale-external-format default-locale)) &allow-other-keys

This function enables users to create a locale object which combines categories from other existing locales. Such a locale is unnamed (i.e., its name slot is nil), and is never returned by find-locale. After specifying the indicated keyword arguments (if you do), then category/locale pairs, specified as strings, indicate what should be merged.

For example,

    (merge-locale-categories :locale (find-locale "af_ZA")
                             "LC_NUMERIC" "fr_FR"
                             "LC_MONETARY" "de_DE"
                             "LC_TIME" "ja_JP")

creates a new unnamed locale object with the categories from locales as specified in the call and all other categories from the af_ZA locale. If :locale is not specified, then the current locale (value of *locale*) is used.

See Localization support in Allegro CL in iacl.html.

# named-function

Macro, excl package

Arguments: name lambda-expression

The macro definition for this extension is approximately:

    (defmacro excl:named-function (name function)
     (declare (ignore name)) `(function ,function))

When compiling a named-function form, the compiler treats the form just like a function form, except that the name is used if possible in the resulting function. This is especially useful for closures of a particular kind, as in the following example:

    user(1): (defun get-one-arg-frobber (ix)
                (named-function frobber
                  (lambda (arg) (frob-by-index ix arg))))
    get-one-arg-frobber
    user(2): (compile *)
    Warning: While compiling these undefined
    functions were referenced: frob-by-index.
    get-one-arg-frobber
    nil
    nil
    user(3): (get-one-arg-frobber 10)
    #<Closure frobber @ #x2065dea9>
    user(4):

Note that the name of the closure is taken from the named-function form. Contrast that with the following definition using the more traditional function form:

    user(7): (defun get-one-arg-frobber (ix)
                (function (lambda (arg)
                             (frob-by-index ix arg))))
    get-one-arg-frobber
    user(8): (compile *)
    Warning: While compiling these undefined
    functions were referenced: frob-by-index.
    get-one-arg-frobber
    nil
    nil
    user(9): (get-one-arg-frobber 12)
    #<Closure (:internal get-one-arg-frobber 0) @ #x20664fa1>
    user(10):

# named-readtable

Function, excl package

Arguments: name &optional (errorp t)

This function looks up a readtable by name. name must be a symbol, but it is coerced to a keyword (so readtables are named by keywords). setf may be used to associate a name to a readtable. The association can be broken by setting to `nil`. Naming readtables is particularly useful for editors (see the description of Emacs file mode line support for named readtables in eli.html).

Here is an example:

    user(2): (setq my-rt (copy-readtable))
    #<readtable @ #x4d4fa2>
    user(3): (setf (named-readtable :mytable) my-rt)
    #<readtable @ #x4d4fa2>
    user(4): (named-readtable :mytable)
    #<readtable @ #x4d4fa2>
    user(5): (setf (named-readtable :mytable) nil)
    nil
    user(6): (named-readtable :mytable nil)
    nil
    user(7): (named-readtable :mytable)
    Error: There is no readtable named :mytable.
    [1] user(8):

# nanp

Function, excl package

Arguments: object

Returns true if object is a floating-point nan. Returns `nil` otherwise.

The actual value when true should not be depended upon, beyond its not being `nil`. The actual value may change in a new release or in an update without notice.

See also exceptional-floating-point-number-p and infinityp and the section on Floating-point infinities and NaNs, and floating-point underflow and overflow in implementation.html.

# native-character-sizeof

Function, excl package

Arguments: character &key (external-format :default)

This function returns an integer.

This function returns the number of bytes needed to represent character using the external-format specified by external-format. Overriding the default external-format is not supported in this Allegro CL release. When `:default` is specified, the value returned by `(find-external-format :default)` is used (see find-external-format).

See also iacl.html for general information on international character set support in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.

# native-string-sizeof

Function, excl package

Arguments: string &key (start 0) (end (length string)) (external-format :default)

This function returns the number of octets needed to represent string (from the start to end arguments) using the external-format specified by external-format.

See also iacl.html for general information on international character set support in Allegro CL.

# native-to-mb

Function, excl package

Arguments: address &key vector length

native-to-mb is the old name for native-to-octets, and is kept for backward compatibility. New code should use native-to-octets. See the description of that function for details.

# native-to-octets

Function, excl package

Arguments: address &key vector length null-terminate aligned

This function returns a Lisp unsigned-byte (8) vector.

This function copies 8-bit byte data from the memory location specified by address into a lisp vector of type (simple-array (unsigned-byte 8) (*)). This vector is returned.

When the null-terminate argument is specified true, the copied string data (in the resulting vector) is null-terminated, that is the byte following the last data element is 0.

If the aligned keyword argument argument is true, then address is an aligned address. Aligned addresses are returned by functions like lispval-to-aligned-malloc-address.

If the vector argument is specified, then its value will be used (and returned) as the destination lisp array. If the vector is not long enough, an error is signaled.

In earlier releases, this function was named native-to-mb. That name is preserved for backward compatibility but new code should use the new name, native-to-octets.

See iacl.html for general information on International Allegro CL, and see octets-to-native.

# native-to-string

Function, excl package

Arguments: address &key string make-string? length (external-format :default) truncate (string-start 0) string-end aligned

This function returns three values: (1) a string, (2) the number of characters copied, and (3) the number of octets used, which is a number representing the actual number of octets used by the conversion process.

This function converts (according to the external-format argument) and copies the string data from the memory location specified by address into a Lisp string. The string is returned. The number of characters copied to the string is returned as the second value and the number of octets used is returned as the third value.

If the aligned keyword argument is true, then address is an aligned address. Aligned addresses are returned by functions like lispval-to-aligned-malloc-address.

If the string argument is specified, then the string data will be copied into this argument. If a string is specified by string and it is not long enough, an error is signaled unless either make-string? is specified as non-nil, in which case a new string is created and string is ignored, or string-end is a number, in which case string will be filled to that point and information on how many characters were put in the string is returned as the second returned value. If string is not specified, make-string? is ignored (a new string is always created).

If the length argument is specified, then this argument's value specifies the number of bytes to copy. Note that if a null character is present in the string, conversion will stop at that character (which is taken to be a terminator) unless length is specified and greater than the location of the null character. See the example below.

The truncate keyword argument controls the behavior when the external-format convertor attempts to go past the end of the octet array. When truncate is true, native-to-string will terminate the current character conversion. When truncate is false, attempts to go past the end of the octet array are treated as external-format eof situations which may cause alternative valid character(s) to be returned. Using `:truncate t` is recommended when the octet array is a buffer that is not known to end with a complete character.

The arguments string-start and string-end are ignored unless string is specified. The string-start keyword argument determines at which position in the target string to insert converted characters. The string-end keyword argument determines the last position in the target string for inserting converted characters (its value, if a number, should be one greater than the last position in which to insert a character).

If string-end is `nil` and there are more characters to be inserted than space in the string, an error is signaled and no characters are inserted at all. If the value of string-end is a number, that error will not be signaled and instead characters are inserted up to position (- string-end 1). (But if string-end is greater than the length of the string, an array out of bounds type error might be signaled: this function does not test whether string-start and string-end have appropriate values.) The purpose of using string-end is to handle situations where you do not know in advance how many characters are to be converted. It allows filling a string, and then, using the third returned value (which tells how many octets were used) to determine if more characters are available, filling additional strings as necessary. (In the case of this function, you actually only know the address of remaining octets, if any. The related octets-to-string takes as its first argument an array of octets so you know how many are unconverted.)

Conversion is done using the specified external-format. If external-format is not specified (or, equivalently, if the value of external-format is `:default`), then the external format returned by the following form is used:

    (locale-external-format *locale*)

    ;; Example of a string with a null charcater

    cl-user(2): (string-to-native (coerce (list #\a (code-char 0) #\b)
    'string))
    549756032096
    4
    cl-user(3): (native-to-string *)
    "a"  ;; default behavior: null terminates
    1
    1
    cl-user(4): (native-to-string 549756032096 :length 4)
    "a^@b^@" ;; this includes the final null-terminator because it was
    generated by the original string-to-native
    4
    4
    cl-user(5):

See locale-external-format and *locale*.

See also octets-to-string, string-to-octets, and string-to-native. See iacl.html for general information on international character set support in Allegro CL and see foreign-functions.html for information on foreign functions.

# new-start-emacs-lisp-interface

Function, excl package

Arguments: &key (background-streams t) (listener-number 1) port announce-to-file

This function starts the emacs-lisp interface.

Users do not typically call this function. Lisp is typically started as a subprocess of Emacs with the Emacs function fi:common-lisp, or perhaps with a custom Emacs function that itself calls fi:common-lisp. (See Functions and variables for Interacting with a CL subprocess in eli.html for a discussion of fi:common-lisp and examples of custom functions.) When Lisp is started in that way, new-start-emacs-lisp-interface is called automatically and transparently. (See also Running Lisp as a subprocess of Emacs in startup.html.)

When a Lisp is started with fi:common-lisp, then this expression:

    -e (new-start-emacs-lisp-interface)

(or an equivalent form) is made a command line argument to Lisp. If, because command-line arguments are ignored, the Emacs-Lisp interface does not start up (or if it does not start up for any other reason), you can start it directly from within Lisp by calling this function.

The arguments are:

- `:background-streams`: if true, then the function use-background-streams is used to initialize background streams, which provide a separate buffer for debugging processes other than the listener process. The value of background-streams is passed to the function use-background-streams (see Debugging background processes in debugging.html). The default value of use-background-streams is `t`.

- `:listener-number`: a value should only be specified when starting using a file as described under the heading Starting the interface after Lisp is already running below. The valuie should be an integer which is not already used for a common-lisp buffer, if any exist. Typical values are 1 (the default) or 2 or 3.

- `:port`: a value should only be specified when starting using a file as described under the heading Starting the interface after Lisp is already running below. The value can be it can be any valid port number on the machine that is not already in use. Specifying the value `nil` (the default) causes the system to choose an appropriate value for the port.

- `:announce-to-file`: a value should only be specified when starting using a file as described under the heading Starting the interface after Lisp is already running below. This file (which should not already exists -- it will be created by this call) is the file used by Eamcs to communicate to Lisp.

The typical form that will start the Emacs-Lisp interface is:

    (excl:new-start-emacs-lisp-interface)

It is not an error to call this function when the Emacs-Lisp interface is in fact running. Doing so will cause some printing to the listener but have no other effect.

Starting the interface after Lisp is already running You can start the interface after Lisp has been started, typically not in Emacs, with this function and the emacs-lisp interface function fi:start-interface-via-file. This is typically done for debugging a running but apparently broken process. To do this, in Lisp call a form like:

    (excl:new-start-emacs-lisp-interface :port 7666 :announce-to-file "~/.eli-startup")

We have not specified a value for the listener-number, so the default 1 is used (if a common-lisp already exists and uses 1, specify a different number), or for background-streams, so the default `t` is used. The value given for port is 7666 (it can be any valid port number on the machine that is not already in use and can be `nil`, which causes the system to choose an appropriate port number), and the value for announce-to-file is the file that will be used (it must not exist; it will be created for this call). Then, sometime later on the emacs side, do this (the host is "pie"):

    (fi:start-interface-via-file "pie" "*common-lisp*" "~/.eli-startup")

The arguments are the host running Lisp, the buffer name, and the filename.

See eli.html for information on the Emacs-Lisp interface.

# nice-signal-name

Function, excl package

Arguments: signal-number

This function returns a string which is a nice (that is a meaningful and easy to interpret) name for signal-number, which must be an integer. This nice name is operating system dependent.

For example, on Solaris and Linux, `(nice-signal-name 1)` returns "Hangup". On FreeBSD and macOS, the same thing returns "Hangup: 1". It is possible the return values for an OS will change over time because of OS changes.

If signal-number does not name a valid signal, `nil` is returned.

The function strsignal is a synonym of this function (its name corresponds to the name of the UNIX library function strsignal()). That library function does not exist on Windows but nice-signal-name and strsignal work on all platforms (using different underlying functionality on Windows).

# normalize-direct-slots

Generic Function, excl package

Arguments: metaclass superclasses name direct-slots

Release 10.1 and later only. Returns a normalized list of slots as part of the macro-expansion of a defclass form. A method specialized on a defclass-embellisher class-metaobject (see the defclass-embellisher-class) can take the opportunity to push extra forms to the resultant macro-expansion. It is expected that call-next-method be used to implement the lower-level functionality of normalizing the slots.

Predefined methods

    (method normalize-direct-slots (t t t t))

A catch-all method: the direct-slots argument is processed and normalized for return.

    (method normalize-direct-slots (symbol t t t))

If the metaclass argument is `nil` then the direct-slots argument is processed and normalized for return, as with the catch-all method above; otherwise, find-class is used to look up the class (which must be defined at the time of the lookup) and normalize-direct-slots is recursed on with that class metaobject.

The example in Metaclasses for embellishing class definitions in implementation.html has an example of this method being used.

# normalize-type

Function, excl package

Arguments: type &key loud msg default environment

Returns the normalized form of type, which should be a type specifier. If environment is provided, then it is consulted for possible type information.

Types are normalized by attempting to find the simplest type specification which fully describes all types of similar specification. Sometimes this means that the normalization is itself simpler, but sometimes it results in a slightly larger specification. So, for example, when type is given `fixnum`, it returns the same thing that evaluating

        `(integer ,most-negative-fixnum ,most-positive-fixnum)

would return. Another example is a combination of `(or fixnum bignum)`. When given that form as an argument, normalize-type returns `(integer * *)`, because fixnums and bignums are an exhaustive subset of the type `integer`.

Arrays are normalized into their `(<array> <etype> <dim>)` form, where might be `array`, `simple-array`, or `excl:short-simple-array`, and is the upgraded array element-type, and forms the dimensions specifications. If the rank of the array type is unknown, * will be used, otherwise a parenthesized form is always given, with * used in individual dimensions that are unkown.

Thus, `(normalize-type '(vector float))` returns the type `(array (float * *) (*))` and `(normalize-type '(simple-bit-vector 10))` returns `(simple-array (integer 0 1) (10))`.

If the type argument does not represent a type at the time of the call, the actions of normalize-type are thus:

- With no values specified for loud or default, `t` is returned.

- If value is specified for default, it is returned.

- If loud is non-`nil`, then it must be a function-spec or a function object which will be funcalled in the following way:

      (funcall loud msg type)

  and if this function returns, then normalize-type will return the default. This allows several styles to be employed, and the most common style is for msg to be a format string which accepts one argument, and loud can either be warn, error, or cerror, though in fact loud and msg can be used in other ways, as well.

If the type argument is a malformed or impossible type, then loud is called (as described above) if specified and the result is returned, and if loud is not specified, `nil` is returned.

The msg argument is used only as the first argument to the function which is the value of loud.

Type specifications returned by normalize-type should be considered immutable, and thus should not be destructively modified.

Examples

We make a distinction above between a malformed or impossible type, where `nil` is returned (absent values specified for default and/or loud) and a value for type that does not represent a type at the time of the call. The following examples should make this distinction clear.

    ;;  Consider the following type specifications and assume they are
    ;;  passed as the TYPE argument:

    'foo

    ;;  If foo hasn't been defined yet, it is an invalid type (though it
    ;;  might become valid at some other time).  NORMALIZE-TYPE returns T,
    ;;  or calls the LOUD function.

    '(array foo)

    ;;  If foo isn't defined, then it is not known whether it will eventually
    ;;  represent a T or some specialized element-type - in this case
    ;;  NORMALIZE-TYPE recursively calls itself with a default of '*.  Back
    ;;  at the other call, if LOUD is specified, it is called, otherwise
    ;;  (ARRAY * *) is returned.

    '(array foo bar bas)

    ;;  This can never be a type, because it is malformed.  Either LOUD is
    ;;  called or NIL is returned.

    '(and fixnum bignum)

    ;; This one might seem like an impossible type, but it is not.
    ;; Since there are no values that are both a fixnum and a bignum,
    ;; the result type is NIL, which means the empty type, and
    ;; LOUD is never called even if specified.

    '(mod -2)

    ;; This is an impossible type The MOD value must be positive).
    ;; Either LOUD is called, or NIL is returned.

# octets-to-char

Macro, excl package

Arguments: name state-loc &key get-next-octet unget-octets octets-count-loc oc-eof-macro external-format

name should be a symbol or an external-format. state-loc a place suitable as the first argument to setf. get-next-octet should be a form. external-format should be an external-format or symbol naming an external-format.

The octets-to-char macro simply expands to the macro stored in the `octets-to-char-macro` slot of the external-format named by name. The external-format must be a base external-format or a macro-based composing external-format (which is, in fact, just a special type of base external-format). The external-format must not be an encapsulating-based composing external-format as it will then not have a filled octets-to-char-macro slot. See the description of def-octets-to-char-macro for descriptions of the return value of the macro's expansion as well as of the get-next-octet, unget-octets, octets-count-loc, and external-format arguments.

The oc-eof-macro argument is not described in the def-octets-to-char-macro description. This argument is a list consisting of a lambda list specification designating a required argument, and a macro defining form. oc-eof-macro can also be `nil`, which specifies that no oc-eof-macro is defined. An oc-eof-macro specifies the action to be taken by the get-next-octet routine when it hits an end-of-data situation. When oc-eof-macro is invoked, the octets-count-loc should hold the number of octets retrieved.

The argument to oc-eof-macro is a boolean which designates whether the end-of-data situation should be considered 'hard' or not. When the argument is true (designating a 'hard' end-of-data situation), the octet input source is to be considered completely empty and no further attempts to extract octets from the source should be made. The octets-to-char macro may then choose to return an alternate character in this case. When the argument is false, the octet input source is to be considered empty at the current time, but further octets may be available in the future. Thus, if there are not enough octets available at the present time to determine which character should be returned, the octets-to-char macro may choose to unget all unused octets (that is, reset the file position so it points to the first newly ungot octet) and indicate the situation (e.g., by a non-local exit) to octets-to-char's caller.

A composing external-format may trap the end-of-data condition using its own oc-eof-macro so that it can return a valid character.

Users generally do not need to invoke the octets-to-char macro. In most cases, it is more convenient to use octets-to-string.

Example:

    ;; Ensure utf8 conversion macros are available by explicitly loading the
    ;; external-format definition.  This suppresses the macro removal
    ;; optimizations that may occur when external-format is autoloaded.
    ;;
    (let ((*modules* (remove "ef-utf8" *modules* :test #'string-equal)))
      (require "ef-utf8"))
    (funcall
     (compile
      nil
      `(lambda ()
        (let ((utf8-vector (make-array 3
                                       :element-type '(unsigned-byte 8)
                                       ;; These three octets are utf8
                                       ;; for hiragana letter A.
                                       :initial-contents '(227 129
                                                           130)))
              (v 0)
              (octets-count 1)
              (state nil))
          (declare (ignorable state))
          (octets-to-char ,(crlf-base-ef :utf8) state
           :get-next-octet (prog1 (aref utf8-vector v)
                             (incf v))
           :octets-count-loc octets-count
           :unget-octets (lambda (n) (decf v n))
           :oc-eof-macro nil)))))

    RETURNS #\hiragana_letter_a

See iacl.html for more information on international character support in Allegro CL.

# octets-to-native

Function, excl package

Arguments: *vector8 * &key address aligned (length (position 0 vector8)) (null-terminate t) result-vector

This function returns an address when result-vector is `nil` and returns result-vector when that argument is non-`nil`.

This function copies the 8-bit bytes from vector8, a `(simple-array (unsigned-byte 8) (*))` array, into one of the following locations, based on the arguments:

- static (i.e., non-Lisp heap) memory, when address and result-vector are unspecified or `nil`. The address of the first character of the copied data is returned.

- **the location specified by address*, when address is non-`nil` and result-vector is unspecified or `nil`. address, which becomes the location of the first byte of the copied data, is returned.

- result-vector, when result-vector is non-`nil` (address is ignored when result-vector is non-`nil`). result-vector is returned.

If the address argument is specified, it must be an integer specifying an address. The address may be in the Lisp heap, but note that in an SMP Lisp, addresses in the Lisp heap are not stable (the address may be valid when this function is called but a gc may happen while this function is running with the possible result that writing to the address can destroy Lisp data and cause Lisp failure). In non-SMP Lisps, it is possible to ensure that garbage collections do not occur while cons-free code is run but that is difficult to impossible in an SMP Lisp. More commonly, the address is in static space. The programmer must ensure that other data is not overwritten by the octets being copied when address is used. The system does no checking on its own. If result-vector is specified non-`nil`, address is ignored.

If address and result-vector are both unspecified or `nil`, new static memory is allocated. When no longer needed, the resulting memory must be passed to aclfree to be reclaimed.

If the aligned keyword argument is true, then address is an aligned address. Aligned addresses are returned by functions like lispval-to-aligned-malloc-address.

If the length argument is specified, then it specifies the number of elements to copy.

If result-vector is specified and not `nil`, it must be an octet vector, i.e. a `(simple-array (unsigned-byte 8)` (*)). vector8 will be copied to that vector. If result-array is in the Lisp heap, Care should be taken not to take the address of the result vector (e.g. with lispval-to-address) until there is no chance for a gc (again, this is hard to do in an SMP Lisp). This is not an issue if result-vector is a static array --see Static arrays in gc.html.

The null-terminate argument controls whether a single 0 octet is appended at the end of the copied bytes. null-terminate defaults to `t`. `:null-terminate nil` can be specified to prevent the addition of the null-terminating octet. If null-terminate is `nil`, then the length keyword must also be specified.

See also iacl.html for general information on international character set support in Allegro CL and see native-to-octets and string-to-native.

# octets-to-string

Function, excl package

Arguments: octet-vector &key string (start 0) (end (or (position 0 octet-vector :start start) (length octet-vector))) make-string? (external-format :default) truncate (string-start 0) string-end

In releases prior to 6.0, this function was named mb-to-string. The old name is preserved for backward compatibility, but users should use the new name.

This function returns three values: (1) a string, (2) the number of characters copied, and (3) the number of octets used, which is a number representing the actual count of octets used by the conversion process.

This function converts (according to the external-format argument) and copies the string data from the subsequence of octet-vector denoted by the start and end arguments into a lisp string. The string is returned. The number of characters copied to the string is returned as the second value and the number of octets used is returned as the third value.

If the string argument is specified, then the string data will be copied into this argument. If a string is specified by string and it is not long enough, an error is signaled unless either make-string? is specified as non-`nil`, in which case a new string is created and string is ignored, or string-end is a number, in which case string will be filled to that point and information on how many octets are used (and thus how many remain) is returned as the third returned value.

The truncate keyword argument controls the behavior when the external-format convertor attempts to go past the end of the octet array. When truncate is true, octets-to-string will terminate the current character conversion. When truncate is false, attempts to go past the end of the octet array are treated as external-format eof situations which may cause alternative valid character(s) to be returned. Using `:truncate t` is recommended when the octet array is a buffer that is not known to end with a complete character.

The arguments string-start and string-end are ignored unless string is specified. The string-start keyword argument determines at which position in the target string to insert converted characters. The string-end keyword argument determines the last position in the target string for inserting converted characters (its value, if a number, should be one greater than the last position in which to insert a character).

If string-end is `nil` and there are more characters to be inserted than space in the string, an error is signaled and no characters are inserted at all. If the value of string-end is a number, that error will not be signaled and instead characters are inserted up to position (- string-end 1). (But if string-end is greater than the length of the string, an array out of bounds type error might be signaled: this function does not test whether string-start and string-end have appropriate values.) The purpose of using string-end is to handle situations where you do not know in advance how many characters are to be converted. It allows filling a string, and then, using the third returned value (which tells how many octets were used) to determine if more octets are available, filling additional strings as necessary.

Conversion is done using the specified external-format. If external-format is not specified (or, equivalently, if the value of external-format is `:default`), then the external format returned by the following form is used:

    (locale-external-format *locale*)

See locale-external-format and *locale*.

See also native-to-string and string-to-octets.

See also iacl.html for general information on international character set support in Allegro CL.

# openssl-version

Function, excl package

Arguments:

This function prints information about the version of OpenSSL loaded into Allegro CL. (On UNIX systems, the command `openssl version` will print the version of the OpenSSL libraries available in the system.)

This function returns two values, each a list of three numbers and two strings. The numbers are the 3 numeric components of the OpenSSL version, the first string contains the letter (or letters) that identify the patch level of the OpenSSL library, and the last string is the hexadecimal representation of the OpenSSL release type, normally "f".

The first return value describes the version number of the OpenSSL shared library that was loaded when the ACL SSL module was loaded. The second value is the version number of the OpenSSL header files used when the aclssl shared library was built.

Here is an example of a returned value and its interpretation. The value you see will possibly be different.

    cl-user(2): (openssl-version)
    (1 0 1 "s" "f")
    (1 0 1 "s" "f")
    ;; Thus the OpenSSL library loaded was version 1.0.1, patch level "s",
    ;; release type 0xf (i.e. the hex number equal to decimal 15).
    ;; The second return value indicates the aclssl library was created
    ;; with the same OpenSSL library version.
    cl-user(3):

OpenSSL is described in The Allegro CL SSL API in socket.html.

# package-alternate-name

Function, excl package

Arguments: package-designator

Returns the package alternate name of the package specified by package-designator, which can be a package object or a symbol naming a package (keywords are good choices) or the package-name (a string).

The package alternate name is the name that will be used when a package name must be printed as a package qualifier of a symbol when using alternate names is called for because *print-alternate-package-name* is true. The alternate name must be either the package name (as returned by package-name) or one of its nicknames (as returned by package-nicknames). The alternate name is specified when the package is created.

If no alternate name has been specified, then the default alternate name is defined to be the first nickname is the list of nicknames (as returned by package-nicknames) or, if no nicknames are defined, the package name.

The alternate name can only be set when the package is created. Both defpackage and make-package accept additional arguments allowing the alternate name to be specified. (See defpackage and in-package, both in implementation.html, for more information on extensions to defpackage and make-package.)

If no alternate name is defined when the package is created, one can be added by recreating the package. The default alternate name, determined as described above, is used as the alternate name if none is defined at package-creation time.

# package-children

function, excl package

Arguments: package-specifier &key (recurse t)

package-specifier must be a package object, or a symbol or string naming a package. This function returns a list of packages below the argument package in the package hierarchy. If recurse is `nil`, the list contains immediate children only. If recurse is true (the default), the list contains all descendent packages.

This function is not intended to be called directly in ordinary circumstances (it might be called in association with debugging).

# package-definition-lock

Function, excl package

Arguments: package

Returns `t` or `nil` as package is or is not definition-locked. package must be a package object (it cannot be a symbol or a string). setf may be used with this function to definition-lock or unlock a package.

Even if a package is package-definition-locked, no error will be signaled when

1. the value of *enable-package-locked-errors* is `nil`;

2. the violation is dynamically inside the body of a call to the macro without-package-locks;

3. the value of *package* is the home package of the symbol being operated on; or

4. the list returned by package-implementation-packages applied to the value of *package* contains the home package of the symbol being operated upon.

If a package-definition-lock violation is encountered while compiling a file, a warning is signaled rather than an error. If the resulting fasl file is loaded, an error will then be signaled.

See packages.html, particularly sections Package definition locking and Implementation packages, and package-implementation-packages.

# package-implementation-packages

Function, excl package

Arguments: package

This function returns the list of strings naming the implementation packages of package. When the value of *package* is one of those implementation packages, definition changes to symbols in package will not signal package-definition-lock warnings or errors, even if package is definition-locked. See package-definition-lock.

This function may be used with setf to change the list of implementation packages. Remember the list must be a list of strings naming packages.

See packages.html for general information on the implementation of packages in Allegro CL and more information on package locking. Implementation packages are defined in Implementation packages in that document.

# package-local-nicknames

Function, excl package

Arguments: package

Release 10.1 and later only. Returns a list of `(local-nickname . actual-package)` pairs for each local-nickname mapping within package, which must be a package-designator.

Example

    cl-user(4): (defpackage :foo)
    #<The foo package>
    cl-user(5): (defpackage :bar)
    #<The bar package>
    cl-user(6): (defpackage :mypack (:use :cl :excl)
                            (:local-nicknames (:f1 :foo) (:b1 :bar)))
    #<The mypack package>
    cl-user(7): (package-local-nicknames :mypack)
    (("f1" . #<The foo package>) ("b1" . #<The bar package>))
    cl-user(8):

See Package-local Nicknames in packages.html for more information in package-local nicknames.

# package-locally-nicknamed-by-list

Function, excl package

Arguments: actual-package

Release 10.1 and later only. actual-package must be a package designator (a symbol, string or package object). This function returns a list of packages which have defined local nicknames for actual-package.

## Example

    cl-user(4): (defpackage :foo)
    #<The foo package>
    cl-user(5): (defpackage :bar (:use :cl :excl)
                            (:local-nicknames (:f1 :foo) (:f2 :foo)))
    #<The bar package>
    cl-user(6): (defpackage :baz (:use :cl :excl)
                            (:local-nicknames (:f3 :foo)))
    #<The baz package>
    cl-user(7): (package-locally-nicknamed-by-list :foo)
    (#<The baz package> #<The bar package>)
    cl-user(8):

See Package-local Nicknames in packages.html for more information in package-local nicknames.

# package-lock

Function, excl package

Arguments: package

Returns `t` or `nil` as package is or is not locked. package must be a package object (it cannot be a symbol or a string). setf[setf] may be used with this function to lock or unlock a package.

Even if a package is package-locked, no error will be signaled when

1. the value of *enable-package-locked-errors* is `nil`;

2. the violation is dynamically inside the body of a call to the macro without-package-locks;

3. the value of *package* is the home package of the symbol being operated on; or

4. the list returned by package-implementation-packages applied to the value of *package* contains the home package of the symbol being operated upon.

See packages.html for general information on the implementation of packages in Allegro CL and see Package locking in that document for more information on package locking.

# package-parent

function, excl package

Arguments: package-specifier

package-specifier must be a package object, or a symbol or string naming a package. This function returns the parent package of the package specified by the argument. An error is signaled if there is not a parent.

This function is not intended to be called directly in ordinary circumstances (it might be called in association with debugging).

See the section Hierarchical Packages in packages.html for information on the hierarchical package extension in Allegro CL. Parent packages are part of that extension.

# parse-re

Function, excl package

Arguments: string &key extended-mode

The several functions that accept quasi-Perl string representation for regular expressions (e.g. match-re) also accept parse tree syntax. parse-re is the function that translates the string representation into the tree representation. It is used internally as the first pass of compile-regexp, but occasionally is may be useful in application code.

The extended-mode keyword argument controls whether the parse begins in regular or extended mode. The default is `nil`. If true, it is as if the regexp string is prefaced with "(?x)".

Example

    cl-user(11): (parse-re ".*")
    (:greedy-repetition 0 nil :everything)
    cl-user(12): (parse-re ".*?")
    (:non-greedy-repetition 0 nil :everything)
    cl-user(13): (parse-re "^[A-E]")
    (:sequence :start-anchor (:char-class (:range #\A #\E)))
    cl-user(14): (parse-re "i.*s")
    (:sequence #\i (:greedy-repetition 0 nil :everything) #\s)
    cl-user(15):

See Regexp trees in regexp.html for information on the tree syntax.

The symbol naming this operator is also exported from the regexp package.

See The new regexp2 module in regexp.html for further information on this function and the regexp2 module.

# parse-ucet

Function, excl package

Arguments: files

files is a pathname of a single file or a list of pathnames of files. The files should be unicode collation element tables describing how characters should be ordered by, so that string< and string> will work as desired. A Lisp ucet (Unicode Collation Element Table) object is returned. This value is suitable as the value of the ucet keyword argument to string-sort-key. The Default Unicode Collation Element Table ucet is already present in Lisp, so there is thus no need to use this function for default Unicode collation behavior.

See String collation with international characters in iacl.html.

# path-namestring

Function, excl package

Arguments: filespec

This function returns the namestring of the pathname which includes the path portion of filespec (with pathname-name or pathname-type both `nil`). On Windows, the result may include pathname-host and pathname-device information. That is, this function returns the result of applying enough-namestring to path-pathname:

    (namestring (path-pathname filespec))

filespec should be a Common Lisp pathname designator, that is a pathname, a string naming a pathname, or a stream open to a file.

Examples

    (path-pathname "/foo/bar/baz.cl") RETURNS #p"/foo/bar/"
    (path-namestring "/foo/bar/baz.cl") RETURNS "/foo/bar/"

    ;; On Windows:

    (path-pathname "d:/foo/bar/baz.cl") RETURNS #p"d:\\foo\\bar\\"
    (path-namestring "d:/foo/bar/baz.cl") RETURNS "d:\\foo\\bar\\"
    (path-pathname "//hobart/c/tmp/foo.cl") RETURNS #p"\\\\hobart\\c\\tmp\\"
    (path-namestring "//hobart/c/tmp/foo.cl") RETURNS "\\\\hobart\\c\\tmp\\"

See pathnames.html.

# path-pathname

Function, excl package

Arguments: filespec

This function returns the pathname which includes the path portion of filespec (with pathname-name or pathname-type both `nil`). On Windows, the result may include pathname-host and pathname-device information. path-namestring returns the namestring associated with the pathname returned by this function.

filespec should be a Common Lisp pathname designator, that is a pathname, a string naming a pathname, or a stream open to a file.

Examples

    (path-pathname "/foo/bar/baz.cl") RETURNS #p"/foo/bar/"
    (path-namestring "/foo/bar/baz.cl") RETURNS "/foo/bar/"

    ;; On Windows:

    (path-pathname "d:/foo/bar/baz.cl") RETURNS #p"d:\\foo\\bar\\"
    (path-namestring "d:/foo/bar/baz.cl") RETURNS "d:\\foo\\bar\\"
    (path-pathname "//hobart/c/tmp/foo.cl") RETURNS #p"\\\\hobart\\c\\tmp\\"
    (path-namestring "//hobart/c/tmp/foo.cl") RETURNS "\\\\hobart\\c\\tmp\\"

See path-namestring and pathnames.html. The function pathname-sans-file essentially does the same thing as this function. This function should be used in preference to pathname-sans-file.

# pathname-as-directory

Function, excl package

Arguments: pathname

Turn pathname, a file namestring or pathname, into a pathname where all of pathname is in the directory component. For example,

>     (pathname-as-directory "foo")

returns the same value as

>     (pathname "foo/")

as does

>     (pathname-as-directory (pathname "foo"))

but

>     (pathname-as-directory "foo/bar")

returns the same value as

>     (pathname "foo/bar/")

# pathname-as-file

Function, excl package

Arguments: pathname

Return a new pathname based on pathname which moves the last directory name in the directory component into the name. #p"" is an illegal value for pathname. Example:

>     user(10): (pathname-as-file #p"foo/")
>     #p".\\foo"

# pathname-resolve-symbolic-links

Function, excl package

Arguments: pathname

The argument must be a existing pathname or something (like a string) coercible to a existing pathname. If the argument is a logical pathname, it is first translated to a physical pathname. The directories of the pathname are then checked from left to right. Whenever a directory component is encountered that is a symbolic link, the target of the link is merged into the pathname, and the new pathname is rescanned, starting from the beginning if the target of the symbolic link was an absolute pathname. When all symbolic links have been resolved, the resultant pathname object is returned.

Error when pathname does not exist

When pathname names a non-existent pathname, an error is signaled, similar to:

>     CL-USER(2): (excl:pathname-resolve-symbolic-links #p"/does/not/exist")
>     Error: realpath failed: No such file or directory [errno=2].
>       [condition type: SYSCALL-ERROR]

See also symbolic-link-p. See pathnames.html for general information on pathnames in Allegro CL.

# pathname-sans-file

Function, excl package

Arguments: pathname

Use of this function is deprecated. Use path-pathname instead. It does essentially the same thing.

Returns a new pathname with the same host, device and directory components of pathname and `nil` file and type components.

See pathnames.html for more infomation on pathnames in Allegro CL.

# peek-byte

function, excl package

Arguments: stream &optional (eof-error-p t) eof-value

This one-byte analog of peek-char is similar to read-byte, but if the result of the read does not cause an eof condition the octet is put back again. If it returns, peek-byte returns either the next octet to be read or the eof-value if at eof. Note that peek-byte is not as complex as peek-char, since there is no concept of whitespace characters when characters are not involved.

As with peek-char, if an eof is read, an error is signaled if eof-error-p is true, otherwise eof-value is returned.

peek-byte is essentially equivalent to a read-byte followed by a possible unread-byte.
Unlike unread-byte, peek-byte is guaranteed to work under all normal circumstances (including at eof).

peek-byte currently does not work in Gray streams - error is called when peek-byte is called on a Gray stream. (Gray streams are discussed in gray-streams.html.)

See peek-byte and unread-byte in streams.html for a general discussion of this function and the related unread-byte.

# pll-file

Function, excl package

Arguments:

Returns the name and perhaps the location of the current .pll file, or `nil` if there is no .pll file associated with the running Lisp. The location information is only returned (along with the name) if the image was created with location information specified along with the name (that is, build-lisp-image was called with the value of the `:pll-file` argument being [directory]/[filename and type] rather than just [filename and type]).

On startup, Lisp looks for the pll file as follows:

- If location information is supplied, look there only (relative to the current directory if the location information is relative).

- If just the filename and type or just the filename is supplied, do:

  1. If there is no type, use the type pll. (Note that the type of the file supplied with the distribution is sometimes epll rather than pll.)

  2. Look in the current directory.

  3. Look in the Allegro directory.

  4. [Windows only] Look in the Windows `system` directory.

# pop-atomic

macro, excl package

Arguments: place

pop-atomic expands into code that acts like pop with the same arguments except that the update to place is atomic with respect to all other processes looking at the same place. That is, any number of simultaneous push-atomic and pop-atomic operations on the same location will act as if they occured sequentially in some unspecified order.

If you just used push and pop, on say the list `(1 2 3)`, then two simulaneous pop's could both return 1 rather than one returning 1 and one returning 2. The list at the end of a series of simultaneous push-atomic's or simultaneous pop-atomic's (but not both) will have the expected length and contents, although for a series of push-atomic's the order of the elements is not specified. The result of a series of combined push-atomic's and pop-atomic's may have an indeterminant number of elements if all the elements of the list were popped before any new element were pushed.

Note on the place argument: not all places legal as the first argument of setf can be used as the place argument to this macro. The list of allowable places can be found in Atomic read-modify-write primitives in smp.html.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# prefixp

Function, excl package

Arguments: prefix sequence

This function returns non-`nil` value if sequence starts with prefix. prefix and sequence can each be any sequence.

The value returned when sequence does start with prefix is the index into sequence just after prefix.

Examples

    (prefixp "foo" "foobar") => 3
    (prefixp "foo" "foo") => 3
    (prefixp "foo1" "foo2") => nil
    (prefixp '(1 2 3) '(1 2 3 4 5 6 7)) => 3
    (prefixp (list #\f) "foo")  => 1
    (prefixp "f" (vector \#f #\o)) => 1

# preload-forms

Macro, excl package

Arguments:

This macro can be used to create a fasl file with CLOS optimizations, as we describe.

A generic function examines its arguments to determine which method or methods are applicable. This is called discrimination. The symbol-function of a generic-function is a discriminator function. There are various kinds of discriminators and the discriminator for a particular generic function may change during the execution of a program.

When Lisp determines that a generic function needs a different kind of discriminator it checks to see if the one it needs has already been built and, if not, creates one. The creation of a discriminator is relatively expensive since it involves the Lisp compiler.

When a CLOS application is loaded the generic-functions all have a simple discriminator which will select the correct discriminator when the generic function is first called. Therefore when a CLOS application starts it will run very slowly unless the discriminators it needs are already built. The only way to tell which discriminators your program needs is to run your program for a while and then look at the list of discriminators that exist. Allegro CL provides a mechanism for dumping out these discriminators and then loading them in with your program so that when the program starts all the discriminators it will need will already exist.

Further, with method-combination a call to a generic function can result in a sequence of methods being called. The code that calls the methods and processes the results of each call is called an effective method. In order to make effective methods fast, Lisp compiles them. In order to cut down on the compilation cost, Lisp actually creates effective-method templates which are functions closed over the particular methods to be called.

Thus many effective methods can share the same code. Just as in the case of discriminators discussed above, it is expensive to start a CLOS application running if the effective methods it will need haven't been compiled already. And again Allegro CL provides a way of saving the effective methods that the application has used so that they can be defined before the application starts.

You can dump discriminator functions and effective methods to a fasl file by compiling a source file that contains the following two lines after loading and running your application:

>     (in-package :clos)
>     (preload-forms)

# print-function-meta-info

Function, excl package

Arguments: func &key (src t) (ask t) terse full sort vars mixed start end current

Returns 0 values after printing information about func for side-effect. func can be a function or closure object or a function name.

If terse is true then 80 columns should be sufficient for the output, otherwise up to 150 columns may be required for the output. Normally, output is restricted to one line per information item. Source forms, when available, are printed using a concise-print technique whereby various values of *print-length* and *print-level* are tried until the whole form fits on one line. However, if full is true, no such testing is done, and whole forms are printed, possibly on multiple lines.

Up to four kinds of information currently presented, depending on various options. These are described more fully described in Printing function meta data and related topics in debugging.html.

- Source debug info: these are records which serve as Lisp breakpoints, and which provide information about what is currently being executed at any particular program counter location. There may be multiple source records with same pc locations. If other information is being printed with these records, then the first column always starts with "S" for "source record".

- Disassembler output: generally, each one or two line record shows a single instruction at a program-counter location. No character is ever printed in the first column of disassembler output.

- Variable transition information: each record represents a transfer of a variable's value to or from a location, either a register or a memory location. Each variable record is printed on a separate line that starts with "V" (for "variable transition").

- Census information: a census point is a pc location which is likely to be seen by the precise-gc, and the census point provides information about what locations on the stack are alive at that pc location. Each Census point is printed on its own line starting with "C" (for "census point").

If src is non-`nil` (the default) and if source-level-debug info is available for func it is used, otherwise the output is presented without source information. If func has been compiled with comp:save-source-level-debug-info-switch on but the fasl file has not been loaded with *load-source-debug-info* on, then source info will be searched using the following steps:

1. If the fasl file was compiled with *record-source-file-info* true, and if *load-source-file-info* was true when the fasl file was loaded, then the location of the fasl file is implied and is re-loaded with only source-debug-info requested.

2. If the source-file information was not recorded or loaded, but source-debug info was recorded (and not loaded), and if ask is non-`nil` (the default) then a prompt is given asking for the name of the file to load. Any string representing the file can be specified, e.g. "dir/file.fasl", "dir/file", "dir/file.cl", etc. If the fasl file associated with the given name exists it is loaded for source debug info and that info becomes available.

3. If ask is `nil`, source-debug info is silently unused.

Information is presented in an order most appropriate for the options given. Sorting can be by requested by source-record (i.e. `:rec`), by program-counter (i.e. `:pc`), or by source-position (i.e. `:pos`). If no options are specified for this function, and if source is available, then only source records will be shown in record order. If src is `nil` or source-debug-info is unavailable, or if either of mixed or vars is non-`nil`, then the presentation will be made in program-counter order.

If mixed is `t` then assembler code is presented in a manner similar to disassemble, but intermixed with any other information (in program-counter order).

If vars is `t`, then variable transitions are presented, interspersed with other information (in program-counter order).

If sort is `:pc` for any reason, census points are presented, in pc order.

If start is not specified, it defaults to 0. Specifies the starting record to print.

If end is not specified, it defaults to `nil`. Specifies one past the end record to print. If end is either nil or greater than the number of records in the function, then it is silently assumed to be one past the last record of the function.

If current is unspecified, it defaults to `nil`. Its values are interpreted as follows:

- If `nil`, nothing is modified.

- If an integer between start (inclusively) and end (exclusively) then when the record number represented by current is printed, it is preceeded by "->" to show it as current. Printing non-current records between start and end result in those records being just indented to match the current record when it prints.

When current is specified and is an integer, the format of print-function-meta-info is similar to what is described in the :flip-tty backend.

When current is specified and is a string, then no header information is printed in an initial line, and the titles for the fields are presented in a descriptive manner in the (single) line printed.

# print-startup-info

Generic Function, excl package

Arguments: type &optional brief

This generic function is used to print information useful to users during the start-up of the Lisp image.

type specifies what information is printed. Its value can be one of the keywords given below (meaning print information on that specific topic), or `nil` (meaning print nothing), or any true value other than one of the keywords below (meaning print the information specified by the variable *print-startup-message*.

The keywords identifying information are:

- `:compiler-optimization`

- `:compiler-switches`

- `:compiler-explain`

- `:case-mode`

- `:source-file-recording`

- `:xref`

brief is a boolean (default t) that indicates whether the message printed should be short (value t) or long (value `nil`). Note that some of the brief messages are empty.

Applications can augment what is seen during Lisp start-up by defining their own eql specialized methods on this generic function and pushing the appropriate information onto the list bound to *print-startup-message*.

Despite its name, this function can be called at any time. Its message contains information about the current state of the Lisp image. Thus, for example, evaluating the following form:

    (excl:print-startup-info :compiler-switches nil)

will print the values of the compiler switches for the current values of speed, safety, space, and debug (see Declarations and optimizations in compiling.html).

And evaluating:

    (excl:print-startup-info :case-mode)

will print the complete information on the the current case mode.

# print-system-state

Function, excl package

Arguments: &optional stream

This function prints, to the argument stream, information about the current state of the running Lisp and details of the operating-system. The intention of this output is to provide information about the Lisp to the Franz Inc. support team in order to make as complete a diagnosis as possible when first seeing a bug report. dribble-bug calls this function to create the initial header of a dribble file. This function returns no values.

The optional stream argument defaults to *standard-output*. If specified `t`, *terminal-io*. Its value can be any stream opened for output.

# print-type-counts

Function, excl package

Arguments: &optional location

Prints a list of quantities and sizes of lisp objects in the specified location in the heap, along with type names and type codes of each object type printed. The list is printed in sorted order starting with the object type with the most bytes in the specified location. Percentages are also printed; these are percentages of the total of the specified location. location is interpreted as follows:

- `:new`: Print information on objects in newspace
- `:pan`: Print information on panified objects (see below)
- `:notpan`: Print information on non-panified objects in newspace (see below)
- `:old`: Print information on objects in oldspace, i.e. tenured objects
- `:malloc`: Print information about the malloc arena.
- `:holes`: Print information about the types and sizes of the objects that were removed on the most recent global-gc. Note that no output is available until the first global-gc is done. See the example below.
- `t`: Print information on all objects. This is the default.

A panified object (from Peter Pan, who never grew up) has a bit set that prevents it from being tenured. Only the system can set this bit. Note that malloc space, stack space, and purespace are not considered to be the heap.

Examples

Here is an example of the information printed when location is `:holes`. Note that no information is printed until the first global garbage collection is done (a global gc is triggered by a call to gc with argument `t`). The output you see will likely be different, of course.

    cl-user(1): (print-type-counts :holes)
    code   type                                 items     bytes

     total bytes = 0
    cl-user(2): (gc t)
    cl-user(3): (print-type-counts :holes)
    code   type                                 items     bytes
     96: (simple-array t)                           33      4656 34.3%
    101: (simple-array character)                   77      2888 21.3%
    100: (simple-array (unsigned-byte 32))           1      2504 18.5%
      1: cons                                      304      2432 17.9%
     15: structure                                  21       840  6.2%
      9: closure                                     7       112  0.8%
     18: bignum                                      9        88  0.6%
      7: symbol                                      1        24  0.2%
     11: readtable                                   1        16  0.1%

     total bytes = 13560
    cl-user(4):

See also gc.html for general information on garbage collection in Allegro CL.

# probe-directory

Function, excl package

Arguments: pathspec

This function tests whether pathspec exists and is a directory, returning the result of applying truename to pathspec if it is, and returning `nil` if it does not exist or is not a directory. pathspec should be a pathname, a string naming a pathname, or a stream open to a file, that is, the argument should be a standard Common Lisp pathname designator.

Examples

    ;; Assume a directory /tmp exists:

    (probe-directory "/tmp/") RETURNS #p"/tmp/"
    (probe-directory "/tmp/foo.cl") RETURNS nil
      ;; (whether or not /tmp/foo.cl exists)

See probe-file and pathnames.html.

# pure-string

Function, excl package

Arguments: x

This is a special analog of cl:string. A pure-string is a string stored in a .pll file. These strings can be shared (among different simultaneous invocations of Lisp), but they are constants and cannot be modified. This function takes x (which must be a string or a symbol) and searches pure space to see if the string (printname if x is a symbol) is already there. If it is, that string is returned. If it is not, a new string is allocated in the heap and returned. So, if you know a string is a constant, you can apply this function to it to get the associated pure string if there is one, and thus save space.

When building a .str file using record-strings, pure-string will record that string that will be returned into the .str file for later processing by cvdcvt, the program that creates pll files. See Creating and using pll files in miscellaneous.html for information on pll files and cvdcvt.

As with string, x can be either a string or a symbol. If it is a string, it or its pure equivalent is returned. If it is a symbol, the printname is returned, again as a pure string if possible.

# push-atomic

macro, excl package

Arguments: value place

push-atomic expands into code that acts like push with the same arguments except that the update to place is atomic with respect to all other processes looking at the same place. That is, any number of simultaneous push-atomic and pop-atomic operations on the same location will act as if they occured sequentially in some unspecified order.

If you just used push and pop, on say the list `(1 2 3)`, then two simulaneous pop's could both return 1 rather than one returning 1 and one returning 2. The list at the end of a series of simultaneous push-atomic's or simultaneous pop-atomic's (but not both) will have the expected length and contents, although for a series of push-atomic's the order of the elements is not specified. The result of a series of combined push-atomic's and pop-atomic's may have an indeterminant number of elements if all the elements of the list were popped before any new element were pushed.

Note on the place argument: not all places legal as the first argument of setf can be used as the place argument to this macro. The list of allowable places can be found in Atomic read-modify-write primitives in smp.html.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# push-defclass-extra-form

Function, excl package

Arguments: form

Release 10.1 and later only. Returns form, and as a side-effect causes form to be pushed onto a list of extra forms which will then appear close to the end of the expanded defclass form. If this function is called while not processing a defclass-embellisher class's meta-data (see the defclass-embellisher-class), then an error will be signaled. The appearence of forms will be in the same order as the calls to this function.

The example in Metaclasses for embellishing class definitions in implementation.html has an example of this function being used.

# puthash-key

Function, excl package

Arguments: key hash-table

As a side effect, may add an entry to a sans values (a key-only) hash table (one created with the values argument to make-hash-table specified `nil`), if the equivalent key entry is not already in the table. Regardless of whether the given key was added or an equivalent entry is found, puthash-key returns the key that is actually in the hash-table. This allows objects to be kept in a hash-table efficiently without duplication.

See the description of extensions to make-hash-table in cl:make-hash-table in implementation.html.

# putprop

Function, excl package

Arguments: symbol value indicator

An old variant of the inverse of get kept for backward compatibility. (This symbol was in the `franz` package in release 4.3 and earlier on Unix. The `franz` package was merged with the `excl` package in release 5.0.)

    (putprop *sym val ind*)

is equivalent to

    (setf (get *sym ind*) *val*)

# quote-re

Function, excl package

Arguments: string

This convenience function accepts a string argument and returns a regular expression that matches that string literally, giving no special interpretation usually given to the special characters in regexp string syntax.

This function is implemented by simply returning a tree form regexp, wrapping a :sequence regexp around the argument string.

Example

    (regexp:quote-re "()")
      ==>
    (:sequence "()")

    (regexp:match-re "()" "(defun foo () ...)")
      ==>
    t
    ""
    ""

    (regexp:match-re (regexp:quote-re "()") "(defun foo () ...)")
    ==>
    t
    "()"

The symbol naming this operator is also exported from the regexp package.

See The new regexp2 module in regexp.html for further information on this function and the regexp2 module.

# ratiop

Function, excl package

Arguments: object

Returns true if the argument is a ratio and returns `nil` otherwise. Note that an integer (a fixnum or a bignum) is not a ratio but is a rational. Integers and ratios partition rationals.

    cl-user(7): (ratiop 1) ;; fixnums are not ratios
    nil
    cl-user(8): (ratiop 1/2)
    t
    cl-user(9): (ratiop 2/1)  ;; Actually the fixnum 2, despite how it
                              ;; is represented
    nil
    cl-user(10): (ratiop 0.5) ;; floats are not ratios
    nil
    cl-user(11): (ratiop nil) ;; returns NIL for non-numbers (does not error)
    nil
    cl-user(12):

See also fixnump, single-float-p, double-float-p, and rationalp.

# rc4-set-key

Function, excl package

Arguments: key-data &key start end external-format

rc4-set-key initializes the stream cipher context based on the key data. key-data can be a string or an usb8 (i.e. (unsigned-byte 8)) vector. If it is a string, then it will be internally converted to an usb8 vector according to the external-format keyword argument (or the default external format, if the keyword argument is not supplied). The start and end keyword arguments indicate the subset of key-data that will be used as the key (as if with subseq).
start defaults to 0 and end defaults to the length of key-data. If key-data is a string, then start/end are in terms of characters, otherwise, they are in terms of bytes.

This function returns a fresh rc4 key context which should be used in subsequent calls to the rc4 function.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# rc4

Function, excl package

Arguments: key src &key src-start sec-end dest dest-start external-format

rc4 encrypts or decrypts src, given a key context key (as created by rc4-set-key).

src can be a string or an usb8 vector. If src is a string, it will be internally converted to an usb8 array according to the external-format keyword argument (or the default external format, if the keyword argument is not supplied). The src-start and src-end keyword arguments indicate the subset of src that will be processed (as if with subseq). src-start defaults to 0 and src-end defaults to the length of src. If src is a string, the src-start/src-end are in terms of characters, otherwise, they are in terms of bytes.

If dest is supplied, it will be used as the output buffer for the encrypted/decryped data. If dest is not supplied, an usb8 array of suitable length will be created. dest-start, if supplied, indicates the offset (default: 0) into dest where the encrypted/decrypted data should be placed.

This function returns dest, if supplied, or the created usb8 array with the encrypted/decrypted data.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html.

# re-case

Macro, excl package

Arguments: string &rest clauses

string must be an expression that evaluates to a string. The clauses are then examined one by one, checking whether it matches string or not. clauses must be one of the following forms:

- `(regexp bindings expr ...)`: if string matches `regexp`, (sub)matches are bound to the variables according to `bindings`, then `expr ...` are evaluated. See the documentation of re-lambda for information on the specifiction of `regexp` and `bindings`.

- `(:test proc expr ...)`: `proc` must be an expression that evaluates to a procedure that takes single argument. `proc` is called with string, and if it returns a true value, evaluates `expr ...`.

- `(:testlet proc var expr ...)`: like `:test` above, but binds the result of `proc` to `var` while evaluating `expr...`.

- `(t expr ...)`: always match and evaluates `expr ...`. This can be used to describe the fallback case.

If no clause match, `nil` is returned.

See also re-let and re-lambda.

Example

    cl-user(4): (setq f
              (re-lambda "([^ ]+) ([^ ]+) ([^ ]+)"
              ((foo 1) (bar 2) (baz 3))
            (list foo bar baz)))
    #<Interpreted Function (unnamed) @ #x71ed7892>
    cl-user(5): (funcall f "foo the bar")
    ("foo" "the" "bar")
    cl-user(6): (re-let "([^ ]+) ([^ ]+) ([^ ]+)"
            "foo the bar"
            ((foo 1) (bar 2) (baz 3))
              (list foo bar baz))
    ("foo" "the" "bar")
    cl-user(7):

    cl-user(9): (re-case "foo the barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    ("barmy")
    cl-user(10): (re-case "foo a barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    ("barmy")
    cl-user(11): (re-case "foo xx barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    :no-match
    cl-user(12):

    cl-user(30): (labels ((parse-date (input)
                            (re-case input
                              ("^(\\d{4})([-/])(\\d{1,2})\\2(\\d{1,2})$"
                               ((year 1) (month 3) (day 4))
                               (mapcar #'read-from-string (list year month day)))
                              ("^(\\d{1,2})([-/])(\\d{1,2})\\2(\\d{4})$"
                               ((year 4) (month 1) (day 3))
                               (mapcar #'read-from-string (list year month day)))
                              ("^(\\d{2})([-/])(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\2(\\d{4})$"
                               ((year 4) (month 3) (day 1))
                               (list
                                (read-from-string year)
                                (cdr
                                 (assoc month
                                        '(("Jan" . 1) ("Feb" . 2) ("Mar" . 3)
                                          ("Apr" . 4) ("May" . 5) ("Jun" . 6)
                                          ("Jul" . 7) ("Aug" . 8) ("Sep" . 9)
                                          ("Oct" . 10) ("Nov" . 11) ("Dec" . 12))
                                        :test #'equal))
                                (read-from-string day))))))
                   (list (parse-date "2004/7/21")
                         (parse-date "7-21-2004")
                         (parse-date "21-Jul-2004")))
    ((2004 7 21) (2004 7 21) (2004 7 21))
    cl-user(31):

The symbol naming this operator is also exported from the regexp package.

See The regexp2 module in regexp.html for further information on this macro and the regexp2 module.

# re-lambda

Macro, excl package

Arguments: regexp bindings &body body

regexp must be a string that specifies a regular expression, or a list of such a string followed by options, or an expression that evaluates to a compiled regular expression.

re-lambda returns a closure which takes the arguments `(string &key if-does-not-match)`.

When the closure is called, it scans the given string by regexp, and if it matches, then evaluates body with the environment where the variables in bindings are bound to the substrings of the match(es). The closure returns the result(s) of the last expression of body.

bindings is like the binding form of let. Each element of bindings must be either one of the following:

- `(var integer)` ;; var binds to integer-th submatch (0 for whole).

- `(var string/symbol)` ;; var binds to the submatch named by string/symbol.

- `var` ;; var binds to the submatch named by var.

If the specified match doesn't have a value, var is bound to `nil`. You can also bind a substring before or after the specified submatch, by giving modifier like `(var integer :before)` or `(var integer :after)`.

If string doesn't match regexp, body is not evaluated, and the value given to the keyword argument if-does-not-match is returned.

If regexp is the form of `(string-re options ...)`, then options are passed to compile-re to create a compiled regular expression. It takes place at macro-expansion time, so options must only contain constant literals.

Examples

    cl-user(26): (funcall (re-lambda "(abc|def)(.*)" ((a 0) (b 1) (c 2))
                                      (list a b c))
                           "defabc")
    ("defabc" "def" "abc")
    cl-user(27): (funcall (re-lambda "(?<foo>[a-z]+)(?<bar>\\d+)" (foo bar)
                                      (list foo bar))
                           "   acl70beta ")
    ("acl" "70")
    cl-user(28): (funcall (re-lambda "cde" ((a 0 :before) (b 0) (c 0 :after))
                             (list a b c))
                           "abcdefg")
    ("ab" "cde" "fg")
    cl-user(29):

See also re-case and re-let.

Example

    cl-user(4): (setq f
              (re-lambda "([^ ]+) ([^ ]+) ([^ ]+)"
              ((foo 1) (bar 2) (baz 3))
            (list foo bar baz)))
    #<Interpreted Function (unnamed) @ #x71ed7892>
    cl-user(5): (funcall f "foo the bar")
    ("foo" "the" "bar")
    cl-user(6): (re-let "([^ ]+) ([^ ]+) ([^ ]+)"
            "foo the bar"
            ((foo 1) (bar 2) (baz 3))
              (list foo bar baz))
    ("foo" "the" "bar")
    cl-user(7):

    cl-user(9): (re-case "foo the barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    ("barmy")
    cl-user(10): (re-case "foo a barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    ("barmy")
    cl-user(11): (re-case "foo xx barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    :no-match
    cl-user(12):

The symbol naming this operator is also exported from the regexp package.

See The new regexp2 module in regexp.html for further information on this macro and the regexp2 module.

# re-let

Macro, excl package

Arguments: regexp string bindings &body body

regexp and bindings are the same as of re-lambda. string must be an expression that evaluates to a string. This macro evaluates string, matches it with regexp, and if it matches, bind variables with (sub)matches according to bindings, then evaluates body. If string doesn't match regexp, body is not evaluated and `nil` is returned.

See also re-case and re-lambda.

Example

    cl-user(4): (setq f
              (re-lambda "([^ ]+) ([^ ]+) ([^ ]+)"
              ((foo 1) (bar 2) (baz 3))
            (list foo bar baz)))
    #<Interpreted Function (unnamed) @ #x71ed7892>
    cl-user(5): (funcall f "foo the bar")
    ("foo" "the" "bar")
    cl-user(6): (re-let "([^ ]+) ([^ ]+) ([^ ]+)"
            "foo the bar"
            ((foo 1) (bar 2) (baz 3))
              (list foo bar baz))
    ("foo" "the" "bar")
    cl-user(7):

    cl-user(9): (re-case "foo the barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    ("barmy")
    cl-user(10): (re-case "foo a barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    ("barmy")
    cl-user(11): (re-case "foo xx barmy"
              ("foo a (.*)" ((it 1)) (list it))
              ("foo the (.*)" ((it 1)) (list it))
              (t :no-match))
    :no-match
    cl-user(12):

    cl-user(29): (re-let "(abc|def)(.*)" "defabc"
                         ((a 0) (b 1) (c 2))
                   (list a b c))
    ("defabc" "def" "abc")
    cl-user(30):

The symbol naming this operator is also exported from the regexp package.

See The new regexp2 module in regexp.html for further information on this macro and the regexp2 module.

# re-submatch

Function, excl package

Arguments: regexp string indexes selector &key (type :string)

This is a convenience function to extract a specified submatch information from the value returned by match-re.

regexp should be a compiled regexp, and indexes should be a list of `(start . end)` index pairs returned by match-re. selector should be an integer that specifies a captured submatch (or 0 for the whole match), or a string or a symbol that names a named submatch.

Alternatively, you can pass the opaque 'match' object returned by match-re with `:return :match` argument, as regexp. The match object knows the information about the match results, so you don't need string and indexes; just pass `nil` to them.

The type argument may be `:string`, `:after`, `:before` or `:index`. It specifies the return value. If it is :string (the default), the substring of the specified submatch is returned. If it is `:after` or `:before`, the substring after or before the specified submatch is returned, respectively. If it is `:index`, a pair of `(start . end)` indexes are returned.

If the specified submatch isn't included in indexes, `nil` is returned.

A typical usage pattern of this function is like this:

    (let ((r (multiple-value-list (match-re regexp string :return :index))))
      (re-submatch regexp string (cdr r) 3)))

Or, if you use the match object, like this:

    (let ((match (match-re regexp string :return :match)))
      (re-submatch match nil nil 3))

Additional examples

    cl-user(25): (let* ((s "abCDEfg")
                        (x (compile-re "[A-Z]([A-Z]+)"))
                        (r (cdr (multiple-value-list
                                 (match-re x s :return :index)))))
                   (list
                    (re-submatch x s r 0)
                    (re-submatch x s r 1)
                    (re-submatch x s r 0 :type :before)
                    (re-submatch x s r 1 :type :before)
                    (re-submatch x s r 0 :type :after)
                    (re-submatch x s r 1 :type :after)))
    ("CDE" "DE" "ab" "abC" "fg" "fg")
    cl-user(26):

The symbol naming this operator is also exported from the regexp package.

See The new regexp2 module in regexp.html for further information on this function and the regexp2 module.

# read-line-into

Function, excl package

Arguments: string &optional stream (eof-error-p t) eof-value &key (start 0) end

This function is a faster variant of read-line designed to place characters, read from a stream, into an existing string. It differs from read-line in (1) using an existing string rather than creating a new one, (2) reading only as many characters from a line as are needed, rather than reading a whole line, and (3) not returning the string where the characters are placed. Instead, filling the string is a side effect and two information values are returned:

1. The number of characters read and stored, (not including a newline if read). If an eof is encountered without reading any characters and eof-error-p was `nil`, then eof-value is returned instead. An error is signaled if an eof is encountered immediately and eof-error-p is non-`nil` (its default is `t`). If any characters are read (including a newline character), no error will be signaled and this first returned value will be an integer.

2. A flag indication the reason reading was stopped. The value `nil` indicates a newline was encountered (as with read-line, reading will not continue after a newline and the newline character will not be added to string). The value `:eof` means an end of file was encountered. The value `:short` means that character reading was stopped because the end of the string (the actual end or the end specified by the end keyword argument) was reached. Unexpected :short instead of nil. When the number of characters in a line is exactly the numbers of characters specified by start and end, this second return value will be `:short` instead of `nil`. Characters are read until the portion of the string specified by start and end is filled. The character after the one read which fills the substring is not read. If it is a newline, then in fact the whole line will be copied into string (just as if end was unspecified and the string was larger) but the system will not know that to be the case. If further reading is done when the next unread character is a newline, no characters will be read and 0 and `nil` will be the return values.

A traditional way to fill a string with characters from a file is to read a line from the file with read-line and copy characters from the string read into the target string. But that process is costly in time and space, as new strings must be allocated by read-line, and characters are copied twice (from the stream to the new string and from the new string to the target string). This function is optimized for the specific purpose of copying characters from a stream into an existing string.

The characters are read from stream and placed into string, beginning at the position specified by start. Characters are continually read until

1. The end argument is satisfied (the value `nil` for end is the same as specifying `(length *string*)`).

2. A newline is encountered (as with read-line, it is not added to the string).

3. An eof is encountered.

If the `:short` situation occurs (i.e. the end argument is satisfied without having encountered a newline) then further processing can be done in subsequent calls without loss of data. It should therefore be possible if desired to implement read-line using excl:read-line-into.

Arguments

- string may be simple or non-simple, but must be a string.

- stream is a stream designator.

- `:start` must be a positive integer less than the length of string. It specifies the first character of string to be replaced with a character read from stream. It defaults to 0

- `:end` is the index one beyond where the last character can be stored. End defaults to `nil`, which is the same as specifying `(length string)`.

- If eof-error-p is non-`nil` (the default) and an eof occurs before any characters have been read, an end-of-file error is signalled. As with read-line, eof-error-p has no effect on an eof encountered after there have been characters read (even if insufficent characters have been read to fill the target string).

- If eof-error-p is `nil` and an eof is encountered before any characters are read, eof-value is returned (and `:eof` is returned as the second value).

The motivation for this function is to provide read-line functionality without an open-ended consing of result strings, and to allow for more control over line-oriented input.

Examples

Assume file is a stream open to a file with contents shown (there are no space characters, the blank line has just a newline character, and the last line ends with an eof, not a newline):

    first line
    second line

    fourth line
    last line

Calls to excl:read-line-into have the following results:

    ;;  Edit to have FILE be a stream open to the file specified above:
    ;;  (setq file (open "myfile.cl" :direction :input)

    (setq string1 "0123456789" string2 "0123456789012345"
          string3 "012345678901234567890")
    (read-line-into string1 file) -> 10 :short
    string1 -> "first line"
    (read-line-into string2 file) -> 0 nil
    string2 -> "0123456789"   ;; no characters read beause
                              ;; a newline was encountered at once
    (read-line-into string2 file nil :eof-at-once :start 0 :end 5)
       -> 5 :short
    string2 -> "secon56789012345"
    (read-line-into string2 file nil :eof-at-once :start 5) -> 6 nil
    string2 -> "second line12345"
    (read-line-into string2 file nil :eof-at-once :start 10) -> 0 nil
    string2 -> "second line12345"  ;; read blank line, no characters added
    (read-line-into string3 file nil :eof-at-once :start 3) -> 11 nil
    string3 -> "012fourth line4567890"
    (read-line-into string3 file) -> 9 :eof
       ;;  If there is a newline at the end of the last line
       ;;  (sometimes editors insert them without being asked to)
       ;;  then this will return '9 nil' instead of '9 :eof'
    string3 -> "last line line4567890"
    (read-line-into string3 file nil :eof-at-once) -> :eof-at-once :eof
    string3 -> "last line line4567890"
    (read-line-into string3 file) -> ERROR ;; eof-error-p is T

See also simple-stream-read-line. That function is less space efficient than this one, but has a simpler interface.

# read-no-hang-p

Function, excl package

Arguments: stream

In brief, if the argument stream is an integer, read-no-hang-p views that integer as an output file-descriptor, and it just checks the file-descriptor for readiness. If stream is a stream, its input-handle is queried to see if reading can be done. True is returned if reading can be done, else `nil` is returned. If the handle is itself a stream (an encapsulation), the stream is examined in a way similar to a listen, but an eof or an error situation always causes a return of true.

The actual implementation is more complicated and probably of interest only to strategy-level programmers. See Simple-stream Description in streams.html for a discussion of different sorts of programmers.

If stream is a dual-channel stream that has the record-end set to -1, read-no-hang-p will call device-finish-record with `:listen` as the value of the blocking argument and `:prime-input` as the value of the action, and return nil if that call returns `nil`, or `t` if that call returns `:eof`.

For other stream types, the buffer is checked for emptiness. If it is not empty, `t` is returned (after a possible record-end check - see below).

If the buffer is empty, then device-read is called with a blocking argument of `nil`. Any eof or error condition will result in `t` being returned, and if no octets were read otherwise, `nil` is returned.

If stream is a dual-channel stream with record-end set, and if the read was able to get some data, or if the buffer was not empty to start with, the the record end is checked. If the record has ended, then device-finish-record is called with null blocking argument and action `:input`, and if it returns `nil`, `nil` is returned. Otherwise, `t` is returned.

See streams.html for information on the simple-streams implementation in Allegro CL.

# read-octets

Function, excl package

Arguments: stream buffer start end blocking

Reads as many octets from the argument stream's handle as possible. The input handle is examined, and if it is a stream (i.e. encapsulated), then that input handle is read from in a manner similar to read-vector, except that no further checking of arguments is done; it is assumed that the caller has done whatever checking that is necessary. Otherwise, if the handle is an operating-system-defined handle, the system read function is called.

buffer is any specialized simple-array of one dimension (it will be treated as if it were a simple vector of octets). Buffer can also be a fixnum, in which case it is treated as an aligned pointer and the "vector" is the memory implied by the aligned pointer. (See Aligned pointers in ftype.html.)

If buffer is `nil`, then the standard buffer slot will be supplied.

The blocking controls what happens if not even one octet can be read. If it is true, the function will block if the first character cannot be read; if it is `nil`, the function does not block. See Blocking behavior in simple-streams in streams.html.

Return values:

- A number greater than or equal to 0: the number of bytes actually read. 0 bytes are only ever transferred when blocking is nil.

- -1: EOF is returned.

- -3: Special return value for a no-hang query. If the start and end arguments are eql and if blocking is nil, then a 0 return means no data will be read, and a -3 value means data would have been read.

- (- -10 errno): the value of the error return from the system operation. For example, -19 represents an errno value of 9, which is EBADF (bad file number) on most systems.

Note: device-read implementations may use the return value of read-octets directly, but if an EOF is not "latching" (i.e. there may be more data read after an EOF condition), then the -1 value should be converted into a -2 value (soft EOF) before returning from the device-read method.

This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# read-tiny-float

Function, excl package

Arguments: string &key (return-zero t)

This is a convenience function which allows users to read a small-magnitude float safely (that is, without floating-point-underflow errors). If the float is smaller in magnitude than the least-positive float of the appropriate format, then zero in the appropriate form (in the appropriate format) is returned by default, or, if the return-zero keyword argument is specified as `nil`, the least-positive or elast negative float of the appropriate format is returned.

string must be a string whose contents read as a single floating-point number. It is an error resulting in undefined behavior if there is more in the string than the representation of a sinlge floating point number. (The function decides on whether the resulting float is positive or negative based on the presence and location of a #- charater. Such characters after the float representation could result in an incorrect value. If string represents a float larger than the least positive float or smaller than the least negative, the read is as if done by read-from-string. No protection is provided against floating-point-overflow errors.

Example

    ;;  This function is intended to allow for forms like the following:
    ;;  (defconstant *app-single-eps*
    ;;               (max least-positive-single-float 1.0e-50))
    ;;  LEAST-POSITIVE-SINGLE-FLOAT is 1.0e-45, so that is the desried value
    ;;  but reading 1.0e-50 may cause a floating-point-underflow error.
    ;;  That can be protected against with this form:
    ;; (defconstant *app-single-eps*
    ;;              (max least-positive-single-float
    ;;                   (read-tiny-float "1.0e-50")))
    ;;
    ;;  In the reamining examples, we assume *read-default-float-format*
    ;;  is single-float.
    ;;
    (read-tiny-float "1.0") **RETURNS** 1.0
    (read-tiny-float "1.0e-50") **RETURNS** 0.0
    (read-tiny-float "1.0e-50" :return-zero nil) **RETURNS** 1.0e-45
            ;; i.e. least-positive-single-float
    (read-tiny-float "-1.0e-50" :return-zero nil) **RETURNS** -1.0e-45
            ;; i.e. least-negative-single-float
    (read-tiny-float "-1.0d-50" :return-zero nil) **RETURNS** -1.0d-50
    (read-tiny-float "-1.0d-550" :return-zero nil) **RETURNS** -5.0d-324
            ;; i.e. least-negative-double-float

See Floating-point infinities and NaNs, and floating-point underflow and overflow in implementation.html for more information and sample handler code to cath the errors.

# read-vector

Function, excl package

Arguments: sequence stream &key start end endian-swap

Return value:

The number of octets actually read is added to the value of the start argument and that result returned. Thus, the return value is the index of the next octet in the vector (the value of sequence) that was not yet replaced.

For a Gray stream:

For a Gray stream, a check is made that the given vector (the value of sequence) is either a string or an octet vector (i.e. a simple-vector of `(signed-byte 8)` or `(unsigned-byte 8)` elements), and the equivalent of read-sequence is performed. Otherwise an error is generated.

For a simple-stream:

The value of sequence must normally be a simple vector, but there are some exceptions. sequence can also be an aligned-pointer (an integer), or a foreign-pointer with an address component that is word-aligned, but if it is either of these two kinds of addresses, then a valid end value must be given; no attempt will be made to figure out the length of the data at the address.

foreign-pointer and ff:ff:aligned-to-address.

If the vector is a string, the equivalent of read-char is performed on the stream and the result is stored into the first character of the portion of the sequence bounded by the start and end arguments. The equivalent of read-char-no-hang is performed for each character thereafter. Following the last-read-character, the unread-char length is set (instead of at every character read). See below for the blocking behavior of this function and the behavior when an EOF is encountered.

If the vector is not a string, the equivalent of read-byte is performed on the stream and the result is stored into the first byte of the portion of the sequence bounded by the start and end arguments. The equivalent of excl::read-byte-no-hang (a internal function alanlogous to read-char-no-hang) is performed for each byte thereafter, for as many octets as are specified for the vector. If each element of the vector consists of more than one octet, then the processing is done in the natural endianness of the machine architecture. On big endian machines octets read will be stored in the most significant through least significant octets of the values in the array. The reverse is true on little endian machines. See below for the blocking behavior of this function and the behavior when an EOF is encountered.

The start and end arguments can be used to modify the number of octets to be read, and are specified as octet offsets into the vector (instead of numbers of elements, as in read-sequence). If the end argument is not specified, the length of the vector adjusted by the element-width is used instead. Note that if the vector is of an element-type that is smaller than an octet (8-bit byte) then the adjustment includes an alignment to the next higher octet boundary. Thus a bit vector of 20 bits will cause a transfer of 3 octets to occur.

The number of octets actually read (and stored into the vector) is added to the start argument and that result returned. Thus, the return value is the index of the next octet in the vector that was not yet replaced.

#### Note on blocking and EOF behavior

read-vector is a B/NB (blocking/non-blocking) function, blocking until the first element is read and not blocking thereafter. See Blocking behavior in simple-streams in streams.html.

This function does not error if an EOF is encountered. It simply returns the number of octets actually read (and stored into the vector) added to the value start argument. That value contains the relevant information (how much was read) and can be analyzed if necessary to determine what occurred. For example

    (read-vector vec stream)

returns 0 if an EOF is encountered immediately. Because at least one object is read if there is anything to read, a return value of 0 can only mean an EOF was encountered before an object was read.

If a value for start is specified and an EOF is encountered immediately, that value is returned (because the return value is the number of octets actually read -- 0 when an EOF is encountered immediately added to the value start argument). This, again assuming trying to read from `stream` will result in an immediate EOF,

    (read-vector vec stream :start 4)

returns 4.

#### The endian-swap argument

The endian-swap keyword argument allows the user to treat I/O with a consistent byte-ordering despite endian issues. It defaults to 0. See section The endian-swap keyword argument to read-vector and write-vector in streams.html.

#### read-vector and cl:read-sequence

Note that read-vector is similar to read-sequence, but is different fundamentally in the following ways:

- read-vector operations on non-strings are done on an octet basis, whereas read-sequence on non-strings is specified to read (variably-sized) bytes on an element-by-element basis. Thus, there is a general packing that occurs in read-vector into any size vector. Also, the start and end keyword arguments and the return value are always in terms of octets, except for string simple-streams, where they are in terms of characters.

- The -sequence (in the name of the function read-sequence) implies too much for efficient implementation since it includes handling of input into lists. read-vector reads into vectors for efficiency.

- read-vector works on specialized simple-arrays of one dimension. (A specialized array, of course, is an array whose element type is a proper subtype of `t`. See Data types in implementation.html for a list of specialized arrays in Allegro CL.)

  read-vector is not supported for non-specialized arrays, non-simple arrays, or arrays of more than one dimension.

See also write-vector.

See streams.html for information on the simple-streams implementation in Allegro CL.

# record-source-file

Function, excl package

Arguments: fspec &key type

This function is used to record the location of built-in and user defined objects in source files.

The built-in types and the forms that use them are:

- `:operator`: defun, defmacro
- `:variable`: defconstant, defparameter, defvar
- `:special-declaration`: defconstant, defparameter, defvar
- `:compiler-macro`: define-compiler-macro
- `:setf-method`: defsetf
- `:type`: defclass, defstruct, deftype

For example, putting the following form into a file, compile and loading it: `(defun foo (x) ...)` will cause foo to be recorded as an `:operator` in the file in which it was defined.

Redefinition warnings occur when a file is loaded and it defines an object of an already existing source file recording type. Objects of different types, say an `:operator` and `:type`, do not cause redefinition warnings.

Users can extend this facility to understand objects they define. The most usual case is a macro that defines a high-level object, such as:

    (defmacro def-frob (name fram)
      `(progn
         (record-source-file ',name :type :frob)
         (def-frob-1 ',name ,fram)))

    ;;  We assume def-frob-1 exists and does something useful.
    ;;  Here is a dummy def-frob-1 that make sthe example work:
    (defun def-frob-1 (name fram) (declare (ignore name fram))
      nil)

Then, if the following form is put into /a/b/foo.cl:

>     (def-frob akbar 'fez)

and is then compiled and loaded, `(source-file 'akbar :frob)` will return a pathname pointing to /a/b/foo.cl.

See also source-file-recording.html for general information on source file recording in Allegro CL.

# register-assert-enable

Function, excl package

Arguments: name index

name is a keyword representing a new assert-enable. index must be an unused index. If there is already an assert-enable registered at the index, an error will be signaled which will identify the current assert-enable and its index.

Note: No effort has been taken to make the registration or unregistration of assert-enables thread-safe. These operations are intended to be low incidence, non-dynamic operations.

See Conditionalizing assert calls in miscellaneous.html for more information.

# relative-package-name-to-package

Function, excl package

Arguments: name

name should be a string naming a relative package or a package. If name names a package, that package is returned. If name is a relative package name (that is, begins with dots (.) and is not itself the name or nickname of a package), this function determines the actual package intended by the relative name and returns it.

This function is not intended to be called directly in ordinary circumstances (it might be called in association with debugging).

# release-dumplisp-virtual-image

Function, excl package

Arguments: virtual-image-object

The argument must be an object that was returned by calling dumplisp with non-`nil` value of the virtual keyword argument (which is supported on Windows only). The first time release-dumplisp-virtual-image is called with a particular legitimate argument, it releases the virtual file and returns `t`. Any subsequest calls with the same argument do nothing, and return `nil`. This function is thread-safe. See Virtual dumplisp: for very large images and pseudo-forks on Windows.

# remove-package-local-nickname

Function, excl package

Arguments: local-nickname &optional housing-package

Release 10.1 and later only. If the housing package designated by housing-package has local-nickname (a string designator) as a local nickname, it is removed and `t` is returned, otherwise `nil` is returned.

Example

    cl-user(18): (package-local-nicknames :hpack)
    (("p-one" . #<The p1 package>) ("p-two" . #<The p2 package>)
     ("p-one-a" . #<The p1 package>))
    cl-user(19): (remove-package-local-nickname :p-one-a :hpack)
    t
    cl-user(20): (package-local-nicknames :hpack)
    (("p-one" . #<The p1 package>) ("p-two" . #<The p2 package>))
    cl-user(21): (remove-package-local-nickname :p-three :hpack)
    nil
    cl-user(22): (package-local-nicknames :hpack)
    (("p-one" . #<The p1 package>) ("p-two" . #<The p2 package>))
    cl-user(23):

See Package-local Nicknames in packages.html for more information in package-local nicknames.

# remove-signal-handler

Function, excl package

Arguments: number

Removes the handler for signal given by number.

See add-signal-handler (which has an example), set-signal-handler, *signals*, and with-signal-handler.

# remove-stream-instance-flags

Macro, excl package

Arguments: stream &rest flag-names

Removes (via logandc2) the specified instance flags from the standard-instance object that is the stream. Note that this flags field has no correlation to a flags slot in the stream. You may inspect a stream in raw mode to see the instance-flags (see inspector.html). This macro may be used in device-close methods.

Valid instance flags are placed into the following groups:

- Direct stream subclass (select exactly one): `:gray` (identifies a Gray or fundamental-stream) or `:simple` (identifies a simple-stream). A stream instance that has neither bit set is not considered a stream.

- Open-ness (select one, both, or none): `:input` (stream may perform input operations); `:output` (stream may perform output operations). A stream instance that has neither bit set is not considered an open stream.

- Direct simple-stream subclass (select zero or one): `:dual` (stream is a dual-channel stream); `:string` (stream is a string-stream). A stream with neither bit set is considered a single-channel stream

You must load the `:iodefs` module to use this macro. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This macro is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# remove-typep-transformer

Function, excl package

Arguments: type

Removes the typep-transformer for type, if there is one. It is not an error to apply this function to a type that does not have a typep-transformer. This function returns `t` if there was a typep-transformer for type and returns `nil` if there was not. Typep transformers are added with add-typep-transformer.

See compiling.html for general information on compiling and see Adding typep-transformers in that document for more information on typep transforms.

# rename-file-acl6.1

Function, excl package

Arguments: filespec new-name

The function is similar to cl:rename-file in that it renames the file or directory specified by the filespec to the file or directory specified by the new-name argument. It is the Allegro CL 6.1 version of cl:rename-file. In Allegro CL 6.2, errors in the implementation of cl:rename-file have been corrected, and a new function, rename-file-raw, has been added (it mimics the behavior of the UNIX mv/Windows Move commands with regard to relative pathnames). Both cl:rename-file and rename-file-raw behave differently under certain circumstances than they did in release 6.1 (and in earlier releases). Users who want the exact Allegro CL 6.1 behavior can use this function.

The behavior of rename-file-acl6.1 depends on the value of *default-pathname-defaults*. If that value is an absolute pathname, rename-file-acl6.1 works like rename-file-raw. If that value is an empty pathname (#p""), rename-file-acl6.1 works like cl:rename-file. The difference can be seen with the following example:

    *default-pathname-defaults*
      -> #p"/usr/home/user1/"

    (rename-file-acl6.1 "tmp/foo.cl" "tmp/baz.cl")
      -> #p"/usr/home/user1/tmp/baz.cl" [and additional values]

    ;;  OR

    *default-pathname-defaults* -> #p""

    (rename-file-acl6.1 "tmp/foo.cl" "tmp/baz.cl")
      -> #p"/usr/home/user1/tmp/tmp/baz.cl" [and additional values]

Like cl:rename-file, rename-file-acl6.1 returns three values: The new name, the truename of filespec, and the truename of the new name.

# rename-file-raw

Function, excl package

Arguments: filespec new-name &key follow-symlinks

The function is similar to cl:rename-file in that it renames the file or directory specified by the filespec to the file or directory specified by the new-name argument. The truename of the renamed file is returned, as a symbolic link (if it is one) if follow-symlinks is `nil` (the default) and as the canonical filename if follow-symlinks is true. (rename-file-raw calls truename passing the value of follow-symlinks. See truename in implementation.html.)

rename-file-raw differs from cl:rename-file in that it mimics the UNIX mv/Windows MOVE method of resolving relative pathnames when renaming files. If new-name is a relative pathname, it is merged with *default-pathname-defaults* to get the actual new name. cl:rename-file merges new-name with filespec. The difference can be seen with the following example:

    ;; *default-pathname-defaults* is an absolute pathname and
    ;; both directories /usr/home/user1/tmp/ and
    ;; /usr/home/user1/tmp/tmp/ exist.
    *default-pathname-defaults*
      -> #p"/usr/home/user1/"

    (probe-file "tmp/foo.cl") -> #p"/usr/home/user1/tmp/foo.cl"
    (probe-file "tmp/tmp/") -> #p"/usr/home/user1/tmp/tmp/"

    ;;  Only one of the following four forms may be evaluated,
    ;;  since after evaluation the file specified by
    ;;  the first argument will not exist.
    ;;  Only the first value returned is shown.

    (rename-file "tmp/foo.cl" "tmp/baz.cl")
      -> #p"/usr/home/user1/tmp/tmp/baz.cl"
    (rename-file-raw "tmp/foo.cl" "tmp/baz.cl")
      -> #p"/usr/home/user1/tmp/baz.cl"

    (rename-file "tmp/foo.cl" "baz.cl")
      -> #p"/usr/home/user1/tmp/baz.cl"
    (rename-file-raw "tmp/foo.cl" "baz.cl")
      -> #p"/usr/home/user1/baz.cl"

Like cl:rename-file, rename-file-raw returns three values: The new name, the truename of filespec, and the truename of the new name. Here is the source, followed by the source of cl:rename-file:

    (defun rename-file-raw (filespec new-name)
      (let ((new-name (pathname new-name))
        (old-truename (truename filespec)))
        (excl::filesys-rename-file (namestring old-truename)
                 (namestring
                  (merge-pathnames
                   (translate-logical-pathname new-name))))
        (values new-name old-truename (truename new-name))))

    (defun rename-file (filespec new-name)
      (let ((defaulted-new-name (merge-pathnames new-name filespec))
        (old-truename (truename filespec)))
        (excl::filesys-rename-file (namestring old-truename)
                 (namestring (translate-logical-pathname
                          (pathname defaulted-new-name))))
        (values defaulted-new-name old-truename
            (truename defaulted-new-name))))

The situation in release 6.1 was confused, because the behavior of cl:rename-file depended on the value of *default-pathname-defaults* in inappropriate ways (when *default-pathname-defaults* was an absolute pathname, 6.1 cl:rename-file worked like the new rename-file-raw; when *default-pathname-defaults* was an empty pathname -- #p"", 6.1 cl:rename-file worked as specified by ANSI, that is, as cl:rename-file works now. An additional function, rename-file-acl6.1 is provided which is the Allegro CL 6.1 implementation of cl:rename-file. Users who want the exact 6.1 behavior can use it.

# replace-re

Function, excl package

Arguments: string regexp substitution &key count (start 0) end case-fold single-line multiple-lines ignore-whitespace

This function replaces substrings in string that matches regexp with substitution, returning the new string. It always returns a new string, even if no substitutions are made.

regexp can be a string that specifies a regular expression, or an already-compiled (by compile-re) regular expression. regexp should match a non-zero length string, or an error is signaled.

substitution can be a string, or a function that takes one argument, a list of match substrings returned by the regexp matcher. The function must return a string, which is then used as a substitution string.

The keyword argument count limits the maximum number of substitutions. If it is `nil`, all occurrences of regexp in string are replaced.

The keyword arguments start and end limit the region in string where matching occurs.

Other keyword arguments are passed to compile-re to compile regexp.

The symbol naming this operator is also exported from the regexp package.

Example

    cl-user(14): (replace-re ":f" "(\\W)(\\w)" "\\1 \\2")
    ": f"
    cl-user(15): (replace-re "00a1b23c99" "\\d+" "#")
    "#a#b#c#"
    cl-user(16): (replace-re "12345" "\\d(\\d+)(\\d)" "#\\1.\\2")
    "#234.5"
    cl-user(17): (replace-re "12345" "\\d(?<middle>\\d+)(?<tail>\\d)"
                              "#\\k<middle>.\\k<tail>")
    "#234.5"
    cl-user(18): (replace-re "a12345b67890c" "\\d(?<middle>\\d+)(?<tail>\\d)"
                              "#\\k<middle>.\\k<tail>")
    "a#234.5b#789.0c"
    cl-user(19): (replace-re "0123456789" "\\d+"
                              (lambda (matches)
                                (format nil "(~a)" (length (car matches)))))
    "(10)"
    cl-user(20): (replace-re "a12345b678c90" "\\d+"
                              (lambda (matches)
                                (format nil "(~a)" (length (car matches)))))
    "a(5)b(3)c(2)"
    cl-user(21): (replace-re "a12345b678c90" "([a-z])(\\d+)"
                              (lambda (matches)
                                (format nil "~a(~a)"
                                        (string-upcase (cadr matches))
                                        (length (caddr matches)))))
    "A(5)B(3)C(2)"
    cl-user(22):

See The new regexp2 module in regexp.html for further information on this function and the regexp2 module.

# replace-regexp

Function, excl package

Arguments: string regexp to-string &rest args &key count start end newlines-special case-fold shortest &allow-other-keys

Replace occurrences of regexp in string with to-string. Regular expression groups in regexp can be referenced with \n in to-string. If count is `nil` or `t`, replace all occurrences; if a number, replace that number of occurrences.

This function accepts all the following match-regexp keywords: newlines-special, case-fold, shortest, start and end, and passes them to match-regexp (used for finding the matches in string). Note that using start and end might be rather inefficient if used repeatedly on a large string, since for each call to replace-regexp, a new string will be created.

Use of this function is deprecated and it is maintained for backward compatibility only. See regexp.html for information on the newer regular expression compiler in Allegro CL. You should use the functionality described there instead of this function is new code.

Examples:

    (replace-regexp "xxx yyy zzz xxx yyy zzz" "xxx" "yyy")
      RETURNS "yyy yyy zzz yyy yyy zzz"
    (replace-regexp "xxx yyy zzz xxx yyy zzz" "xxx" "RR")
      RETURNS "RR yyy zzz RR yyy zzz"
    (replace-regexp "123 yyy zzz 123 yyy zzz 123" "y" "WHY")
      RETURNS "123 WHYWHYWHY zzz 123 WHYWHYWHY zzz 123"

    (replace-regexp "xxx yyy zzz xxx yyy zzz xxx" "xxx" "yyy"
            :start 3 :end 20)
      RETURNS "xxx yyy zzz yyy yyy zzz xxx"
    (replace-regexp "xxx yyy zzz xxx yyy zzz xxx" "xxx" "RR"
                    :start 3 :end 20)
      RETURNS "xxx yyy zzz RR yyy zzz xxx"

    (replace-regexp "xxx yyy zzz xxx yyy zzz xxx" "xxx" "yyy"
                   :start 3 :end 23)
      RETURNS "xxx yyy zzz yyy yyy zzz xxx"

    (replace-regexp "123 yyy zzz 123 yyy zzz 123" "123" "yyy"
                    :start 3 :end 27)
      RETURNS "123 yyy zzz yyy yyy zzz yyy"
    (replace-regexp "123 yyy zzz 123 yyy zzz 123" "123" "9999"
                    :start 3 :end 27)
    "123 yyy zzz 9999 yyy zzz 9999"

    ;; Here is a more complicated example that extracts some
    ;; fields out of a standard Unix passwd entry:

    (replace-regexp "joe:*:512:50:Joe User:/home/joe:/bin/csh"
            "^\\([^:]*\\):[^:]*:\\([0-9]*\\):[0-9]*:\\([^:]*\\):.*$"
            "Login {\\1} Full Name {\\3} UID {\\2}")
     **RETURNS** "Login {joe} Full Name {Joe User} UID {512}"

    ;; Here is is in action:

    (with-open-file (f "/etc/passwd")
      (loop repeat 5
          as entry = (read-line f nil nil)
          while entry
          collect (replace-regexp
               entry
               "^\\([^:]*\\):[^:]*:\\([0-9]*\\):[0-9]*:\\([^:]*\\):.*$"
               "Login {\\1} Full Name {\\3} UID {\\2}")))
    **RETURNS**
    ("Login {root} Full Name {system PRIVILEGED account} UID {0}"
     "Login {+} Full Name {} UID {0}"
     "Login {daemon} Full Name {system background account} UID {1}"
     "Login {bin} Full Name {system librarian account} UID {3}"
     "Login {uucp} Full Name {UNIX-to-UNIX Copy} UID {4}")

# required-thread-binding

function, excl package

Arguments: variable form-to-eval

Adds to *required-thread-bindings* list the variable and form-to-eval as an alist entry. This is the preferred interface to add thread bindings.

# required-top-level-binding

Macro, excl package

Arguments: variable form-to-eval

Adds to *required-thread-bindings* list the variable and form-to-eval as an alist entry. This is the preferred interface to add thread bindings.

# resident-function

Function, excl package

Arguments: func

In previous releases, this function ensured that the function object specified as the argument was fully loaded and then returned the (perhaps now fully loaded) function object. When a fasl file was loaded in libfasl (Allegro Presto) mode, it was typically only partially loaded until used. In 7.0, the Allegro Presto facility has been removed. This function is kept for backward compatibility only and is essentially equivalent to the identity function, simply returning its argument. (The argument func must still be a function object -- not a symbol naming a function.)

See The Allegro Presto facility has been removed in loading.html for further information.

# restore-file-positions

Function, excl package

Arguments: ident-object &optional (errorp t) error-value

This function by default returns the value of the saved character position after positioning the file to the locations saved by with-saved-file-positions and identified by ident-object. Or it will return the value of error-value if the original internal (byte) file-position value saved was `nil` and if errorp is specified as `nil` (meaning that the stream is inapppropriate for file-positioning). If the original file-position value saved was `nil` and errorp is unspecified or is specified as true, error is called and the function does not return.

The ident-object must be one that was created within a with-saved-file-positions form. Its extent is indefinite, and this function can be called with the ident-object at any time after its creation, although if the stream has been closed error will be called.

The character position returned might be `nil`, in which case the file-character-position had originally returned `nil` (meaning no character position data had been available).

See Preserving file positions in miscellaneous.html for more information and for an example of this function's operation.

# rmd160-file

Function, excl package

Arguments: filespec &key return

Using rmd160-init, rmd160-update, and rmd160-final, compute the RMD160 hash on the contents of the file given by filespec. Returns the value of rmd160-final on the implicitly created context. The return argument is passed to rmd160-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-file.

# rmd160-final

Function, excl package

Arguments: context &key return

Finalize and return the RMD160 hash from context in a format determined by the return keyword argument.

return can be one of the following values:

- `:integer` (the default): the return value is an integer of up to 128 bits representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octets containing only zeroes. Care should be taking when using this return type if you intend to further encode the digest (such as to a base64-encoded string). See the example below.

- `:usb8`: return an (unsigned-byte 8) array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (rmd160-init))
    #S(excl::md-context :ctx 9183168 :size 20)
    cl-user(5): (rmd160-update c "foo")
    cl-user(6): (rmd160-final c :return :usb8)
    #(66 207 162 17 1 142 164 146 253 238 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to RMD160-FILE which calls
    ;;  RMD160-FINAL and returns the value RMD160-FINAL returns.
    ;;
    ;;  Here we get the rmd160 value in a shell:
    % openssl dgst -rmd160 -hex qall.jpg
    RIPEMD160(qall.jpg)= 05e527b6387540cc9162049b5f60e960f00f8299

    ;; Now we get it with RMD160-FILE:
    cl-user(17): (rmd160-file "~/qall.jpg")
    33655283890170409359154440781670075183125201561
    cl-user(18): (format t "~x" *)
    5e527b6387540cc9162049b5f60e960f00f8299
    nil
    cl-user(19):

    ;; Note the hex values are the same but the leading 0 is not printed
    ;; by Lisp, which is dealing with the value as an integer. The leading
    ;; 0 is preserved when the :return is :hex:
    cl-user(19): (rmd160-file "~/qall.jpg" :return :hex)
    "05e527b6387540cc9162049b5f60e960f00f8299"
    cl-user(20):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-final.

# rmd160-init

Function, excl package

Arguments:

Returns an initialized RMD160 context, used by the other RMD160 functions.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-init.

# rmd160-string

Function, excl package

Arguments: string &key start end external-format return

Using rmd160-init (which creates a context), rmd160-update (which updates the context with the argument string), and rmd160-final (which finalizes the hash), this function computes the RMD160 hash for string.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context. start defaults to 0, end defaults to the length of string, and external-format defaults to the default external format. These arguments, along with string, are passed to rmd160-update.

The format of the result, just as for rmd160-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See rmd160-final for information on these values and the corresponding formats of the returned value.

    cl-user(4): (rmd160-string "foo")  ;; default return format :integer
    381423763107660302516367369772054956593396934771
    cl-user(5): (rmd160-string "foo" :return :usb8)
    #(66 207 162 17 1 142 164 146 253 238 ...)
    cl-user(6):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-string.

# rmd160-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running RMD160 computation in context (rmd160-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external format of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

This function returns no values, but side-effects context.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-update.

# rsa-decrypt

Function, excl package

Arguments: value key &key string

RSA decrypt value using key. key can be a public or private key. If the value was encrypted with the public key then it should be decrypted with the private key, and vice versa. (See Support for RSA encryption in miscellaneous.html for a description of key objects. Possible keys are returned by the function generate-rsa-keys.)

value can be

- a vector of element-type (unsigned-byte 8) that was the result of a call to rsa-encrypt.

- integer which was the result of calling rsa-encrypt on an integer.

If value is an (unsigned-byte 8) vector (also called an octet vector) then the result of rsa-decrypt is either an octet array or, if string is true, a string.

If value is an integer then the result is an integer.

rsa-decrypt will signal an error if the given key is so far from the correct key to decrypt the value that it can't even run the decryption algorithm using it.

See also rsa-encrypt and generate-rsa-keys.

See Support for RSA encryption in miscellaneous.html for information on RSA encryption and RSA encryption support in Allegro CL. There are examples of RSA encryption and decryption in that section. Support for encryption in the same document discusses encryption support in Allegro CL in general.

# rsa-encrypt

Function, excl package

Arguments: value key

RSA encrypt value using key. key can be a public or private key. (Recall that keys are vectors with three values: t/nil (distinguishing public from private but not used in actual encryption); the modulus value; and the exponent value. See Support for RSA encryption in miscellaneous.html for details. Possible keys are returned by the function generate-rsa-keys.)

value can be:

- an array of element-type (unsigned-byte 8).

- a string (which is converted to an array of (unsigned-byte 8) using the :utf-8 external format).

- an integer less than the modulus of the key.

The result of encryption will be an (unsigned-byte 8) vector (also called an octet vector) if value is a string or octet array and it will be an integer if value is an integer.

See rsa-decrypt and generate-rsa-keys.

See Support for RSA encryption in miscellaneous.html for information on RSA encryption and RSA encryption support in Allegro CL. There are examples of RSA encryption and decryption in that section. Support for encryption in the same document discusses encryption support in Allegro CL in general.

# run-shell-command

Function, excl package

Arguments: command &key input output error-output separate-streams (wait t) if-input-does-not-exist if-output-exists if-error-output-exists show-window environment directory uid gid effective initgroups-user (share-open-files t)

Introductory comments

The `:osi` module (see Operating System Interface Functionality in os-interface.html) has these new operators relating to running subprocesses: the function command-output and the macros with-command-output and with-command-io. They are higher-level than run-shell-command and shell and are now recommended when the interaction with the subprocess requires input or produces output that must be captured. The new operators do not have separate description pages. They are described in OSI process/uid/gid interface functions in os-interface.html.

This function, originally written and named for Unix machines, is badly misnamed for Windows, because on Windows, you can only run programs. Shell commands, such as dir, are not acceptable as a value of the command argument. See below in this entry for discussion on this point.

Also note that there is often a Lisp tool equivalent to a command. (For example, the Lisp function directory can be used in place of dir on Windows and ls on Unix. See below under the heading run-shell-command and Windows for why "dir" cannot be the value of the command argument.) It is always preferable to use Lisp tools where possible.

This is particularly true in an application delivered to others. The action of spawning a process, which might involve spawning a shell, may have consequences on another user's machine which you (the application developer) do not expect, and these consequences may interfere with the operation of your application in ways that are difficult to debug.

This is a powerful but complicated function, which has many options and modes of behavior. We have tried to provide sufficient internal links to navigate about this description. All necessary information is here somewhere, so if you scroll done you will likely find what you need.

## 0. Beginning of function documentation: input to and output from the command and return values

The process spawned by this function will generally have (always on UNIX, console apps on Windows) standard input, standard output, and standard error. If you want input beyond what is part of the command argument, you need to get a handle on the standard input. If you want to capture (and possibly redirect) the output or the error output, you need to get a handle on standard output and standard error.

You can, as we describe in the discussion of the input, output, and error-output keyword arguments below, set things up yourself, by specifying streams or file pathnames. And, when the wait keyword argument is `nil`, you can have run-shell-command set up Lisp streams to connect to process's input, output, and error-output. In that case, the created streams are among the multiple values returned by run-shell-command, as we describe next in the discussion of return values.

This function returns either one value when the wait argument is true (it defaults to `t`), or three or four values when wait is `nil`. When wait is `nil`, the number of values depends on the value of the separate-streams argument (described below).

When commands display information (such as ls displaying file and directory information), that information is not what is returned by run-shell-command. When wait is true (the default), the single return value is the exit status of the spawned process. When wait is `nil`, the multiple return values are 2 or 3 values which can be streams or `nil` and a final value which is the pid (process id number) of the spawned process. Output from the command is sent to whatever the standard out of the spawned process is connected to.

Other actions when run-shell-command runs: Lisp tries to close all open file descriptors in the process spawned by run-shell-command except for stdin, stdout and stderr. It does this by cycling through the set of legal file descriptors trying to close each one. The overhead is generally insignificant given the low frequency and heavy cost of the operation as a whole. However, this action can cause problems when you are doing performance analysis, particularly involving strace. A sequence of 65000 or so system calls can confuse the analysis. You can limit the number of invalid-fd error returns accepted on closes of sequential fds during this operation. See the function invalid-fd-close-on-fork-limit for more information.

## 1A. Return value when :wait is t (the default)

When run-shell-command is called with the wait keyword argument is true (or unspecified since the default is `t`), then the single return value is the exit status of the spawned process. You must set up handling of the spawned process's input, output, and error-output using the input, output, and error-output keyword arguments as described below. Here are two examples showing what we mean. These examples use printenv and so do not work on Windows, but they do illustrate thr return value.

    ;; The command is 'printenv DISPLAY'. First we call it with
    ;; :wait t (just for emphasis, :wait defaults to t):

    cl-user(131): (run-shell-command "printenv DISPLAY" :wait t)
    192.132.95.16:12.0
    0

    ;; The DISPLAY value is printed BUT NOT RETURNED. What is returned
    ;; is the single value 0, the exit status of the call to printenv.
    ;; This is made clear by the following:

    cl-user(133): (multiple-value-list (run-shell-command "printenv DISPLAY"))
    192.132.95.16:12.0
    (0)

    ;; Here we let :wait simply default to t. Again the DISPLAY value is
    ;; printed, but, as trhe singleton list of return values -- (0) -- shows,
    ;; not returned. The output is being sent to the standard out of the Lisp
    ;; process, which the spawned process inherits.

    ;; In our final example, we send the process output to a stream open to
    ;; a file:

    cl-user(136): (with-open-file (s "test.txt" :direction :output
                       :if-exists :supersede)
            (run-shell-command "printenv DISPLAY" :output s))
    0

    ;; And here are the contents of the file:

    cl-user(137): (run-shell-command "cat test.txt")
    192.132.95.16:12.0
    0
    cl-user(138):

## 1B. Return values when :wait is nil

If you specify `:wait nil`, be sure to also see More on the :wait argument below for information on reaping the process when it completes.

When wait is specified `nil`, run-shell-command returns three or four values: three when the separate-streams keyword argument is `nil`, four when separate-streams is true. The separate-streams argument is discussed in this section and in its own section below).

When the value of the wait keyword argument is specified `nil`, then you can have run-shell-command create streams for any or all of the spawned process's standard input, output, and error-output. Any created streams must be made available, and this is done by returning them. (run-shell-command returns immediately when wait is nil, and so any returned streams are available at once.)

The interface is complex and admittedly non-intuitive (but it has been around so long that it cannot be easily changed). Just keep in mind that multiple values are returned, that the last return value is the pid of the spawned process's pid, and that the earlier return values are either streams set up by run-shell-command or `nil`.

The streams that run-shell-command might set up are individual streams for the spawned process's standard in and out, a bidirectional stream for both standard in and out, and/or an individual stream for the spawned process's error output.

run-shell-command will set up a stream for standard input when input is `:stream`, for standard output when output is `:stream`, and for error output when error-output is `:stream`. If both input and output are `:stream`, a single bidirection stream is set up for both unless the separate-streams keyword argument is specified true, in which case different streams are set up for input and output. run-shell-command will not itself set up a stream for input, output, or error output when, respectively, input, output, and error-output have any value other than `:stream`. The other allowable values for those arguments are discussed below.

Here are some sample calling templates to illustrate the range of possible return values. Unspecified keyword arguments (indicated by suspension points -- ...) do not affect the indicated return values.

    ;;  First a reminder about calls with :wait t.
    ;;  When the :wait argument is true (as it is by default),
    ;;  a single value is returned. Here are two examples with :wait t.
    ;;  The second signals an error since none of :input, :output, or
    ;;  :error-output can be :stream when :wait is true.

    (run-shell-command command :wait t ...)
    ;; RETURNS as a single value the exit status of the spawned
    ;;   process which executes *command* (note that the default value
    ;;   of :wait is T so ':wait t' need not be specified)

    (run-shell-command command :wait t
                       :input :stream
                       :output :stream
                       :error-output :stream
                       ...)
    ;; ERROR: none of :input, :output, or :error-output can be :stream
    ;;   when :wait is t.

In all remaining examples, wait is `nil` and multiple values are returned. input, output, and error can each have the value `:stream` or other values described below. For showing what is returned, it only matters whether each of the arguments input, output, and error is `:stream` or not, so we show the value as :stream, or [some value other than :stream], or [any value including :stream].

run-shell-command, when wait is `nil`, returns three values when the separate-streams keyword argument is `nil` (the default), and returns four values when separate-streams is true. separate-streams refers to streams for input and output: when `nil`, a single stream is set up for input, or output, or both (a bidirectional stream in that case; when true, separate streams are set up.

    ;; separate-streams is nil in the first set of examples:

    (run-shell-command command
                       :input [some value other than :stream]
                       :output [some value other than :stream]
                       :error-output [some value other than :stream]
                       :separate-streams nil :wait nil ...)
     **RETURNS three values**
     nil
     nil
     the process id of the spawned process

    (run-shell-command command
                       :input :stream
                       :output [some value other than :stream]
                       :error-output [some value other than :stream]
                       :separate-streams nil :wait nil ...)
     **RETURNS three values**
     a stream (which acts as standard input to the spawned process)
     nil
     the process id of the spawned process

    (run-shell-command command
                       :input [some value other than :stream]
                       :output :stream
                       :error-output [some value other than :stream]
                       :separate-streams nil :wait nil ...)
     **RETURNS three values**
     a stream (which acts as standard output from the spawned process)
     nil
     the process id of the spawned process

    (run-shell-command command
                       :input :stream
                       :output :stream
                       :error-output [some value other than :stream]
                       :separate-streams nil :wait nil ...)
     **RETURNS three values**
     bi-directional-stream (standard in and standard out of spawned process)
     nil
     the process id of the spawned process

    (run-shell-command command
                       :input [any value including :stream]
                       :output [any value including :stream]
                       :error-output :stream
                       :separate-streams nil :wait nil ...)
     **RETURNS three values:**
     stream-or-nil (stream if either :input or :output is :stream)
     stream (for standard error of the spawned process)
     the process id of the spawned process

    ;;  **In the next example, *separate-streams* is
    ;;  `t` and four values are returned.**

    (run-shell-command command :separate-streams t :wait nil ...)
     **RETURNS four values:**
     stream-or-nil (a stream to standard input if :input is :stream, nil otherwise)
     stream-or-nil (a stream to standard output if :output is :stream, nil otherwise)
     stream-or-nil (a stream to error-output if :error-output is :stream, nil otherwise)
     the process id of the spawned process

    ;; In this next example, we create a stream ourselves and use it for
    ;; :output. Note that RUN-SHELL-COMMAND returns NIL for the output stream
    ;; value (second returned value since separate-streams is true)
    ;; even though output is actually a stream, since RUN-SHELL-COMMAND
    ;; itself set up the stream:

    cl-user(139): (with-open-file (s "test.txt" :direction :output
                       :if-exists :supersede)
            (run-shell-command "printenv DISPLAY" :output s :wait nil
                       :separate-streams t))
    nil
    nil
    nil
    13147
    cl-user(140):

## 2. The command argument

The command argument can be a string containing a shell command (in Unix) or a program (in Windows). On Unix only, command can be a simple vector (element type t).

- If command is a string, a shell is spawned which parses and executes the command.

- If command is a simple vector (Unix only), its elements should be coercible to strings. The zeroth element and the remainder of the vector, converted to C strings, are passed as the two arguments to execvp() (and thus bypassing the intermediate shell process despite the name of this function). This is faster than spawning a shell and it avoids processing of shell initialization files such as .cshrc. Further, a shell will treat certain characters (such as quotes, asterisks, question marks, semicolons, spaces) as special. Such special treatment is a potential security risk if part of the command string contains untrusted input.

Here are two Unix invocations, one using a vector and one a string:

    (run-shell-command #("ls" "ls" "-l" "dcl"))
    (run-shell-command "ls -l dcl")

Note that when command is a string, and wait is `nil`, the returned process-id will be that of the shell, not the command itself, unless the command is prefaced with the shell `exec` built-in command. Thus

    (run-shell-command "ls" :wait nil)

will return the process-id of the shell in which ls is run while

    (run-shell-command "exec ls" :wait nil)

will return the process-id of ls as will

    (run-shell-command #("ls" "ls") :wait nil)

## 3. input, output, and error-output keyword arguments

The values of input, output, and error-output keyword arguments control what the spawned process will use as standard input (file descriptor 0), standard output (file descriptor 1) and standard error (file descriptor 2). The values can be

- `nil` - inherit standard input, output or error (respectively) from Lisp. Note that this is Unix standard input and output inherited from the Lisp process and is unrelated to the Lisp variables *standard-input* and *standard-output*.

- a pathname (or string) - open the file specified by the pathname (or string) and use the resulting stream;

- a stream - use the stream. The stream must be of a kind that has a Unix file descriptor in the appropriate direction. (Remember that input and output from the point of view of the spawned process are the opposite when viewed from Lisp. A stream which is the value of output will receive data from the spawned process; that which is the value of input will transmit data to the spawned process.) Examples include a stream open to a file or a hardware device or a Unix socket. A string output stream, for example, is not an appropriate value;

- the keyword `:stream` - create a stream and return it to the Lisp program. Since waiting and having a stream open to a process can cause the process to hang, `:wait` must be `nil`; if `:wait` is `t`, an error will result. (When `:stream` is specified, the actual stream is not available to the program until run-shell-command returns, at which time it is really too late to be useful when `:wait` is `t`.)

error-output has an additional allowed value: `:output`, which directs standard error to the same place as standard output (file descriptor 1 rather than 2).

The default value in all cases is `nil`.

## 4. The directory keyword argument

The directory keyword argument can be used to specify the directory in which the command runs. It defaults to `nil`, which results in the command being run in the directory returned by current-directory. If its value is a directory pathname or namestring, the command is run in that directory.

## 5. More on the :wait argument

wait may be `t` or `nil`. If wait is `t`, Lisp will wait for the command to exit before resuming. If wait is `nil`, Lisp will start the process and then resume without waiting for it to finish. The default for wait is `t`.

Note that if wait is specified as `nil`, then the process will remain in the system after it completes until either Lisp exits or Lisp executes sys:reap-os-subprocess to inquire about the exit status. To prevent the system becoming clogged with processes, a program that spawns a number of processes with :wait set to `nil` must be sure to call reap-os-subprocess after each process finishes. Further, the streams returned by run-shell-command must be closed (the system will not close them automatically).

Also see Killing a process started with :wait nil below.

## 6. The :if-* arguments

The keyword arguments if-input-does-not-exist, if-output-exists and if-error-output-exists are used when input, output or error-output are pathnames (or strings naming files).

Lisp uses cl:open to open a stream to the file identified by the pathname (or string) and the values of if-input-does-not-exist, if-output-exists and if-error-output-exists are passed to the cl:open function as the value of its if-does-not-exist parameter (for input) and the if-exists parameter (for output and error-output.)

The permissible values for if-does-not-exist are `:error`, `:create` and `nil`.

Those for if-output-exists and if-error-output-exists are `:error`, `:overwrite`, `:append`, `:supersede` and `nil`. The default is `:error` in all cases.

## 7. The separate-streams keyword argument

The separate-streams keyword argument causes separate streams to be created and returned (rather than a single, bi-directional stream) when input and output are both `:stream`. When separate-streams is true, four values are returned, for the input stream, the output stream, and the error-output stream.

In all cases, `nil` will be returned in place of a stream if the relevant argument is not `:stream` (see the call templates Again, the allowed values are described above).

The value of separate-streams only matters when the value of the wait is `nil`.

## 8. The environment keyword argument

The value of environment should be an association list of names and values or a list of lists, where the name is the first element of the list and the value is the second (further elements are ignored). Names and values should be strings. Each name should be the name of an environment variable to set in the process being spawned, and the corresponding value should be the desired value for that variable. The environment variable is only set in the process being spawned, and is not set in the process executing the run-shell-command, nor is it remembered in future calls to run-shell-command.

run-shell-command adds the specified environment variables and values to the existing environment and passes that to the subprocess it is starting. Specifying an environment name that already exists will cause that name's value to be replaced with the new value specified.

4096 bytes is allocated for storing new names and values.

In the following example, we show that the DISPLAY environment variable has a value, but that value is changed in the spawned process when we specify `:environment '(("DISPLAY" "111.222.33.444:0"))`, and that the change is not remembered.

    cl-user(6): (run-shell-command "printenv DISPLAY")
    192.132.95.213:0
    0
    cl-user(7): (run-shell-command "printenv DISPLAY"
                                   :environment
                                   '(("DISPLAY" "111.222.33.444:0")))
    111.222.33.444:0
    0
    cl-user(8): (run-shell-command "printenv DISPLAY")
    192.132.95.213:0
    0
    cl-user(9):

## 9. run-shell-command and Windows

On all Windows OS's, run-shell-command executes programs but does not invoke shell commands. The function is therefore misnamed for Windows. It is called run-shell-command to provide cross-platform compatibility between Windows and Unix. It does behave differently on Windows and Unix. The difference is related to differences between UNIX and Windows.

On Unix run-shell-command spawns a Unix process and runs the executable program or Unix shell command provided as argument to the function. On Windows, the argument to run-shell-command command is started directly and so works with programs but the Windows command shell is not invoked and so run-shell-command does not work with shell commands. An example of a program is Notepad. Either of these forms will start Notepad on Windows:

    (run-shell-command "notepad")
    (run-shell-command "notepad.exe")

To run a DOS shell command, the argument to run-shell-command has to start the shell and tell it to run the command.

Here is an example:

On Windows the name of the shell is cmd.exe. Here is an example of using run-shell-command on Windows:

    (run-shell-command "cmd /c start \"c:\\Program Files\\\"")

which opens a command prompt in the c:\Program Files\ directory.

This displays the Windows explorer and avoids cmd altogether:

    (run-shell-command "explorer c:\\acl")

Also:

- The first argument to run-shell-command has to be a string (the Unix version will accept a vector of strings).

- The run-shell-command command will be started directly and the Windows command shell will not be invoked to start the command. Because the Windows shell is not involved, you cannot include shell operators in the command (e.g. `<<, <, >`, and | ).

- If the keyword arguments input, output and error-output are given stream values, then that stream must be open to a file on the disk. In particular a stream such as *terminal-io* will not be accepted here, nor will a socket stream nor a stream returned by a previous run-shell-command.

- You can start a DOS (Console mode) or a Windows program with run-shell-command.

  Note: Windows programs are unlikely to use standard input, output or error.

- When you use streams to communicate with a spawned process, keep in mind that the streams are operating in a raw mode that doesn't translate a carriage-return linefeed to a linefeed on input, and a linefeed to a carriage return followed by a linefeed on output.

## 10. The :show-window keyword argument (Windows only)

The show-window keyword argument only has effect on Windows. The value controls how the window created by the program run by run-shell-command first appears. The value can be an integer. The integer should be the value of one of the SW_ constants defined in the winuser.h include file that is part of the Windows SDK. The symbolic value should be preferred over an integer, however, since this will be portable in the face of changes to the Windows SDK header files and use on other operating systems. The value can also be one of the following symbols:

- `nil`: let the process itself determine how it will show its window.

- `:normal`: display a window in neither a maximized nor minimized state. Same as integer value SW_NORMAL.

- `:showna`: show but do not select (i.e. display the window but do not bring it to the front). Same as integer value SW_SHOWNA. Warning: this value may work inconsistently on different versions of Windows. Use `:minimized` to ensure the window is not in front but is accessible, or `:hide` if accessing the window is never important.

- `:hide`: hide the window completely. It doesn't even appear in the task bar. Same as integer value SW_HIDE.

- `:minimized`: display the window as an icon in the task bar. Same as integer value SW_MINIMIZED.

- `:maximized`: display the window as a full screen maximized window. Same as integer value SW_MAXIMIZED. Console windows can not be maximized, however.

## 11. The :share-open-files keyword argument (Windows only)

When share-open-files is true (the default value), behavior is as it has been before this argument was added: all open file handles that could be shared will be shared.

When share-open-files is specified as `nil`, then the input, output, and error-output keyword arguments must also be `nil` (which is their default). In this case no open file handles will be shared and the spawned process will open its own standard io handles if it needs them.

## 12. Threads and streams on Windows

On Windows, Allegro CL starts an operating system thread for each output stream created, to be a transfer agent for the data. This thread cannot exit until it knows all the data has been transferred from the external shell process to the Lisp world. This will happen if the external process finishes and the agent has read all the data it produced, or if the stream is explicitly closed on the Lisp side. Since the Lisp portion of the stream has a limited buffer space, there may well be data still to be read long after the external process finishes; the agent cannot transfer all the data to the Lisp buffer until Lisp activity makes room for it by reading the earlier data. The Lisp application that uses run-shell-command with stream output should explicitly close any stream it does not read to the end, or it risks finding the available pool of OS threads completely taken up by zombie stream agents.

## 13. run-shell-command and Unix

run-shell-command starts a process with execlp() when command is a string and (as we said above) execvp() when command is a simple vector.

The SHELL environment variable is used to determine the type of shell spawned. If SHELL has no value. /bin/csh is used. If that fails, /bin/sh is used.

## 14. The environment in which run-shell-command runs its processes

run-shell-command starts up subprocesses of the Lisp process. In order to modify an environment variable for these subprocesses, you must modify the environment for the Lisp process -- it does no good to modify the environment for the parent process of the Lisp process (i.e. the shell where Lisp was started, or Emacs, if Lisp is started as a subprocess of Emacs).

You can poll environment variables with getenv, and you can set environment variables for the Lisp process, and thus for subprocesses created by Lisp (by run-shell-command, e.g.) with setf and getenv.

## 15. The uid, gid, effective, and initgroups-user keyword arguments

These arguments only have meaning on UNIX platforms. They are not supported on Windows.

uid and gid are numbers representing user and group ids. effective is a boolean which indicates that uid and gid are effective user and group ids. initgroups-user is a string naming a user.

Here is an example using command-output (which also has the new arguments):

    cl-user(1): (require :osi)
    t
    cl-user(2): (excl.osi:command-output "whoami" :uid 483)
    ("layer")
    nil
    0
    cl-user(3): (excl.osi:command-output "whoami")
    ("root")
    nil
    0
    cl-user(4):

The gid, initgroups-user, and uid arguments are independent and are processed in the following order, using the indicated system calls (on most UNIX platforms):

argument | system call
--- | ---
gid | setgid(), setegid()
initgroups-user | initgroups()
uid | setuid(), seteuid()

The group is always set first, since after changing users that user may not have permission to change groups.

## 16. A couple of Unix examples

    ;; The current values of the environment variables on your system may,
    ;; of course, be different from what appears in this example.
    user(2): (sys:getenv "SHELL")
    "/bin/csh"
    user(3): (setf (sys:getenv "SHELL") "/bin/sh")
    "/bin/sh"
    user(4): (sys:getenv "SHELL")
    "/bin/sh"

Here are a couple of examples of run-shell-command. In the first, we simply have run-shell-command execute a simple command (who).

    USER(1): (run-shell-command "who")
    rlogin ttyb Aug 19 08:26
    sdj ttyp0 Aug 18 16:08 (rubix)
    adam ttyp2 Aug 18 16:17 (rubix)
    dm ttyp4 Aug 19 10:24 (rubix)
    0
    USER(2):

The second example is more complicated. We cause run-shell-command to spawn a shell and then we communicate with the shell via the stream set up by run-shell-command.

    ;; First we define a function to read the output from the shell. This
    ;; function is pretty simple -- it reads characters and prints them
    ;; out but it does show how a more useful function could be implemented.
    USER(24): (defun get-from-shell (stream)
                 (do ((ch (read-char-no-hang stream)
                          (read-char-no-hang stream)))
                     ((null ch))
                   (write-char ch)))
    GET-FROM-SHELL
    ;; Now we initiate the shell:
    USER(25): (setq shell-stream
                    (excl:run-shell-command "csh"
                                            :input :stream
                                            :output :stream
                                            :wait nil))
    #<EXCL::BIDIRECTIONAL-TERMINAL-STREAM @ #x10a4aa6>
    USER(26): (format shell-stream "who~%")
    NIL
    USER(27): (force-output shell-stream)
    NIL
    USER(28): (get-from-shell shell-stream)
    rlogin ttya Aug 19 07:06
    rlogin ttyb Aug 19 08:26
    sdj ttyp0 Aug 18 16:08 (rubix)
    cheetham ttyp1 Aug 18 17:17 (frozen)
    adam ttyp2 Aug 18 16:17 (rubix)
    NIL
    ;; We exit the shell:
    USER(29): (format shell-stream "exit~%")
    NIL
    ;; and close the stream.
    USER(30): (close shell-stream)
    T
    ;; We call sys:reap-os-subprocess because we called
    ;; run-shell-command with :wait nil:
    USER(31): (sys:reap-os-subprocess)
    0
    3995
    nil
    USER(32):

## 17A. excl:run-shell-command and SMP

A call to run-shell-command with `:wait t` (the default for the wait keyword argument is `t`) in an SMP Lisp blocks the Lisp process than calls run-shell-command but does not block other running processed. This is in contrast to the behavior of non-SMP multiprocessing, where a call to run-shell-command with `:wait t` blocks everything until the shell command completes, as we describe under the next heading.

## 17B. excl:run-shell-command and non-SMP multiprocessing

run-shell-command does not take multiprocessing into consideration. Therefore, if it is called with the :wait argument true (the default is t), all of Lisp waits for the call to complete, not just the process or thread that called run-shell-command. It is that behavior which is multiprocessing unfriendly. The following is a multiprocessing friendly call to run-shell-command. It does cause the calling process or thread to wait but does not cause the entire Lisp process to wait for the shell command to finish.

    (multiple-value-bind (s errs my-pid)
        (run-shell-command "sleep 5; ls /usr/bin" :wait nil)
      (declare (ignore errs s))
      (let ((my-status nil))
        (mp::process-wait "for run-shell-command to finish"
                          #'(lambda ()
                             (setq my-status
                              (or my-status
                                 (sys:reap-os-subprocess
                                  :pid my-pid :wait nil)))))
        my-status))

Notes:

1. Calling run-shell-command with :wait `nil` allows Lisp to continue in any case, and that might be what you want.

2. To repeat what we said above, most things can be done better from Lisp without recourse to run-shell-command, which is inherently risky (to some extent, it puts the fate of the Lisp process in the hands of a non-Lisp program over which Lisp may not have control). Whenever you are tempted to use run-shell-command, consider performing the same action within Lisp (perhaps using foreign functions).

## 18. A note on the order of execution when reading from a program to be reaped in a non-multiprocessing environment

Code written similar to the following skeleton of code may hang:

    (multiple-value-bind (shell-stream error-stream process)
        (excl:run-shell-command cmd
           :input :stream :output :stream :error :stream)

      (when process
        (loop (when (sys:reap-os-subprocess :pid process :wait nil)
             (return))))

      ;; now read from shell-stream and then close the streams

      )

In the code sample, the process is reaped prior to reading the process output. While this often works, because many programs don't bother to wait for all of their writes to complete before exiting, it may cause hanging if the pipe to which the data is sent fills up and thus not all data can be written until some reading is done, or the child program waits until each input has been read before writing more data. Some operating systems will cause select() to not return ready status on the output descriptor if any data at all is in that pipe, regardless of whether a call to write() would have succeeded.

The correct outline for the code is:

    (multiple-value-bind (shell-stream error-stream process)
        (excl:run-shell-command cmd
           :input :stream :output :stream :error :stream)

      ;; do all the reading from shell-stream

      (when process
        (loop (when (sys:reap-os-subprocess :pid process :wait nil)
             (return))))

      ;;  close the streams
    )

When you are using multiprocessing, you can use multiprocessing tools such as process-wait to ensure that no hanging occurs, as is done in the example under the heading excl:run-shell-command and multiprocessing above.

## 19. Killing a process started with :wait nil

Such processes often exit on there own or are killed by the user of the application but you may wish to kill them yourself from within Lisp. To do this, you need the pid value (which is the third returned value from run-shell-command when :wait is nil). We assume in what follows that the pid value is pid. Then:

Killing a :wait nil process on UNIX

The function in the excl.osi package kill takes pid and a kill signal as arguments. For example,

    (multiple-value-setq (v1 v2 xterm-pid)
       (run-shell-command "exec xterm" :wait nil))
    nil
    nil
    3187
    ;; An xterm appears. The pid is 3187, which is the value of XTERM-PID

    ;; Later: (excl.osi:kill 3187 excl::*sigkill*)
    ;; excl::*sigkill* is the constant associated with that signal
    ;; The xterm is killed.
    ;;
    ;; ALWAYS reap the killed process
    (sys:reap-os-subprocess :pid 3187)
    0
    3187
    9

Note the call to sys:reap-os-subprocess. This cleans the process from the system. If you neglkect to do this and you start many subprocesses, the system will clog up.

This method does not work on Windows (kill signals an error if called in a Windows Lisp).

Killing a :wait nil process on Windows

This is a bit more complicated because:

- Some processes are started directly and some through a command shell. (run-shell-command can only start programs, not shell commands, as described above.)

- Some processes are special, like the explorer (which in fact runs all the time).

In light of these differrences, be sure to test potential uses of killing spawned processes to ensure that what you want dome is actually done.

The following form kills the process with pid pid:

     (run-shell-command (format nil "taskkill /f /pid ~a" pid))

So, for example, we start notepad and then kill it:

    (multiple-value-setq (v1 v2 pid)
      (run-shell-command "notepad" :wait nil))

    ;; Notepad runs

    (run-shell-command (format nil "taskkill /f /pid ~a" pid))
    ;; Notepad is killed

    (sys:reap-os-subprocess :pip pid)
    ;; we reap the process

See also shell. See os-interface.html for general information on the interface between Allegro CL and the operating system and for information on shell commands.

# safe-ssl-methods

Function, excl package

Arguments:

The return value is a list of keywords naming SSL/TLS methods which are, at the time of publication, considered safe. It is also dependent on the version of OpenSSL currently in use by the `:ssl` module. The value of this function can only change when installing patches or using a new major or minor release of Allegro Common Lisp. Insecure methods are removed when they transition from safe to unsafe, as deemed so by the community at large. The best source for what is safe is Transport Layer Security on wikipedia.org.

For OpenSSL 1.1 or later, as of April 2025, the value is `(:tlsv1.2 :tlsv1.3)`.

# saved-byte-file-position

Function, excl package

Arguments: ident-object

Returns the saved byte (octet) file-position component of the ident-object. The ident-object is bound in the current dynamic extent of a with-saved-file-positions form. Note however that the object itself is of indefinite extent, and will be valid as long as the ident-object's stream has not been closed. So assignment of this variable to another of larger extent is possible.

# saved-char-file-position

Function, excl package

Arguments: ident-object

Returns the saved character file-position component of the ident-object. The ident-object must be one bound in the current dynamic extent of a with-saved-file-positions form. Note however that the object itself is of indefinite extent, and will be valid as long as the ident-object's stream has not been closed. So assignment of this variable to another of larger extent is possible.

# schedule-finalization

Function, excl package

Arguments: object function &key queue

Returns a finalization for object. When the garbage collector identifies object as garbage (meaning only the finalization and possibly weak vectors reference it), the garbage collector notes this fact and when it finishes garbage collecting, it either (depending on the value of the queue argument) calls the function denoted by function with object as the single argument or enqueues a list of two elements (the function from the finalization and the object in question) on the queue denoted by queue.

When the system sees that a finalization should be applied, it creates a hard reference to the object until the finalization is applied, preventing additional finalizations on that object from triggering until after the finalization is complete. Any particular finalization will only trigger once. When the triggered finalization is about to be applied, either by calling the finalization function or by enqueueing the list, its hard reference to the object is broken, so that even if the finalization object remains live, it will not keep the object alive. Then the finalization function is called (if queue is `nil`) or enqueued (if queue is true) and the finalization is disabled.

When queue is `nil`, the function is called and after a finalization function returns, the finalization is disabled so that (assuming that nothing in function caused object not to be garbage) the object is again identified as garbage during the next garbage collection and then scavenged (or global gc'ed) away.

If queue is non-`nil`, it must be an instance of queue. As said, the system only places the list of the finalization function and the object on that queue. It is the programs responsibility to apply the function call-finalizer to that list.

object can be any Lisp object; function can be a function object or a symbol denoting a function. The function must accept one argument.

Multiple finalizations can be scheduled for the same object; all are run if and when the gc identifies the object as garbage, though not necessarily during the same gc. The order of the running of multiple finalizations is unspecified. The functions may be run asynchronously after being triggered by a gc.

A finalization can be unscheduled with unschedule-finalization.

See also gc.html for general information on garbage collection Allegro CL. See section Finalizations in that document for details of finalizations.

# set-8-bit-input

Function, excl package

Arguments:

Performs the UNIX `ioctl` that tells the terminal driver not to strip off the 8th bit from data input. This is equivalent to executing `stty -istrip` to the shell. Note that this function has a side effect on the terminal driver which remains in effect after the Lisp process has exited. To re-enable 8th bit stripping after the Lisp is exited, one can execute stty istrip at the shell.

See iacl.html for information on character sets in Allegro CL.

# set-assert-enable

Function, excl package

Arguments: name value

Release 10.1 and later only. Returns value after enabling or disabling the named assert-enable. The name must be one of the registered assert-enables (see list-assert-enables) and value is either `nil` (which unsets or disables) or non-`nil` (which sets or enables) the assert-enable.

Note: One of the built-in assert-enables added in release 11.0 is the `:generic-checks` assert-enable. This assert-enable is always set, and should never be unset for any application that will allow other applications or libraries to be loaded into the same lisp. Unsetting this assert-enable causes normally safe functions like svref and its inverse and other low-level accessors like standard-instance accessors and defstruct slot accessors to become globally unsafe. If this assert-enable is set to `nil`, the results of the start of a dribble-bug or a print-system-state will note that run-time code will be unsafe and you will be asked to rerun your test with the assert-enable set to true.

See Conditionalizing assert calls in miscellaneous.html for more information.

# set-case-mode

Function, excl package

Arguments: new-mode &key (adjust-readtables-case t)

This function sets the case mode of Lisp to that specified by the new-mode argument. The value of that argument must be one of the following three keywords:

- `:case-insensitive-upper`

- `:case-insensitive-lower`

- `:case-sensitive-lower`

set-case-mode converts the running Lisp to use the new mode for subsequent reading and returns a keyword denoting the previous mode. This function must do quite a bit of consistency checking when changing between modes with different case preferences, and may take as long as several minutes to complete. As we say below, it is much better to use an image with the desired case mode rather than changing the case mode after the image has started.

Note that the typical case mode is `:case-sensitive-lower`. Allegro CL is distributed with modern (`:case-sensitive-lower`) images (named mlisp and mlisp8) and ANSI (`:case-insensitive-upper`) images (named alisp and alisp8). Rather than changing case mode after starting, it is best to start the image with the desired case mode.

The :adjust-readtables-case argument

In releases prior to 6.1, Allegro CL ignored readtable-case in all case modes except `:case-insensitive-upper` (the ANSI mode). Starting in release 6.1 of Allegro CL, readtable-case is not ignored unless set-case-mode is called with a case-mode other than `:case-insensitive-upper` and adjust-readtables-case specified `nil`.

The adjust-readtables-case keyword argument to set-case-mode allows control of ignoring or not ignoring readtable-case in non-ANSI modes.

The default setting of adjust-readtables-case is `t`. The value `t` has two effects: (1) it ensures that readtable-case is not ignored; and (2) it modifies the readtable-case of existing readtables as described next.

When adjust-readtables-case is true, set-case-mode sets the readtable-case of the Lisp standard readtable and other readtables listed below to the appropriate value for the new case-mode, which is shown in the table below. Along with the Lisp standard readtable, all existing readtables except for those readtables which have previously been modified by (setf readtable-case) are affected.

This table shows the set-case-mode effect when adjust-readtables-case is true (the action on symbol names assumes that mixed-case symbols are converted, which they are by default. See convert-mixed-case-symbols).

new-mode | action on symbol-names | readtable-case setting
--- | --- | ---
`:case-insensitive-upper` | symbol names are upcased | `:upcase`
`:case-sensitive-lower` | symbol names are downcased | `:preserve`
`:case-insensitive-lower` | symbol names are downcased | `:downcase`

In rare cases, some code's behavior may be affected by the updated casemode behavior. For such code, the previous Allegro CL behavior can be restored with the following call:

    (excl:set-case-mode excl:*current-case-mode* :adjust-readtables-case nil)

As described above, that call causes readtable-case to be ignored in non-ANSI modes.

The code most likely to be affected will be that which depends on prior symbol printing while in the less frequently used case-insensitive-lower casemode. While specific code instances may need further analysis, generally adding *print-case* bindings in such places is a completely adequate and portable fix; and is preferable to using set-case-mode for restoring prior Allegro CL behavior.

Issues with changing the case mode after startup

If CLX has been loaded into Lisp, you cannot change the case mode at all with this function. Unfortunately, no error is signaled but problems will occur later. Note that both Allegro Composer and Allegro Common Windows (both only available on Unix) use CLX.

This function can be called at any time but should, if possible, be called as the first action in a fresh invocation of Lisp (and better would be to use the image with the desired case mode and do not use this function at all). This function takes a lot of time and uses a lot of space, so should never be called in a loop.

Note that the system will not be able to resolve conflicts if case mode is changed after Lisp has been running for some time. However, sometimes it is necessary to change case modes more than once. Suppose you want to work in case-sensitive, lowercase preferred mode but need to load files written for a standard (case-insensitive, uppercase) Lisp. You might first set the mode to `:case-insensitive-lower`, load the files, and then set the mode to the desired `:case-sensitive-lower`.

Since set-case-mode alters the names of symbols in the currently running lisp environment, users are advised not to use this function lightly as it may introduce subtle problems. The following Lisp session illustrates:

The initial set of commands establishes state and demonstrates that case is preserved by the reader in a case-sensitive-lower (modern-mode) lisp:

    cl-user(1): (defparameter mixed-sym-name "aBc")
    mixed-sym-name
    cl-user(2): (defparameter mixed-sym (read-from-string mixed-sym-name))
    mixed-sym
    cl-user(3): mixed-sym
    aBc
    cl-user(4): (eq mixed-sym (read-from-string mixed-sym-name))
    t

The subsequent set of commands demonstrates that taking a round-trip through case-mode conversions (from modern-mode to ansi-mode back to modern-mode) affects the lisp environment. We assume convert-mixed-case-symbols returns true.

    cl-user(5): (set-case-mode :case-insensitive-upper)
    :CASE-SENSITIVE-LOWER
    CL-USER(6): (set-case-mode :case-sensitive-lower)
    :case-insensitive-upper
    cl-user(7): mixed-sym
    abc
    cl-user(8): (eq mixed-sym (read-from-string mixed-sym-name))
    nil
    cl-user(9):

See also case.html, *current-case-mode*, *ignore-package-name-case*, and convert-mixed-case-symbols.

# set-signal-handler

Function, excl package

Arguments: number function

function is made the signal handler for signal number. It replaces the previous handler for the signal instead of pushing a new handler on *signals*.

The handling of operating system dependent signals generated during program execution is not part of Common Lisp. A signal is a small integer. The list of valid signals is given in a system dependent file, usually on UNIX something like /usr/include/signals.h. Signals are either synchronous or asynchronous, but there is no distinction made in this interface--the handling of both types of signals is the same. A handler for a signal is a function of two arguments, signal number and t. If there is no handler for a particular signal, then some default action is invoked, which is usually to signal an error. Signals handlers should return a true value if they handle the signal, so that other, nested handlers are not invoked to handle the signal. A signal that is posted during a gc is processed immediately after the gc finishes.

See add-signal-handler (which has an example), remove-signal-handler, *signals*, and with-signal-handler.

# sha1-file

Function, excl package

Arguments: filespec &eky return

Using sha1-init, sha1-update, and sha1-final, compute the SHA1 hash on the contents of the file given by filespec. Returns the value of sha1-final on the implicitly created context. The return argument is passed to sha1-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-file.

# sha1-final

Function, excl package

Arguments: context &key return

Finalize and return the SHA1 hash from context in a format determined by the return keyword argument.

return can be one of the following values:

- `:integer` (the default): the return value is an integer of up to 160 bits representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octets containing only zeroes. Care should be taking when using this return type if you intend to further encode the signature (such as to a base64-encoded string). See the example below.

- `:usb8`: return an (unsigned-byte 8) array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (sha1-init))
    #S(excl::md-context :ctx 156672 :size 20)
    cl-user(5): (sha1-update c "foo")
    cl-user(6): (sha1-final c :return :usb8)
    #(11 238 199 181 234 63 15 219 201 93 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to SHA1-FILE which calls
    ;;  SHA1-FINAL and returns the value SHA1-FINAL returns.
    ;;
    ;;  Here we get the sha1 value in a shell:
    %  openssl dgst -sha1 -hex cmp05-optdialog.jpg
    SHA1(cmp05-optdialog.jpg)= 9bd9c1bbd45ec006e281cf056227898c5996bb87

    ;; Now we get it with SHA1-FILE:
    cl-user(17): (sha1-file "~/cmp05-optdialog.jpg")
    889749707772052021200163874326026364472582912903
    cl-user(18): (format t "~x" *)
    9bd9c1bbd45ec006e281cf056227898c5996bb87
    nil
    cl-user(19):

    ;; Note the hex values are the same but the leading 0 is not printed
    ;; by Lisp, which is dealing with the value as an integer. The leading
    ;; 0 is preserved when the :return is :hex:
    cl-user(21): (sha1-file "~/cmp05-optdialog.jpg" :return :hex)
    "9bd9c1bbd45ec006e281cf056227898c5996bb87"
    cl-user(22):

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-final.

# sha1-init

Function, excl package

Arguments:

Returns an initialized SHA1 context, used by the other SHA1 functions.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-init.

# sha1-string

Function, excl package

Arguments: string &key start end external-format return

Using sha1-init (which creates a context), sha1-update (which updates the context with the argument string), and sha1-final (which finalizes the hash), this function computes the SHA1 hash for string.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context. start defaults to 0, end defaults to the length of string, and external-format defaults to the default external format. These arguments, along with string, are passed to sha1-update.

The format of the result, just as for sha1-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See sha1-final for information on these values and the corresponding formats of the returned value.

    cl-user(4): (sha1-string "foo")  ;; default return format :integer
    68123873083688143418383284816464454849230703155
    cl-user(5): (sha1-string "foo" :return :usb8)
    #(11 238 199 181 234 63 15 219 201 93 ...)
    cl-user(6):

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-string.

# sha1-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running SHA1 computation in context (sha1-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

Earlier versions of sha1-update had two required and one optional argument, len, specifying the number of characters of the argument string to use (that is, start was hardwired to 0 and the optional argument specified a value for end). This argument style is still accepted, though with a warning. Note len refers to the number of characters, not the number of bytes in the external hashing.

This function returns no values, but side-effects context.

See MD5, SHA*, HMAC, RC4, and other message digest support in miscellaneous.html. See also digest-update.

# sha224-file

Function, excl package

Arguments: filespec &key return

Using sha224-init, sha224-update, and sha224-final, compute the SHA224 hash on the contents of the file given by filespec. Returns the value of sha224-final on the implicitly created context. The return argument is passed to sha224-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-file.

# sha224-final

Function, excl package

Arguments: context &key return

Finalize and return the SHA224 hash from context in a format determined by the return keyword argument.

return can be one of the following values:

- `:integer` (the default): the return value is an integer of up to 128 bits representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octets containing only zeroes. Care should be taking when using this return type if you intend to further encode the signature (such as to a base64-encoded string). See the example below.

- `:usb8`: return an (unsigned-byte 8) array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (sha224-init))
    #S(excl::md-context :ctx 9183104 :size 28)
    cl-user(5): (sha224-update c "foo")
    cl-user(6): (sha224-final c :return :usb8)
    #(8 8 246 78 96 213 137 121 252 182 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to SHA224-FILE which calls
    ;;  SHA224-FINAL and returns the value SHA224-FINAL returns.
    ;;
    ;;  Here we get the sha224 value in a shell:
    % openssl dgst -sha224 -hex uninstall.jpg
    SHA224(uninstall.jpg)= 012d03e402813fa87201182a9fa8dc71d5662e07a3298e6e3fee902a

    ;; Now we get it with SHA224-FILE:
    cl-user(17): (sha224-file "~/uninstall.jpg")
    123830469993168619693673182033704503020973917482279183198628778026
    cl-user(18): (format t "~x" *)
    12d03e402813fa87201182a9fa8dc71d5662e07a3298e6e3fee902a
    nil
    cl-user(19):

    ;; Note the hex values are the same but the leading 0 is not printed
    ;; by Lisp, which is dealing with the value as an integer. The leading
    ;; 0 is preserved when the :return is :hex:
    cl-user(21): (sha224-file "~/unistall.jpg" :return :hex)
    "012d03e402813fa87201182a9fa8dc71d5662e07a3298e6e3fee902a"
    cl-user(22):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-final.

# sha224-init

Function, excl package

Arguments:

Returns an initialized SHA224 context, used by the other SHA224 functions.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-init.

# sha224-string

Function, excl package

Arguments: string &key start end external-format return

Using sha224-init (which creates a context), sha224-update (which updates the context with the argument string), and sha224-final (which finalizes the hash), this function computes the SHA224 hash for string.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context. start defaults to 0, end defaults to the length of string, and external-format defaults to the default external format. These arguments, along with string, are passed to sha224-update.

The format of the result, just as for sha224-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See sha224-final for information on these values and the corresponding formats of the returned value.

    cl-user(4): (sha224-string "foo")  ;; default return format :integer
    846185141210288911164176837699981668991754445367816825983107266779
    cl-user(5): (sha224-string "foo" :return :usb8)
    #(8 8 246 78 96 213 137 121 252 182 ...)
    cl-user(6):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-string.

# sha224-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running SHA224 computation in context (sha224-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

This function returns no values, but side-effects context.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-update.

# sha256-file

Function, excl package

Arguments: filespec &key return

Using sha256-init, sha256-update, and sha256-final, compute the SHA256 hash on the contents of the file given by filespec. Returns the value of sha256-final on the implicitly created context. The return argument is passed to sha256-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-file.

# sha256-final

Function, excl package

Arguments: context &key return

Finalize and return the SHA256 hash from context in a format determined by the return keyword argument.

return can be one of the following values:

- `:integer` (the default): the return value is an integer of up to 128 bits representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octets containing only zeroes. Care should be taking when using this return type if you intend to further encode the signature (such as to a base64-encoded string). See the example below.

- `:usb8`: return an (unsigned-byte 8) array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (sha256-init))
    #S(excl::md-context :ctx 9183616 :size 32)
    cl-user(5): (sha256-update c "foo")
    cl-user(6): (sha256-final c :return :usb8)
    #(44 38 180 107 104 255 198 143 249 155 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to SHA256-FILE which calls
    ;;  SHA256-FINAL and returns the value SHA256-FINAL returns.
    ;;
    ;;  Here we get the sha256 value in a shell:
    % openssl dgst -sha256 -hex tab-order.jpg
    SHA256(tab-order.jpg)= 079331d027a95cc63d1466fdf859e0c6b83532199e1c935f30a658bf8e5f8e29

    ;; Now we get it with SHA256-FILE:
    cl-user(17): (sha256-file "~/tab-order.jpg")
    3426260256022037745305111919104592478490763621909092613016648559449698438697
    cl-user(18): (format t "~x" *)
    79331d027a95cc63d1466fdf859e0c6b83532199e1c935f30a658bf8e5f8e29
    nil
    cl-user(19):

    ;; Note the hex values are the same but the leading 0 is not printed
    ;; by Lisp, which is dealing with the value as an integer. The leading
    ;; 0 is preserved when the :return is :hex:
    cl-user(21): (sha256-file "~/tab-order.jpg" :return :hex)
    "079331d027a95cc63d1466fdf859e0c6b83532199e1c935f30a658bf8e5f8e29"
    cl-user(22):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-final.

# sha256-init

Function, excl package

Arguments:

Returns an initialized SHA256 context, used by the other SHA256 functions.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-init.

# sha256-string

Function, excl package

Arguments: string &key start end external-format return

Using sha256-init (which creates a context), sha256-update (which updates the context with the argument string), and sha256-final (which finalizes the hash), this function computes the SHA256 hash for string.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context. start defaults to 0, end defaults to the length of string, and external-format defaults to the default external format. These arguments, along with string, are passed to sha256-update.

The format of the result, just as for sha256-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See sha256-final for information on these values and the corresponding formats of the returned value.

    cl-user(4): (sha256-string "foo")  ;; default return format :integer
    19970150736239713706088444570146546354146685096673408908105596072151101138862
    cl-user(5): (sha256-string "foo" :return :usb8)
    #(44 38 180 107 104 255 198 143 249 155 ...)
    cl-user(6):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-string.

# sha256-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running SHA256 computation in context (sha256-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

This function returns no values, but side-effects context.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-update.

# sha384-file

Function, excl package

Arguments: filespec &key return

Using sha384-init, sha384-update, and sha384-final, compute the SHA384 hash on the contents of the file given by filespec. Returns the value of sha384-final on the implicitly created context. The return argument is passed to sha384-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-file.

# sha384-final

Function, excl package

Arguments: context &key return

Finalize and return the SHA384 hash from context in a format determined by the return keyword argument.

return can be one of the following values:

- `:integer` (the default): the return value is an integer of up to 128 bits representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octets containing only zeroes. Care should be taking when using this return type if you intend to further encode the signature (such as to a base64-encoded string). See the example below.

- `:usb8`: return an (unsigned-byte 8) array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (sha384-init))
    #S(excl::md-context :ctx 9183040 :size 48)
    cl-user(5): (sha384-update c "foo")
    cl-user(6): (sha384-final c :return :usb8)
    #(152 193 31 253 253 213 64 103 107 26 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to SHA384-FILE which calls
    ;;  SHA384-FINAL and returns the value SHA384-FINAL returns.
    ;;
    ;;  Here we get the sha384 value in a shell:
    % openssl dgst -sha384 -hex alpha7.png
    SHA384(alpha7.png)= 050636aaa2227c310baf6bd61ad776ee570e5397c34bbcfc70e77c64732f77815014ea901e82295680cf1884aceaa58c

    ;; Now we get it with SHA384-FILE:
    cl-user(17): (sha384-file "~/alpha7.png")
    773306181619244679031124675510480299112986182387103599724892235134372856148817968769021349632470443136944358204812
    cl-user(18): (format t "~x" *)
    50636aaa2227c310baf6bd61ad776ee570e5397c34bbcfc70e77c64732f77815014ea901e82295680cf1884aceaa58c
    nil
    cl-user(19):

    ;; Note the hex values are the same but the leading 0 is not printed
    ;; by Lisp, which is dealing with the value as an integer. The leading
    ;; 0 is preserved when the :return is :hex:
    cl-user(21): (sha384-file "~/alpha7.png" :return :hex)
    "050636aaa2227c310baf6bd61ad776ee570e5397c34bbcfc70e77c64732f77815014ea901e82295680cf1884aceaa58c"
    cl-user(22):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-final.

# sha384-init

Function, excl package

Arguments:

Returns an initialized SHA384 context, used by the other SHA384 functions.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-init.

# sha384-string

Function, excl package

Arguments: string &key start end external-format return

Using sha384-init (which creates a context), sha384-update (which updates the context with the argument string), and sha384-final (which finalizes the hash), this function computes the SHA384 hash for string.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context. start defaults to 0, end defaults to the length of string, and external-format defaults to the default external format. These arguments, along with string, are passed to sha384-update.

The format of the result, just as for sha384-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See sha384-final for information on these values and the corresponding formats of the returned value.

    cl-user(4): (sha384-string "foo")  ;; default return format :integer
    23511053105975915490324558251149394787462862571386435492625900837428290411153055157553730780078824283730695011154619
    cl-user(5): (sha384-string "foo" :return :usb8)
    #(152 193 31 253 253 213 64 103 107 26 ...)
    cl-user(6):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-string.

# sha384-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running SHA384 computation in context (sha384-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

This function returns no values, but side-effects context.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-update.

# sha512-file

Function, excl package

Arguments: filespec &key return

Using sha512-init, sha512-update, and sha512-final, compute the SHA512 hash on the contents of the file given by filespec. Returns the value of sha512-final on the implicitly created context. The return argument is passed to sha512-final (where the various possible values are discussed). Note the warning about integer returns perhaps losing leading 0's.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-file.

# sha512-final

Function, excl package

Arguments: context &key return

Finalize and return the SHA512 hash from context in a format determined by the return keyword argument.

return can be one of the following values:

- `:integer` (the default): the return value is an integer of up to 128 bits representing the digest. Warning: note that an integer representation of the digest potentially loses information if the generated signature has leading octets containing only zeroes. Care should be taking when using this return type if you intend to further encode the signature (such as to a base64-encoded string). See the example below.

- `:usb8`: return an (unsigned-byte 8) array containing the digest.

- `:hex`: return a string containing the hexadecimal representation of the digest. See hex-string-to-integer.

    cl-user(4): (setq c (sha512-init))
    #S(excl::md-context :ctx 9184192 :size 64)
    cl-user(5): (sha512-update c "foo")
    cl-user(6): (sha512-final c :return :usb8)
    #(247 251 186 110 6 54 248 144 229 111 ...)

    ;;  Potential problem with :return :integer (or :return unspecified
    ;;  as the default is :integer). The call is to SHA512-FILE which calls
    ;;  SHA512-FINAL and returns the value SHA512-FINAL returns.
    ;;
    ;;  Here we get the sha512 value in a shell:
    % openssl dgst -sha512 -hex cmp04-profmenu.jpg
    SHA512(cmp04-profmenu.jpg)= 083059e92e5cecc3bbcf1707bc0f167564f7981a03b5340b1d1755f84ef04b239929c56c3b08409d31188a8103e24daf1311f5f4d01cb55180b1a000d5edf58f

    ;; Now we get it with SHA512-FILE:
    cl-user(17): (sha512-file "~/cmp04-profmenu.jpg")
    428886023486142793197430632417588933862863719105103677963658399518713040127487056708272152409738347556264379546041790497093717768109375086135443767293327
    cl-user(18): (format t "~x" *)
    83059e92e5cecc3bbcf1707bc0f167564f7981a03b5340b1d1755f84ef04b239929c56c3b08409d31188a8103e24daf1311f5f4d01cb55180b1a000d5edf58f
    nil
    cl-user(19):

    ;; Note the hex values are the same but the leading 0 is not printed
    ;; by Lisp, which is dealing with the value as an integer. The leading
    ;; 0 is preserved when the :return is :hex:
    cl-user(21): (sha512-file "~/cmp04-profmenu.jpg" :return :hex)
    "083059e92e5cecc3bbcf1707bc0f167564f7981a03b5340b1d1755f84ef04b239929c56c3b08409d31188a8103e24daf1311f5f4d01cb55180b1a000d5edf58f"
    cl-user(22):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html.
See also digest-final.

# sha512-init

Function, excl package

Arguments:

Returns an initialized SHA512 context, used by the other SHA512 functions.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-init.

# sha512-string

Function, excl package

Arguments: string &key start end external-format return

Using sha512-init (which creates a context), sha512-update (which updates the context with the argument string), and sha512-final (which finalizes the hash), this function computes the SHA512 hash for string.

The start and end arguments specify the portion of the string to be considered and the external-format argument specifies the external hashing of the string that will be used to update the context. start defaults to 0, end defaults to the length of string, and external-format defaults to the default external format. These arguments, along with string, are passed to sha512-update.

The format of the result, just as for sha512-final, is determined by the return keyword argument. The possible values are `:integer`, `:usb8`, and `:hex`. See sha512-final for information on these values and the corresponding formats of the returned value.

    cl-user(4): (sha512-string "foo")  ;; default return format :integer
    12987939986214020250966660712033957353007235086850047381859749614626672930051732582287570074038770950702449273708266406011450193361958914603201704396463831
    cl-user(5): (sha512-string "foo" :return :usb8)
    #(247 251 186 110 6 54 248 144 229 111 ...)
    cl-user(6):

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-string.

# sha512-update

Function, excl package

Arguments: context data &key start end external-format

Add data to the running SHA512 computation in context (sha512-init returns a context). data may be a string or an (unsigned-byte 8) vector.

If data is a string, the start and end keyword arguments specify character positions in the string. start defaults to 0 and end defaults to `nil`, equivalent to the length of the string. external-format specifies the external hashing of the string that will be used to update the context. If not specified, the default external format will be used.

If data is an (unsigned-byte 8) vector, start and end refer to locations in the vector (again defaulting to 0 and `nil`, meaning the length of the vector). external-format is ignored.

This function returns no values, but side-effects context.

See MD*, SHA*, HMAC, and other message digest support in miscellaneous.html. See also digest-update.

# shell

Function, excl package

Arguments: &optional cmd &key show-window

The `:osi` module (see Operating System Interface Functionality in os-interface.html) has these operators relating to running subprocesses: the function command-output and the macros with-command-output and with-command-io. They are higher-level than run-shell-command and shell and are recommended when the interaction with the subprocess requires input or produces output that must be captured. Those operators do not have separate description pages. They are described in OSI process/uid/gid interface functions in os-interface.html.

On Windows, an interactive shell cannot be started, so the optional cmd must be specified. In general, Windows users should consider run-shell-command or one of the OSI functions mentioned above as alternatives.

On UNIX, the shell function used by shell is /bin/sh.

If the command argument is not given, then an interactive shell is spawned. To get back to Lisp, exit from the shell. If the command (a string) is given as the value of cmd, then a shell is spawned and directed to execute that command.

The show-window keyword argument is only applicable on Windows. It specifies how the window associated with the cmd will be displayed. The default is `:minimized`, which produces the same behavior as in earlier releases, which was, the window was not displayed but an entry for it appeared on the task bar. Another possible value is `:showna`, which is supposed to display the window but not select it. Note that the `:showna` option does not seem to work correctly on some versions of Windows. See the description of the show-window argument to run-shell-command for the possible values (all values accepted by run-shell-command are valid for shell) and a discussion of the `:showna` problems.

On UNIX, the show-window keyword argument is accepted but ignored.

See also run-shell-command. See os-interface.html for general information on the interface between Allegro CL and the operating system, and information on shell commands.

# short-array-p

Function, excl package

Arguments: object

Returns true if object is a short array (an array created with the :short keyword argument to make-array specified true). Short arrays take up one fewer word of memory than normal arrays, but most standard Common Lisp array functions (aref being an exception) do not work on short arrays.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-bit-vector-p

Function, excl package

Arguments: object

Returns true if object is a short bit-vector (a bit-vector created with the :short keyword argument to make-array specified true). Short arrays take up one fewer word of memory than normal arrays, but most standard Common Lisp array functions (aref being an exception) do not work on short arrays.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-simple-array-p

Function, excl package

Arguments: object

Returns true if object is a short simple-array (a simple-array created with the :short keyword argument to make-array specified true). Short arrays take up one fewer word of memory than normal arrays, but most standard Common Lisp array functions (aref being an exception) do not work on short arrays.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-simple-bit-vector-p

Function, excl package

Arguments: object

Returns true if object is a short simple bit-vector (a simple bit-vector created with the :short keyword argument to make-array specified true). Short arrays take up one fewer word of memory than normal arrays, but most standard Common Lisp array functions (aref being an exception) do not work on short arrays.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-simple-string-p

Function, excl package

Arguments: object

Returns true if object is a short simple string (a simple string created with the :short keyword argument to make-array specified true). Short arrays take up one fewer word of memory than normal arrays, but most standard Common Lisp array functions (aref being an exception) do not work on short arrays.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-simple-vector-p

Function, excl package

Arguments: object

Returns true if object is a short simple vector (a simple vector created with the :short keyword argument to make-array specified true). Short arrays take up one fewer word of memory than normal arrays, but most standard Common Lisp array functions (aref being an exception) do not work on short arrays.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-string-p

Function, excl package

Arguments: object

Returns true if object is a short string (a string created with the :short keyword argument to make-array specified true). Short arrays take up one fewer word of memory than normal arrays, but most standard Common Lisp array functions (aref being an exception) do not work on short arrays.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-string

Function, excl package

Arguments: x

Returns a short string constructed from x, analogous to string. x can be a short string, a regular string, a symbol of a character. Here is the action of short-string in each case:

- x is a short string: x is returned.

- x is a regular string: a new short string is created containing all the characters in x (up to the fill pointer, if there is one) and the new short string is returned.

- x is a character: a new short string of length 1 containing that character is returned.

- x is a symbol: a new short string is constructed from the print-name of x and returned.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-vector-p

Function, excl package

Arguments: object

Returns true if object is a short vector (a vector created with the :short keyword argument to make-array specified true). Short arrays take up one fewer word of memory than normal arrays, but most standard Common Lisp array functions (aref being an exception) do not work on short arrays.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# short-vector

Function, excl package

Arguments: &rest args

Create a new short vector whose elements are args. The short array equivalent of vector.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# shorts-to-double-float

Function, excl package

Arguments: hwhi hwlo lwhi lwlo

Returns a boxed double-float number whose bits include the 16 bits from hwhi as the most-significant 2 bytes, followed by the 16 bits of hwlo, followed by the 16 bits of lwhi, followed finally by the 16 bits of lwlo as its least significant 2 bytes. The only consing that is done is to allocate the double-float.

See also single-float-to-shorts, double-float-to-shorts, and shorts-to-single-float.

# shorts-to-single-float

Function, excl package

Arguments: hi lo

Returns a boxed single-float number whose bits include the 16 bits from hi as the most-significant 2 bytes, and the 16 bits of lo as its least significant 2 bytes. The only consing that is done is to allocate the single-float.

See also single-float-to-shorts, double-float-to-shorts, and shorts-to-double-float.

# short*-wcslen

Function, excl package

Arguments: address &optional aligned

Computes and returns the length of the C style (null-terminated) fat (2-bytes per character) string located at address by looking for the null terminator.

If the optional aligned argument is true, then address is an aligned address. Aligned addresses are returned by functions like lispval-to-aligned-malloc-address.

See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.

# show-system

Generic Function, excl package

Arguments: system

The default method for this generic function describes system and each of the modules in system, including the dependencies between modules. system can be a system-name or a system-object.

    USER(20): (defsystem :my-serial-sys ()

    (:serial "my1" "my2"))
    :MY-SERIAL-SYS
    USER(21): (show-system :my-serial-sys)
    ; System: "MY-SERIAL-SYS"
    ; default package: #<The COMMON-LISP-USER package>
    ; default pathname: #p"./"
    ; default module class: DEFSYSTEM:LISP-MODULE
    ; the system contains the following modules:
    ; Module-group: "<unnamed>"
    ; default module class: DEFSYSTEM:LISP-MODULE
    ; the module-group contains the following modules:
    ; Module: "my1"
    ; source file: "my1"
    ; Module: "my2"
    ; source file: "my2"
    ; Dependencies:
    ; before COMPILE dependencies:
    ; LOAD #<DEFSYSTEM:LISP-MODULE "my1" @ #x6b638e>
    ; before LOAD dependencies:
    ; LOAD #<DEFSYSTEM:LISP-MODULE "my1" @ #x6b638e>
    NIL
    USER(22):

Although the home package of the symbol naimg this operator is the excl package, it is also exported from the defsystem package.

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# simple-stream-read-line

Function, excl package

Arguments: stream eof-error-p eof-value &optional given-string

This function implements read-line for simple-streams. In addition, it allows an optional string as a buffer into which to store characters being read. Unless an EOF is encountered immediately, in which case an error is signaled or eof-value is returned, the first return value is a string. If the given-string is supplied but is too small to hold the whole line, a new string of the exact size needed is allocated and returned. (If a new string is allocated, the contents of a provided given-string when this function returns are undefined -- they will likely have been changed in anticipation of the string being used.)

Two values are always returned (following the behavior of read-line and a third value is sometimes returned. The first two return values are:

1. The result string, or the eof-value. If an EOF is not encountered immediately, and if the given-string is supplied but is not large enough, this value will be a newly allocated string large enough to hold the entire line exactly.

2. A flag indicating why reading stopped: `nil`, if the line was terminated with a newline; and `t` if the line was not terminated with a newline (that is, the end of file was reached).

A third value is returned when given-string is large enough to hold the line read. (No third value is returned when given-string is not supplied or when given-string is too small). The third value is:

3. The number of characters read and stored in given-string, (which does not include a newline if read).

Since you do not typically know in advance whether the given-string or a new string is returned, the number of characters read (not counting the newline) is the value of

      (or end (length string))
      ;; END is the third return value, STRING the first

given-string may be simple or non-simple, but must be a string. The other arguments are as for read-line (note there is no recursive-p argument and stream, eof-error-p, and eof-value are required, not optional).

The motivation for this function is twofold: to provide a direct implementation for read-line for simple-streams, and to provide a tradeoff for consing between that of read-line and that of excl:read-line-into (excl:read-line-into does no consing but requires more bookkeeping). If the supplied string is large enough, then most of the time consing will not occur, but for the occasional larger-than-expected line, the allocation of a string is automatic.

See also read-line-into. That function is more space efficient than this one, but has a more complicated interface.

Examples

    ;; Assume the file myfile.txt contains (no trailing spaces):
    12345

    12345678901234567890
    123456789
    1234567890
    123456789012345

    ;; That is 6 lines or lengths 5, 0, 20, 9, 10, 15, 0, not counting
    ;; the newlines.
    ;;
    ;; We read the file one line at a time:
    (with-open-file (f "myfile.txt" :direction :input)
      (let (res stopped end
        (given-string (make-string 10 :initial-element #\a)))
        (loop
          (multiple-value-setq (res stopped end)
        (simple-stream-read-line f nil f given-string))
          (when (eq res f) (return))
          (format t " res is ~S, eq to given-string ~S~% ~
                         length ~D, given-string is ~S~%"
              res (eq res given-string) (or end (length res)) given-string))))
     res is "12345aaaaa", eq to given-string t
     length 5, given-string is "12345aaaaa"
     res is "12345aaaaa", eq to given-string t
     length 0, given-string is "12345aaaaa"
     res is "12345678901234567890", eq to given-string nil
     length 20, given-string is "1234567890"  ;; actual value may be different
     res is "1234567890", eq to given-string t
     length 9, given-string is "1234567890"   ;; given-string is used
     res is "1234567890", eq to given-string nil
     length 10, given-string is "1234567890"  ;; given-string is not used
                                              ;; see note after the
                                              ;; example text
     res is "123456789012345", eq to given-string nil
     length 15, given-string is "1234567890"
    nil
    ;;  One trick is, when a new string is allocated, use that string
    ;;  as the given-string from then on. (It already exists, so no
    ;;  extra allocation and it is bigger so more likely not to overflow.)
    ;;  Here is the same example with using any newly allocated string:
    (with-open-file (f "myfile.txt" :direction :input)
      (let (res stopped end
        (given-string (make-string 10 :initial-element #\a)))
        (loop
          (multiple-value-setq (res stopped end)
        (simple-stream-read-line f nil f given-string))
          (when (eq res f) (return))
          (format t " res is ~S, eq to given-string ~S~% ~
                         length ~D, given-string is ~S~%"
              res (eq res given-string) (or end (length res)) given-string)
          (unless end (setq given-string res))
          )))
     res is "12345aaaaa", eq to given-string t
     length 5, given-string is "12345aaaaa"
     res is "12345aaaaa", eq to given-string t
     length 0, given-string is "12345aaaaa"
     res is "12345678901234567890", eq to given-string nil
     length 20, given-string is "1234567890"  ;; actual value may be different
     res is "12345678901234567890", eq to given-string t
     length 9, given-string is "12345678901234567890" ;; Note: given-string
                                                  ;; is now last returned string
     res is "12345678901234567890", eq to given-string t
     length 10, given-string is "12345678901234567890"
     res is "12345678901234567890", eq to given-string t
     length 15, given-string is "12345678901234567890"
    nil

How large must the given-string be?

The examples above include a case where the line has 10 characters, and the given-string is length 10 but it is not used. Instead, a new string of length 10 is allocated. Why is the given-string insufficient? The problem is that the most efficient time to allocate a new string when necessary is to do it when the given-string is full and there is known to be at least one more character to read, but before it is known what that character is. If that additional character turns out to be a newline, then in fact the given-string was big enough but by this time the new string is already allocated.

Therefore, given-string must be larger than the anticipated maximum line length in order that it always be used. (For common external formats, it must be one larger. There may be external formats where more that one extra character is needed.)

This need for a longer given-string than the maximal line length (not counting the newline) is suboptimal behavior, and may be replaced in a future release if an efficient implementation can be discovered. However, as currently implemented, too much extra time would have to be spent in order to determine whether a line is or is not exactly as big as the given-string.

# single-float-p

Function, excl package

Arguments: object

Returns `t` if the argument is a single-float and returns `nil` otherwise.

See also double-float-p and fixnump.

# single-float-to-shorts

Function, excl package

Arguments: single-float

Returns two values, each 16-bit unsigned numbers that represent the highest 16 bits of the single-float followed by the lowest 16 bits of the single-float. No consing is done, except on the sparc, where the pseudo-resourced multiple-values-vector might be consed the first time after a scavenge. Each succeeding call will reuse the values vector normally.

See also double-float-to-shorts, shorts-to-single-float, and shorts-to-double-float.

# slot-atomic-update-using-class

generic-function, excl package

Arguments: new-value class object slot test-value

This generic-function, new as of the 11.0 release, is not part of the MOP, and so is not exported from the aclmop package. Instead it is exported from the excl package, but it still works similarly to the other *-using-class generic-functions specified by the MOP and is documented here in a similar way:

Called in situations with

    (atomic-conditional-setf (slot-value object slot)
      new-value test-value)

where there are non-standard methods defined on the metaclass. Should return `t` if and only if the atomic-conditional-setf into the specified slot is appropriate, i.e. the value in the slot matches the test-value and the new-value is stored into the slot, all without the possibility of interrupt.

Methods:

Primary Method excl:slot-atomic-update-using-class new-value (class standard-class) object (slot standard-effective-slot-definition)

Primary Method excl:slot-atomic-update-using-class new-value (class funcallable-standard-class) object (slot standard-effective-slot-definition) test-value

These methods implement the full behavior of this generic function for slots with allocation `:instance` and `:class`. If the supplied slot has an allocation other than `:instance` or `:class` an error is signaled.

Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.

Primary Method excl:slot-atomic-update-using-class new-value (class built-in-class) object slot test-value

Primary Method excl:slot-atomic-update-using-class new-value (class structure-class) (object structure-object) slot test-value

These methods signal an error.

# slot-value-using-class-name

Macro, excl package

Arguments: class-name object slotd-name &optional slots-vector

Release 10.1 and later only. Returns the value of the slot accessed within object that has the slot name slotd-name. The class-name argument is intended to be the name of an existing class which presumably has a fixed-index value attached to the slot. If any of the first three arguments given to slot-value-using-class-name are not constant then the macro expands to a call to slot-value. If the slots-vector is not given, the slots vector is accessed each time this macro is given. If slots-vector is given, it provides the slots-vector from which the macro accesses using svref. If many accesses are being made to the same object, then near-defstruct-like speed can be approached by getting the slots-vector at the beginning of a block of code and then using this macro to access the slots with one instruction for each access.

Note on safety: This macro does not perform any checks, and does not guard against wrong slot-values being given or unbound-slots being accessed.

Note on setf: there is no setf version of this macro, but because it is a macro and expands to simple svref or slot-value forms the macro can be used in a setf form.

See Optimizing slot-value calls with fixed indices in implementation.html for examples of how this macro is used in optimizing accessing slot value of instances.

See Appendix: Effective-method selection in Allegro CL CLOS and Associated Optimizations for more information on this function in implementation.html.

# sm

Macro, excl package

Arguments: slot-name stream

Returns the value of the named slot in the stream. If within a with-stream-class form a fast access (one or two memory reference instructions) is generated, otherwise a warning is given and an unoptimized slot-value is performed. See with-stream-class for further information and examples.

You must load the `:iodefs` module to use this macro. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This macro is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# sniff-for-unicode

Function, excl package

Arguments: stream

This function checks stream, which must be either a character stream or a simple-stream, for the unicode byte-order marker and returns two values. The first returned value is either the `:unicode` external-format (if the unicode byte-order marker is found) or the stream's current external-format (if the unicode byte-order marker is not found).

The second returned value is a boolean indicating whether the first returned value is the stream's current external-format (which it always is when the unicode byte-order marker is not found and may or may not be when the unicode byte-order marker is found).

This function operates by using peek-char on the stream. The file-position for the stream remains unchanged after calling sniff-for-unicode.

See The unicode and fat External-Format Types in iacl.html for information on the unicode external format and iacl.html in general for information on international character support in Allegro CL.

# source-context

Function, excl package

Arguments:

Creates and returns a source-context struct as long as some slot of the struct is non-`nil`. Otherwise returns `nil`. See the examples below.

A source-context struct is created by the this function, if appropriate. One is also created whenever conditions (warnings, errors, etc) are created and that one is placed into the condition object's property list where it can be shown later by the :error top-level-command.

A source-context struct has the following slots (those marked with (*) are only set when source-level-debugging is enabled, see save-source-level-debug-info-switch):

- pathname: The pathname of the file being compiled, or `nil` if at top-level.

- function: the function being compiled or interpreted.

- when: a keyword indicating the operation currently being performed. Current values are `:compiling`, `:file-compiling`, or `:evaluating`.

- form: (*) the source of the form being compiled or macroexpanded.

- start-char: (*) starting character in source file of form.

- end-char: (*) one past the last character of form.

- charp: (*) true if the last two positions are characters, false if they are octets.

- enclosing-form: (*) if not `nil`, the form which really has position info that encloses the context's form.

- backtrace: if not `nil`, a list of forms that are being processed as a compilation is proceeding.

Generally, when a source-context is printed as part of a condition only those parts of the source-context that were not printed earlier are printed. So if there are several warnings in the same file the file will only be printed once, and if the same function has multiple warnings the function's name will only be printed once. Also, if a form is to be printed, concise-printing is used.

The backtrace slot holds the raw data for a compiler backtrace which may or may not include position information for any of its elements. This slot is only populated when compiling.

Examples

Source-contexts are created during compilation, loading, or evaluation. In the examples, we embed calls to source-context in situations where those operations are going on.

    ;; We have a source file foobar.cl containing:
    ;;
    cl-user(1): (shell "cat foobar.cl")

    (defun bar (x y)
      (foo x y))

    (bar 10 20)
    0

    ;; We define a macro which contains a call to SOURCE-CONTEXT:
    ;;
    cl-user(2): (defmacro foo (x y) (setq *sc* (source-context)) `(list ,x ,y))
    foo

    ;; We compile a function that includes a call to the macro FOO:
    cl-user(3): (compile (defun bar (x y) (foo x y)))
    bar
    nil
    nil

    ;; And a non-empty source-context is created:
    ;;
    cl-user(4): (pprint *sc*)

    #S(source-context :pathname nil
                      :function bar
                      :when :compiling
                      :form nil
                      :start-char nil
                      :end-char nil
                      :charp nil
                      :enclosing-form nil
                      :backtrace (((foo x y)) ((block bar (foo x y)))))

    ;; We set the DEBUG optimization quality to 3 so the compiler
    ;; switch SAVE-SOURCE-LEVEL-DEBUG-INFO-SWITCH will be true,
    ;; as well as setting variables that will ensure that the
    ;; debug info will be loaded automatically:
    ;;
    cl-user(5): (declaim (optimize debug))
    t
    cl-user(6): (setq *load-local-names-info* t *load-source-file-info* t *load-source-debug-info* t)
    t
    cl-user(7): (setq *record-source-file-info* t)
    t

    ;; And we compile the file foobar.cl mentioned above (there may be
    ;; a warning about BAR being defined in a new place, which can
    ;; be ignored):
    ;;
    cl-user(8): :cf foobar
    ;;; Compiling file foobar.cl
    ;;; Writing fasl file /tmp/cfta244392359301
    ;;; Moving fasl file /tmp/cfta244392359301 to foobar.fasl
    ;;; Fasl write complete

    ;; Now we have a source-context with more slots filled in:
    ;;
    cl-user(9): (pprint *sc*)

    #S(source-context :pathname #P"foobar.cl"
                      :function bar
                      :when :file-compiling
                      :form (foo x y)
                      :start-char 20
                      :end-char 29
                      :charp t
                      :enclosing-form nil
                      :backtrace (((foo x y) (20 29))))
    ;; Now we load the fasl file in:
    ;;
    cl-user(10): :ld foobar
    ; Fast loading /net/gemini/home/duane/foobar.fasl

    ;; But note that the source-context hasn't changed, because it is only
    ;; built at macroexpand time:
    ;;
    cl-user(11): (pprint *sc*)

    #S(source-context :pathname #P"foobar.cl"
                      :function bar
                      :when :file-compiling
                      :form (foo x y)
                      :start-char 20
                      :end-char 29
                      :charp t
                      :enclosing-form nil
                      :backtrace (((foo x y) (20 29))))

    ;; On the other hand, if we load the source file
    ;; (which overwrites the compiled function with
    ;; an interpreted one), we do get a different source-context,
    ;; although the position-information is the same.  Note also
    ;; that the compiler-backtrace is not in this one, because
    ;; we're not compiling when this new source-context was captured:
    ;;
    cl-user(12): :ld foobar.cl
    ; Loading /net/gemini/home/duane/foobar.cl
    cl-user(13): (pprint *sc*)

    #S(source-context :pathname nil
                      :function #<Interpreted Macro Function foo @
                                  #x20f9c80a>
                      :when :evaluating
                      :form nil
                      :start-char 32
                      :end-char 44
                      :charp t
                      :enclosing-form nil
                      :backtrace nil)
    cl-user(14):

# source-file

Function, excl package

Arguments: object &optional type

This function returns the source file for object if such information is available and returns `nil` otherwise.

object identifies the object for which source-file information is desired. type, if provided, may be a symbol, a list or t. The behavior of source-file depends on the value of type. If type is not provided, and there is a single source file defining object, the pathname of that file is returned. If there is no source file information, `nil` is returned. If there are different source files in which are different types of definitions related to object, a continuable error is signaled and specific type information is requested if one continues from the error.

type may be any symbol, a list of symbols, or `t`. If unspecified, `:function` and `:macro` are tried (i.e., if object is or names a macro, type defaults to `:macro`, otherwise it defaults to `:function`, except it will just return `nil` rather than erroring if object does not name a function).

The predefined symbols are `:function`, `:macro`, `:operator`, `:type`, and `:variable`.

`:function` is used for functions, generic functions and methods, flavor methods, and defstruct accessors.

`:macro` is used for macros.

`:operator` is used for any type of operator (sort of a union of `:function` and `:macro`).

`:type` is used for classes.

`:variable` is used for variables and constants.

Those are the only objects for which source file information is automatically recorded. If type is one of these symbols, the pathname of the relevant source file is returned if the information exists, and `nil` if it does not exist. If there is no object of the specified type identified by object, an error is signaled. If no type is specified and no object is found, `nil` is returned.

For example, if `foo` is a function (and has no other definitions recorded),

    (source-file 'foo :function)

and

    (source-file 'foo)

both return the pathname of the source file, if it is known, and `nil` if it is not known, but

    (source-file 'foo :macro)

will signal an error.

Note: there may be several source files defining generic functions and methods named by a symbol. All of these files are remembered, but only the latest one is printed by

    (source-file 'foo :function)

or

    (source-file 'foo)

However,

    (source-file 'foo t)

prints a list of dotted pairs identifying all files where something named by `foo` is defined, including the file with the defgeneric (if there is one) and all files containing defmethod's.

If type is a list of allowable types, a list of dotted pairs of the form

    (type . pathname)

is returned with a pair for each type for which a source file can be found. If no source files can be found, `nil` is returned. No error is signaled even if object is neither a macro nor a function.

If type is `t`, again a list of dotted pairs is returned with pairs for each of the allowable types for which a source file is known. No error is signaled if no source file is known for a given type.

setf can be used to record source file information manually, in which case the type must be given and be a symbol.

Note that the value of *source-pathname* is a string, while source-file returns a pathname. The pathname is simply generated by calling the pathname function with the string as an argument.

The source file for a definition typed to the top-level is the keyword `:top-level`.

See also source-file-recording.html for general information on source file recording in Allegro CL.

# split-re

Function, excl package

Arguments: regexp string &key count (start 0) *end (return :string) case-fold single-line multiple-lines ignore-whitespace limit

This function scans string for a delimiter given by regexp and returns a list of substrings. If count is given, then split into no more than count substrings, in which case the last substring will contain the rest of the string. If start and end are specified, the whole string is scanned but only delimiters between start (inclusive) and end (exclusive) are considered.

If limit is specified, it should be a non-negative integer. 0 means no limit. Any positive value means no more than that number of strings will be returned, with the last string containing the rest of the output, if any:

    cl-user(8): (split-re ":" "a:b:c:d" :limit 3)
    ("a" "b" "c:d")

In most cases, limit is like count (which limits the number of matches), but not in the case where the empty string is matched. limit should be used instead of count.

If count is given, then split into no more than count substrings, in which case the last substring will contain the rest of the string. Use of count is deprecated in favor of the limit keyword argument.

If regexp matches a zero length string, split-re works to split each individual characters, excluding the characters that matched the regexp.

    (split-re "/*" "/foo/bar") => ("f" "o" "o" "b" "a" "r")

If input is empty, `nil` is returned unless non-zero limit argument is given.

The trailing empty fields are removed unless non-zero limit is given.

    (split-re ":" ":a:b:c:::") -> ("" "a" "b" "c")
    (split-re ":" ":a:b:c:::" :limit 100) -> ("" "a" "b" "c" "" "" "")

The return argument can be `:string` (the default, the return value will be a list of strings) or `:index` (the return value will be a list of dotted pairs or indexes into string corresponding to the substrings that would have been returned if return was :string). See the example.

See the section Matching mode in the regexp2 module in regexp.html for information on the case-fold, single-line, multiple-lines, and ignore-whitespace keyword arguments.

The symbol naming this operator is also exported from the regexp package.

Examples

    (excl:split-re "-" "a-b-c-d")
      --> ("a" "b" "c" "d")
    (split-re ":" "1:2:3:4:5")
      --> ("1" "2" "3" "4" "5")
    (split-re ":" "1:2:3:4:5" :return :index)
      --> ((0 . 1) (2 . 3) (4 . 5) (6 . 7) (8 . 9))
    (split-re ":" "1:2:3:4:5" :limit 2)
      --> ("1" "2" "3:4:5")
    (split-re ":" "1:2:3:4:5" :start 2)
      --> ("1:2" "3" "4" "5")
    (split-re ":" "1:2:3:4:5" :start 2 :return :index)
      --> ((0 . 3) (4 . 5) (6 . 7) (8 . 9))

    cl-user(23): (split-re "/+" "abc/def")
    ("abc" "def")
    cl-user(24): (split-re "/+" "/abc//def///ghi")
    ("" "abc" "def" "ghi")
    cl-user(25):

See The new regexp2 module in regexp.html for further information on this function and the regexp2 module.

# split-regexp

Function, excl package

Arguments: regexp string &rest args &key count start end &allow-other-keys

Scan string for a delimiter given by regexp and return a list of substrings. If count is given, then split into no more than count substrings, in which case the last substring will contain the rest of the string.

Use of this function is deprecated and it is maintained for backward compatibility only. See regexp.html for information on the newer regular expression compiler in Allegro CL. You should use the functionality described there instead of this function is new code.

Examples:

    (split-regexp (make-string 1 :initial-element #\newline)
                  (format nil "1~%2~%3~%4~%5"))
      --> ("1" "2" "3" "4" "5")

    (split-regexp ":" "1:2:3:4:5")
     --> ("1" "2" "3" "4" "5")

    (split-regexp ":" "1:2:3:4:")
      --> ("1" "2" "3" "4")

# ssbit

Function, excl package

Arguments: short-simple-bit-array &rest subscripts

Like sbit applied to simple-bit-arrays, ssbit works on short simple-bit-arrays. (It is an error to pass a short simple-bit-array to sbit or a normal simple-bit-array to ssbit.) Except for the nature of the argument, this function works just like sbit.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# sschar

Function, excl package

Arguments: short-simple-string index

Like schar applied to simple-strings, sschar works on short simple-strings. (It is an error to pass a short simple-string to schar or a normal simple-string to sschar.) Except for the nature of the argument, this function works just like schar.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# ssvref

Function, excl package

Arguments: short-simple-vector index

Like svref applied to simple-vectors, ssvref works on short simple-vectors. (It is an error to pass a short simple-vector to svref or a normal simple-vector to ssvref.) Except for the nature of the argument, this function works just like svref.

See Arrays and short arrays in implementation.html for a definition of short arrays and a discussion of the array implementation in Allegro CL.

# start-emacs-lisp-interface

Function, excl package

Arguments: &optional use-background-streams emacs-listener-number port announce-to-file

This function is obsolete. It has been replaced by new-start-emacs-lisp-interface. This function is still defined to handle one anomalous case: you are using a 6.2 version of the Emacs-Lisp interface even though you are running Allegro CL 7.0. In that case, when you want to start theemacs-lisp interface and you are not doing so in the standard way (by calling the emacs function fi:common-lisp), you may have to use this function on the Lisp side. You are using the 7.0 Emacs-Lisp interface if evaluating the emacs variable `fi:emacs-lisp-interface-version` results in a value "3.9" or larger. (You can evaluate an emacs variable in the *scratch8 buffer by entering the variable name and then Control-J.) If you are using the 6.2 interface, we recommend you update to the 7.0 version.

This function starts the 6.2 emacs-lisp interface (see eli.html) on the Lisp side. The only situation in which you should call this function is:

- You are running the 6.2 emacs-lisp interface

- You are trying to connect Emacs to an already running Lisp.

Starting the interface after Lisp is already running

You can start the interface after Lisp has been started, typically not in Emacs, with this function and the 6.2 emacs-lisp interface function fi:start-interface-via-file. This is typically done for debugging a running but apparently broken process. To do this, in Lisp call a form like:

    (excl:start-emacs-lisp-interface t 1 7666 "~/.eli-startup")

Note we have specified the emacs-listener-number as 1 (it must not be a number already used for a common-lisp buffer, if any exist), the port as 7666 (it can be any valid port number on the machine that is not already in use and can be `nil`, which causes the system to choose an appropriate port number), and announce-to-file as the file that will be used (it will be created for this call). Then, sometime later on the emacs side, do this (the host is "pie"):

    (fi:start-interface-via-file "pie" "*common-lisp*" "~/.eli-startup")

The arguments are the host running Lisp, the buffer name, and the filename.

The arguments to start-emacs-lisp-interface are:

- use-background-streams: if true, then the function use-background-streams is used to initialize background streams, which provide a separate buffer for debugging processes other than the listener process. The value of use-background-streams is passed to the function use-background-streams (see Debugging background processes in debugging.html). The default value of use-background-streams is `t`.

- emacs-listener-number: a value should only be specified when starting using a file as described under the heading Starting the interface after Lisp is already running below. The valuie should be an integer which is not already used for a common-lisp buffer, if any exist. Typical values are 1 or 2 or 3.

- port: a value should only be specified when starting using a file as described under the heading Starting the interface after Lisp is already running below. The value can be it can be any valid port number on the machine that is not already in use. Specifying the value `nil` (the default) causes the system to choose an appropriate value for the port.

- announce-to-file: a value should only be specified when starting using a file as described under the heading Starting the interface after Lisp is already running below. This file (which should not already exists -- it will be created by this call) is the file used by Eamcs to communicate to Lisp.

# std-dc-newline-in-handler

Function, excl package

Arguments: stream character

Returns the character argument, after side-effecting the stream specified by stream. If reading, the charpos (stream-line-column) slot is set to 0, otherwise the charpos (stream-line-column) slot is set to -1, to anticipate the charpos increment that is performed by the character reading strategy.

This function is an element of certain control tables for stream input/output. Programs do not typically call it directly.

See Control-character Processing in streams.html.

# std-instance-slots

Macro, excl package

Arguments: instance

Release 10.1 and later only. This macro returns the slots vector from the standard instance. It can be used as an interediary step for accessing more than one slot in an instance within a section of code. See slot-value-using-class-name.

See Appendix: Effective-method selection in Allegro CL CLOS and Associated Optimizations in implementation.html for more information on this function.

# std-instance-wrapper

Macro, excl package

Arguments: instance

Release 10.1 and later only. This macro returns the wrapper from the standard instance. The wrapper represents the class of the instance, and points to that class. If the wrapper is valid, the first element, which is always an integer, will be non-zero. If the wrapper is invalid then steps need to be taken to get the current wrapper from the class and use it.

See Appendix: Effective-method selection in Allegro CL CLOS and Associated Optimizations in implementation.html for more information on this function.

# std-newline-out-handler

Function, excl package

Arguments: stream character

Returns `nil` (indicating that further character processing should be done) after side-effecting the stream specified by stream by setting the charpos (stream-line-column) slot to -1, to anticipate the charpos increment that is performed by the character writing strategy.

This function is an element of certain control tables for stream input/output. Programs do not typically call it directly.

See Control-character Processing in streams.html.

# std-tab-out-handler

Function, excl package

Arguments: stream character

Returns `nil` (indicating that further character processing should be done) after side-effecting the stream specified by stream by setting the charpos (stream-line-column) slot to one less than the next modulo 8 column, (to anticipate the charpos increment that is performed by the character reading strategy).

This function is an element of certain control tables for stream input/output. Programs do not typically call it directly.

See Control-character Processing in streams.html.

# stream-advance-to-column

Generic Function, excl package

Arguments: stream column

Writes enough blank space so that the next character will be written at the specified column. Returns true if the operation is successful, or `nil` if it is not supported for stream. This is intended for use by the pretty printer and format ~T. The default method uses stream-line-column and repeated calls to stream-write-char with a #\space character; it returns `nil` if stream-line-column returns `nil`.

See also streams.html for general information on streams in Allegro CL.

# stream-clear-input

Generic Function, excl package

Arguments: stream

Implements clear-input for stream, returning `nil`. The default method does nothing.

See also streams.html for general information on streams in Allegro CL.

# stream-clear-output

Generic Function, excl package

Arguments: stream

Implements clear-output. The default method does nothing.

See also streams.html for general information on streams in Allegro CL.

# stream-error-action

Function, excl package

Arguments: stream-error-condition

Accesses (reader only) the `action` slot of the condition stream-error. The value of this slot is typically a string describing the operation in progress when the error occurred.

See More on cl:stream-error in errors.html.

# stream-error-code

Function, excl package

Arguments: stream-error-condition

Accesses (reader only) the `code` slot of the condition stream-error. The value is the operating system dependent error code (if any).

See More on cl:stream-error in errors.html.

# stream-error-identifier

Function, excl package

Arguments: stream-error-condition

Accesses (reader only) the `identifier` slot of the condition stream-error. The value of this slot is typically a symbol denoting this error. See Errors in socket.html for possible values of this slot for socket-error.

See More on cl:stream-error in errors.html.

# stream-error-string

Function, excl package

Arguments: errno-stream-error-condition

Accesses (reader only) the `string` slot of the condition <a href="excl-classes.html#errno-stream-error>errno-stream-error.

See More on cl:stream-error in errors.html.

# stream-finish-output

Generic Function, excl package

Arguments: stream

Implements finish-output. The default method does nothing.

See also streams.html for general information on streams in Allegro CL.

# stream-force-output

Generic Function, excl package

Arguments: stream

Implements force-output. The default method does nothing.

See also streams.html for general information on streams in Allegro CL.

# stream-fresh-line

Generic Function, excl package

Arguments: stream

Used by fresh-line. The default method uses stream-start-line-p and stream-terpri.

See also streams.html for general information on streams in Allegro CL.

# stream-input-fn

Generic Function, excl package

Arguments: stream

This and stream-output-fn are accessors that return the input or output Unix file descriptor for streams that have them, or `nil`. For some streams the input and output file descriptors may be the same.

See also streams.html for general information on streams in Allegro CL.

# stream-input-timeout

Generic Function, excl package

Arguments: simple-stream

This generic function returns the input timeout limit for simple-stream, which may be `nil` (no limit) or a positive integer noting how many seconds to wait for input before erroring because there is no input on the stream. See also the related stream-output-timeout.

Timeouts may be particularly useful for socket streams. The example is for demonstration only and is not recommended:

    ;; For demonstration only. Do not try this at home!
    cl-user(3): (setf (stream-input-timeout *standard-output*) 3)

    3
    cl-user(4):  ;; we do not type anything and we get an error:
    Error: #<stream-error @ #x10000e35692>
      [condition type: stream-error]

    Restart actions (select using :continue):
     0: Return to Top Level (an "abort" restart).
     1: Abort entirely from this (lisp) process.
    [1] cl-user(5): ;; repeated errors:
    Error: #<stream-error @ #x10000e35692>
      [condition type: stream-error]

    Restart actions (select using :continue):
     0: Return to Debug Level 1 (an "abort" restart).
     1: Return to Top Level (an "abort" restart).
     2: Abort entirely from this (lisp) process.
    [2] cl-user(6): (setf (stream-input-timeout *standard-output*) nil)
        ;; we set the value back.

    nil
    [2] cl-user(7): :res
    cl-user(8):  ;; no more errors.

# stream-line-column

Generic Function, excl package

Arguments: stream

This function returns the column number where the next character will be written, or `nil` if that is not meaningful for stream. The first column on a line is numbered 0. This function is used in the implementation of the pretty printer and the format ~T directive. For every character output stream class that is defined, a method must be defined for this function, although it is permissible for it to always return `nil`.

Beginning with version 6.1, simple-streams now implement stream-line-column as a part of the standard interface, rather than as a simple call to charpos when the :gray-compat module is loaded. For simple-streams, stream-line-column is setf'able. See the discussion of charpos and stream-line-column in Details of stream-line-column and charpos in streams.html.

See also streams.html for general information on streams in Allegro CL.

# stream-listen

Generic Function, excl package

Arguments: input-stream

Used by listen. Returns true or `nil`. The default method uses stream-read-char-no-hang and stream-unread-char. Most streams should define their own method since it will usually be trivial and will always be more efficient than the default method.

See also streams.html for general information on streams in Allegro CL.

# stream-output-fn

Generic Function, excl package

Arguments: stream

This and stream-input-fn are accessors that return the output or input Unix file descriptor for streams that have them, or `nil`. For some streams the input and output file descriptors may be the same.

See also streams.html for general information on streams in Allegro CL.

# stream-output-timeout

Generic Function, excl package

Arguments: simple-stream

This generic function returns the output timeout limit for simple-stream, which may be `nil` (no limit) or a positive integer noting how many seconds to wait for output before erroring because there is no output on the stream.

Timeouts may be particularly useful for socket streams. The example (using the related stream-input-timeout) is for demonstration only and is not recommended:

    ;; For demonstration only. Do not try this at home!
    cl-user(3): (setf (stream-input-timeout *standard-output*) 3)

    3
    cl-user(4):  ;; we do not type anything and we get an error:
    Error: #<stream-error @ #x10000e35692>
      [condition type: stream-error]

    Restart actions (select using :continue):
     0: Return to Top Level (an "abort" restart).
     1: Abort entirely from this (lisp) process.
    [1] cl-user(5): ;; repeated errors:
    Error: #<stream-error @ #x10000e35692>
      [condition type: stream-error]

    Restart actions (select using :continue):
     0: Return to Debug Level 1 (an "abort" restart).
     1: Return to Top Level (an "abort" restart).
     2: Abort entirely from this (lisp) process.
    [2] cl-user(6): (setf (stream-input-timeout *standard-output*) nil)
        ;; we set the value back.

    nil
    [2] cl-user(7): :res
    cl-user(8):  ;; no more errors.

# stream-output-width

Generic Function, excl package

Arguments: stream

Returns an integer width of stream or `nil`. The default method for this function returns `nil` for all streams.

See also streams.html for general information on streams in Allegro CL.

# stream-peek-char

Generic Function, excl package

Arguments: stream

Used to implement peek-char; this corresponds to the case where the peek-type argument to peek-char is `nil`. It returns either a character or `:eof`. The default method calls stream-read-char and stream-unread-char.

See also streams.html for general information on streams in Allegro CL.

# stream-read-byte

Generic Function, excl package

Arguments: binary-input-stream

Used by read-byte; returns either an integer, or the symbol `:eof` if stream is at end-of-file.

See also streams.html for general information on streams in Allegro CL.

# stream-read-char-no-hang

Generic Function, excl package

Arguments: character-input-stream

This is used to implement read-char-no-hang. It returns either a character, or `nil` if no input is currently available, or `:eof` if end-of-file is reached. The default method provided by fundamental-character-input-stream simply calls stream-read-char; this is sufficient for file streams, but interactive streams should define their own method.

See also streams.html for general information on streams in Allegro CL.

# stream-read-char

Generic Function, excl package

Arguments: character-input-stream

This reads one character from stream. It returns either a character object, or the symbol `:eof` if the stream is at end-of-file. Every subclass of fundamental-character-input-stream must define a method for this function.

See also streams.html for general information on streams in Allegro CL.

# stream-read-line

Generic Function, excl package

Arguments: stream

Used by read-line. A string is returned as the first value. The second value is true if the string was terminated by end-of-file instead of the end of a line. The default method uses repeated calls to stream-read-char.

See also streams.html for general information on streams in Allegro CL.

# stream-read-sequence

Generic Function, excl package

Arguments: fundamental-input-stream sequence

The nongeneric functions read-sequence and write-sequence are implemented by calling this generic function and stream-write-sequence. Methods are defined for these functions that handle all legal calls, but not all legal calls will have highly efficient execution. The existing methods will handle non-simple vector sequence arguments efficiently, and will also handle start and end arguments efficiently. The Allegro CL implementation will also accept and efficiently transfer data to and from higher-dimension arrays in the usual row-major order, although this is an extension to the language and not defined by the X3J13 specification. (The portable way to do this is to displace a vector to the higher-rank array.)

The implementation contains optimized methods for input and output (but not bidirectional) file-streams of all element types.

See also streams.html for general information on streams in Allegro CL.

# stream-start-line-p

Generic Function, excl package

Arguments: stream

This is a predicate which returns `t` if stream is positioned at the beginning of a line, else returns `nil`. It is permissible to always return `nil`. This is used in the implementation of fresh-line. Note that while a value of 0 from stream-line-column also indicates the beginning of a line, there are cases where stream-start-line-p can be meaningfully implemented although stream-line-column can't be. For example, for a window using variable-width characters, the column number isn't very meaningful, but the beginning of the line does have a clear meaning. The default method for stream-start-line-p on class fundamental-character-output-stream uses stream-line-column, so if that is defined to return `nil`, then a method should be provided for either stream-start-line-p or stream-fresh-line.

See also streams.html for general information on streams in Allegro CL.

# stream-terpri

Generic Function, excl package

Arguments: stream

Writes an end of line, as for terpri. Returns `nil`. The default method does

    (stream-write-char stream #\newline)

See stream-write-char and also streams.html for general information on streams in Allegro CL.

# stream-unread-char

Generic Function, excl package

Arguments: stream character

Undoes the last call to stream-read-char, as in unread-char.
Returns `nil`. Every subclass of fundamental-character-input-stream must define a method for this function. As with unread-char, only one character may be returned to the builtin stream classes.

See also streams.html for general information on streams in Allegro CL.

# stream-write-byte

Generic Function, excl package

Arguments: binary-output-stream integer

Writes integer to binary-output-stream and returns integer. Used by write-byte.

See also streams.html for general information on streams in Allegro CL.

# stream-write-char

Generic Function, excl package

Arguments: character-output-stream character

Writes character to character-output-stream and returns character. Every subclass of fundamental-character-output-stream must have a method defined for this function.

See also streams.html for general information on streams in Allegro CL. Note this function is defined in the streamc module which is not inlcuded in the image by default. Load it with `(require :streamc)`.

# stream-write-sequence

Generic Function, excl package

Arguments: fundamental-output-stream string &optional start end

The nongeneric functions read-sequence and write-sequence are implemented by calling stream-read-sequence and this generic function. Methods are defined for these functions that handle all legal calls, but not all legal calls will have highly efficient execution. The existing methods will handle non-simple vector sequence arguments efficiently, and will also handle start and end arguments efficiently. The Allegro CL implementation will also accept and efficiently transfer data to and from higher-dimension arrays in the usual row-major order, although this is an extension to the language and not defined by the X3J13 specification. (The portable way to do this is to displace a vector to the higher-rank array.)

The implementation contains optimized methods for input and output (but not bidirectional) file-streams of all element types.

See also streams.html for general information on streams in Allegro CL.

# stream-write-string

Generic Function, excl package

Arguments: character-output-stream string &optional start end

This is used by write-string. It writes string to stream, optionally delimited by start and end, which default to 0 and `nil`. The string argument is returned. The default method provided by fundamental-character-output-stream uses repeated calls to stream-write-char.

See also streams.html for general information on streams in Allegro CL. Note this function is defined in the streamc module which is not inlcuded in the image by default. Load it with `(require :streamc)`.

# stream-y-or-n-p

Generic Function, excl package

Arguments: stream &optional format-string &rest args

This and stream-yes-or-no-p are generic function analogues of yes-or-no-p and y-or-n-p.

See also streams.html for general information on streams in Allegro CL.

# stream-yes-or-no-p

Generic Function, excl package

Arguments: stream &optional format-string &rest args

This and stream-y-or-n-p are generic function analogues of yes-or-no-p and y-or-n-p.

See also streams.html for general information on streams in Allegro CL.

# string-sort-key

Function, excl package

Arguments: string &key ucet start end overwrite

This function returns a string suitable for passing to string< and string> so that string will be correctly compared to other strings also passed to string-sort-key.

The ucet argument is a ucet object as returned by parse-ucet. If unsupplied, a ucet object created from the Default Unicode Collation Element Table is used.

start and end specify what portion of string should be considered. overwrite specifies whether string can be modified.

See String collation with international characters in iacl.html.

# string-to-base64-string

Function, excl package

Arguments: usb8-array &key (wrap-at-column 52) start end external-format*

This function is similar to usb8-array-to-base64-string except it takes a string rather than a usb8 array as its argument and also allows specification of an external format with the external-format keyword argument (which defaults to (crlf-base-ef :latin1), see crlf-base-ef). See also base64-string-to-string.

Like usb8-array-to-base64-string and related functions, the arguments to this function were changed in release 8.1 to include the keyword arguments. The wrap-at-column keyword argument was an optional argument in earlier releases and a call with its value specified as if for an optional argument (i.e. `(string-to-base-64-string "bother" 23)` is accepted thugh discouraged. No other keyword argument may be specified if the optional argument style is used.

See Base64 Support in miscellaneous.html for information on Base64 and Base64 support in Allegro CL.

# string-to-euc

Function, excl package

Arguments: string &key null-terminate

This function is obsolete. Users are encouraged to use string-to-octets instead. The equivalance is:

    (string-to-octets string
                      :null-terminate null-terminate
                      :external-format :euc)

See also with-native-string.

This function creates a Lisp `(unsigned-byte 8 (*))` array containing the EUC character translations for the characters in string. If the value of the :null-terminate keyword argument is t (the default), then a null character is placed at the end of the result array. (When passed to C, of course, the Lisp array looks like a C string containing EUC characters.)

See iacl.html for information on character sets in Allegro CL.

# string-to-mb

Function, excl package

Arguments: string &key (null-terminate t) (start 0) (end (length string)) mb-vector make-mb-vector? (external-format :default)

string-to-mb is the pre-Release-6.0 name of the function string-to-octets. Please see the description of string-to-octets for details. string-to-mb is preserved as a name for that function for backward compatibility.

# string-to-native

Function, excl package

Arguments: string &key (start 0) (end (length string)) address (external-format :default) aligned (null-terminate t) result-vector

There are two return values. The second return value is always the number of bytes copied. The first return value depends on the value of the result-vector argument:

- If result-vector is `nil` (the default), the first return value is the address of the first copied byte.

- If result-vector is an octet vector, it is returned as the first return value.

This function converts (according to the external-format argument) and copies the string data from indices specified by start to end out of the Lisp string into a location determined by other arguments. Here is where the data is copied to:

- If result-vector and address are both `nil` or unspecified, the string data is copied to static (ie, non-Lisp heap) memory. In that case the address of the first character of the copied data is returned.

- If address is specified (as an integer giving a valid address) and result-vector is `nil` or unspecified, the string data is copied to that address and no new memory is allocated. address is typically in static space (having previously been allocated and now being reused). Extreme care should be excercised when address is in the Lisp heap as addresses may not remain valid after a garbage collection. Note in SMP Lisps, garbage collections cannot be avoided with certainty. Copying data to an incorrect address in the Lisp heap can cause the data to be lost or can cause data corruption and Lisp failure. Do not specify an address in the Lisp heap when using a SMP Lisp. address is returned as the first return value.

- If result-vector is an octet vector (of type (unsigned-byte 8)) and address is `nil`: the string data will be copied to it and it is returned as the first return value. (It is an error to specify non-`nil` values for both address and result-vector.) The vector can be a static vector (see Weak vectors, finalizations, static arrays, etc. in gc.html), in which case its address can be used freely. If result-vector is stored in the Lisp heap, care should be taken not to take the address of the result vector (e.g. with lispval-to-address) until there is no chance for a gc. In an SMP Lisp, it is difficult to impossible to ensure garbage collections do not happen.

If the aligned keyword argument is true, then address is an aligned address. Aligned addresses are returned by functions like lispval-to-aligned-malloc-address.

The copied string data will be null-terminated if the null-terminate keyword argument is true (the default). Null terminated means that the byte following the last data element is 0. The number of 8-bit bytes copied including the null-terminator if present is returned as the second value of this function.

Conversion is done using the specified external-format. If external-format is not specified (or, equivalently, if the value of external-format is `:default`), then the external format returned by the following form is used:

    (locale-external-format *locale*)

See locale-external-format and *locale*. See also string-to-octets, native-to-string, octets-to-native, and with-native-string.

See also iacl.html for general information on international character set support in Allegro CL. See foreign-functions.html for information on foreign functions.

# string-to-octets

Function, excl package

Arguments: string &key (null-terminate t) (start 0) (end (length string)) mb-vector make-mb-vector?(external-format :default)

In releases prior to 6.0, this function was named string-to-mb. The old name is preserved for backward compatibility, but users should use the new name.

This function returns a Lisp (simple-array (unsigned-byte 8) (*)) vector and the number of bytes copied.

This function converts (according to the external-format argument) and copies the string data from indices specified by start to end out of the lisp string into a lisp array of type (simple-array (unsigned-byte 8) (*)). This array is returned.

If the mb-vector argument is specified, then its value will be used (and returned) as the destination lisp array. If a vector is specified with the mb-vector argument and it is not long enough, an error is signaled unless make-mb-vector? is specified as non-`nil`, in which case a new vector is created and returned (and mb-vector is ignored).

When the null-terminate argument is true, the copied string data (in the resulting vector) is null-terminated, that is the byte following the last data element is 0. The number of 8-bit bytes copied including the null-terminator is returned as the second value of this function.

Conversion is done using the specified external-format. If external-format is not specified (or, equivalently, if the value of external-format is `:default`), then the external format returned by the following form is used:

    (locale-external-format *locale*)

See locale-external-format and *locale*.

See also octets-to-string and string-to-native.

See also iacl.html for general information on international character set support in Allegro CL.

# string-to-universal-time

Function, excl package

Arguments: string &key format native time-zone

This function is in the `:anydate` module, which is autoloaded, if necessary, when this function is called.

This function converts a string containing a date and possibly a time representation into a universal time, or, with the right arguments including a non-`nil` value for the native keyword argument, a date-time object. This function is a rough inverse of universal-time-to-string (exact inverse or not depending on the format argument and the native argument).

string is parsed according to the value of the format. If format is not specified, then possible formats are tried in order and the first that results in a successful parse is used. If none of the formats results in a successful parse, `nil` is returned (note: an error is not signaled in that case).

The format supported are (in the order they will be tried if format is not specified):

- `:rfc2822`: sample string is "Wed, 02 Jan 2013 15:16:17 -0800", see http://www.ietf.org/rfc/rfc2822.txt.

- `:w3cdtf`: sample string is "2013-01-02T15:16:17-08:00", see http://www.w3.org/TR/NOTE-datetime. This format accepts dates prior to midnight, January 1, 1900 (universal time 0) and even negative years (years BCE). See below under the heading Years prior to 1900 and BCE years for further information.

- `:iso8601`: sample string is "2013-01-02T15:16:17-08:00", see date-time.html.

- `:asctime`: sample string is "Wed Jan 2 15:16:17 2013", see http://www.cplusplus.com/reference/ctime/asctime/.

- `:mssql`: sample string is "2013-01-02 15:16:17", see http://msdn.microsoft.com/en-us/library/ms187819.aspx.

All sample strings are the universal time 3566157377 in the US/Pacific time zone. The linked websites describe the given formats.

If specified, format should be a single keyword from the list above, or a list of those keywords. If a list, each format in the list will be used to attempt to parse string, and the first successful parse will be returned (if none succeeds, `nil` is returned). The value may also be `nil`, which is the same as not specifying a value and, equivalently, as specifying all the above keywords in order.

The native keyword argument: if specified non-`nil` when format is `:iso8601` or `nil` and string parses as an `:iso8601` string, then a date-time object is returned as the first returned value rather than a universal time. This provides better performance than the form

    (util.date-time:ut-to-date-time
      (string-to-universal-time string :format :iso8601))

native is ignored if format* is neither `nil` nor `:iso8601` or if *string does not parse as an `:iso8601` string.

The time-zone keyword argument: if non-`nil`, then it is the time zone in which to interpret the time given by string. If the time zone is given in string, time-zone is ignored. If non-`nil`, time-zone must be a numerical time zone, acceptable as an argument to < encode-universal-time. If time-zone is `nil` or not given and string has no time zone, then the currently defined time zone is used.

For some formats, `:rfc2822`, `:iso8601` and `:w3cdtf`, the time-zone keyword is ignored and must be specified in string, if you wish to use a time zone other than the default.

Lisp and iso8601 use opposite signs for time zones. So

    cl-user(2): (string-to-universal-time "2003-12-31T10:14:55-08:00" :format :w3cdtf)
    3281883295
    :w3cdtf
    28800
    cl-user(3): (decode-universal-time *)
    55
    14
    10
    31
    12
    2003
    2
    nil
    8
    cl-user(4):
    cl-user(6): (universal-time-to-string 3281883295
                          :format :w3cdtf :time-zone -8)
    "2004-01-01T02:14:55+08:00"
    cl-user(7): (universal-time-to-string 3281883295
                          :format :w3cdtf :time-zone 8)
    "2003-12-31T10:14:55-08:00"
    cl-user(8):

Return values

If a successful parse is completed, then multiple values are returned, otherwise the single value `nil` is returned. Malformed dates merely cause `nil` to be returned rather than an error being signaled. It is the responsibility of the caller to signal an error, if one is desired. A correctly formed date outside the range of universal time (which is times after is midnight GMT January 1, 1900) as can happen with some formats, as noted below) will signal an error.

The values returned upon a successful parse:

1. When native is `nil`, the first returned value is the universal time corresponding to the date in string, when fractional seconds are not used in string. If fractional seconds are used, a ratio is returned that represents the universal time plus the fractional seconds. The formats which allow fractional seconds are `:iso8601`, `:w3cdtf` and `:mssql`. For example, `(string-to-universal-time "2013-01-01T00:00:00.1")` returns (as the first value) 35660160001/10, where 3566016000 is the universal time corresponding to "2013-01-01T00:00:00" and 1/10 is the fractional seconds corresponding to ".1". When native is non-`nil` and format is `:iso8601` (or `nil` and string is parsed as an `:iso8601` string), the first return value is a date-time object rather than an integer or ratio. When format is any other value or `nil` and string is not parsed as an `:iso8601` string, native is ignored and the behavior is as if native were `nil`.
2. A keyword naming the format for the successful parse -- the values are the same as the valid values of format.
3. If the format does not support specification of a time zone (as with `:asctime` and `:mssql`) or string does not contain a time zone, then `:time-zone-not-specified` is returned for this third returned value. Otherwise, the time zone, in positive seconds west of GMT or negative seconds east of GMT, is returned.

Further notes

- For some formats, it is possible that a legal values for string cannot be represented by a proper universal time. This can happen in `:iso8601` and `:mssql`. When the format is `:iso8601`, you may get a negative result (as universal times are extended to work with date-time objects outside the range of universal time). Note it is an error to for string to specify a time outside the universal time range and the consequences are undefined if such a time is specified.

- The `:rfc2822` parser recognizes the character-based time zone abbreviations defined in RFC 2822, which are:

      EST / EDT
      CST / CDT
      MST / MDT
      PST / PDT

  In addition, we recognize the following (technically) invalid time zones:

      ET is treated as EST
      CT is treated as CST
      MT is treated as MST
      PT is treated as PST

See universal-time-to-string, ut-to-string-formatter, and the General date to universal time parsers section of date-time.html for more information. The date-time.html document also describes the date-time module which provides additional ISO-8601 support.

Examples

    (string-to-universal-time "Thu, 01 Jan 04 19:48:21 GMT" :format :rfc2822)
      => 3281975301 :rfc2822 0
    (universal-time-to-string 3281975301 :format :rfc2822)
      => "Thu, 01 Jan 2004 11:48:21 -0800"
    (string-to-universal-time "Thu, 01 Jan 04 19:48:21 GMT")
      => 3281975301 :rfc2822 0
    (universal-time-to-string 3281975301)
      => "2004-01-01T11:48:21"

    (string-to-universal-time "Thu, 01 Jan 2004 19:48:21 GMT" :format :rfc2822)
      => 3281975301 :rfc2822 0
    (universal-time-to-string 3281975301 :format :rfc2822)
      => "Thu, 01 Jan 2004 11:48:21 -0800"
    (string-to-universal-time "Thu, 01 Jan 2004 19:48:21 GMT")
      => 3281975301 :rfc2822 0
    (universal-time-to-string 3281975301)
      => "2004-01-01T11:48:21"

    (string-to-universal-time "2003-12-31T10:14:55-08:00" :format :w3cdtf)
      => 3281883295 :w3cdtf 28800
    (universal-time-to-string 3281883295 :format :w3cdtf)
      => "2003-12-31T10:14:55"
    (string-to-universal-time "2003-12-31T10:14:55-08:00")
      => 3281883295 :w3cdtf 28800
    (universal-time-to-string 3281883295)
      => "2003-12-31T10:14:55"

    (string-to-universal-time "2003-12-31T10:14:55Z" :format :w3cdtf)
      => 3281854495 :w3cdtf 0
    (universal-time-to-string 3281854495 :format :w3cdtf)
      => "2003-12-31T02:14:55"
    (string-to-universal-time "2003-12-31T10:14:55Z")
      => 3281854495 :w3cdtf 0
    (universal-time-to-string 3281854495)
      => "2003-12-31T02:14:55"

    (string-to-universal-time "2003" :format :w3cdtf)
      => 3250396800 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3250396800 :format :w3cdtf)
      => "2003-01-01T00:00:00"
    (string-to-universal-time "2003")
      => 3250396800 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3250396800)
      => "2003-01-01T00:00:00"

    (string-to-universal-time "2003-12" :format :w3cdtf)
      => 3279254400 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3279254400 :format :w3cdtf)
      => "2003-12-01T00:00:00"
    (string-to-universal-time "2003-12")
      => 3279254400 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3279254400)
      => "2003-12-01T00:00:00"

Years prior to 1900 and BCE years

string-to-universal-time will accepts dates and times prior to midnight, January 1, 1900 GMT (universal time 0), but specified in `:w3cdtf` format only. `:w3cdtf` only accepts four digit years so years between 1000 BCE and 1000 CE must have leading 0's (so 0001, -0044, and 0999). Negative years are accepted. Note there is a year 0 (which indicates 1 BCE), so 44 BCE is specified -0043. Also, it is assumed the Gregorian Calendar (used more or less worldwide today although other calendars are also used for some purposes) has been used throughout history when in fact it was introduced in 1582 and not adopted more or less worldwide until the twentieth century. See encode-extended-time and decode-extended-time for more information. Dates and times prior to prior to midnight, January 1, 1900 GMT (universal time 0) have negative universal times. See also universal-time-to-string.

    cg-user(20): (string-to-universal-time "2003-12-31T10:14:55-08:00" :format :w3cdtf)
    3281883295
    :w3cdtf
    28800
    cg-user(21): (string-to-universal-time "0003-12-31T10:14:55-08:00" :format :w3cdtf)
    -59832020705
    :w3cdtf
    28800
    cg-user(22): (string-to-universal-time "-0012-12-31T10:14:55-08:00" :format :w3cdtf)
    -60305319905
    :w3cdtf
    28800
    cg-user(23): (string-to-universal-time "-0043-03-15T10:00:00+01:00" :format :w3cdtf)
    -61308802800
    :w3cdtf
    -3600
    cg-user(24): (string-to-universal-time "1492-12-31T10:00:00+01:00" :format :w3cdtf)
    -12843673200
    :w3cdtf
    -3600

# switch-ef-to-runtime

Function, excl package

Arguments: external-format

external-format should be an external-format.

Switches an external-format to runtime mode. The def-ef-switch-to-runtime macro is used to name a function (or function object) that when funcalled clears structures used by the macros that are not needed when the external-format is in runtime mode. switch-ef-to-runtime funcalls this function and also clears the char-to-octets/octets-to-char convertor macros.

Generally, users will not call switch-ef-to-runtime. When an external-format is autoloaded, an attempt is made to autoload the pre-filled external-format code templates. These pre-filled templates are stored in separate fasl files, usually with names that begin with 'efft-'. If the pre-filled templates are successfully loaded, then Allegro CL automatically switches the just-loaded external-format to runtime mode using switch-ef-to-runtime.

See iacl.html for more information on international character support in Allegro CL.

# symbolic-link-p

Function, excl package

Arguments: pathname

If pathname names a symbolic link, returns the physical pathname of the file pointed to by the link. If pathname does not name a symbolic link, this function returns `nil`. `nil` is also returned if the item named by pathname does not exist, or the directory or filesystem do not exist but an error is signaled if pathname names a logical pathname with an undefined or untranslatable logical host.

pathname should be a pathname object or a string naming a pathname. The behavior when pathname names a circular link is undefined.

See also pathnames.html for general information on pathnames in Allegro CL and see pathname-resolve-symbolic-links.

# synchronized-output-stream-p

op, excl package

Arguments: stream

Returns whether stream is suitable to be a staging stream in a call to with-staged-output. You can used setf to set the value returned by this function.

# syscall-error-errno

Generic Function, excl package

Arguments: syscall-error

This generic function is the accessor to the `errno` slot of the condition syscall-error.

The home package of the symbol `syscall-error` is `excl.osi`. However, it is also exported from the `excl` package and so is available when the `osi` module is not loaded.

# tenuring

Macro, excl package

Arguments: &body body

Use this macro to immediately tenure all objects allocated while within the scope of body. This macro is normally used when loading files, or performing some other operation where the objects created will not become garbage in the short term. (Objects with lispval-storage-type `:panified` are never tenured and are thus unaffected.)

A tenuring form returns the values of the last form of body, as if in a progn.

This macro is very useful for preventing newspace expansion. Without the tenuring macro, loading a very large fasl file may cause the newspace to expand to several times its previous size. With the tenuring macro, the newspace will not grow as severely, which will usually improve performance in the resulting Lisp.

tenuring works (as can be seen in the macroexpansion) by setting the :generation-spread gsgc-parameter to 0, then executing the body, then calling gc (without arguments thus performing a scavenge) twice, and finally resetting the :generation-spread to its old value. There may be additional scavenges while the body is executing. gc is called twice because objects that according to the parameters should be tenured during a scavenge sometimes are not for system reasons. The additional scavenge usually ensures such objects are indeed tenured.

See also gc.html for general information on garbage collection in Allegro CL.

# touch-system

Generic Function, excl package

Arguments: system &rest rest &key &allow-other-keys

This generic function makes the fasl files of the modules in system up-to-date by performing a Unix touch command (or equivalent) on each of the fasl files. This is similar to make -t in Unix. The defsystem facility uses the Unix filesystem creation timestamp when checking whether a source file needs to be reloaded or recompiled.

The &allow-other-keys allows any keywords to be specified. The default method looks at only two: silent and simulate.

The value of the silent keyword argument can be `t` or `nil`. Its default value is `nil`. `t` means do not print anything while performing the operation. This is similar to make -s. A true value of simulate overrides silent `t`.

The value of the simulate keyword argument can be `t` or `nil`. `t` means print the list of actions that would be taken if the operations were to be performed at this time, but do not actually perform the operations. This is similar to make -n.

Although the home package of the symbol naimg this operator is the excl package, it is also exported from the defsystem package.

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# unadvise-1

Function, excl package

Arguments: fspec class name

Starting in Allegro CL release 6.0, the new fwrapper facility, described in fwrappers-and-advice.html, replaces the advice facility, and continued use of the advice facility is deprecated.

This is the functional form of the macro excl:unadvise. All arguments are required. All the arguments have the same interpretation as with excl:unadvise, and the calls have the same effect, except that the arguments are (of course) evaluated.

See also fwrappers-and-advice.html for general information on the new fwrapper facility and the older, now deprecated, advice facility in Allegro CL.

# unadvise

Macro, excl package

Arguments: &optional fspec class name

Starting in Allegro CL release 6.0, the new fwrapper facility, described in fwrappers-and-advice.html, replaces the advice facility, and continued use of the advice facility is deprecated.

This macro removes advice with the class and name specified from the function (or macro) specified by fspec. Any of the three arguments may be `nil`. `nil` works like a wildcard: all advice specified by the other arguments is removed. All of the arguments default to `nil`.

It is an error to unadvise a function named by a symbol which has been fmakunbound. Doing so may result in the symbol again having a function definition.

Note: unadvise called without arguments removes all advice from all functions and macros.

See also fwrappers-and-advice.html for general information on the new fwrapper facility and the older, now deprecated, advice facility in Allegro CL.

# uncompile

Function, excl package

Arguments: function-name

This function uncompiles the function named by function-name (which must be a symbol). That is, it replaces the compiled function object with an interpreted function object. This replacement will only succeed if the interpreted function information is available. (That is, this function does not analyze the compiled code and infer the Lisp source which produced it. Instead, it finds the original source code if it can, and uses that. If it cannot find the original source code, it will not succeed.)

This function will work if the following two conditions are true:

1. the function was originally compiled with the compile function (as opposed to having been in a file that was compiled with compile-file and subsequently loaded); and

2. the value of the variable *save-function-lambda-expression* was true when the compilation was done. (The initial value of that variable is `nil` so unless the value is changed, uncompile may not work.)

uncompile will also succeed if source debug information for the function has been stored, which will happen if the compiler switch save-source-level-debug-info-switch was true when the function was compiled. For functions de3fined in files, if source file recording was not enabled when the fasl file associated with the function was loaded, the user might be prompted for the source file location. If source file information (and source level debugging information) were enabled, the system will find the source (assuming the necessary files still exist and are accessible). Source file recording is enabled when *record-source-file-info* and *load-source-file-info* are both true.

uncompile only works for function-names that are symbols, not function-specs.

# undefsystem

Macro, excl package

Arguments: system-name

This macro removes system-name from the list of defined systems. system-name must be a symbol which names a defined system.

The defsystem facility keeps an internal alist of pretty-names and system-object pairs. This macro returns the contents of the pretty-name alist after system-name has been deleted. If this macro deletes the last system definition, then the macro will return `nil`. It is not an error to attempt to delete an undefined system.

    USER(42): (defsystem :my-serial-sys ()

    (:serial "my1" "my2"))
    :MY-SERIAL-SYS
    USER(43): (undefsystem :my-serial-sys)
    NIL

See also defsystem.html for general information on the defsystem facility in Allegro CL.

# unicode-combining-class

Function, excl package

Arguments: char

This function returns the Unicode Canonical Combining Class value for char. For more information on Unicode Canonical Combining Classes, see the report "Unicode Data File Format" (http://www.unicode.org/Public/UNIDATA/UnicodeData.html).

See iacl.html.

# unicode-nfd

Function, excl package

Arguments: string &key (start 0) (end nil)

This function returns three values:

1. The Unicode Canonical Decomposition (Normalization Form D (NFD)) for string (or the portion of string specified by start and end). But if the argument string which is already normalized, it is simply returned with start and end ignored. (This avoids unnecessary copying.)

2. The normalized start (or start if the string is returned unchanged).

3. The normalized end (or end if the string is returned unchanged).

For more information on Unicode Decomposition, see the report "Unicode Normalization Forms" (http://www.unicode.org/unicode/reports/tr15).

See iacl.html.

# universal-time-to-string

Function, excl package

Arguments: ut &key relative format time-zone (show-date t) (show-time t) (show-time-zone t) (locale *locale|*) stream

This function is in the `:anydate` module, which is autoloaded, if necessary, when this function is called.

This function takes a universal time (perhaps an extended universal time which includes fractional seconds and dates and times prior to universal time 0) and creates a string which represents the time in a specified format. That string is printed to stream, if stream is non-`nil`, and returned if stream is `nil`. `:stream t` causes the output to be printed to *standard-output*. If stream is `t` or a stream, `nil` is returned. If steam is `nil` or unspecified, the output string is returned.

This function is a rough inverse of string-to-universal-time (an exact inverse when the value of the format argument to each function is the same and non-`nil` and the universal time value/string are valid values).

The output is controlled by the relative keyword argument. If `nil` (the default) a string representing the time in standard format (modified as necessary by other keyword arguments) is created. If relative is non-`nil`, it should be another universal time value and the output will describe the duration from the value of relative to the value of ut. We describe the behavior when relative is `nil` and then the behavior when relative is a universal time. Note that the allowable values for the format argument are different in the two cases.

** relative is nil**

format should be one of the following keywords: `:rfc2822`, `:w3cdtf` (the default), `:iso8601`, `:asctime`, or `:mssql` (see string-to-universal-time for information on how the various keywords display dates and times); or a string containing field descriptor definitions (and other charaters as desired) defined in the description of locale-format-time. When format is a string, the locale keyword argument can be used to change the locale used for the rendering the printed representation of ut (*locale*). format can also be unspecified or `nil`, either of which are the same as `:w3cdtf`.

The show-date, show-time, and show-time-zone keyword arguments are used only when format is `:iso8601` or `:w3cdtf`. When format is one of those values, displaying the date, time and/or time zone can be suppressed by specifying `nil` as the value of the relevant argument (all default to `t`). It is an error to specify `nil` as the value of all three arguments.

The time-zone can be used to reinterpret ut in a specific time zone. If not specified, the current, default time zone will be used. Note: you may get different results when specifying the current time zone and letting the default behavior happen, because daylight savings time is not applied when the time-zone is supplied. See encode-universal-time for more information.

Fractional seconds are allowed for certain formats. See string-to-universal-time for details.

** relative is a universal time**

When relative is a universal-time, the output string will describe the duration between the value of relative and the value of ut. The duration is the time between ut and relative, regardless of which is later (so the absolute value of the difference between the two is used):

    ;; When :RELATIVE is a universal time, the duration is the same
    ;; whether :RELATIVE is bigger or smaller that the UT (required)
    ;; argument:

    cl-user(5): (universal-time-to-string 100 :relative 101)
    "00:00:01"
    cl-user(6): (universal-time-to-string 101 :relative 100)
    "00:00:01"
    cl-user(7):

The content of the string depends on the format argument, which may have any of the following values:

- A function which accepts five arguments: stream (a stream, `t` or `nil`), seconds (an integer or a ratio), minutes (an integer), hours (an integer), and days (an integer).

*A string suitable as the first argument to ut-to-string-formatter.

The function ut-to-string-formatter returns a function suitable to be used as the value of format. When format is a string, that string is passed to ut-to-string-formatter.

A function returned by ut-to-string-formatter constructs a string using the supplied formatter string (the string argument to format or the first argument passed to ut-to-string-formatter) and the seconds, minutes, hours, and days values and, like universal-time-to-string itself, writes it to the stream if stream is a stream (and also returns `nil`); writes it to *standard-output* if stream is `t` (and also returns `nil`); and returns it if stream is `nil`.

When relative is a universal time, the stream argument to universal-time-to-string is passed as the stream argument to the function which is the value of format (or constructed from the string which is the value of format). time-zone is ignored (both ut and relative are taken to be in the same time zone, and a duration is not affected by time zone), as are show-date, show-time, show-time-zone, and locale.

See ut-to-string-formatter, string-to-universal-time, and the General date to universal time parsers section of date-time.html for more information. The date-time.html document also describes the date-time module which provides additional ISO-8601 support.

Examples

    (string-to-universal-time "Thu, 01 Jan 04 19:48:21 GMT" :format :rfc2822)
      => 3281975301 :rfc2822 0
    (universal-time-to-string 3281975301 :format :rfc2822)
      => "Thu, 01 Jan 2004 11:48:21 -0800"
    (string-to-universal-time "Thu, 01 Jan 04 19:48:21 GMT")
      => 3281975301 :rfc2822 0
    (universal-time-to-string 3281975301)
      => "2004-01-01T11:48:21"

    (string-to-universal-time "Thu, 01 Jan 2004 19:48:21 GMT" :format :rfc2822)
      => 3281975301 :rfc2822 0
    (universal-time-to-string 3281975301 :format :rfc2822)
      => "Thu, 01 Jan 2004 11:48:21 -0800"
    (string-to-universal-time "Thu, 01 Jan 2004 19:48:21 GMT")
      => 3281975301 :rfc2822 0
    (universal-time-to-string 3281975301)
      => "2004-01-01T11:48:21"

    (string-to-universal-time "2003-12-31T10:14:55-08:00" :format :w3cdtf)
      => 3281883295 :w3cdtf 28800
    (universal-time-to-string 3281883295 :format :w3cdtf)
      => "2003-12-31T10:14:55"
    (string-to-universal-time "2003-12-31T10:14:55-08:00")
      => 3281883295 :w3cdtf 28800
    (universal-time-to-string 3281883295)
      => "2003-12-31T10:14:55"

    (string-to-universal-time "2003-12-31T10:14:55Z" :format :w3cdtf)
      => 3281854495 :w3cdtf 0
    (universal-time-to-string 3281854495 :format :w3cdtf)
      => "2003-12-31T02:14:55"
    (string-to-universal-time "2003-12-31T10:14:55Z")
      => 3281854495 :w3cdtf 0
    (universal-time-to-string 3281854495)
      => "2003-12-31T02:14:55"

    (string-to-universal-time "2003" :format :w3cdtf)
      => 3250396800 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3250396800 :format :w3cdtf)
      => "2003-01-01T00:00:00"
    (string-to-universal-time "2003")
      => 3250396800 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3250396800)
      => "2003-01-01T00:00:00"

    (string-to-universal-time "2003-12" :format :w3cdtf)
      => 3279254400 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3279254400 :format :w3cdtf)
      => "2003-12-01T00:00:00"
    (string-to-universal-time "2003-12")
      => 3279254400 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3279254400)
      => "2003-12-01T00:00:00"

    (string-to-universal-time "2003-12-31" :format :w3cdtf)
      => 3281846400 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3281846400 :format :w3cdtf)
      => "2003-12-31T00:00:00"
    (string-to-universal-time "2003-12-31")
      => 3281846400 :w3cdtf :time-zone-not-specified
    (universal-time-to-string 3281846400)
      => "2003-12-31T00:00:00"

    (string-to-universal-time "20031231" :format :iso8601)
      => 3281846400 :iso8601 :time-zone-not-specified
    (universal-time-to-string 3281846400 :format :iso8601)
      => "2003-12-31T00:00:00"
    (string-to-universal-time "20031231")
      => 3281846400 :iso8601 :time-zone-not-specified
    (universal-time-to-string 3281846400)
      => "2003-12-31T00:00:00"
    (string-to-universal-time "20031231" :format :iso8601 :native t)
      => #<util.date-time:date-time "2003-12-31" @ #x1000117b1f2> nil nil

    (string-to-universal-time "Sun Jan  4 16:29:06 2004" :format :asctime)
      => 3282251346 :asctime :time-zone-not-specified
    (universal-time-to-string 3282251346 :format :asctime)
      => "Sun Jan  4 16:29:06 2004"
    (string-to-universal-time "Sun Jan  4 16:29:06 2004")
      => 3282251346 :asctime :time-zone-not-specified
    (universal-time-to-string 3282251346)
      => "2004-01-04T16:29:06"

    (string-to-universal-time "2004-07-08 23:56:58" :format :mssql)
      => 3298345018 :mssql :time-zone-not-specified
    (universal-time-to-string 3298345018 :format :mssql)
      => "2004-07-08 23:56:58"
    (string-to-universal-time "2004-07-08 23:56:58")
      => 3298345018 :iso8601 :time-zone-not-specified
    (universal-time-to-string 3298345018)
      => "2004-07-08T23:56:58"

    (string-to-universal-time "2004-07-08 23:56:58.1" :format :mssql)
      => 32983450181/10 :mssql :time-zone-not-specified
    (universal-time-to-string 32983450181/10 :format :mssql)
      => "2004-07-08 23:56:58.1"
    (string-to-universal-time "2004-07-08 23:56:58.1")
      => 32983450181/10 :iso8601 :time-zone-not-specified
    (universal-time-to-string 32983450181/10)
      => "2004-07-08T23:56:58.1"

    ;; This example uses *locale*:
    (excl::universal-time-to-string (get-universal-time) :format "%H:%M:%S")
      => "11:01:44"

    ;; When RELATIVE is a universal time, FORMAT can be unspecified and
    ;; a suitable formatting function will be used:
    (setq ut 3603660634)
    (universal-time-to-string ut :relative (+ ut 1 (* 10 3600)))
      => "10:00:01"

    ;; Compiling the function returned by UT-TO-STRING-FORMATTER improves
    ;; efficiency but is not required.
    (setq f (compile nil (ut-to-string-formatter "%Dd%2Hh%2Mm%2Ss")))
    (universal-time-to-string ut :relative (+ ut (* 40 3666)) :format f)
      => "1d16h44m00"

    ;; The string argument to UT-TO-STRING-FORMATTER can be passed as the
    ;; format argument to UNIVERSAL-TIME-TO-STRING with the same result:
    (universal-time-to-string ut :relative (+ ut (* 40 3666))
                              :format "%Dd%2Hh%2Mm%2Ss")
      => "1d16h44m00"

    (setq f (compile nil (ut-to-string-formatter
                      "%D day%p, %H hour%p, %M minute%p and %S second%p")))
    (universal-time-to-string 3603660634
                  :relative (+ 3603660634 (* 41 3666))
                  :format f)
      => "1 day, 17 hours, 45 minutes and 6 seconds"

Negative universal times

This function accepts negative values for the ut argument. This produces results prior to midnight, January 1, 1900 GMT (universal time 0). The format must be `:w3cdtf` (which is the default when ut is negative). That is also the required format for dates and times outside the universal time range passed to universal-time-to-string. See also encode-extended-time and decode-extended-time.

    cg-user(52): (string-to-universal-time "2003-12-02T02:14:55" :format :w3cdtf)
    3279348895
    :w3cdtf
    :time-zone-not-specified
    cg-user(53): (universal-time-to-string 3279348895 :format :w3cdtf)
    "2003-12-02T02:14:55"
    cg-user(54): (string-to-universal-time "-0043-03-15T10:00:00" :format :w3cdtf)
    -61308770400
    :w3cdtf
    :time-zone-not-specified
    cg-user(55): (universal-time-to-string -61308770400)
    "-43-03-15T10:00:00"
    cg-user(56): (string-to-universal-time "1492-12-02T02:14:55" :format :w3cdtf)
    -12846174305
    :w3cdtf
    :time-zone-not-specified
    cg-user(57): (universal-time-to-string -12846174305)
    "1492-12-02T02:14:55"
    cg-user(58):

# unread-byte

function, excl package

Arguments: stream

This function is similar to unread-char, but it backs up to the previous octet rather than character. It is also similar in that if unread-byte is called immediately after a "back-up" function (i.e. peek-char/peek-byte or unread-char/unread-byte) it may fail. However, it need not fail; if the stream being operated on is not currently positioned at the beginning of its buffer, even after a backup function has just been called, then unread-byte may still succeed. There is currently no portable way to know whether an unread-byte will work, unless the last operation on the stream was a read operation other than a back-up function.

unread-byte currently does not work on Gray streams - error is called when unread-byte is called on a Gray stream. (Gray streams are discussed in gray-streams.html.)

See peek-byte and unread-byte in streams.html for a general discussion of this function and the related peek-byte.

# unregister-assert-enable

Function, excl package

Arguments: name index

Release 10.1 and later only. name is a keyword representing a current assert-enable. index must be its index. That assert enable will be removed for the list of assert enables. It is an error to try to remove a reserved assert enable (the first 6 in the list.

Best practice has assert enables registered, used, and unregistered by the same software as modify assert enables added or used by other software make interfere with its proper use.

Note: No effort has been taken to make the registration or unregistration of assert-enables thread-safe. These operations are intended to be low incidence, non-dynamic operations.

See Conditionalizing assert calls in miscellaneous.html for more information.

# unschedule-finalization

Function, excl package

Arguments: fp

Unschedules the finalization fp (which must have been scheduled by schedule-finalization). This means that when the object with which the finalization is associated is identified as garbage, the finalization will not be run. The argument fp must be the value returned by schedule-finalization.

See gc.html for general information on garbage collection and section Finalizations for details of finalizations.

# until

macro, excl package

Arguments: condition &rest forms

Evaluates forms repeatedly until condition (which should be a Lisp form) evaluates to a true value.

The definition of until is

    (defmacro until (condition &rest forms)
      `(loop (when ,condition (return)) ,@forms))

Note that loop surrounds its body with a block named `nil` (as used by the return form which is the consequent of the when form). This macro returns `nil`.

See also while.

# update-atomic

macro, excl package

Arguments: (var place) form

This macro expands into code that does a read-modify-write operation that is atomic with respect to the value in place. That is, the value in place is read and bound to a local variable; the value of a form is computed; then the result is stored back in place as long as that value hasn't changed since the update-atomic code read and saved it. If it has changed (tested using eq, then the new value is acquired and bound to the local variable, the form value is recomputed, and another conditional store attempt is made. This loop continues until the store is successful.

The arguments are:

- var: a symbol naming the local variable that will be bound to the value in place while form is being evaluated.

- place: a form denoting a place acceptable to atomic-conditional-setf. See note below.

- form: a form that computes a value to replace the original value in place. Subforms of form are evaluated once each, in the order they appear in place, as for all setf-type macros.

Note on the place argument: not all places legal as the first argument of setf can be used as the place argument to this macro. The list of allowable places can be found in Atomic read-modify-write primitives in smp.html.

update-atomic could be used to implement `(incf-atomic (car x))` like this:

    (update-atomic (v (car x)) (1+ v))

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# update-bundle-files

Function, excl package

Arguments: &key include-new-efs files bundle tdir bundle-prog bli-tf

Although this function can be called at any time, it is generally only needed if a patch is downloaded from Franz Inc., which when built into the Lisp, displays a message at startup time advising the user to call this function.

If a user defines a new external-format which s/he wants to be autoloadable in a runtime application, the definition should be made in a file named code/ef-[name].fasl (where code/ is a subdirectory of the Allegro CL directory). When this function is called, a copy of the external-format definition file will be put into the bundle and runtime bundle. Note that only files named code/ef-*.fasl are placed into the bundle by this function.

This function updates the bundle file (returned by bundle-pathname) and also the runtime bundle file runtime.bu (if there is one). After the update, all module fasl files downloaded to the code/ subdirectory of the Allegro Directory will be included in the bundle. External format definitions not in the bundle will also be included.

Note that updating the bundle can take an appreciable amount of time.

The arguments are all keyword arguments. It is recommended that update-bundle-files be run without arguments (that is, the defaults be accepted in all cases). The arguments are:

- `:include-new-efs`: Include external-format definitions found in #p"sys;code;" which aren't already in the bundle.

- `:files`: list of pairs of pathnames. These correspond to the original names and target names of files to be updated.

- `:bundle`: the primary file to be updated.

- `:tdir`: pathname of temporary directory to be used. This directory should not exist. Furthermore, the directory is removed before the function returns.

- `:bundle-prog`: name of bundle manipulation program.

- `:bli-tf`: the temporary script file name used to hold the forms passed to build-lisp-image, a function called by update-bundle-files.

# usb8-array-to-base64-string

Function, excl package

Arguments: usb8-array &key (wrap-at-column 52) start end

Takes the (unsigned-byte 8) array specified by the usb8-array, assumes it is a base64 encoding (with the first (index 0 or index start) element the most significant), and converts it to a base64 string. If wrap-at-column is non-`nil`, its value must be a positive integer and newlines are inserted in the string each time that number of characters is output. If wrap-at-column is `nil`, no newlines are inserted. start and end specify the portion of the usb8-array to convert. If unspecified, the whole array is converted.

The function base64-string-to-usb8-array converts a base64 string (the output of this function) back to an (unsigned-byte 8) array.

Here are some examples. First we show that the first array element is the most significant (using base64-string-to-integer). Then we give a more complex example.

    cl-user(2): (setq ar1 (make-array 2 :element-type '(unsigned-byte 8)
                              :initial-contents '(10 40)))
    #(10 40)
    cl-user(3): (setq b1 (usb8-array-to-base64-string ar1))
    "Cig="
    cl-user(4): (base64-string-to-integer b1)
    2600  ;;  equals (+ (* 10 (expt 2 8)) 40) equals (+ 2560 40)

    cl-user(5): (setq a (string-to-octets
                 (setq s
                   "
    (defun deep-thought ()
      (sleep (years2secs 7500000))
      42)
    ")))
    #(10 40 100 101 102 117 110 32 100 101 ...)
    cl-user(6): (usb8-array-to-base64-string a)
    "CihkZWZ1biBkZWVwLXRob3VnaHQgKCkKICAoc2xlZXAgKHllYXJz
    MnNlY3MgNzUwMDAwMCkpCiAgNDIpCgA="
    cl-user(7): (base64-string-to-usb8-array *)
    #(10 40 100 101 102 117 110 32 100 101 ...)
    cl-user(8): (setq a2 *)
    #(10 40 100 101 102 117 110 32 100 101 ...)
    cl-user(9): (equalp a a2)
    t
    cl-user(10): (octets-to-string a2)
    "
    (defun deep-thought ()
      (sleep (years2secs 7500000))
      42)
    "
    61
    61

See Base64 Support in miscellaneous.html for information on Base64 and Base64 support in Allegro CL.

# usb8-array-to-hex-string

Function, excl package

Arguments: array &key start end

This function converts the portion of array delimited by start and end (defaults: beginning and end of the array) to a string of hexadecimal characters. Example:

    (usb8-array-to-hex-string #(1 255 2 80)) ==> "01ff0250"

This function is useful with encryption routines. See, for example, Support for Blowfish encryption in miscellaneous.html. Support for encryption in the same document discusses encryption support in Allegro CL in general.

See also hex-string-to-usb8-array, hex-string-to-integer and integer-to-hex-string.

# use-background-streams

Function, excl package

Arguments:

Returns `nil` but this function is called for its side effects when using the emacs-lisp interface. This function sets up a mechanism within Lisp to catch errors and breaks in background processes (i.e. processes that are not listener processes) and, if possible, create a new Lisp listener in another emacs buffer connected to the broken process.

If you did not start Lisp in emacs with fi:common-lisp, the system will not be able to create a listener buffer. In that case, Lisp will behave as if this function had not been called. The error message will be printed in the Initial Lisp Listener. See eli.html.

It is not an error to call this function when the emacs-lisp interface is not being used (but doing so has no practical effect). Nor is it an error to call this function when background streams are already enabled.

See Debugging background processes in debugging.html for more information.

# use-pll-file

Function, excl package

Arguments: file &key global-gc

If the current Lisp has no .pll file, an association is made with the file file and the heap is remapped to use the resulting new pure space. An error is signaled if the current Lisp already has a .pll file. All code vectors in the heap are redirected if they have a corresponding bit-equivalent code vector in the file specified by file. Strings are redirected if they have equivalents in file, and if they appear as symbol-names in symbols, or if they appear in the constant vectors of function objects. All other strings must be purified by the program using `excl::maybe-purify-string` or pure-string, documented elsewhere. Warning: the program must be careful not to purify a string that is not a constant; if subsequent modification of string contents is attempted, an error will be signaled.

The global-gc argument defaults to `t`. Specifying `nil` for this argument allows the user to delay the global GC until all strings are purified. A global GC is necessary to remove all old code vectors and strings that have now been replaced in pure space.

You should ensure that there are no closed old areas before performing a global gc intended to get rid of purified strings. Do the following before the call to use-pll-file or before the final global gc:

    ((setf (sys:gsgc-parameter :open-old-area-fence) 0)

See System parameters and switches in gc.html for information on the `:open-old-area-fence` gsgc parameter.

There are other ways a global gc can automatically occur. See gc.html, particularly section Global garbage collection, for more information on global GCs and for general information on garbage collection.

# username-to-home-directory

Function, excl package

Arguments: name

On UNIX, name must be a string. This function returns a pathname with the directory component holding the named user's home directory. Returns `nil` if name is not recognized by the system.

On Windows, which does not support finding the home directory of any user except the current user, the name is ignored. This function essentially calls user-homedir-pathname regardless of the value of the name argument. The behavior of that function on Windows is discussed in What user-homedir-pathname does on Windows in implementation.html.

See os-interface.html for general information on the interface to the operating system.

# ut-to-string-formatter

Function, excl package

Arguments: string

This function is in the `:anydate` module, which is autoloaded, if necessary, when this function is called.

This function converts string, containing text and directives, into a function suitable as the value of the format argument to universal-time-to-string when the relative keyword argument to that function is a universal time. The function, which converts relative times to strings, is then returned. The function accepts five arguments: a stream (or `t` or `nil`), an integer or ratio indicating seconds, an integer representing minutes, and integer representing hours, and an integer representing days.

The returned function is an interpreted function object. We recommend you compile it (assuming the compiler is available) as in the following example:

    (setq f (compile nil (ut-to-string-formatter "%Dd%2Hh%2Mm%2Ss")))

    ;; Now F can be used as the value of the FORMAT argument:
    (universal-time-to-string ut :relative (+ ut (* 40 3666)) :format f)
    ;; See the examples below for the result of this call.

The string can contain any text and also the following directives (case is important, %d is not the same as %D):

- %S - the value of the seconds argument

- %M - the value of the minutes argument

- %H - the value of the hours argument

- %D - the value of the days argument

- %p plural for the most recent value printed

- %% - the % character (so % can appear in the string)

A "2" can optionally follow the % and preceed the single-letter directive. For example, strings and possible output:

    "%H:%M:%S"      "2:1:1"
    "%2H:%2M:%2S"       "02:01:01"
    "%D day%p, %H hour%p, %M minute%p and %S second%p"
                        "1 day, 2 hours, 59 minutes and 10 seconds"
    "%Dd%2Hh%2Mm%2Ss"   "15d17h48m20"

See universal-time-to-string, string-to-universal-time, and the General date to universal time parsers section of date-time.html for more information. The date-time.html document also describes the date-time module which provides additional ISO-8601 support.

Examples

    ;; When RELATIVE is a universal time, FORMAT can be unspecified and
    ;; a suitable formatting function will be used (and so a call to
    ;; UT-TO-STRING-FORMATTER is not necessary:
    (setq ut 3603660634)
    (universal-time-to-string ut :relative (+ ut 1 (* 10 3600)))
      => "10:00:01"

    ;; Compiling the function returned by UT-TO-STRING-FORMATTER improves
    ;; efficiency but is not required.
    (setq f (compile nil (ut-to-string-formatter "%Dd%2Hh%2Mm%2Ss")))
    (universal-time-to-string ut :relative (+ ut (* 40 3666)) :format f)
      => "1d16h44m00"

    ;; The string argument to UT-TO-STRING-FORMATTER can be passed as the
    ;; format argument to UNIVERSAL-TIME-TO-STRING with the same result:
    (universal-time-to-string ut :relative (+ ut (* 40 3666))
                              :format "%Dd%2Hh%2Mm%2Ss")
      => "1d16h44m00"

    (setq f (compile nil (ut-to-string-formatter
                      "%D day%p, %H hour%p, %M minute%p and %S second%p")))
    (universal-time-to-string 3603660634
                  :relative (+ 3603660634 (* 41 3666))
                  :format f)
      => "1 day, 17 hours, 45 minutes and 6 seconds"

# utf-8s-transcoding-error-char

Function, excl package

Arguments: &optional char-or-code

Release 10.1 and later only. This function queries or modifies the character used to replace invalid characters or character sequences when the `:utf-8s` external format encounters a transcoding error, i.e. on input a Unicode character or character sequence that does not have a corresponding UTF-8 encoding or on output an invalid sequence of octets is detected (every valid utf-8 code sequence has a Unicode equivalent).

If the argument is omitted or `nil`, return the current error character, i.e. the character that is inserted in the input or output stream instead of the invalid source.

If the argument is a character with a code in the single octet range, set the error character to the argument and return the same value.

If the argument is an integer that denotes a valid single-octet Unicode character, set the error character to that character and return it.

Otherwise signal a type error.

See Strict external formats which do not allow improper characters in iacl.html for more information on the `:utf-8s` external format, international characters and external formats in general.

# validate-lisp-source

Arguments: function &key reachable (ordering t) (edges t) trace

The validate-lisp-source function was significantly and incompatibly changed in version 11.0 compared to versions 10.0 and 10.1. If you are using a pre-11.0 version be sure to consult the older documentation available on the Franz Inc website franz.com.

Source-level debug info is propagated from the source all the way through the compilation of a function, and depending on the compexity of the function this information can become garbled along the way, due to reorderings, optimizations, implementation strategies, or simply high function complexity.

This function returns the number of problems seen after analyzing the source-level-debug info for function. If trace is given and true, progress will be printed verbosely whenever searching for a path from one program counter in the function to another. Program counters are always relative to the start of the function, beginning with 0. Function can be a function or closure object, or it can be any fboundp function spec. When source forms are printed, concise-printing is used.

The current validation styles available currently are reachable, ordering, and edges. Note that ordering and edges default to true, and reachable defaults to `nil`. It is much more likely that a function will have problems with reachablity than with ordering or edge inconsistencies, so a quick test for gross errors would be something like

     (validate-lisp-source 'foo)

If you want to validate only reachable problems, use

     (validate-lisp-source 'foo :reachable t :ordering nil)

and if you want all validations, use

     (validate-lisp-source 'foo :reachable t)

validate-lisp-source is highly compute-intensive. You can demonstrate this by calling with the trace keyword argument non-`nil`.

Source record validation concepts

A Lisp source record is identified by its index, and it contains a number of fields which are important to validation and which can be seen by using print-function-meta-info:

- The next and branch fields: labelled "nxt" and "br", respectively, in the print-function-meta-info output, these fields specify one or more indexes each indicating where execution might continue from here.

- The previous field: labelled "prev" in the print-function-meta-info output, this field specifies one or more indexes each indicating from whence execution might have come.

- The parent/child fields: Like the next and branch fields, the parent ("par") and child ("chld") fields are each an index, indicating a macroexpansion relationship. The child field indicates that this record is a macro form: the child field indexes the record which represents the form this form expanded to (each expansion is a single macroexpansion, as with macroexpand-1 or excl::compiler-macroexpand-1). The parent field indexes the parent, and each pair always reference each other. If the child record is also a macro form, it will also have a child record which indexes a third record, which will in turn point back to it via the parent field.

- The pc, next-pc, and branch-pc fields: Labelled "pc", "nxt", and "br" in the second half of each record in print-function-meta-info output, these values are actual relative program-counter values. A record has only one pc field, and may have 0 or more next-pc and branch-pc fields, depending on the branch-type.

- The entry-type field: this field describes in a keyword what kind of record this is. `nil` in this field means that there is no special consideration for this record. A non-exhaustive list of entry-types is:

  - `:ref` - A variable is being referenced.

  - `:call` - A call to a function is about to occur; arguments have already been placed.

  - `:early` - A call to a function is being considered, but arguments have not yet been placed.

  - `:clone` - assembler code has split off into two or more branches in implementing this form, and this record is a copy of a previous record.

  - `:init` - This record represents the storing of an initialization form into a variable being bound by a let form.

  - `:setq` - A variable is about to be setq'd.

- The branch-type field: this field describes what the branching characteristics are of this record. If the field is nil, then no branching occurs; the record only contains one next or branch field, and thus only one next-pc or branch-pc field. A non-exhaustive list of branch-types is:

  - `:bcc` - Branch on Condition Code: A decision will be made whether to branch or not. A next and branch field will always be present.

  - `:jmp` - branch unconditionally: Usually the branch/branch-pc fields will point to the target record/pc, and there will be no next/next-pc fields.

  - `:call` - A call to a function. The function is determined by what is in the function name register, and a decision about whether to break at the beginning of that function is determined by the step type. The next fields will be filled in with the next record after the call, unless it is a tail-call.

  - `:ret` - This record is a return record; there are no next or branch fields.

  - `:case` - This record represents a table-calculated jump, which may have next fields but always has multiple branch fields.

  - `:noreturn` - This record represents dead code, which will not be returned to (e.g. by a tail call).

The current validations are:

- `:ordering`: This validation ensures that the pc, next-pc, and branch-pc fields are consistent with the record and its next and branch fields. Inconsistencies might result in the sudden loss of stopping while single-stepping, as the stepper sets only breakpoints where the code is likely to hit, moving forward from the currently-stopped record. For example, if Record 3 has pc=27, and it has a next record index of 4 but record 4 has a pc of 25, then record 3 will also have a next-pc of 25, and stepping from record 3 to record 4 will not stop when desired because the breakpoint has been set "behind" the current breakpoint. Some error messages that might be seen:

  - "pc is missing." This occurs when the compiler has not properly propagated the source record all the way to the in-core assembler, which should then assign a program counter to the record.

  - "bcc: one of next-pc (~d) or branch-pc (~d) is missing." This occurs sometimes in high optimization and complex code situations, where perhaps both branches to a decision point go to the same place

  - "no next or branch pc" Unless this is dead code, the record should always have at least one next-pc or branch-pc

  - "next-pc (~d) doesn't follow pc (~d)" The next-pc field of this record represents a point "earlier" in the program execution order. The next-pc might not be actually larger in value than the current pc, but as long as the next-pc can be reached by jumping and/or branching starting at this pc, this error will not be flagged.

- `:edges`: This validation ensures that the `next` and `branch` fields are consistent with the `prev` and `parent` fields of two records If one record points to another in its `next` or `branch` field, that pointed-to record should then point directly to the first via its `prev` field, or indirectly via it `parent` field. As implied by the description of the parent/child relationship above, the `parent` field represents a reversal of the macroexpansion of a macro form, and there may be any number of these levels.

- `:reachable`: This validation ensures that a reverse mapping from pc to record number finds a record whose source actually correponds to the instruction at that pc. Failure for a pc to be reachable by the source record which caused it will sometimes result in a breakpoint being set in an unexpected location.

Consider the following scenario with a function #'bas on some imaginary architecture:

    Record: 23 ... next: 24  ... pc: 120  next-pc: 95 form: (foo x)
    Record: 24 ... next: 25  ... pc: 95 ...           form: (bar (foo x))

Record 23 has been placed after record 24, so it has a higher pc value.

If we intersperse source and assembler records (a truncated version of what (print-function-meta-info 'bas :mixed t) would print), then we might have something like this:

    Record 24: pc: 95  ... form: (bar (foo x))
       95: call bar
       98: ...

    Record 10: pc: 112 ... form: (/ z 0)
       112: load r1, z-in-memory
       117: jmp 128
    Record 23: pc: 120  ...  form: (foo x)
       120: call foo
       125: jmp 95
       128: div 0
       133: ...
    Record 40...

If for some reason (such as a divide by 0) an error occurs at the instruction at 128, then the :zoom command would look at the pc at 128 and (incorrectly) associated it with record 23, instead of associating it with record 10 as it should. This is because the segment of code between 128 and 133 is not assocated with the source record it should be, and thus the instructions ar 128 and 133 are "not reachable" by record 23. Note the jump at 125 which is a good indicator of such a problem - a jump instruction without a source record immediately following will always result in a reachable failure.

The message in the example situation above will be

    Record 23 at pc: 120: (foo x)
      pc 133 doesn't follow record.

Version 10.0 and 10.1 behavior. See above for version 11.0 and later behavior.

Function, excl package

Arguments: function &optional reachable (ordering t) trace

Source-level debug info is propagated from the source all the way through the compilation of a function, and depending on the compexity of the function this information can become garbled along the way, due to reorderings, optimizations, implementation strategies, or simply high function complexity.

This function returns the number of problems seen after analyzing the source-level-debug info for function. If trace is given and true, progress will be printed verbosely whenever searching for a path from one program counter in function to another. Program counters are always relative to the start of function, beginning with 0. Function can be a function or closure object, or it can be any fboundp function spec. When source forms are printed, concise-printing is used.

The validation styles available currently are reachable and ordering. Note that ordering defaults to true, and reachable defaults to `nil`. It is much more likely that a function will have problems with reachablity than with ordering, so a quick test for gross errors would be something like

     (validate-lisp-source 'foo)

If you want to validate only reachable problems, use

     (validate-lisp-source 'foo t nil)

and if you want all validations, use

     (validate-lisp-source 'foo t)

validate-lisp-source is highly compute-intensive. You can demonstrate this by calling with the trace argument non-`nil`.

Source record validation concepts

A Lisp source record is identified by its index, and it contains a number of fields which are important to validation and which can be seen by using print-function-meta-info:

- The next and branch fields: labelled "nxt" and "br", respectively, in the print-function-meta-info output, these fields specify one or more indexes each indicating where execution might continue from here.

- The parent/child fields: Like the next and branch fields, the parent ("par") and child ("chld") fields are each an index, indicating a macroexpansion relationship. The child field indicates that this record is a macro form: the child field indexes the record which represents the form this form expanded to (each expansion is a single macroexpansion, as with macroexpand-1 or excl::compiler-macroexpand-1). The parent field indexes the parent, and each pair always reference each other. If the child record is also a macro form, it will also have a child record which indexes a third record, which will in turn point back to it via the parent field.

- The pc, next-pc, and branch-pc fields: Labelled "pc", "nxt", and "br" in the second half of each record in print-function-meta-info output, these values are actual relative program-counter values. A record has only one pc field, and may have 0 or more next-pc and branch-pc fields, depending on the branch-type.

- The entry-type field: this field describes in a keyword what kind of record this is. `nil` in this field means that there is no special consideration for this record. A non-exhaustive list of entry-types is:

  - `:ref` - A variable is being referenced.

  - `:call` - A call to a function is about to occur; arguments have already been placed.

  - `:early` - A call to a function is being considered, but arguments have not yet been placed.

  - `:clone` - assembler code has split off into two or more branches in implementing this form, and this record is a copy of a previous record.

  - `:init` - This record represents the storing of an initialization form into a variable being bound by a let form.

  - `:setq` - A variable is about to be setq'd.

- The branch-type field: this field describes what the branching characteristics are of this record. If the field is nil, then no branching occurs; the record only contains one next or branch field, and thus only one next-pc or branch-pc field. A non-exhaustive list of branch-types is:

  - `:bcc` - Branch on Condition Code: A decision will be made whether to branch or not. A next and branch field will always be present.

  - `:jmp` - branch unconditionally: Usually the branch/branch-pc fields will point to the target record/pc, and there will be no next/next-pc fields.

  - `:call` - A call to a function. The function is determined by what is in the function name register, and a decision about whether to break at the beginning of that function is determined by the step type. The next fields will be filled in with the next record after the call, unless it is a tail-call.

  - `:ret` - This record is a return record; there are no next or branch fields.

  - `:case` - This record represents a table-calculated jump, which may have next fields but always has multiple branch fields.

  - `:noreturn` - This record represents dead code, which will not be returned to (e.g. by a tail call).

The current validations are:

- `:ordering`: This validation ensures that the pc, next-pc, and branch-pc fields are consistent with the record and its next and branch fields. Inconsistencies might result in the sudden loss of stopping while single-stepping, as the stepper sets only breakpoints where the code is likely to hit, moving forward fromthe currently-stopped record. For example, if Record 3 has pc=27, and it has a next record index of 4 but record 4 has a pc of 25, then record 3 will also have a next-pc of 25, and stepping from record 3 to record 4 will not stop when desired because the breakpoint has been set "behind" the current breakpoint. Some error messages that might be seen:

  - "pc is missing." This occurs when the compiler has not properly propagated the source record all the way 1to the in-core assembler, which should then assign a program counter to the record.

  - "bcc: one of next-pc (~d) or branch-pc (~d) is missing." This occurs sometimes in high optimization and complex code situations, where perhaps both branches to a decision point go to the same place

  - "no next or branch pc" Unless this is dead code, the record should always have at least one next-pc or branch-pc

  - "next-pc (~d) doesn't follow pc (~d)" The next-pc field of this record represents a point "earlier" in the program execution order. The next-pc might not be actually larger in value than the current pc, but as long as the next-pc can be reached by jumping and/or branching starting at this pc, this error will not be flagged.

- `:reachable`: This validation ensures that a reverse mapping from pc to record number finds a record whose source actually correponds to the instruction at that pc. Failure for a pc to be reachable by the source record which caused it will sometimes result in a breakpoint being set in an unexpected location.

Condsider the following scenario with a function #'bas on some imaginary architecture:

    Record: 23 ... next: 24  ... pc: 120  next-pc: 95 form: (foo x)
    Record: 24 ... next: 25  ... pc: 95 ...           form: (bar (foo x))

Record 23 has been placed after record 24, so it has a higher pc value.

If we intersperse source and assembler records (a truncated version of what (print-function-meta-info 'bas :mixed t) would print), then we might have something like this:

    Record 24: pc: 95  ... form: (bar (foo x))
       95: call bar
       98: ...

    Record 10: pc: 112 ... form: (/ z 0)
       112: load r1, z-in-memory
       117: jmp 128
    Record 23: pc: 120  ...  form: (foo x)
       120: call foo
       125: jmp 95
       128: div 0
       133: ...
    Record 40...

If for some reason (such as a divide by 0) an error occurs at the instruction at 128, then the :zoom command would look at the pc at 128 and (incorrectly) associated it with record 23, instead of associating it with record 10 as it should. This is because the segment of code between 128 and 133 is not assocated with the source record it should be, and thus the instructions ar 128 and 133 are "not reachable" by record 23. Note the jump at 125 which is a good indicator of such a problem - a jump instruction without a source record immediately following will always result in a reachable failure.

The message in the example situation above will be

    Record 23 at pc: 120: (foo x)
      pc 133 doesn't follow record.

# weak-vector

Function, excl package

Arguments: n

Returns a weak vector of n elements. The vector will be similar to a simple general vector in that the value of each slot can be any Lisp object and it cannot have a fill-pointer. The fact that a slot in a weak vector contains an object does not protect that object from being identified as garbage and scavenged (or global-gc'ed) away. (In contrast, if an object was the value of a slot of an ordinary vector which was not itself garbage, the object could not be garbage.) If the object is disposed of by the garbage collector, the value of the slot in any weak vectors pointing to it is changed to `nil`.

In addition to weak-vector, make-array takes a :weak keyword argument, which defaults to `nil`. If specified `t`, a weak vector of the specified type is returned. It is an error to specify both :weak and :displaced-to.

As with a normal vector, the values of slots can be accessed with aref and set with setf used in conjunction with aref.

See gc.html for general information on garbage collection and Weak vectors, finalizations, static arrays, etc. in that document for more on weak vectors.

# week-number

Function, excl package

Arguments: ut &key (first-day-of-week :monday)

Release 10.1 and later only. The value returned by week-number and related functions depends on the time zone where the machine running Lisp is located and also on whether daylight saving time is in effect. See the discussion in Day and date calculation functions and their relation to time zones in miscellaneous.html for examples of how time zone and daylight saving time can affect results.

This function performs calculations on the day/date portion of a universal time, that is the decoded universal time ignoring the second, minute, and hour values (see decode-universal-time).

This function returns the week number of the universal time ut, which must be a non-negative integer and is interpreted as a universal time (see get-universal-time). The week number is defined in detail below but in short, the first full (7-day) week in the year is week 1. The partial week prior to week 1 is week 0. (If January 1 falls on the first-day-of-week, then there is no week 0.) Weeks are numbered sequentially after week 1. The return value is an integer in the range 0 to 53.

The first-day-of-week keyword argument allows you to specify `:monday` (the default) or `:sunday` as the week's start. `:sunday` and `:modnday` are the only allowable values for this argument.

The week number is calculated as follows: if January 1 falls on the first-day-of-week day, week there is no week 0 and week number 1 is January 1 through January 7, week number 2 is January 8 through January 14, and so on, with the last complete seven day week being week 52, December 24 through December 30 (in a non-leap year), December 23 through December 29 in a leap year, and week 53 is the one day week, December 31 only, in a non-leap year, and the two day week December 30 and 31 in a leap year.

If January 1 is not the first-day-of-week day, then there is a week 0 and it contains less than seven days, from January 1 through the day before the first-day-of-week day, the next seven days are week 1, and so on until the end of the year where, in a non-leap year, week 52 contains December 31 and seven less than the number of days from January 1 to the first-day-of-week day other days (so seven days if January 1 is the day before the first day of the week, six days if Janyaury 1 is two days before the first day of the week, and so on).

In a leap year, week 52 contain one day more unless January 1 is the day before the first-day-of-week day, in which case week 52 contains seven days and week 53 contains only December 31.

Leap years having 54 numbered weeks (0 through 53) are a bit confusing so here is an example. Consider the year 2012 (a leap year) and suppose the first-day-of-week day is the default, `:monday`. January 1, 2012 is a Sunday and December 31, 2012, is a Monday. Week 0 contains January 1 only. Weeks 1 through 52 all contain 7 days, with week 52 ending on Sunday, December 30 (which is day 365, 364 days after January 1, since 2016 is a leap year). Week 53 contains the single day, Monday, December 31.

    ;; Results depend on the timezone value and whether daylight saving
    ;; time is in effect. These are not settable by this function and
    ;; the values are inherited from the Operating system. To see them,
    ;; evaluate (decode-universal-time (get-universal-time)):

    cl-user(29): (decode-universal-time (get-universal-time))
    RETURNS 11 38 14 5 12 2017 1 nil 8

    ;; That form was evaluated at 2:38:11 PM (14:38:11) on Tuesday,
    ;; December 5 at Franz Inc. HQ in Oakland, California. The eighth
    ;; return value (nil) indicates daylight saving time was not in effect.
    ;; The ninth return value (8) means the timezone was 8, 8 hours
    ;; earlier than Greenwich Mean Time (GMT). If you are in a different
    ;; location or the date is different, you will get different values.

    ;; January 1, 2012 was a Sunday. January 5 the following Thursday, and
    ;; January 30 a Monday. Here are the universal times for noon on those
    ;; days:
    cl-user(46): (setq ut010112 (encode-universal-time 0 0 12 1 1 2012))
    3534436800
    cl-user(47): (setq ut050112 (encode-universal-time 0 0 12 5 1 2012))
    3534782400
    cl-user(48): (setq ut300112 (encode-universal-time 0 0 12 30 1 2012))
    3536942400
    cl-user(49):

    (week-number ut010112) RETURNS 0 ;; When January 1 is not the first day
                                     ;; of the week, there is a week 0
                                     ;; and it has fewer that 7 days
    (week-number ut050112) RETURNS 1 ;; The default first-day-of-week is
                                     ;; :monday so Thursday, January 5
                                     ;; is in week 1
    (week-number ut050112 :first-day-of-week :sunday) RETURNS 1
                                     ;; Sunday, January 1 falls on the
                                     ;; first day of the week so there
                                     ;; is no week 0 and week 1 is
                                     ;; January 1 through January 7,
                                     ;; which includes January 5

See Day and date calculation functions and their relation to time zones in miscellaneous.html for more information on this and related functions.

# while

macro, excl package

Arguments: condition &rest forms

Evaluates forms repeatedly until condition (which should be a Lisp form) evaluates to `nil`.

The definition of while is

    (defmacro while (condition &rest forms)
      `(loop (unless ,condition (return)) ,@forms))

Note that loop surrounds its body with a block named `nil` (as used by the return form which is the consequent of the unless. This macro returns `nil`.

See also until.

# winapi-error-code

Generic Function, excl package

Arguments: winapi-error

This generic function is the accessor to the `code` slot of the condition winapi-error.

# with-at-most-one-form

Function, excl package

Arguments: (&key if-null-body) &body body

Release 10.1 and later only. The purpose of this macro is to ensure that one and only one of a set of conditionalized forms results from the evaluation of body. So in an example below, we conditionalize for Linux and Windows. If later we start running on a Mac, the with-at-most-one-form will error because we forgot to add a mac-conditionalized form.

When a with-at-most-one-form is macroexpanded, the result is either:

- The single form that body is read and returned by the Lisp reader.

- The value of the if-null-body argument if that argument is specified and no forms are returned for the body by the Lisp reader.

- An error being signaled (meaning with body consisted of more than one form or body was empty and if-null-body is not given a value).

Examples

    ;; This would signal an error at macroexpand time if run on a
    ;; non-Linux or non-Windows version of Allegro CL:
    (with-at-most-one-form ()
      #+linux (do-linux-stuff)
      #+mswindows (do-windows-stuff))

    ;; The result of this form would be 10 on Windows and 11 elsewhere:
    (with-at-most-one-form (:if-null-body 11)
      #+mswindows 10)

    ;; This call will always error (at macroexpand time) as body has
    ;; two forms:
    (with-at-most-one-form ()
      (setq author "Bill")
      (setq editor "Helen"))
    -> ERROR

# with-breakpoints-installed

This macro has been renamed with-ldb-stepping-enabled. Only the name has changed (the new name more clearly describes its function). Please use the new name though the old name (with-breakpoints-installed) still names the macro.

# with-coverage

Arguments: (&key (limit 0) verbose functions) &body body

Executes body and returns the result. As a side-effect, the functions specified by the functions list (either as function objects or as function specs) are instrumented with breakpoints that will determine how well those functions are being exercised in the body form. When the body form is finished, statitics are printed on how good the coverage is.

verbose defaults to `nil` and when t presents explanations for the instrumentation phase of the coverage macro execution.

limit (which defaults to 1) determines the level of records which will be included in the instrumentation. It may be any positive integer or T (which means all records allowed).

Certain additional tools must be activated. The compiler switch save-source-level-debug-info-switch must be true during compilation (which is the default happens when the debug optimization quality is 3). Further source file recording must be on, that is *record-source-file-info* and *load-source-file-info* must both be true (if source file info is recorded but not loaded, you will be prompted for the name of the relevant fasl file).

Example script

    (with-open-file (ff "cov-test.cl"
             :direction :output
             :if-exists :supersede)
      (setq *load-source-file-info* t *record-source-file-info* t)
      (write-string "

    (eval-when (load compile eval) (require :coverage))

    (eval-when (compile) (declaim (optimize (debug 3))))

    (defun foo ()
      (let ((x (random 3)))
        (cond ((zerop x) (write-string \"yes \"))
              (t (bar \"no \")))))

    (defun bar (x)
      (if (string= x \"yes \")
          (progn (write-string x) (write-string \"!\"))
        (write-string x)))
    " ff))

    (compile-file "cov-test.cl")
    (load "cov-test.fasl")

    (excl::with-coverage (:functions foo bar)
      (funcall 'foo)
      (funcall 'foo))

    ;; The last form produces the following output (what you see
    ;; if you try this may differ in detail):

    ;; Found 9 applicable records for #<Function foo>:
      pc 0: (defun foo ()
              (let ((x (random 3)))
                (cond ((zerop x) (write-string yes )) (t (bar no )))))
      pc 31: (let ((x (random 3)))
               (cond ((zerop x) (write-string yes )) (t (bar no ))))
      pc 31: (random 3)
      (duplicate)
      pc 56: ((x (random 3)) x nil)
      pc 56: (cond ((zerop x) (write-string yes )) (t (bar no )))
      (duplicate)
      pc 56: (zerop x)
      (duplicate)
      pc 65: (write-string yes )
      pc 108: (bar no )
      pc 84: (defun foo ()
               (let ((x (random 3)))
                 (cond ((zerop x) (write-string yes )) (t (bar no )))))
    ;; Found 6 applicable records for #<Function bar>:
      pc 0: (defun bar (x)
              (if (string= x yes )
                  (progn (write-string x) (write-string !))
                (write-string x)))
      pc 37: (string= x yes )
      pc 53: (progn (write-string x) (write-string !))
      pc 53: (write-string x)
      (duplicate)
      pc 64: (write-string !)
      pc 88: (write-string x)
    ;; Starting executing of ((funcall 'foo) (funcall 'foo))
    no no
    ;; Finished executing.

    Coverage report for #<Function foo>:
        Not hit: (write-string "yes ")
      subtotal = 88%  (8 of 9 breakpoints hit).

    Coverage report for #<Function bar>:
        Not hit: (write-string "!")
        Not hit: (write-string x)
        Not hit: (progn (write-string x) (write-string "!"))
      subtotal = 50%  (3 of 6 breakpoints hit).
    Total coverage = 73%  (11 of 15 breakpoints hit).
    "no "
    cl-user(6):

See Coverage analysis in Allegro CL in miscellaneous.html.

# with-current-source-form

Arguments: (form &rest forms) &body body

Executes body and returns the result values. Allows the user to specify that a form or forms is/are being examined by the compiler while compiling the body. At least one form is required, but if more than one form is seen, they should be ordered in expanding order, with the first form specified being the innermost form. The compiler will, if it can, assign character positions to the form(s) it sees and they will be included in the compiler backtrace that is lodged with conditions that contain source-context. See the example of this macro in action.

# with-delayed-interrupts

macro, excl package

Arguments: &body body

with-delayed-interrupts is the replacement for without-interrupts. (Note that without-interrupts continues to be supported.) It evaluates and compiles exactly as without-interrupts did. In an SMP lisp it provides no cross-process protection of shared objects. Its entire purpose in that environment is to protect blocks of code that need to run to completion even in the face of timeouts and possible process-interrupt calls from other processes. body will complete before the executing process handles any signals accumulated by the low-level asynchronous signal handler and before responding to process-interrupt requests.

See the code example in the description of fast-and-clean.

Any requests for Lisp interrupts or gc are honored only when the outermost dynamic invocation of this form is exited. (In an SMP Lisp, they are honored immediately when exiting. In a non-SMP Lisp, it is at the next safe point in the computation.)

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# with-function-input-stream

Macro, excl package

Arguments: (sym function &rest args) &body body

with-function-input-stream evalutes body as an implicit progn with sym bound to the stream returned by make-function-input-stream.
When control leaves the body, either normally or abnormally (such as by the use of throw), the stream is automatically closed.

See make-function-input-stream for details.

#### Example 1

    (defun filler (writeto count)
      (dotimes (n count)
         (write-byte n writeto))
      (close writeto))

    (with-function-input-stream (readfrom #'filler 5)
      (let ((count 0)
            (sum 0)
            got)
        (while (setf got (read-byte readfrom nil nil))
           (incf sum got)
           (incf count))
        (format t "Read ~d bytes, totalling ~a~%" count sum)))

#### Example 2

    (defun head-filter (outstream instream &key (lines 10))
      (dotimes (n lines)
        (let ((line (read-line instream nil nil)))
          (if (null line)
          (return))
          (write-line line outstream))))

    (defun tail-filter (outstream instream &key (lines 10))
      (let ((buffer (make-array lines))
        (pos 0)
        (wrapped nil)
        line)
        (while (setf line (read-line instream nil nil))
          (setf (aref buffer pos) line)
          (incf pos)
          (if (= pos lines)
          (progn
            (setf pos 0)
            (setf wrapped t))))

        (if wrapped
        (dotimes (n (- lines pos))
          (write-line (aref buffer (+ n pos)) outstream)))

        (dotimes (n pos)
          (write-line (aref buffer n) outstream))))

    (defun uniq-filter (outstream instream)
      (let (lastline
        line)
        (while (setf line (read-line instream nil nil))
          (if (or (not lastline) (string/= line lastline))
          (progn
            (write-line line outstream)
            (setf lastline line))))))

    ;; uniq the last 5 of the first 10 lines of the sourcefile.
    (defun test-filters (sourcefile)
      (with-open-file (f sourcefile)
        (with-function-input-stream (headstream #'head-filter f)
          (with-function-input-stream (tailstream #'tail-filter headstream
                              :lines 5)
        (uniq-filter *terminal-io* tailstream)))))

# with-input-from-buffer

Macro, excl package

Arguments: (var buffer &key index start end external-format) forms

Similar to with-input-from-string but with an octet buffer (a vector that is a simple-array with element type `(unsigned-byte 8)` or `(signed-byte 8)`) instead of a lisp string. The external-format argument should be the name of an external-format, or `:default` will cause it to be looked up in the locale.

See streams.html for information on the simple-streams implementation in Allegro CL.

# with-ldb-stepping-enabled

Macro, excl package

Arguments: &body body

Returns the result of the evaluation of the body form. Prior to evaluation, the breakpoint set is installed, and they are then uninstalled after body completion. Breakpoints are added, for example, with add-breakpoint. See also the top-level command :ldb. Using this macro is equivalent to calling `:ldb t`, evaluating body, and then calling `:ldb nil`.

See The Lisp DeBug (ldb) stepper in debugging.html.

# with-locked-object

macro, excl package

Arguments: (object &key *type block non-smp typecheck) &body body

This macro expands into code that waits until the executing process acquires control of the object, then evaluates the forms in the body as an implicit progn. It then releases control of the object and returns whatever values the last form in the body returned.

The arguments are:

- object: a form that is evaluated once to get the object to be locked. the object must be an instance of lockable-object or of a subclass of lockable-object unless the type argument is included and specifies otherwise. Object can also be a class object (an instance of standard-class). The instances of such classes are not necessarily lockable; the class would need to inherit from lockable-object for the instances to be lockable.

- `:type`: can be one of the following

  - `:clos` (the default): the object form must evaluate to an instance of lockable-object or of a subclass of lockable-object.

  - `:struct`: the object form must evaluate to an instance of synchronizing-structure or of a subtype of synchronizing-structure.

- `:block`: used for special internal functions. Users should not specify this.

- `:non-smp`: what code to generate in a non-smp lisp. Legal values are:

  - `:without-scheduling` to get the equivalent of `(without-scheduling . body)`

  - `:without-interrupts` to get the equivalent of `(with-delayed-interrupts . body)`

  - `:atomically` (only valid when the type argument is `:struct`) to get the equivalent of `(fast-and-clean . body)`

  - [omitted]: to get object-locking code like SMP. This may be inefficient or even problematic in a non-smp Lisp, and is not allowed in the 8.1 patch.

- `:typecheck`: if specified as `nil`, the generated code does not include an explicit typecheck of the object. If specified as non-`nil` the generated code checks that the object is of the appropriate type. If typecheck is ommitted, the type check code is generated unless the type argument is `:clos` (explicitly or by default)

It is not an error for a process that already owns an object to try to lock it again. When this happens, the object is not released until the outermost lock form is exited.

The release of the object is performed in an unwind-protect cleanup form, so non-local exits from body are allowed.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# with-locked-stream

macro, excl package

Arguments: (stream &key type block non-smp typecheck) &body body

This macro is like with-locked-object (see the description of with-locked-object for details of the keyword arguments), but applies to objects that are streams. For technical and efficiency reasons, these are handled specially.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# with-locked-structure

macro, excl package

Arguments: (struct &key block non-smp typecheck timeout) &body body

This macro expands into code that waits until the executing process acquires control of the structure object, then evaluates the forms in the body as an implicit progn. It then releases control of the object and returns whatever values the last form in the body returned.

The arguments are:

- struct: a form that is evaluated once to get the object to be locked. The object must be an instance of synchronizing-structure or of a subtype of synchronizing-structure.

- `:block`: used for special internal functions. Users should not specify this.

- `:non-smp`: what code to generate in a non-smp lisp. Legal values are:

  - :without-scheduling to get the equivalent of `(mp:without-scheduling . body)`

  - :without-interrupts to get the equivalent of `(excl:without-interrupts . body)`

  - :atomically to get the equivalent of `(excl:atomically . body)`

  - (omitted) to get object-locking code like smp. This may be inefficient or even problematic in a non-smp lisp.

- `:typecheck`: if specified as `nil`, the generated code does not include an explicit typecheck of the structure object. Otherwise, (whether omitted or specified non-`nil`) the generated code checks that struct is a synchronizing structure before trying to lock it.

- `:timeout`: If specified, the value must be `nil` or a real number. If `nil` (or unspecified), the body will be evaluated if and when the lock is acquired. A value greater than 0 specifies a timeout of that many seconds; when the timeout occurs before the lock is acquired, the body is not evaluated and the entire form evaluates to `nil`. A value less than or equal to 0 specifies an immediate timeout; the body is evaluated only if the lock can be acquired with no delay. If the body itself return `nil`, one cannot then tell from the return value whether the body executed or not. See mp:with-process-lock for an example where timing out causes additional code to run which can make clear whether the body did or did not execute.

It is not an error for a process that already owns an object to try to lock it again. When this happens, the object is not released at the end of the body code.

The release of the object is performed in an unwind-protect cleanup form, so non-local exits from body are allowed.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# with-named-readtable

Macro, excl package

Arguments: (name) &body body

Binds `cl:*readtable*` to the readtable named by name around the execution of body. See named-readtable.

# with-native-string

Macro, excl package

Arguments: (string-var string-exp &key (start 0) end native-length-var (external-format :default) &body body

This macro provides an efficient, portable, and non-garbage (from the lisp garbage collector's point of view) way of converting lisp-strings to addresses acceptable for foreign functions expecting native string arguments.

The string-exp argument can specify an expression returning a lisp string. If either start or end is specified, the substring bounded by the start and end arguments is used.

The string-exp argument may also specify an expression returning a lisp vector of octet integers. In this case, no external-format conversion occurs, but the subsequence bounded by the start and end arguments is copied into a dynamic-extent array and bound by string-var as described below.

If string-exp is a string, then conversion is done using the specified external-format. If external-format is not specified (or, equivalently, if the value of external-format is `:default`, then the external format returned by the following form is used:

    (locale-external-format *locale*)

See locale-external-format and *locale*.

The forms of body are evaluated (an implicit progn) with the variable string-var bound to the address of the null-terminated converted string. If a variable is specified with native-length-var, that variable will be bound to the length in 8-bit bytes of the converted string. The native-length-var variable's value does not include the null-terminator byte(s). The ef-nulls function can be used to determine how many null terminator bytes are being used.

Note that the data assigned to string-var is considered to have dynamic-extent. This means that the value of string-var is not considered valid outside of the forms specified in body.

Note: For non-constant strings named by string-exp, this macro internally uses static (non-lisp heap) memory to hold the conversion buffer while the forms in body are being evaluated. Thus, this macro is a convenient way of ensuring string data passed to foreign functions will not be asynchronously moved by lisp's garbage collector. For optimization reasons, however, static storage is not necessarily used when string-exp names a literal string.

To force non-garbage-collected static storage to be used with constant strings by this macro, use a non-constant string expression. Example:

    (let ((my-string "My String"))
      (with-native-string (my-converted-string my-string)
        ...))

The macro with-native-strings* allows allows nesting of with-native-string calls.

See also iacl.html for general information on international character set support in Allegro CL and see string-to-native, native-to-string, and foreign-functions.html for information on foreign functions.

# with-native-strings*

Macro, excl package

Arguments: ((string-var1 string-exp1 &key (start 0) end native-length-var (external-format :default) (string-var1 string-exp1 &key (start 0) end native-length-var (external-format :default)) ... (string-varN string-expN &key (*start 0) end native-length-var (external-format :default))) &body body

This macro expands into a series of nested calls to with-native-string.

Example

    (with-native-strings* ((a "foo") (b "bar")) (baz a b))

expands to

    (with-native-string (a "foo")
     (with-native-string (b "bar")
      (baz a b)))

See also iacl.html for general information on international character set support in Allegro CL.

# with-object-lock-released

macro, excl package

Arguments: (object) &body body

This macro can only appear lexically inside the body of a with-locked-object macro. The locked object must be specified as the object argument. The lock obtained in the immediately enclosing with-locked-object macro is released, body is executed, and then the lock is reobtained. When the enclosing with-locked-object macro specifies a non-smp value, the with-object-lock-released cooperates to manipulate the corresponding state. This macro isn't allowed in a non-smp lisp if the enclosing lock form designates `:atomically` as the non-smp strategy. with-object-lock-released is rarely used, and is never actually needed; there are alternate ways of achieving the same thing that are usually clearer.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# with-output-to-buffer

Macro, excl package

Arguments: (var &optional buffer &key external-format) forms

Similar to with-output-to-string but with an octet buffer (a vector that is a simple-array with element type `(unsigned-byte 8)` or `(signed-byte 8)`) instead of a Lisp string. The external-format argument should be the name of an external-format, or `:default`. `:default` will cause the external format to be looked up in the locale. with-output-to-buffer is implemented using a buffer-output-simple-stream.

The return value depends on the value of the buffer argument. Return values are described below.

The buffer argument can either be an octet buffer (described above), or `nil`, or unsupplied (unsupplied is not the same as `nil`), or `:growable` (equivalent to unsupplied). If an octet buffer is supplied, an error will be signaled if the buffer overflows. The `:growable` value is necessary because some value must be supplied when a value is given for the external-format keyword argument.

If buffer is unsupplied or `:growable`, a suitable buffer is created and used. That buffer extends automatically as needed and so cannot overflow. The contents are available in the body of this macro using get-output-stream-buffer.

If buffer is `nil`, the stream acts like a counting bit-bucket: no output is generated, and so no overflow can occur, but the file-position of the stream can be queried at the end of the write. This allows the following to be done:

    cl-user(1): (with-output-to-buffer (stm nil)
                  (write-string "hello" stm)
                  (file-position stm))
    5
    cl-user(2):

This macro returns the contents of the created buffer if buffer is unsupplied or `:growable`. If buffer is an octet array or `nil`, this macro returns, as multiple values, all values returned by the last form of the body.

    ;; buffer not supplied
    cl-user(3): (with-output-to-buffer (b)
                  (values (write-string "hello" b) 1 2 3))
    #(104 101 108 108 111)

    ;; buffer eq :growable
    cl-user(5): (with-output-to-buffer (b :growable)
                  (values (write-string "hello" b) 1 2 3))
    #(104 101 108 108 111)

    ;; buffer = nil
    cl-user(4): (with-output-to-buffer (b nil)
                  (values (write-string "hello" b) (file-position b) 'more 'output))
    "hello"
    5
    more
    output

    ;; non-nil buffer supplied
    cl-user(12): (with-output-to-buffer
                    (b (make-array 20 :element-type '(unsigned-byte 8)))
                  (values (write-string "hello" b) 1 2 3))
    "hello"
    1
    2
    3

    ;; non-nil buffer supplied but it is too small,
    ;; so an error is signaled:
    cg-user(13): (with-output-to-buffer
                    (b (make-array 10 :element-type '(unsigned-byte 8)))
                  (values (write-string "hello, how are you today?" b) 1 2 3))
    Error: In sc-write-char-direct: Output exceeds workspace for #<buffer-output-simple-stream  pos 10 @ #x202796082>
    [condition type: simple-error]
    cg-user(14):

The macro with-underlying-simple-vector may be useful in conjunction with this macro as it allows any `(unsigned-byte 8)` or `(signed-byte 8)` array (not just simple one or just vectors) to be effectively used as the buffer.

See streams.html for information on the simple-streams implementation in Allegro CL.

# with-pinned-objects

macro, excl package

Arguments: (forms) &body body

This is the replacement for excl::atomically when it was used to prevent object relocation by a garbage collection. The new macro exists to provide self-documentation of the intended use.

It compiles to code that evaluates as if it were

    (progn form1 form2 ... formn body)

In addition, it interacts with the garbage collector to ensure that the objects obtained by evaluating the forms are not moved by a gc while the forms of body are evaluated. This may place some limits on what forms can appear in body. Currently, body must be appropriate for fast-and-clean, but extensions to the garbage collector are planned to ease this restriction.

See smp.html and multiprocessing.html for more information on this macro and on multiprocessing.

# with-saved-file-positions

Macro, excl package

Arguments: (ident stream) &body body

This macro returns the evaluation of the body form. The ident argument must be a bindable symbol that will name a lexical variable bound by the macro. The stream argument must be an expression that evaluates to the stream of interest. The macro binds the ident variable to an opaque object derived from the stream and the current file positions, if available. Within the body form the ident may be passed as an argument to restore-file-positions, saved-char-file-position, or saved-byte-file-position. Alternatively, the ident may be saved within the body form to another variable that has larger extent, and it may be used anywhere as long as the stream associated with the ident is still open.

See Preserving file positions in miscellaneous.html for more information and for an example of this macro's operation.

# with-signal-handler

Macro, excl package

Arguments: (signo function) &rest body

This macro installs a handler using function for signal number signo for the dynamic extent of the execution of body.

The handling of operating system dependent signals generated during program execution is not part of Common Lisp. A signal is a small integer. The list of valid signals is given in a system dependent file, usually on UNIX something like /usr/include/signals.h. Signals are either synchronous or asynchronous, but there is no distinction made in this interface--the handling of both types of signals is the same. A handler for a signal is a function of two arguments, signal number and t. If there is no handler for a particular signal, then some default action is invoked, which is usually to signal an error. Signals handlers should return a true value if they handle the signal, so that other, nested handlers are not invoked to handle the signal. A signal that is posted during a gc is processed immediately after the gc finishes.

    ;; This macro is defined in terms of the other signal handling
    ;; primitives, with some protection for multiprocessing as well:
    (defmacro with-signal-handler ((signo function) &rest body)
      (let ((cellvar (gensym "cell")))
        `(let ((,cellvar (cons ,signo ,function)))
           (progn
             (push-atomic ,cellvar (globalq *signals*)))
           (unwind-protect
               (progn ,@body)
             (delete-signal-handler ,cellvar)))))

See also add-signal-handler (which has an example), set-signal-handler, *signals*, and remove-signal-handler.

# with-stack-list

Macro, excl package

Arguments: (var &rest elements) &body body

Returns the result of evaluating body as if in a progn. var is bound to a list which may or may not be consed on the stack.

    (excl:with-stack-list (var e1 e2 ... en) ...)

is like

    (let ((var (list e1 e2 ... en))) (declare (dynamic-extent var)) ...)

WARNING: the value of the variable must not be used outside of the dynamic scope of the with-stack-list form, since it may be allocated on the stack and thus would be invalid after with-stack-list returns.

See also with-stack-list*.

# with-stack-list*

Macro, excl package

Arguments: (var &rest elements) &body body

Returns the result of evaluating body as if in a progn. This is just like with-stack-list, except that the list is as if created with list* instead of list. See with-stack-list for more information.

WARNING: the value of the variable must not be used outside of the dynamic scope of the with-stack-list* form, since it may be allocated on the stack and thus would be invalid after with-stack-list* returns.

# with-staged-output

macro, excl package

Arguments: (staging-stream stream) &body body

If output to stream is synchronized (as per synchronized-output-stream-p), then this macro causes staging-stream to be bound to a string output stream whose contents are written atomically to stream upon leaving body (even if by a non-local exit). Atomicity in this context means that stream is locked with with-locked-stream, thus output is safe even in face of concurrent use, provided that all threads use with-staged-output or lock the stream directly.

Currently almost all functions that write streams employ with-staged-output, so that the user only has to `(setf (synchronized-output-stream-p stream) t)` and output to the stream will not be mixed, lost, etc. even if several threads write the stream at the same time.

All of print-unreadable-object, write, write-sequence, write-vector, write-string, write-line, pprint, pprint-fill, pprint-linear, pprint-tabular use with-staged-output. Additionally, format does too except when creating a string (i.e. its first argument is nil).

Notable functions that do not use with-staged-output (because the overhead would be too high): write-char, write-byte, and terpri.

#### Notes:

1. The staging-stream is a single channel output stream (buffer-output-simple-stream or a string-output-simple-stream). If the underlying stream is to be used for input (and output) then with-staged-output may not be the best idea. Input synchronization is not currently supported.

2. The dynamic context in which actual output is written is different, so one must be careful with - among other things - condition handlers.

3. Closing the underlying stream before the contents of the staging stream are written to it is not allowed.

Nested occurences of with-staged-output do the right thing by default: unless the staging stream is synchronized, the inner with-staged-output will simply bind staging-stream to stream.

# with-stream-class

Macro, excl package

Arguments: (class-name &optional stream) &body body

Returns the resulting values of the body forms. Within the body, all sm, funcall-stm-handler, and funcall-stm-handler-2 forms are expanded in such a way that the access into the stream requires only one or two memory-reference instructions, as indicated next.

- If the optional stream argument is not specified or is nil, an sm form will require two memory-reference instructions -- one to load the slots vector of the stream instance, and one to get the slot.

- If the optional stream argument is specified, it must be the stream argument to sm. Such specification results in a temporary variable being set up and the slots vector loaded into that variable, and from then on every access requires only one memory-reference instruction, because the slots vector is already available. The stream argument to sm is ignored in this situation.

- If the slot-name of the sm (or funcall...) form does not name a fixed-index slot within the stream of the specified class-name, a warning is issued and an unoptimized call to slot-value is used instead.

The decision as to whether to use the optional stream argument or not depends on whether there are more than one access anticipated. If two or more accesses are done within the body form, then the stream argument should be specified. If only one access is done, it is not necessary to specify the stream argument. However, if two with-stream-class forms are nested and the outer form specifies a stream argument, then the inner form must also specify the stream argument, otherwise the accesses within the inner form will be from the wrong object.

Example

This example is taken from real source. Note that the stream argument is specified, because there are 3 accesses here: one to grab the co-state slot, one to funcall the j-write-char function, and one to get the plist slot of the stream. All three accesses take one instruction each, after with-stream-class arranges for an extra variable to be pre-loaded with the instance slots vector of the stream.

    (defmethod (setf stream-external-format)
        :after (external-format (stream single-channel-simple-stream))
      (with-stream-class (single-channel-simple-stream stream)
        (when (sm co-state stream)
          ;; stream has an ef writer state, flush ef here.
          (funcall-stm-handler-2 j-write-char nil stream))
        (install-single-channel-character-strategy
         stream external-format (getf (sm plist stream) 'access))))

This example demonstrates a nested with-stream-class. Note that the optional stream argument to the outer form isn't really necessary, but presumably a real-life situation would have more than one access to stream. Also, note that if the inner macro did not specify a new optional stream argument (i.e. dribble), then the funcall-stm-handler-2 would have gotten its write-char handler from the wrong stream.

    (defun do-a-dribble (stream char)
      (with-stream-class (dual-channel-simple-stream stream)
        (let ((dribble (sm dribble stream)))
           (when dribble
             (with-stream-class (stream dribble)
           (funcall-stm-handler-2
            j-write-char char dribble))))))

You must load the `:iodefs` module to use this macro. Do that by evaluating `(require :iodefs)`. (It is not an error to evaluate that form if the module is already loaded.) This macro is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# with-underlying-simple-vector

Macro, excl package

Arguments: (array simple-vector-var &optional displacement-var length-var explicit-end allow-nil) &body body

This macro returns the last values of the implict progn of the body of the macro.

#### The simple-vector-var and array arguments

Within the body of this macro, the simple-vector-var, which must be a symbol, and it is lexically or specially bound to the array's most primitive data vector, which will always be a simple-array of 1 dimension and the same element type as the array.

The array must be an array of any kind; it may itself be a simple-array, and it can be of any dimensionality.

#### The displacement-var argument

If displacement-var is supplied, it must be a symbol, and it is lexically or specially bound to the total displacement of the array onto its underlying data. If an array is displaced to another array which is also displaced, then the displacements are added together; the displacement-var will contain the sum of the displacements.

#### The length-var and explicit-end arguments

If length-var is supplied it must be a symbol, and it is lexically or specially bound to the sum of the total displacement of the array onto its underlying data and one of the following values:

- If explicit-end is supplied and non-`nil`, the value of explicit-end, or

- If array is a vector, the length of the vector (as would be returned by a call to length), or

- If array is multidimensional, the first (most significant) dimension of the array.

explicit-end supplies one of the values used in the computation of length-var, which overrides the macro's concept of the upper boundary of the array. This value is not checked against any real storage; care must be given when providing explicit-end that it does not overreach the bounds of the simple-vector-var.

#### More on displacement-var, length-var, and explicit-end arguments when array is a vector

If array is a vector, displacement-var, length-var, and explicit-end can be summarized as follows:

> displacement-var and length-var are the real bounding index designators of simple-vector-var which correspond to the virtual bounding index designators 0 and explicit-end (which defaults to the length of array) of array.

#### The allow-nil argument

If allow-nil is supplied and non-`nil`, and if the array is `nil` then no initialization is done for the displacememt-var, if supplied, and the length-var, if supplied, gets the value most-positive-fixnum. The body code is still responsible for testing the simple-vector-var value for nil, but at least the with-underlying-simple-vector macro will not complain about a supplied array value of `nil`, if allow-nil is true.

Declarations for the variables can be made immediately following the argument list, and will be transferred to the final expanded form.

#### Example

    **The following code:**

    (deftype adim () '(mod #.array-dimension-limit))

    (defun simple-write-string (string stream &optional (start 0) end)
      (declare (type adim start)
           (optimize speed))
      (excl::with-underlying-simple-vector (string str disp len end t)
        (declare (type adim disp)
             (type (simple-array character 1) str))
        (when string
          (do* ((i (+ start disp) (1+ i)))
          ((>= i len))
        (declare (type adim i))
        (write-char (aref str i) stream))))
      string)

    **Results in the following output:**

    cl-user(2): **(setq sstring "hello")**
    "hello"
    cl-user(3): **(setq string (make-array 3
                                         :element-type 'character
                                         :displaced-to sstring
                                         :displaced-index-offset 2))**
    "llo"
    cl-user(4): **(simple-write-string nil *standard-output*)**
    nil
    cl-user(5): **(simple-write-string sstring *standard-output*)**
    hello
    "hello"
    cl-user(6): **(simple-write-string string *standard-output*)**
    llo
    "llo"
    cl-user(7):

# with-unreachable-code-allowed

Macro, excl package

Arguments: &body body

Release 10.1 and later only. Returns the values of body, but this macro is designed to affect compilation warnings. When code wrapped in this macro is compiled, no warnings of type compiler-unreachable-code-warning are signaled.

Normally when a cond or case statement terminates early due to a constantly true key predicate form, any clauses after that apparent `otherwise/t` form are considered unreachable and a warning is signaled. This warning can be ignored, but it is cleaner, if it is known that an automatic code generator is prone to generate such constantly true keys, if the warning is not generated at all.

## Example:

    cl-user(1): (defun foo (arg)
                   (cond ((= arg 10) (print 10))
                          (t (print t))
                          ((= arg 20) (print 20)) ;; This clause is unreachable
                          )
                    )
    foo
    cl-user(2): (foo 10)
    10
    10
    cl-user(3): (foo 20)
    t
    t

    ;; When compiled an unreachable clause warning is signaled:
    cl-user(6): (compile 'foo)
    ; While compiling #'foo at top level:
    Warning: cond clause ((= arg 20) (print 20)) is unreachable
    foo
    t
    nil

    ;; We wrap the COND form with WITH-UNREACHABLE-CODE-ALLOWED:
    cl-user(7): (defun foo (arg)
              (with-unreachable-code-allowed
              (cond ((= arg 10) (print 10))
                (t (print t))
                ((= arg 20) (print 20)) ;; This clause is unreachable
                       )
            ))
    foo
    cl-user(8): (foo 10)
    10
    10
    cl-user(9): (foo 20)
    t
    t

    ;; Now when compiled no warning is signaled.
    cl-user(10): (compile 'foo)
    foo
    nil
    nil
    cl-user(11):

# without-interrupts

Macro, excl package

Arguments: &body body

Use of this macro is deprecated. A warning will be signaled when the compiler encounters any use of this macro. The problem with this macro and also the related sys:without-scheduling is they cannot work when Symmetric Multiprocessing (SMP) is used. See smp.html for full details, but in brief, without-interrupts and sys:without-scheduling effectively provided object locking -- because they prevented process switches, and only one Lisp process could ever run at a time, no object could be modified by another process while code wrapped in the macros was being run. In an SMP Lisp, that is no longer true because processes can run on separate processors simultaneously. Therefore, object locking must be achieved in some other fashion. See smp.html for links to object locking functionality, particularly the section Non-synchronizing usages which discusses the macro with-delayed-interrupts.

Even though its use is deprecated, without-interrupts and sys:without-scheduling will continue to exist and work in non-SMP images as they have in earlier releases and currently. Users who do not wish to use SMP can use non-SMP images, which will be available on platforms which support SMP along with SMP images and need not modify their code at all because of the introduction of SMP (beyond suppressing the compiler warning as described above).

This macro executes body, protecting against any handling of asynchronous interrupts. Execution of body is guaranteed to complete without any other process running, or any asynchronous interrupt being dispatched, unless the process does something to block or otherwise explicitly yield to the scheduler (e.g. with mp:process-allow-schedule).

without-interrupts is implemented very efficiently and so may be executed frequently. It is generally bad style to wrap a without-interrupts around a body of code that takes a significant amount of time to execute because that may impose inappropriate high interrupt latency on other (possibly unrelated) interrupt handlers. without-interrupts is intended to be used around short critical sections of code; use of a process-lock may be more appropriate for protecting long bodies of code.

In native threads (:os-threads) implementations of multiprocessing, a lisp process calling a foreign function can release control of the lisp environment so that another lisp process can run. Any attempt to perform such a heap-releasing call within the scope of a without-interrupts block signals an error and does not release the heap. Whether error processing overrides the without-interrupts block depends on the coding of the particular application.

See also sys:without-scheduling and multiprocessing.html for general information on multiprocessing in Allegro CL.

# without-package-locks

Macro, excl package

Arguments: &body body

This macro will execute all forms in its body with *enable-package-locked-errors* bound to `nil`, so no package-locked-errors or compile-time warnings will be signaled for the dynamic extent of the body.

See packages.html for information on packages in Allegro CL and on package locking.

# without-redefinition-warnings

Macro, excl package

Arguments: &body body

Evaluates body without signaling any redefinition warnings. (A redefinition warning may be signaled if something defined in one place, e.g. a file, is redefined in another place, e.g. another file or at the top-level.)

See Redefinition warnings in source-file-recording.html for more information on redefinition warnings. See also *redefinition-warnings*.

# write-all-octets

Function, excl package

Arguments: stream buffer start end

Returns the number of octets written. This function is similar to write-octets, except that it will not return until all octets (specified by start and end) have been actually written, or unless an error occurs.

buffer is any specialized simple-array of one (it will be treated as if it were a simple vector of octets).

This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# write-no-hang-p

Function, excl package

Arguments: stream

If the argument stream is an integer, write-no-hang-p views that integer as an output file-descriptor, and it just checks the file-descriptor for readiness.

When stream is a stream, the output-handle of stream is queried to see if writing can be done. true is returned if writing can be done, else `nil` is returned. If the handle is itself a stream (an encapsulation), the stream is examined for output availability. If an error would be signalled on the stream, then true is returned, as if writing can be done.

In more detail, regardless of the type of stream, the buffer is checked for fullness. If it is not full, then true is returned.

If the buffer is full, then device-write is called with `nil` as the buffer, 0 as both start and end arguments, and blocking set to `nil`. If these return an indication that a write is possible, then true is returned, otherwise `nil` is returned.

See streams.html for information on the simple-streams implementation in Allegro CL.

# write-octets

Function, excl package

Arguments: stream buffer start end blocking

This function starts by blocking until any unwritten contents of the argument stream's output buffer are written out. Then it writes as many octets as possible from the buffer specified by the buffer argument to stream's output handle. The output handle is examined, and if it is a stream (i.e. encapsulated), then that output handle is written to in a manner similar to write-vector, except that no further checking of arguments is done; it is assumed that the caller has done whatever checking that is necessary. Otherwise, if the handle is an operating-system-defined handle, the system write function is called.

buffer is any specialized simple-array of one dimension (it will be treated as if it were a simple vector of octets). Buffer can also be a fixnum, in which case it is treated as an aligned pointer and the "vector" is the memory implied by the aligned pointer. (See Aligned pointers in ftype.html.)

The blocking controls what happens if not even one octet can be written. If it is true, the function will block if the first character cannot be written; if it is `nil`, the function does not block. See Blocking behavior in simple-streams in streams.html.

Return values:

- A number greater than or equal to 0: the number of bytes actually written. 0 bytes are only ever transferred when blocking is nil.

- -3: Special return value for a no-hang query. If the start and end arguments are eql and if blocking is nil, then a 0 return means no data can be written, and a -3 value means data could have been written.

- (- -10 errno): the value of the error return from the system operation. For example, -19 represents an errno value of 9, which is EBADF (bad file number) on most systems.

This function is intended for implementing device-level functionality and should not be used except for that purpose. See Simple-stream Description in streams.html for a description of the device-level.

See streams.html for information on the simple-streams implementation in Allegro CL.

# write-vector

Function, excl package

Arguments: sequence stream &key start end endian-swap

For a Gray stream, a check is made that the given vector is either a string or an octet vector (i.e. a simple-vector of (signed-byte 8) or (unsigned-byte 8) elements), and the equivalent of write-sequence is performed. Otherwise an error is generated.

In addition, write-vector utilizes with-staged-output if stream is marked as synchronized output-stream-p.

For a simple-stream:

The value of sequence must normally be a simple vector, but there are some exceptions. sequence can also be an aligned-pointer (an integer), or a foreign-pointer with an address component that is word-aligned, but if it is either of these two kinds of addresses, then a valid end value must be given; no attempt will be made to figure out the length of the data at the address. sequence can also be a single-float or a double-float; see below

This function starts by blocking until any unwritten buffer contents are written out. Then if the vector is a string, then the equivalent of write-string is performed.

If the vector is not a string, then the equivalent of write-byte is performed on each byte of the vector, for as many octets as are specified for the vector. If each element consists of more than one octet, then the processing is done in the natural endianness of the machine architecture. start and end arguments can be used to modify the number of octets written, and are specified as octet offsets into the vector (instead of numbers of elements, as in write-sequence). If the end argument is not specified, the length of the vector adjusted by the element-width is used instead. Note that if the vector is of an element-type that is smaller than an octet (8-bit byte) then the adjustment includes an alignment to the next higher octet boundary. Thus a bit vector of 10 bits will cause a transfer of 3 octets to occur.

write-vector is a B/NB (blocking/non-blocking) function, blocking until the first element is written and not blocking thereafter. See Blocking behavior in simple-streams in streams.html.

The number of octets actually written (and stored from the vector) is added to the start argument and that result returned. Thus, the return value is the index of the next octet in the vector that was not yet written. This interface more closely resembles that of read-vector/read-sequence, rather than that of write-sequence, which always returns the sequence argument. The reason for this implementation is to allow for partial and asynchronous writes.

If the sequence argument is a single-float or double-float (and thus not an actual vector), it is treated specially and its bits are written as if the object were a vector of size one with element-type single- or double-float (as appropriate). This is an optimization to prevent consing when passing floats.

The endian-swap keyword argument allows the user to treat I/O with a consistent byte-ordering despite endian issues. See section The endian-swap keyword argument to read-vector and write-vector in streams.html.

Note: write-vector is similar to write-sequence, but is different fundamentally in the following ways:

1. write-vector operations on non-strings are done on an octet basis, whereas write-sequence on non-strings is specified to write (variably-sized) bytes on an element-by-element basis. Thus, there is a general unpacking that occurs in write-vector.

2. The name "-sequence" implies too much; it includes handling of output from lists. write-vector writes vectors only for efficiency.

3. write-vector works on simple-arrays of one dimension with an element-type other than `t` (these arrays contain data rather than pointers to data); it may not work on non-simple arrays or on arrays of more than one dimension.

Note 2: the write-byte equivalent functionality can be optimized in the following way: If the stream's output buffer is not empty, it is written out with device-write. Then device-write is called for write-vector's vector argument, passing through the start and end arguments. This optimization only works if the vector is large and the length of the portion of the vector to be written exceeds a buffer-size. If the transfer is to be small, then it is worth taking the extra time to copy bytes into the stream's buffer, in order to avoid a device-write call for every call to write-vector.

See also read-vector.

See streams.html for information on the simple-streams implementation in Allegro CL.

Copyright (c) Franz Inc. Lafayette, CA., USA. All rights reserved.

ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 11.0