-
Notifications
You must be signed in to change notification settings - Fork 10
/
files.tex
3019 lines (2600 loc) · 133 KB
/
files.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%Part{Files, Root = "CLM.MSS"}
%%%Chapter of Common Lisp Manual. Copyright 1984, 1988, 1989 Guy L. Steele Jr.
\clearpage\def\pagestatus{FINAL PROOF}
\chapter{File System Interface}
\label{FILES}
%\chapter{Работа с файловой системой}
%\label{FILES}
A frequent use of streams is to communicate with a \emph{file system}
to which groups of data (files) can be written and from which files
can be retrieved.
Потоки чаще всего используются для работы с \emph{файловой системой}, в которую
могут быть записаны данные (файлы) и из которой после эти файлы могут быть
прочитаны.
Common Lisp defines a standard interface for dealing with such a file system.
This interface is designed to be simple and general enough to
accommodate the facilities provided by ``typical'' operating system
environments within which Common Lisp is likely to be implemented.
The goal is to make Common Lisp programs that perform only simple operations
on files reasonably portable.
Common Lisp определяет стандартный интерфейс для работы с файловой системой.
Данные интерфейс спроектирован простым и достаточно обобщённым для того, чтобы
предоставлять функционал <<типичной>> операционной системы, в которой работает
реализация Common Lisp'а. Целью является переносимость Common Lisp'овых программ
в случае, если они используют простые операции над файлами.
To this end, Common Lisp assumes that files are named, that given a name one
can construct a stream connected to a file of that name, and that the
names can be fit into a certain canonical, implementation-independent
form called a \emph{pathname}.
И наконец, Common Lisp предполагает, что файлы имеют имена, которые используются
при создании файлового потока. Эти имена абстрагируются в системонезависимую
форму - \emph{pathname}.
Facilities are provided for manipulating pathnames, for creating
streams connected to files, and for manipulating the file system
through pathnames and streams.
Интерфейс предоставляет функционал для управления именами-файлов, для создания
файловых потоков, и для управления файловой системой с помощью имён-файлов и
потоков.
\section{File Names}
%\section{Имена файлов}
Common Lisp programs need to use names to designate files.
The main difficulty in dealing with names of files is that different
file systems have different naming formats for files.
For example, here is a table of several file systems (actually,
operating systems that provide file systems) and what equivalent
file names might look like for each one:
\begin{flushleft}
\begin{tabular}{@{}l@{\hskip 2pc}l@{}}
System&File Name \\
\hlinesp
{TOPS-20}&\cd{<LISPIO>FORMAT.FASL.13} \\
{TOPS-10}&\cd{FORMAT.FAS{\Xlbracket}1,4{\Xrbracket}} \\
{ITS}&\cd{LISPIO;FORMAT FASL} \\
{MULTICS}&\cd{>udd>LispIO>format.fasl} \\
{TENEX}&\cd{<LISPIO>FORMAT.FASL;13} \\
{VAX}/{VMS}&\cd{{\Xlbracket}LISPIO{\Xrbracket}FORMAT.FAS;13} \\
{UNIX}&\cd{/usr/lispio/format.fasl} \\
\hline
\end{tabular}
\end{flushleft}
It would be impossible for each program that deals with file names to
know about each different file name format that exists; a new Common Lisp
implementation might use a format different from any of its predecessors.
Therefore, Common Lisp provides \emph{two} ways to represent file names:
\emph{namestrings}, which are strings in the implementation-dependent form
customary for the file system, and \emph{pathnames}, which are special abstract
data objects that represent file names in an implementation-independent
way. Functions are provided to convert between these two representations,
and all manipulations of files can be expressed in machine-independent
terms by using pathnames.
In order to allow Common Lisp programs to operate in a network environment
that may have more than one kind of file system, the pathname facility
allows a file name to specify which file system is to be used.
In this context, each file system is called a \emph{host}, in keeping
with the usual networking terminology.
\begin{newer}
Different hosts may use different notations for file names.
Common Lisp allows customary notation to be used for each host, but
also supports
a system of logical pathnames that provides a standard framework for naming
files in a portable manner (see section~\ref{LOGICAL-PATHNAMES-SECTION}).
\end{newer}
\subsection{Pathnames}
\label{PATHNAME}
All file systems dealt with by Common Lisp are forced into a common framework,
in which files are named by a Lisp data object of type \cdf{pathname}.
A pathname always has six components, described below. These components
are the common interface that allows programs to work the same way with
different file systems; the mapping of the pathname components into the
concepts peculiar to each file system is taken care of by the Common Lisp
implementation.
\begin{flushdesc}
\item[\emph{host}]
The name of the file system on which the file resides.
\item[\emph{device}]
Corresponds to the ``device'' or ``file structure'' concept in many
host file systems: the name of a (logical or physical) device containing files.
\item[\emph{directory}]
Corresponds to the ``directory'' concept in many host file systems:
the name of a group of related files
(typically those belonging to a single
user or project).
\item[\emph{name}]
The name of a group of files that can be thought of as
the ``same'' file.
\item[\emph{type}]
Corresponds to the ``filetype'' or ``extension'' concept in many host
file systems; identifies the type of file. Files with the same names
but different types are usually related in some specific way, for instance,
one being a source file, another the compiled form of that source,
and a third the listing of error messages from the compiler.
\item[\emph{version}]
Corresponds to the ``version number'' concept in many host file systems.
Typically this is a number that is incremented every time the file is modified.
\end{flushdesc}
Note that a pathname is not necessarily the name of a specific file.
Rather, it is a specification (possibly only a partial specification) of
how to access a file. A pathname need not correspond to any file that
actually exists, and more than one pathname can refer to the same file.
For example, the pathname with a version of ``newest'' may refer to the
same file as a pathname with the same components except a certain number
as the version. Indeed, a pathname with version ``newest'' may refer to
different files as time passes, because the meaning of such a pathname
depends on the state of the file system. In file systems with such
facilities as ``links,'' multiple file names, logical devices, and so on,
two pathnames that look quite different may turn out to address the same
file. To access a file given a pathname, one must do a file system
operation such as
\cdf{open}.
Two important operations involving pathnames are \emph{parsing} and
\emph{merging}. Parsing is the conversion of a namestring (which might be
something supplied interactively by the user when asked to supply the
name of a file) into a pathname object. This operation is
implementation-dependent, because the format of namestrings
is implementation-dependent.
Merging takes a pathname with missing components
and supplies values for those components from a source of defaults.
Not all of the components of a pathname need to be specified. If a
component of a pathname is missing, its value is {\nil}. Before the file
system interface can do anything interesting with a file, such as opening the
file, all the missing components of a pathname must be filled in
(typically from a set of defaults). Pathnames with missing components
may be used internally for various purposes;
in particular, parsing a namestring
that does not specify certain components will result in a pathname with
missing components.
\begin{newer}
X3J13 voted in January 1989 \issue{PATHNAME-UNSPECIFIC-COMPONENT}
to permit any component of a pathname to have the value \cd{:unspecific},
meaning that the component simply does not exist,
for file systems in which such a value makes sense.
(For example, a UNIX file system usually does not support version numbers,
so the version component of a pathname for a UNIX host might be
\cd{:unspecific}. Similarly,
the file type is usually regarded in a UNIX file system as the part
of a name after a period, but some file names contain no periods and therefore have
no file types.)
When a pathname is converted to a namestring, the values \cdf{nil} and \cd{:unspecific}
have the same effect: they
are treated as if the component were empty (that is, they each cause the
component not to appear in the namestring).
When merging, however, only a \cdf{nil} value for a component will be
replaced with the default for that component; the value \cd{:unspecific}
will be left alone as if the field were filled.
The results are undefined if \cd{:unspecific} is supplied
to a file system in a component for which
\cd{:unspecific} does not make sense for that file system.
Programming hint:
portable programs should be prepared to handle the value \cd{:unspecific} in the device,
directory, type, or version field in some implementations.
Portable programs should not explicitly place \cd{:unspecific} in any
field because it might not be permitted in some situations,
but portable programs may sometimes do so implicitly (by copying
such a value from another pathname, for example).
\end{newer}
What values are allowed for components of a pathname depends, in general,
on the pathname's host. However, in order for pathnames to be usable
in a system-independent way, certain global conventions are adhered to.
These conventions are stronger for the type and version than for the
other components, since the type and version are explicitly manipulated by
many programs, while the other components are usually treated as something
supplied by the user that just needs to be remembered and copied
from place to place.
The type is always a string or {\nil} or \cd{:wild}.
It is expected that most
programs that deal with files will supply a default type for each file.
The version is either a positive integer or a special symbol. The
meanings of {\nil} and \cd{:wild} have been explained
above. The keyword \cd{:newest} refers to the largest version number
that already exists in the file system when reading a file, or to
a version number
greater than any already existing in the file system
when writing a new file. Some Common Lisp implementors
may choose to define other special version symbols.
Some semi-standard names, suggested but not required to be supported
by every Common Lisp implementation, are
\cd{:oldest}, to refer to the smallest version number that exists
in the file system;
\cd{:previous}, to refer to the version previous to the newest version;
and \cd{:installed}, to refer to a version that is officially installed
for users (as opposed to a working or development version).
Some Common Lisp implementors may also choose to attach a meaning to
non-positive version numbers (a typical convention is that \cd{0}
is synonymous with \cd{:newest} and \cd{-1} with \cd{:previous}),
but such interpretations are implementation-dependent.
The host may be a string, indicating a file system, or a list
of strings, of which the first names the file system and the rest
may be used for such a purpose as inter-network routing.
\begin{newer}
X3J13 voted in June 1989 \issue{PATHNAME-COMPONENT-VALUE}
to approve the following clarifications and specifications
of precisely what are valid values for the various components
of a pathname.
\makeatletter
\def\@listi{\leftmargin\leftmargini \labelsep\leftmargin
\parsep 3pt\relax
\topsep 2pt plus 5pt\relax
\itemsep\topsep}
\makeatother
Pathname component value strings never contain the punctuation
characters that are used to separate fields in a namestring (for example,
slashes and
periods as used in UNIX file systems). Punctuation characters appear only in namestrings.
Characters used as punctuation can appear in pathname component values
with a non-punctuation meaning if the file system allows it (for example,
UNIX file systems allow a file name to begin with a period).
When examining pathname components, conforming programs must be prepared
to encounter any of the following siutations:
\begin{itemize}
\item Any component can be \cdf{nil}, which means the component has not
been specified.
\item Any component can be \cd{:unspecific}, which means the component has
no meaning in this particular pathname.
\item The device, directory, name, and type can be strings.
\item The host can be any object, at the discretion of the implementation.
\item The directory can be a list of strings and symbols as described in
section~\ref{STRUCTURED-DIRECTORY-SECTION}.
\item The version can be any symbol or any integer. The symbol \cd{:newest}
refers to the largest version number that already exists in the file
system when reading, overwriting, appending, superseding, or
directory-listing an existing file; it refers to the smallest version number
greater than any existing version number when creating a new file.
Other symbols and integers have implementation-defined meaning.
It is suggested, but not required, that implementations use positive
integers starting at 1 as version numbers, recognize the symbol \cd{:oldest}
to designate the smallest existing version number, and use keyword
symbols for other special versions.
\end{itemize}
When examining wildcard components of a wildcard pathname, conforming programs
must be prepared to encounter any of the following additional values
in any component or any element of a list that is the directory component:
\begin{itemize}
\item The symbol \cd{:wild}, which matches anything.
\item A string containing implementation-dependent special wildcard
characters.
\item Any object, representing an implementation-dependent wildcard pattern.
\end{itemize}
When constructing a pathname from components, conforming programs
must follow these rules:
\begin{itemize}
\item Any component may be \cdf{nil}. Specifying \cdf{nil} for the host may,
in some implementations,
result in using a default host
rather than an actual \cdf{nil} value.
\item The host, device, directory, name, and type may be strings. There
are implementation-dependent limits on the number and type of
characters in these strings. A plausible assumption is that letters (of a single case)
and digits are acceptable to most file systems.
\item The directory may be a list of strings and symbols as described in
section~\ref{STRUCTURED-DIRECTORY-SECTION}. There are
implementation-dependent limits on the length and contents of the list.
\item The version may be \cd{:newest}.
\item Any component may be taken from the corresponding component
of another pathname. When the two pathnames are for different
file systems (in implementations that support multiple file
systems), an appropriate translation occurs. If no meaningful
translation is possible, an error is signaled. The definitions
of ``appropriate'' and ``meaningful'' are implementation-dependent.
\item When constructing a wildcard pathname, the name, type, or version
may be \cd{:wild}, which matches anything.
\item An implementation might support other values for some components,
but a portable program should not use those values. A conforming program
can use implementation-dependent values but this can make it
non-portable; for example, it might work only with UNIX file systems.
\end{itemize}
\end{newer}
The best way to compare two pathnames for equality is with \cdf{equal},
not \cdf{eql}.
(On pathnames, \cdf{eql} is simply the same as \cdf{eq}.)
Two pathname objects are \cdf{equal} if and only if
all the corresponding components
(host, device, and so on) are equivalent. (Whether or not
uppercase and lowercase letters are considered equivalent
in strings appearing in components depends on the file
name conventions of the file system.) Pathnames
that are \cdf{equal} should be functionally equivalent.
\subsection{Case Conventions}
\label{PATHNAME-COMPONENT-CASE-SECTION}
Issues of alphabetic case in pathnames are a major source of problems.
In some file systems, the customary case is lowercase, in some uppercase,
in some mixed. Some file systems are case-sensitive (that is, they treat
\cdf{FOO} and \cdf{foo} as different file names) and others are not.
There are two kinds of pathname case portability problems: moving
programs from one Common Lisp to another, and moving pathname component
values from one file system to another. The solution to the first problem
is the requirement that all
Common Lisp implementations that support a particular file system must
use compatible representations for pathname component values. The solution to
the second problem is the use of a common representation for the
least-common-denominator pathname component values that exist on all
interesting file systems.
Requiring a common representation directly conflicts with the
desire among programmers that use only one file system to work with the
local conventions and to ignore issues of porting to other file
systems. The common representation cannot be the same as local (varying)
conventions.
X3J13 voted in June 1989 \issue{PATHNAME-COMPONENT-CASE} to
add a keyword argument \cd{:case} to each of the functions
\cdf{make-pathname}, \cdf{pathname-host},
\cdf{pathname-device}, \cdf{pathname-directory}, \cdf{pathname-name},
and \cdf{pathname-type}.
The possible values for the argument are \cd{:common} and \cd{:local}.
The default is \cd{:local}.
The value \cd{:local} means that strings given to \cdf{make-pathname}
or returned by any of the pathname component accessors
follow the local file system's conventions for alphabetic case.
Strings given to \cdf{make-pathname} will be used exactly as written if
the file system supports both cases. If the file system
supports only one case, the strings will be translated to that case.
The value \cd{:common} means that strings given to \cdf{make-pathname}
or returned by any of the pathname component accessors
follow this common convention:
\begin{itemize}
\item All uppercase means that a file system's customary case will be used.
\item All lowercase means that the opposite of the customary case will be used.
\item Mixed case represents itself.
\end{itemize}
Uppercase is used as the common case for no better reason than
consistency with Lisp symbols.
The second and third points allow translation from local representation to
common and back to be information-preserving. (Note that translation
from common to local representation and back may or may not be information-preserving,
depending on the nature of the local representation.)
Namestrings always use \cd{:local} file system case conventions.
Finally, \cdf{merge-pathnames} and \cdf{translate-pathname} map customary case in the
input pathnames into customary case in the output pathname.
Examples of possible use of this convention:
\begin{itemize}
\item TOPS-20 is case-sensitive and prefers uppercase,
translating lowercase to uppercase unless escaped with \cd{{\Xcircumflex}V};
for a TOPS-20--based
file system, a Common Lisp implementation
should use identical
representations for common and local.
\item UNIX is case-sensitive and prefers lowercase; for a UNIX-based file system,
a Common Lisp implementation should translate between
common and local representations by inverting the case of non-mixed-case strings.
\item VAX/VMS is uppercase-only (that is, the file system translates all file
name arguments to uppercase); for a VAX/VMS-based file system,
a Common Lisp implementation should
translate common representation to local by
converting to uppercase and should translate local representation
to common with no change.
\item The Macintosh operating system is case-insensitive and prefers lowercase,
but remembers the cases of letters actually used to name a file;
for a Macintosh-based file system, a Common Lisp implementation should translate
between common and local representations by inverting the case of non-mixed-case strings
and should ignore case when determining whether two pathnames are \cdf{equal}.
\end{itemize}
\newpage%required
Here are some examples of this behavior. Assume that the host \cdf{T} runs
TOPS-20, \cdf{U} runs UNIX, \cdf{V} runs VAX/VMS, and \cdf{M} runs the Macintosh
operating system.
\begin{lisp}
;;; Returns two values: the PATHNAME-NAME from a namestring \\*
;;; in :COMMON and :LOCAL representations (in that order). \\*
(defun pathname-example (name) \\*
~~(let ((path (parse-namestring name)))) \\*
~~~~(values (pathname-name path :case :common) \\*
~~~~~~~~~~~~(pathname-name path :case :local)))) \\
\\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\EV\ "FOO" \textrm{and} \="FOO" \kill
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;\textrm{Common}\>\textrm{Local} \\*
(pathname-example "T:<ME>FOO.LISP")~~~~~~~~\EV\ "FOO" \textrm{and} "FOO" \\*
(pathname-example "T:<ME>foo.LISP")~~~~~~~~\EV\ "FOO" \textrm{and} "FOO" \\*
(pathname-example "T:<ME>{\Xcircumflex}Vf{\Xcircumflex}Vo{\Xcircumflex}Vo.LISP")~~\EV\ "foo" \textrm{and} "foo" \\
(pathname-example "T:<ME>TeX.LISP")~~~~~~~~\EV\ "TEX" \textrm{and} "TEX" \\
(pathname-example "T:<ME>T{\Xcircumflex}VeX.LISP")~~~~~~\EV\ "TeX" \textrm{and} "TeX" \\
(pathname-example "U:/me/FOO.lisp")~~~~~~~~\EV\ "foo" \textrm{and} "FOO" \\
(pathname-example "U:/me/foo.lisp")~~~~~~~~\EV\ "FOO" \textrm{and} "foo" \\
(pathname-example "U:/me/TeX.lisp")~~~~~~~~\EV\ "TeX" \textrm{and} "TeX" \\
(pathname-example "V:[me]FOO.LISP")~~~~~~~~\EV\ "FOO" \textrm{and} "FOO" \\
(pathname-example "V:[me]foo.LISP")~~~~~~~~\EV\ "FOO" \textrm{and} "FOO" \\
(pathname-example "V:[me]TeX.LISP")~~~~~~~~\EV\ "TEX" \textrm{and} "TEX" \\
(pathname-example "M:FOO.LISP")~~~~~~~~~~~~\EV\ "foo" \textrm{and} "FOO" \\*
(pathname-example "M:foo.LISP")~~~~~~~~~~~~\EV\ "FOO" \textrm{and} "foo" \\*
(pathname-example "M:TeX.LISP")~~~~~~~~~~~~\EV\ "TeX" \textrm{and} "TeX"
\end{lisp}
The following example illustrates the creation of new pathnames.
The name is converted from common representation to local because
namestrings always use local conventions.
\begin{lisp}
(defun make-pathname-example (h n) \\*
~~(namestring (make-pathname :host h :name n :case :common)) \\
\\
(make-pathname-example "T" "FOO") \EV\ "T:FOO" \\*
(make-pathname-example "T" "foo") \EV\ "T:{\Xcircumflex}Vf{\Xcircumflex}Vo{\Xcircumflex}Vo" \\
(make-pathname-example "T" "TeX") \EV\ "T:T{\Xcircumflex}VeX" \\
(make-pathname-example "U" "FOO") \EV\ "U:foo" \\
(make-pathname-example "U" "foo") \EV\ "U:FOO" \\
(make-pathname-example "U" "TeX") \EV\ "U:TeX" \\
(make-pathname-example "V" "FOO") \EV\ "V:FOO" \\
(make-pathname-example "V" "foo") \EV\ "V:FOO" \\
(make-pathname-example "V" "TeX") \EV\ "V:TeX" \\
(make-pathname-example "M" "FOO") \EV\ "M:foo" \\
(make-pathname-example "M" "foo") \EV\ "M:FOO" \\*
(make-pathname-example "M" "TeX") \EV\ "M:TeX"
\end{lisp}
A big advantage of this set of conventions is that one can, for example,
call \cdf{make-pathname} with \cd{:type~"LISP"} and \cd{:case~:common},
and the result will appear in a namestring as \cd{.LISP} or \cd{.lisp},
whichever is appropriate.
\subsection{Structured Directories}
\label{STRUCTURED-DIRECTORY-SECTION}
X3J13 voted in June 1989 \issue{PATHNAME-SUBDIRECTORY-LIST}
to define a specific pathname component format for structured directories.
The value of a pathname's directory component may be a list. The
\emph{car} of the list should be a keyword, either \cd{:absolute} or \cd{:relative}.
Each remaining element of the list should be a string or a symbol (see below).
Each string names a single level of directory structure and should consist
of only the directory name without any punctuation characters.
A list whose \emph{car} is the symbol \cd{:absolute} represents a directory path
starting from the root directory. For example, the list \cd{(:absolute)} represents
the root directory itself; the list \cd{(:absolute "foo" "bar" "baz")} represents
the directory that in a UNIX file system would be called \cd{/foo/bar/baz}.
A list whose \emph{car} is the symbol \cd{:relative} represents a directory path
starting from a default directory. The list \cd{(:relative)} has the same
meaning as \cdf{nil} and hence normally is not used. The list \cd{(:relative "foo" "bar")}
represents the directory named \cdf{bar} in the directory named \cdf{foo} in the
default directory.
In place of a string, at any point in the list, a symbol may occur to
indicate a special file notation. The following symbols have standard
meanings.
\begin{indentdesc}{}
\item[\cd{:wild}]
Wildcard match of one level of directory structure
\item[\cd{:wild-inferiors}]
Wildcard match of any number of directory levels
\item[\cd{:up}]
Go upward in directory structure (semantic)
\item[\cd{:back}]
Go upward in directory structure (syntactic)
\end{indentdesc}
(See section~\ref{WILD-PATHNAME-SECTION} for a discussion of wildcard pathnames.)
Implementations are permitted to add additional objects of any
non-string type if necessary to represent features of their file systems
that cannot be represented with the standard strings and symbols.
Supplying any non-string, including any of the symbols listed below, to a
file system for which it does not make sense signals an error of type
\cdf{file-error}. For example, most implementations of the UNIX file system
do not support \cd{:wild-inferiors}. Any directory list in which
\cd{:absolute} or \cd{:wild-inferiors} is immediately followed by \cd{:up} or \cd{:back}
is illegal and when processed causes an error to be signaled.
The keyword \cd{:back} has a ``syntactic'' meaning that depends only on the pathname
and not on the contents of the file system. The keyword \cd{:up} has a ``semantic''
meaning that depends on the contents of the file system; to resolve
a pathname containing \cd{:up} to a pathname whose directory component
contains only \cd{:absolute} and strings requires a search of the file system.
Note that use of \cd{:up} instead of \cd{:back} can result in designating a different
actual directory only in file systems that support multiple
names for directories, perhaps via symbolic links. For example,
suppose that there is a directory link such that
\begin{lisp}
(:absolute "X" "Y")~~\textrm{is linked to}~~(:absolute "A" "B")
\end{lisp}
and there also exist directories
\begin{lisp}
(:absolute "A" "Q")~~\textrm{and}~~(:absolute "X" "Q")
\end{lisp}
Then
\begin{lisp}
(:absolute "X" "Y" :up "Q")~~\textrm{designates}~~(:absolute "A" "Q")
\end{lisp}
but
\begin{lisp}
(:absolute "X" "Y" :back "Q")~~\textrm{designates}~~(:absolute "X" "Q")
\end{lisp}
If a string is used as the value of the \cd{:directory} argument to
\cdf{make-pathname}, it should be the name of a top-level directory and should
not contain any punctuation characters. Specifying a string \emph{s} is
equivalent to specifying the list \cd{(:absolute \emph{s\/})}. Specifying the symbol
\cd{:wild} is equivalent to specifying the list \cd{(:absolute :wild-inferiors)}
(or \cd{(:absolute :wild)} in a file system that does not support \cd{:wild-inferiors}).
The function \cdf{pathname-directory} always returns \cdf{nil}, \cd{:unspecific}, or a
list---never a string, never \cd{:wild}.
If a list is returned, it is not guaranteed to be freshly consed; the
consequences of modifying this list are undefined.
In non-hierarchical file systems, the only valid list values for the
directory component of a pathname are \cd{(:absolute \emph{s})} (where \emph{s}
is a string) and
\cd{(:absolute :wild)}. The keywords \cd{:relative},
\cd{:wild-inferiors}, \cd{:up}, and \cd{:back} are not used in non-hierarchical file
systems.
Pathname merging treats a relative directory specially. Let
\emph{pathname\/} and \emph{defaults\/} be the first two arguments to
\cdf{merge-pathnames}. If \cd{(pathname-directory \emph{pathname\/})} is a list whose
\emph{car} is \cd{:relative}, and \cd{(pathname-directory \emph{defaults\/})} is a list, then
the merged directory is the value of
\begin{lisp}
(append (pathname-directory \emph{defaults\/}) \\*
~~~~~~~~(cdr~~~~~;\textrm{Remove \cd{:relative} from the front} \\*
~~~~~~~~~~(pathname-directory \emph{pathname\/})))
\end{lisp}
except that if the resulting list contains a string or \cd{:wild} immediately
followed by \cd{:back}, both of them are removed. This removal of redundant
occurrences of \cd{:back} is repeated as many times as possible.
If \cd{(pathname-directory \emph{defaults\/})} is not a list or
\cd{(pathname-directory \emph{pathname\/})} is not a list whose \emph{car} is \cd{:relative}, the
merged directory is the value of
\begin{lisp}
(or (pathname-directory \emph{pathname\/}) \\
~~~~(pathname-directory \emph{defaults\/}))
\end{lisp}
A relative directory in the pathname argument to a function such as
\cdf{open} is merged with the value of \cd{*default-pathname-defaults*} before the
file system is accessed.
Here are some examples of the use of structured directories.
Suppose that host \cdf{L} supports a Symbolics Lisp Machine file system,
host \cdf{U} supports a UNIX file system, and
host \cdf{V} supports a VAX/VMS file system.
\begin{lisp}
(pathname-directory (parse-namestring "V:[FOO.BAR]BAZ.LSP")) \\*
~~~\EV\ (:ABSOLUTE "FOO" "BAR")
\end{lisp}
\begin{lisp}
(pathname-directory (parse-namestring "U:/foo/bar/baz.lisp")) \\*
~~~\EV\ (:ABSOLUTE "foo" "bar")
\end{lisp}
\begin{lisp}
(pathname-directory (parse-namestring "U:../baz.lisp")) \\*
~~~\EV\ (:RELATIVE :UP)
\end{lisp}
\begin{lisp}
(pathname-directory (parse-namestring "U:/foo/bar/../mum/baz")) \\*
~~~\EV\ (:ABSOLUTE "foo" "bar" :UP "mum")
\end{lisp}
\begin{lisp}
(pathname-directory (parse-namestring "U:bar/../../ztesch/zip")) \\*
~~~\EV\ (:RELATIVE "bar" :UP :UP "ztesch")
\end{lisp}
\begin{lisp}
(pathname-directory (parse-namestring "L:>foo>**>bar>baz.lisp")) \\*
~~~\EV\ (:ABSOLUTE "FOO" :WILD-INFERIORS "BAR")
\end{lisp}
\begin{lisp}
(pathname-directory (parse-namestring "L:>foo>*>bar>baz.lisp")) \\*
~~~\EV\ (:ABSOLUTE "FOO" :WILD "BAR")
\end{lisp}
\subsection{Extended Wildcards}
\label{WILD-PATHNAME-SECTION}
Some file systems provide more complex conventions for wildcards than
simple component-wise wildcards representable by \cd{:wild}.
For example, the namestring \cd{"F*O"} 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 \cdf{F} and ending with \cdf{O};
or perhaps a wild match spanning multiple directories. Similarly, the
namestring \cd{">foo>**>bar>"} might imply that the middle directory is
named \cd{"**"}; the middle directory is \cd{:wild};
there are zero or more middle directories that are \cd{:wild};
or perhaps that the middle directory name matches any two-letter name.
Some file systems support even more complex wildcards, such as
regular expressions.
X3J13 voted in June 1989 \issue{PATHNAME-WILD} to provide
some facilities for dealing with more general wildcard pathnames
in a fairly portable manner.
\begin{defun}[Function]
wild-pathname-p pathname &optional field-key
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 \cdf{type-error} is
signaled.
If no \emph{field-key} is provided, or the \emph{field-key} is \cdf{nil}, the
result is true if and only if \emph{pathname} has any wildcard components.
If a non-null \emph{field-key} is provided, it must be one of \cd{:host},
\cd{:device}, \cd{:directory}, \cd{:name}, \cd{:type}, or \cd{:version}. In
this case, the result is true if and only if the indicated component of
\emph{pathname} is a wildcard.
Note that X3J13 voted in June 1989 \issue{PATHNAME-COMPONENT-VALUE} to specify
that an implementation need not support wildcards in all fields; the only
requirement is that the name, type, or version may be \cd{:wild}. However,
portable programs should be prepared to encounter either \cd{:wild} or
implementation-dependent wildcards in any pathname component. The function
\cdf{wild-pathname-p} provides a portable way for testing the presence of
wildcards.
\end{defun}
\begin{defun}[Function]
pathname-match-p pathname wildname
This predicate is true if and only if the \emph{pathname} matches the
\emph{wildname}. The matching rules are implementation-defined but should be
consistent with the behavior of the \cdf{directory} function. Missing
components of \emph{wildname} default to \cd{:wild}.
If either argument is not a pathname, string, or file stream, an error of type
\cdf{type-error} is signaled. It is valid for \emph{pathname} to be a wild
pathname; a wildcard field in \emph{pathname} will match only a wildcard field
in \emph{wildname}; that is, \cdf{pathname-match-p} is not commutative. It is
valid for \emph{wildname} to be a non-wild pathname; I believe that in this case
\cdf{pathname-match-p} will have the same behavior as \cdf{equal}, though the
X3J13 specification did not say so.
\end{defun}
\begin{defun}[Function]
translate-pathname source from-wildname to-wildname &key
Translates the pathname \emph{source}, which must match \emph{from-wildname},
into a corresponding pathname (call it \emph{result}), which is constructed so
as to match \emph{to-wildname}, and returns \emph{result}.
The pathname \emph{result} is a copy of \emph{to-wildname} with each missing or
wildcard field replaced by a portion of \emph{source}; for this purpose a
wildcard field is a pathname component with a value of \cd{:wild}, a \cd{:wild}
element of a list-valued directory component, or an implementation-defined
portion of a component, such as the \cdf{*} in the complex wildcard string
\cd{"foo*bar"} that some implementations support. An implementation that adds
other wildcard features, such as regular expressions, must define how
\cdf{translate-pathname} extends to those features. A missing field is a
pathname component that is \cdf{nil}.
The portion of \emph{source} that is copied into \emph{result} is
implementation-defined. Typically it is determined by the user interface
conventions of the file systems involved. Usually it is the portion of
\emph{source} that matches a wildcard field of \emph{from-wildname} that is in
the same position as the missing or wildcard field of \emph{to-wildname}. If
there is no wildcard field in \emph{from-wildname} at that position, then
usually it is the entire corresponding pathname component of \emph{source} or,
in the case of a list-valued directory component, the entire corresponding list
element. For example, if the name components of \emph{source},
\emph{from-wildname}, and \emph{to-wildname} are \cd{"gazonk"}, \cd{"gaz*"}, and
\cd{"h*"} respectively, then in most file systems the wildcard fields of the
name component of \emph{from-wildname} and \emph{to-wildname} are each \cd{"*"},
the matching portion of \emph{source} is \cd{"onk"}, and the name component of
\emph{result} is \cd{"honk"}; however, the exact behavior of
\cdf{translate-pathname} is not dictated by the Common Lisp language and may
vary according to the user interface conventions of the file systems involved.
During the copying of a portion of \emph{source} into \emph{result}, additional
implementation-defined translations of alphabetic case or file naming
conventions may occur, especially when \emph{from-wildname} and
\emph{to-wildname} are for different hosts.
If any of the first three arguments is not a pathname, string, or file stream,
an error of type \cdf{type-error} is signaled. It is valid for \emph{source} to
be a wild pathname; in general this will produce a wild \emph{result} pathname.
It is valid for \emph{from-wildname} or \emph{to-wildname} or both to be
non-wild. An error is signaled if the \emph{source} pathname does not match the
\emph{from-wildname}, that is, if \cd{(pathname-match-p \emph{source}
\emph{from-wildname})} would not be true.
There are no specified keyword arguments for \cdf{translate-pathname}, but
implementations are permitted to extend it by adding keyword arguments. There
is one specified return value from \cdf{translate-pathname}; implementations are
permitted to extend it by returning additional values.
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 \emph{from-wildname}
and \emph{to-wildname} are matched by whether they are wildcards, not by depth
in the directory hierarchy. If the piece in \emph{to-wildname} is present and
not wild, it is copied into the result. If the piece in \emph{to-wildname} is
\cd{:wild} or \cdf{nil}, the corresponding piece in \emph{source} is copied into
the result. Otherwise, the piece in \emph{to-wildname} might be a complex
wildcard such as \cd{"foo*bar"}; the portion of the piece in \emph{source} that
matches the wildcard portion of the corresponding piece in \emph{from-wildname}
(or the entire \emph{source} piece, if the \emph{from-wildname} piece is not
wild and therefore equals the \emph{source} piece) replaces the wildcard portion
of the piece in \emph{to-wildname} and the value produced is used in the result.
X3J13 voted in June 1989 \issue{PATHNAME-COMPONENT-CASE} to
require \cdf{translate-pathname} to map customary case in argument
pathnames to the customary case in returned pathnames
(see section~\ref{PATHNAME-COMPONENT-CASE-SECTION}).
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.
\begin{lisp}
(wild-pathname-p (make-pathname :name :wild)) \EV\ t \\*
(wild-pathname-p (make-pathname :name :wild) :name) \EV\ t \\
(wild-pathname-p (make-pathname :name :wild) :type) \EV\ nil \\
(wild-pathname-p (pathname "S:>foo>**>")) \EV\ t~~~~~~~~~;\textrm{Maybe} \\*
(wild-pathname-p (make-pathname :name "F*O")) \EV\ t~~~~~;\textrm{Probably}
\end{lisp}
One cannot rely on \cdf{rename-file} to handle wild pathnames in a predictable
manner. However, one can use \cdf{translate-pathname} explicitly to control
the process.
\begin{lisp}
(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))))
\end{lisp}
\end{defun}
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.
\begin{lisp}
(rename-files "/usr/me/*.lisp" "/dev/her/*.l") \\*
~~~\textrm{renames}\=~~/usr/me/init.lisp \\
\textrm{to}~~/dev/her/init.l \\
\\
(rename-files "/usr/me/pcl*/*" "/sys/pcl/*/") \\*
~~~\textrm{renames}~~/usr/me/pcl-5-may/low.lisp \\*
\textrm{to}~~/sys/pcl/pcl-5-may/low.lisp \\*
~~~\textrm{(in some file systems the result might be}~/sys/pcl/5-may/low.lisp\textrm{)} \\
\\
(rename-files "/usr/me/pcl*/*" "/sys/library/*/") \\*
~~~\textrm{renames}~~/usr/me/pcl-5-may/low.lisp \\*
\textrm{to}~~/sys/library/pcl-5-may/low.lisp \\*
~~~\textrm{(in some file systems the result might be}~/sys/library/5-may/low.lisp\textrm{)} \\
\\
(rename-files "/usr/me/foo.bar" "/usr/me2/") \\*
~~~\textrm{renames}~~/usr/me/foo.bar \\
\textrm{to}~~/usr/me2/foo.bar \\
\\
(rename-files "/usr/joe/*-recipes.text" \\*
~~~~~~~~~~~~~~"/usr/jim/personal/cookbook/joe's-*-rec.text") \\*
~~~\textrm{renames}~~/usr/joe/lamb-recipes.text \\*
\textrm{to}~~/usr/jim/personal/cookbook/joe's-lamb-rec.text~~~~ \\
~~~\textrm{renames}~~/usr/joe/veg-recipes.text \\*
\textrm{to}~~/usr/jim/personal/cookbook/joe's-veg-rec.text~~~~~ \\
~~~\textrm{renames}~~/usr/joe/cajun-recipes.text \\*
\textrm{to}~~/usr/jim/personal/cookbook/joe's-cajun-rec.text~~~ \\
~~~\textrm{renames}~~/usr/joe/szechuan-recipes.text \\*
\textrm{to}~~/usr/jim/personal/cookbook/joe's-szechuan-rec.text
\end{lisp}
The following examples use UNIX syntax and the wildcard conventions of one
particular version of UNIX.
\begin{lisp}
(namestring \\*
~~(translate-pathname "/usr/dmr/hacks/frob.l" \\*
~~~~~~~~~~~~~~~~~~~~~~"/usr/d*/hacks/*.l" \\*
~~~~~~~~~~~~~~~~~~~~~~"/usr/d*/backup/hacks/backup-*.*")) \\*
~~~\EV\ "/usr/dmr/backup/hacks/backup-frob.l"
\end{lisp}
\goodbreak
\begin{lisp}
(namestring \\*
~~(translate-pathname "/usr/dmr/hacks/frob.l" \\*
~~~~~~~~~~~~~~~~~~~~~~"/usr/d*/hacks/fr*.l" \\*
~~~~~~~~~~~~~~~~~~~~~~"/usr/d*/backup/hacks/backup-*.*")) \\*
~~~\EV\ "/usr/dmr/backup/hacks/backup-ob.l"
\end{lisp}
The following examples are similar to the preceding examples
but use two different hosts; host \cdf{U} supports a UNIX file system
and host \cdf{V} supports a VAX/VMS file system. Note the translation
of file type (from \cdf{l} to \cdf{LSP}) and the change of alphabetic case conventions.
\begin{lisp}
(namestring \\*
~~(translate-pathname "U:/usr/dmr/hacks/frob.l" \\*
~~~~~~~~~~~~~~~~~~~~~~"U:/usr/d*/hacks/*.l" \\*
~~~~~~~~~~~~~~~~~~~~~~"V:SYS\$DISK:[D*.BACKUP.HACKS]BACKUP-*.*")) \\*
~~~\EV\ "V:SYS\$DISK:[DMR.BACKUP.HACKS]BACKUP-FROB.LSP"
\end{lisp}
\begin{lisp}
(namestring \\*
~~(translate-pathname "U:/usr/dmr/hacks/frob.l" \\*
~~~~~~~~~~~~~~~~~~~~~~"U:/usr/d*/hacks/fr*.l" \\*
~~~~~~~~~~~~~~~~~~~~~~"V:SYS\$DISK:[D*.BACKUP.HACKS]BACKUP-*.*")) \\*
~~~\EV\ "V:SYS\$DISK:[DMR.BACKUP.HACKS]BACKUP-OB.LSP"
\end{lisp}
The next example is a version of the
function \cdf{translate-logical-pathname} (simplified a bit) for a logical host named \cdf{FOO}.
The points of interest are the use of \cdf{pathname-match-p} as
a \cd{:test} argument for \cdf{assoc} and the use of \cdf{translate-pathname}
as a substrate for \cdf{translate-logical-pathname}.
\begin{lisp}
(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/*/"))) \\*
~~~\EV\ \#P"U:/lib/foo/basic.l"
\end{lisp}
\newpage%required
\subsection{Logical Pathnames}
\label{LOGICAL-PATHNAMES-SECTION}
Pathname values are not portable, but sometimes they must be mentioned in a
program (for example, the names of files containing the program and the data
used by the program).
X3J13 voted in June 1989 \issue{PATHNAME-LOGICAL} to provide
some facilities for portable pathname values. The idea is to provide
a portable framework for pathname values; these logical pathnames
are then mapped to physical (that is, actual) pathnames by a set of implementation-dependent
or site-dependent rules. The logical pathname facility therefore
separates the concerns of program writing and user software architecture
from the details of how a software system is embedded in a particular
file system or operating environment.
Pathname values are not portable because not all Common Lisp implementations use
the same operating system and file name syntax varies widely among operating
systems. In addition, corresponding files at two different sites may have
different names even when the operating system is the same; for example, they
may be on different directories or different devices. The Common Lisp logical
pathname system defines a particular pathname structure and namestring syntax
that must be supported by all implementations.
\begin{defun}[Class]
logical-pathname
This is a subclass of \cdf{pathname}.
\end{defun}
\subsubsection{Syntax of Logical Pathname Namestrings}
The syntax of a logical pathname namestring is as follows:
\begin{tabbing}
\emph{logical-namestring\/} ::= \Mopt{host\/ \cd{:}} \Mopt{\cd{;}} \Mstar{directory\/ \cd{;}}
\Mopt{name} \Mopt{\cd{.} type\/ \Mopt{\cd{.} version}}
\end{tabbing}
Note that a logical namestring has no \emph{device} portion.
\begin{tabbing}
\emph{host\/} ::= \emph{word\/} \\*
\emph{directory\/} ::= \emph{word\/} {\Mor} \emph{wildcard-word\/} {\Mor} \emph{wildcard-inferiors\/} \\
\emph{name\/} ::= \emph{word\/} {\Mor} \emph{wildcard-word\/} \\
\emph{type\/} ::= \emph{word\/} {\Mor} \emph{wildcard-word\/} \\
\emph{version\/} ::= \emph{word\/} {\Mor} \emph{wildcard-word\/} \\
\emph{word\/} ::= \Mplus{letter\/ {\Mor} digit\/ {\Mor} \cdf{-}} \\
\emph{wildcard-word\/} ::= \Mopt{word} \cdf{*} \Mstar{word\/ \cdf{*}} \Mopt{word} \\*
\emph{wildcard-inferiors\/} ::= \cdf{**}
\end{tabbing}
A \emph{word} consists of one or more uppercase letters, digits, and hyphens.
A \emph{wildcard word} consists of one or more asterisks, uppercase letters,
digits, and hyphens, including at least one asterisk, with no two
asterisks adjacent.
Each asterisk matches a sequence of zero or more
characters. The wildcard word \cdf{*} parses as \cd{:wild}; all others parse
as strings.
Lowercase letters may also appear in a word or wildcard word
occurring in a namestring. Such letters are converted to uppercase
when the namestring is converted to a pathname.
The consequences of using other characters are unspecified.
The \emph{host} is a word that has been defined as a logical pathname host by
using \cdf{setf} with the function \cdf{logical-pathname-translations}.
There is no device, so the device component of a logical pathname is
always \cd{:unspecific}. No other component of a logical pathname can be \cd{:unspecific}.
Each \emph{directory} is a word, a wildcard word, or \cdf{**} (which is parsed as \cd{:wild-inferiors}).
If a semicolon precedes the directories, the directory component is
relative; otherwise it is absolute.
The \emph{name} is a word or a wildcard word.
The \emph{type} is a word or a wildcard word.
The \emph{version} is a positive decimal integer or the word \cdf{NEWEST} (which is parsed
as \cd{:newest}) or \cdf{*} (which is parsed as \cd{:wild}).
The letters in \cdf{NEWEST} can be in either alphabetic case.
The consequences of using any value not specified here as a logical
pathname component are unspecified.
The null string \cd{""} is not a valid value for any component of a logical pathname,
since the null string is not a word or a wildcard word.
\subsubsection{Parsing of Logical Pathname Namestrings}
Logical pathname namestrings are recognized by the functions \cdf{logical-pathname}
and \cdf{translate-logical-pathname}. The host portion
of the logical pathname namestring and its following colon must appear in
the namestring arguments to these functions.
The function \cdf{parse-namestring} recognizes a logical pathname
namestring when the \emph{host} argument is logical or the \emph{defaults} argument is
a logical pathname. In this case the host portion of the logical
pathname namestring and its following colon are optional. If the host
portion of the namestring and the \emph{host} argument are both present and do
not match, an error is signaled.
The host argument is logical if it is supplied and came from
\cdf{pathname-host} of a logical pathname. Whether a host argument is logical