Previous Section | Next Section | Table of Contents | Glossary | Index |
As of release 0.11, CCL
addresses the fact that
foreign type, constant, record, field, and function nams are
case-sensitive and provides mechanisms to refer to these names
via lisp symbols.
Previous versions of CCL
have tried to ignore that
fact, under the belief that case conflicts were rare and that
many users (and implementors) would prefer not to deal with
case-related issues. The fact that some information in the
interface databases was incomplete or inaccessible because of
this policy made it clearer that the policy was untenable. I
can't claim that the approach described here is aesthetically
pleasing, but I can honestly say that it's less unpleasant
than other approaches that I'd thought of. I'd be interested
to hear alternate proposals.
The issues described here have to do with how lisp symbols are used to denote foreign functions, constants, types, records, and fields. It doesn't affect how other lisp objects are sometimes used to denote foreign objects. For instance, the first argument to the EXTERNAL-CALL macros is now and has always been a case-sensitive string.
The primary way of referring to foreign constant and
function names in CCL
is via the #$ and #_ reader
macros. These reader macro functions each read a symbol into
the "OS" package, look up its constant or function definition
in the interface database, and assign the value of the
constant to the symbol or install a macroexpansion function on
the symbol.
In order to observe case-sensitivity, the reader-macros now read the symbol with (READTABLE-CASE :PRESERVE) in effect.
This means that it's necessary to type the foreign constant or function name in correct case, but it isn't necessary to use any special escaping constructs when writing the variable name. For instance:
(#_read fd buf n) ; refers to foreign symbol "read" (#_READ fd buf n) ; refers to foreign symbol "READ", which may ; not exist ... #$o_rdonly ; Probably doesn't exist #$O_RDONLY ; Exists on most platforms
Constructs like RLET expect a foreign type or record name to be denoted by a symbol (typically a keyword); RREF (and PREF) expect an "accessor" form, typically a keyword formed by concatenating a foreign type or record name with a sequence of one or more foreign field names, separated by dots. These names are interned by the reader as other lisp symbols are, with an arbitrary value of READTABLE-CASE in effect (typically :UPCASE.) It seems like it would be very tedious to force users to manually escape (via vertical bar or backslash syntax) all lowercase characters in symbols used to specify foreign type, record, and field names (especially given that many traditional POSIX structure, type, and field names are entirely lowercase.)
The approach taken by CCL
is to allow the symbols
(keywords) used to denote foreign type, record, and field
names to contain angle brackets (<
and
>
). Such symbols are translated to
foreign names via the following set of conventions:
All instances of < and > in the symbol's pname are balanced and don't nest.
Any alphabetic characters in the symbol's pname that aren't enclosed in angle brackets are treated as lower-case,regardless of the value of READTABLE-CASE and regardless of the case in which they were written.
Alphabetic characters that appear within angle brackets are mapped to upper-case, again regardless of how they were written or interned.
There may be many ways of "escaping" (with angle
brackets) sequences of upper-case and non-lower-case
characters in a symbol used to denote a foreign name. When
translating in the other direction, CCL
always escapes the
longest sequence that starts with an upper-case character and
doesn't contain a lower-case character.
It's often preferable to use this canonical form of a foreign type name.
The accessor forms used by PREF/RREF should be viewed as a series of foreign type/record and field names; upper-case sequences in the component names should be escaped with angle brackets, but those sequences shouldn't span components. (More simply, the separating dots shouldn't be enclosed, even if both surrounding characters need to be.)
Older POSIX code tends to use lower-case exclusively for
type, record, and field names; there are only a few cases in
the CCL
sources where mixed-case names need to be
escaped.
Previous Section | Next Section | Table of Contents | Glossary | Index |