282 lines
15 KiB
HTML
282 lines
15 KiB
HTML
![]() |
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
|
||
|
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
|
||
|
<HEAD>
|
||
|
<TITLE>23.1.4. Extended Wildcards</TITLE>
|
||
|
</HEAD>
|
||
|
<BODY>
|
||
|
<meta name="description" value=" Extended Wildcards">
|
||
|
<meta name="keywords" value="clm">
|
||
|
<meta name="resource-type" value="document">
|
||
|
<meta name="distribution" value="global">
|
||
|
<P>
|
||
|
<b>Common Lisp the Language, 2nd Edition</b>
|
||
|
<BR> <HR><A NAME=tex2html4143 HREF="node208.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html4141 HREF="node203.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html4135 HREF="node206.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html4145 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html4146 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
|
||
|
<B> Next:</B> <A NAME=tex2html4144 HREF="node208.html"> Logical Pathnames</A>
|
||
|
<B>Up:</B> <A NAME=tex2html4142 HREF="node203.html"> File Names</A>
|
||
|
<B> Previous:</B> <A NAME=tex2html4136 HREF="node206.html"> Structured Directories</A>
|
||
|
<HR> <P>
|
||
|
<H2><A NAME=SECTION002714000000000000000>23.1.4. Extended Wildcards</A></H2>
|
||
|
<P>
|
||
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
|
||
|
<A NAME=WILDPATHNAMESECTION>Some</A>
|
||
|
file systems provide more complex conventions for wildcards than
|
||
|
simple component-wise wildcards representable by <tt>:wild</tt>.
|
||
|
For example, the namestring <tt>"F*O"</tt> might mean a normal three-character
|
||
|
name; a three-character name with the middle character wild;
|
||
|
a name with at least two characters, beginning with <tt>F</tt> and ending with <tt>O</tt>;
|
||
|
or perhaps a wild match spanning multiple directories. Similarly, the
|
||
|
namestring <tt>">foo>**>bar>"</tt> might imply that the middle directory is
|
||
|
named <tt>"**"</tt>; the middle directory is <tt>:wild</tt>;
|
||
|
there are zero or more middle directories that are <tt>:wild</tt>;
|
||
|
or perhaps that the middle directory name matches any two-letter name.
|
||
|
Some file systems support even more complex wildcards, such as
|
||
|
regular expressions.
|
||
|
<P>
|
||
|
X3J13 voted in June 1989 (PATHNAME-WILD) <A NAME=26321> </A> to provide
|
||
|
some facilities for dealing with more general wildcard pathnames
|
||
|
in a fairly portable manner.
|
||
|
<P>
|
||
|
<BR><b>[Function]</b><BR>
|
||
|
<tt>wild-pathname-p <i>pathname</i> &optional <i>field-key</i></tt>
|
||
|
<p>
|
||
|
Tests a pathname for the presence of wildcard components. If the
|
||
|
first argument is not a pathname, string, or file
|
||
|
stream, an error of type <tt>type-error</tt> is
|
||
|
signaled.
|
||
|
<p>
|
||
|
If no <i>field-key</i> is provided, or the <i>field-key</i> is
|
||
|
<tt>nil</tt>, the result is true if and only
|
||
|
if <i>pathname</i> has any wildcard components.
|
||
|
<P>
|
||
|
If a non-null <i>field-key</i> is provided, it must be one of <tt>:host</tt>,
|
||
|
<tt>:device</tt>,
|
||
|
<tt>:directory</tt>, <tt>:name</tt>, <tt>:type</tt>, or <tt>:version</tt>.
|
||
|
In this case, the result is true if and only
|
||
|
if the indicated component of <i>pathname</i> is a wildcard.
|
||
|
<P>
|
||
|
Note that X3J13 voted in June 1989
|
||
|
(PATHNAME-COMPONENT-VALUE) <A NAME=26336> </A>
|
||
|
to specify that an implementation need not support wildcards in all fields;
|
||
|
the only requirement is that the name, type, or version may be <tt>:wild</tt>.
|
||
|
However, portable programs should be prepared to encounter either <tt>:wild</tt>
|
||
|
or implementation-dependent wildcards in any pathname component.
|
||
|
The function <tt>wild-pathname-p</tt> provides a portable way for testing
|
||
|
the presence of wildcards.
|
||
|
<P>
|
||
|
<BR><b>[Function]</b><BR>
|
||
|
<tt>pathname-match-p <i>pathname</i> <i>wildname</i></tt><P> This predicate is true if and only if the <i>pathname</i>
|
||
|
matches the <i>wildname</i>. The matching rules
|
||
|
are implementation-defined but should be consistent with the behavior of the
|
||
|
<tt>directory</tt> function. Missing components of <i>wildname</i> default to <tt>:wild</tt>.
|
||
|
<P>
|
||
|
If either argument is not a pathname, string, or file stream, an error
|
||
|
of type <tt>type-error</tt> is signaled. It is valid for <i>pathname</i> to be a
|
||
|
wild pathname; a wildcard field in <i>pathname</i> will match only a
|
||
|
wildcard field in <i>wildname</i>; that is, <tt>pathname-match-p</tt> is not commutative.
|
||
|
It is valid for <i>wildname</i> to be a non-wild pathname;
|
||
|
I believe that in this case <tt>pathname-match-p</tt> will have the same
|
||
|
behavior as <tt>equal</tt>, though the X3J13 specification did not say so.
|
||
|
<P>
|
||
|
<BR><b>[Function]</b><BR>
|
||
|
<tt>translate-pathname <i>source</i> <i>from-wildname</i> <i>to-wildname</i> &key</tt><P> Translates the pathname <i>source</i>, which must match <i>from-wildname</i>, into
|
||
|
a corresponding pathname (call it <i>result</i>), which is constructed
|
||
|
so as to match <i>to-wildname</i>, and returns <i>result</i>.
|
||
|
<P>
|
||
|
The pathname <i>result</i> is a copy of
|
||
|
<i>to-wildname</i> with each missing or wildcard
|
||
|
field replaced by a portion of <i>source</i>; for this purpose a wildcard field is a
|
||
|
pathname component with a value of <tt>:wild</tt>, a <tt>:wild</tt> element of a
|
||
|
list-valued directory component, or an implementation-defined portion
|
||
|
of a component, such as the <tt>*</tt> in the complex wildcard string
|
||
|
<tt>"foo*bar"</tt> that some implementations support. An implementation that
|
||
|
adds other wildcard features, such as regular expressions, must define
|
||
|
how <tt>translate-pathname</tt> extends to those features. A missing field is
|
||
|
a pathname component that is <tt>nil</tt>.
|
||
|
<P>
|
||
|
The portion of <i>source</i> that is copied into <i>result</i> is
|
||
|
implementation-defined. Typically it is determined by the user interface conventions
|
||
|
of the file systems involved. Usually it is the portion of <i>source</i>
|
||
|
that matches a wildcard field of <i>from-wildname</i> that is in the same
|
||
|
position as the missing or wildcard field of <i>to-wildname</i>. If there
|
||
|
is no wildcard field in <i>from-wildname</i> at that position, then usually
|
||
|
it is the entire corresponding pathname component of <i>source</i> or, in
|
||
|
the case of a list-valued directory component, the entire corresponding
|
||
|
list element. For example, if the name components of <i>source</i>,
|
||
|
<i>from-wildname</i>, and <i>to-wildname</i> are <tt>"gazonk"</tt>, <tt>"gaz*"</tt>, and <tt>"h*"</tt>
|
||
|
respectively, then in most file systems the wildcard fields of the
|
||
|
name component of <i>from-wildname</i> and <i>to-wildname</i> are each <tt>"*"</tt>, the
|
||
|
matching portion of <i>source</i> is <tt>"onk"</tt>, and the name component of
|
||
|
<i>result</i> is <tt>"honk"</tt>; however, the exact behavior of <tt>translate-pathname</tt>
|
||
|
is not dictated by the Common Lisp language and may
|
||
|
vary according to the user interface conventions of the file systems
|
||
|
involved.
|
||
|
<P>
|
||
|
During the copying of a portion of <i>source</i> into <i>result</i>, additional
|
||
|
implementation-defined translations of alphabetic case or file naming
|
||
|
conventions may occur, especially when <i>from-wildname</i> and
|
||
|
<i>to-wildname</i> are for different hosts.
|
||
|
<P>
|
||
|
If any of the first three arguments is not a pathname, string, or file
|
||
|
stream, an error of type <tt>type-error</tt> is signaled. It is valid for
|
||
|
<i>source</i> to be a wild pathname; in general this will produce a wild
|
||
|
<i>result</i> pathname. It is valid for <i>from-wildname</i> or <i>to-wildname</i> or both
|
||
|
to be non-wild. An error is signaled if the <i>source</i> pathname does not
|
||
|
match the <i>from-wildname</i>, that is,
|
||
|
if <tt>(pathname-match-p <i>source</i> <i>from-wildname</i>)</tt> would not be true.
|
||
|
<P>
|
||
|
There are no specified keyword arguments for <tt>translate-pathname</tt>, but
|
||
|
implementations are permitted to extend it by adding keyword arguments.
|
||
|
There is one specified return value from <tt>translate-pathname</tt>;
|
||
|
implementations are permitted to extend it by returning additional
|
||
|
values.
|
||
|
<P>
|
||
|
Here is an implementation suggestion. One file system performs this operation by
|
||
|
examining corresponding pieces of the three pathnames in turn, where a piece is a
|
||
|
pathname component or a list element of a structured component such as
|
||
|
a hierarchical directory. Hierarchical directory elements in
|
||
|
<i>from-wildname</i> and <i>to-wildname</i> are matched by whether they are
|
||
|
wildcards, not by depth in the directory hierarchy. If the piece in
|
||
|
<i>to-wildname</i> is present and not wild, it is copied into the result.
|
||
|
If the piece in <i>to-wildname</i> is <tt>:wild</tt> or <tt>nil</tt>, the corresponding
|
||
|
piece in <i>source</i> is
|
||
|
copied into the result. Otherwise, the piece in <i>to-wildname</i> might be
|
||
|
a complex wildcard such as <tt>"foo*bar"</tt>; the portion of the piece in <i>source</i>
|
||
|
that matches the
|
||
|
wildcard portion of the corresponding piece in <i>from-wildname</i> (or the entire
|
||
|
<i>source</i> piece, if the <i>from-wildname</i> piece is not wild and therefore
|
||
|
equals the <i>source</i> piece) replaces the wildcard
|
||
|
portion of the piece in <i>to-wildname</i> and the value produced is used in
|
||
|
the result.
|
||
|
<P>
|
||
|
X3J13 voted in June 1989 (PATHNAME-COMPONENT-CASE) <A NAME=26422> </A> to
|
||
|
require <tt>translate-pathname</tt> to map customary case in argument
|
||
|
pathnames to the customary case in returned pathnames
|
||
|
(see section <A HREF="node205.html#PATHNAMECOMPONENTCASESECTION">23.1.2</A>).
|
||
|
<P>
|
||
|
Here are some examples of the use of the new wildcard pathname facilities.
|
||
|
These examples are not portable. They are written to run
|
||
|
with particular file systems and particular wildcard conventions and are
|
||
|
intended to be illustrative, not prescriptive.
|
||
|
Other implementations may behave differently.
|
||
|
<P><pre>
|
||
|
(wild-pathname-p (make-pathname :name :wild)) => t
|
||
|
(wild-pathname-p (make-pathname :name :wild) :name) => t
|
||
|
(wild-pathname-p (make-pathname :name :wild) :type) => nil
|
||
|
(wild-pathname-p (pathname "S:>foo>**>")) => t ;Maybe
|
||
|
(wild-pathname-p (make-pathname :name "F*O")) => t ;Probably
|
||
|
</pre><P>
|
||
|
One cannot rely on <tt>rename-file</tt> to handle wild pathnames in a predictable
|
||
|
manner. However, one can use <tt>translate-pathname</tt> explicitly to control
|
||
|
the process.
|
||
|
<P><pre>
|
||
|
(defun rename-files (from to)
|
||
|
"Rename all files that match the first argument by
|
||
|
translating their names to the form of the second
|
||
|
argument. Both arguments may be wild pathnames."
|
||
|
(dolist (file (directory from))
|
||
|
;; DIRECTORY produces only pathnames that match from-wildname.
|
||
|
(rename-file file (translate-pathname file from to))))
|
||
|
</pre><P>
|
||
|
<P>
|
||
|
Assuming one particular set of popular wildcard conventions,
|
||
|
this function might exhibit the following behavior.
|
||
|
Not all file systems will run this example exactly as written.
|
||
|
<P><pre>
|
||
|
(rename-files "/usr/me/*.lisp" "/dev/her/*.l")
|
||
|
renames /usr/me/init.lisp
|
||
|
to /dev/her/init.l
|
||
|
|
||
|
(rename-files "/usr/me/pcl*/*" "/sys/pcl/*/")
|
||
|
renames /usr/me/pcl-5-may/low.lisp
|
||
|
to /sys/pcl/pcl-5-may/low.lisp
|
||
|
(in some file systems the result might be /sys/pcl/5-may/low.lisp)
|
||
|
|
||
|
(rename-files "/usr/me/pcl*/*" "/sys/library/*/")
|
||
|
renames /usr/me/pcl-5-may/low.lisp
|
||
|
to /sys/library/pcl-5-may/low.lisp
|
||
|
(in some file systems the result might be /sys/library/5-may/low.lisp)
|
||
|
|
||
|
(rename-files "/usr/me/foo.bar" "/usr/me2/")
|
||
|
renames /usr/me/foo.bar
|
||
|
to /usr/me2/foo.bar
|
||
|
|
||
|
(rename-files "/usr/joe/*-recipes.text"
|
||
|
"/usr/jim/personal/cookbook/joe's-*-rec.text")
|
||
|
renames /usr/joe/lamb-recipes.text
|
||
|
to /usr/jim/personal/cookbook/joe's-lamb-rec.text
|
||
|
renames /usr/joe/veg-recipes.text
|
||
|
to /usr/jim/personal/cookbook/joe's-veg-rec.text
|
||
|
renames /usr/joe/cajun-recipes.text
|
||
|
to /usr/jim/personal/cookbook/joe's-cajun-rec.text
|
||
|
renames /usr/joe/szechuan-recipes.text
|
||
|
to /usr/jim/personal/cookbook/joe's-szechuan-rec.text
|
||
|
</pre><P>
|
||
|
<P>
|
||
|
The following examples use UNIX syntax and the wildcard conventions of one
|
||
|
particular version of UNIX.
|
||
|
<P><pre>
|
||
|
(namestring
|
||
|
(translate-pathname "/usr/dmr/hacks/frob.l"
|
||
|
"/usr/d*/hacks/*.l"
|
||
|
"/usr/d*/backup/hacks/backup-*.*"))
|
||
|
=> "/usr/dmr/backup/hacks/backup-frob.l"
|
||
|
</pre><P>
|
||
|
<P><pre>
|
||
|
(namestring
|
||
|
(translate-pathname "/usr/dmr/hacks/frob.l"
|
||
|
"/usr/d*/hacks/fr*.l"
|
||
|
"/usr/d*/backup/hacks/backup-*.*"))
|
||
|
=> "/usr/dmr/backup/hacks/backup-ob.l"
|
||
|
</pre><P>
|
||
|
The following examples are similar to the preceding examples
|
||
|
but use two different hosts; host <tt>U</tt> supports a UNIX file system
|
||
|
and host <tt>V</tt> supports a VAX/VMS file system. Note the translation
|
||
|
of file type (from <tt>l</tt> to <tt>LSP</tt>) and the change of alphabetic case conventions.
|
||
|
<P><pre>
|
||
|
(namestring
|
||
|
(translate-pathname "U:/usr/dmr/hacks/frob.l"
|
||
|
"U:/usr/d*/hacks/*.l"
|
||
|
"V:SYS$DISK:[D*.BACKUP.HACKS]BACKUP-*.*"))
|
||
|
=> "V:SYS$DISK:[DMR.BACKUP.HACKS]BACKUP-FROB.LSP"
|
||
|
</pre><P>
|
||
|
<P><pre>
|
||
|
(namestring
|
||
|
(translate-pathname "U:/usr/dmr/hacks/frob.l"
|
||
|
"U:/usr/d*/hacks/fr*.l"
|
||
|
"V:SYS$DISK:[D*.BACKUP.HACKS]BACKUP-*.*"))
|
||
|
=> "V:SYS$DISK:[DMR.BACKUP.HACKS]BACKUP-OB.LSP"
|
||
|
</pre><P>
|
||
|
The next example is a version of the
|
||
|
function <tt>translate-logical-pathname</tt> (simplified a bit) for a logical host named <tt>FOO</tt>.
|
||
|
The points of interest are the use of <tt>pathname-match-p</tt> as
|
||
|
a <tt>:test</tt> argument for <tt>assoc</tt> and the use of <tt>translate-pathname</tt>
|
||
|
as a substrate for <tt>translate-logical-pathname</tt>.
|
||
|
<P><pre>
|
||
|
(define-condition logical-translation-error (file-error))
|
||
|
|
||
|
(defun my-translate-logical-pathname (pathname &key rules)
|
||
|
(let ((rule (assoc pathname rules :test #'pathname-match-p)))
|
||
|
(unless rule
|
||
|
(error 'logical-translation-error :pathname pathname))
|
||
|
(translate-pathname pathname (first rule) (second rule))))
|
||
|
|
||
|
(my-translate-logical-pathname
|
||
|
"FOO:CODE;BASIC.LISP"
|
||
|
:rules '(("FOO:DOCUMENTATION;" "U:/doc/foo/")
|
||
|
("FOO:CODE;" "U:/lib/foo/")
|
||
|
("FOO:PATCHES;*;" "U:/lib/foo/patch/*/")))
|
||
|
=> #P"U:/lib/foo/basic.l"
|
||
|
</pre><P>
|
||
|
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
|
||
|
<P>
|
||
|
<BR> <HR><A NAME=tex2html4143 HREF="node208.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html4141 HREF="node203.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html4135 HREF="node206.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html4145 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html4146 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
|
||
|
<B> Next:</B> <A NAME=tex2html4144 HREF="node208.html"> Logical Pathnames</A>
|
||
|
<B>Up:</B> <A NAME=tex2html4142 HREF="node203.html"> File Names</A>
|
||
|
<B> Previous:</B> <A NAME=tex2html4136 HREF="node206.html"> Structured Directories</A>
|
||
|
<HR> <P>
|
||
|
<HR>
|
||
|
<P><ADDRESS>
|
||
|
AI.Repository@cs.cmu.edu
|
||
|
</ADDRESS>
|
||
|
</BODY>
|