PFSNames.mesa
Copyright Ó 1988, 1991 by Xerox Corporation. All rights reserved.
Carl Hauser, June 8, 1989 5:17:24 pm PDT
Willie-s, August 20, 1991 12:18 pm PDT
~
BEGIN
ROPE: TYPE = Rope.ROPE;
Comparison: TYPE = Basics.PartialComparison;
PATH: TYPE = REF PathObject;
PathObject: TYPE = RECORD [REF PrivatePathObject];
PrivatePathObject: TYPE;
ComponentNamePart:
TYPE =
RECORD [base:
ROPE, start, len:
NAT];
0 <= start <= start+len <= base.length expected but not enforced; clients are to consider ComponentNamePart's as immutable.
Component:
TYPE =
RECORD [
name: ComponentNamePart ¬ [NIL, 0, 0],
version: Version ¬ [none]
];
VersionKind: TYPE = {numeric, none, lowest, highest, next, all};
Version:
TYPE =
RECORD [
versionKind: VersionKind,
version:
CARDINAL ¬ 0
meaningful only if versionKind=numeric; -- this is really a variant record, but doing it this way works better.
];
EmptyPath: READONLY PATH; -- non-NIL PATH semantically equivalent to NIL
Operations on Paths
ExpandName:
PROC [name:
PATH, wDir:
PATH ¬
NIL]
RETURNS [
PATH];
If name is not absolute and wDir is absolute then prepends wDir to name.
ComponentCount:
PROC [name:
PATH]
RETURNS [count:
NAT];
The number of components making up name.
Compare: PROC [n1, n2: PATH, case: BOOL ¬ FALSE] RETURNS [Comparison];
Equal:
PROC [n1, n2:
PATH, case:
BOOL ¬
FALSE]
RETURNS [
BOOL] ~
INLINE {
RETURN[Compare[n1, n2, case]=equal]
};
SubName:
PROC [name:
PATH, start:
NAT ¬ 0, count:
NAT ¬
NAT.
LAST, absolute, directory:
BOOL ¬
FALSE]
RETURNS [
PATH];
The result PATH takes its absolute and directory fields from the arguments (not from name).
ShortName:
PROC [name:
PATH]
RETURNS [shortName: Component];
The last component of a PATH
ShortNameRope:
PROC [name:
PATH]
RETURNS [shortName:
ROPE];
The last component of a PATH as a ROPE (for convenience)
Cat:
PROC [n1, n2:
PATH]
RETURNS [
PATH];
Ignores n1.directory, n2.absolute;
Fetch:
PROC [name:
PATH, index:
NAT]
RETURNS [Component];
NOT index IN [0..ComponentCount[name]) => BoundsFault.
ComponentRope:
PROC [comp: Component]
RETURNS [
ROPE] ~
INLINE {
RETURN [Rope.Substr[comp.name.base, comp.name.start, comp.name.len]];
};
IsAPrefix:
PROC [prefix, name:
PATH]
RETURNS [isa:
BOOL, suffix:
PATH];
If `prefix' is a prefix of name, returns isa=TRUE and the rest of name in `suffix'. Otherwise, isa=FALSE and `suffix' is meaningless.
IsADirectory:
PROC [name:
PATH]
RETURNS [
BOOL];
name.directory
EnsureDirectory:
PROC [name:
PATH]
RETURNS [
PATH];
returns name with TRUE substituted for name.directory;
IsAbsolute:
PROC [name:
PATH]
RETURNS [
BOOL];
name.absolute
EnsureAbsolute:
PROC [name:
PATH]
RETURNS [
PATH];
returns name with TRUE substituted for name.absolute;
StripVersionNumber:
PROC [name:
PATH]
RETURNS [
PATH];
returns name with [none[]] substituted for name.lastComp.version.
SetVersionNumber:
PROC [name:
PATH, version: Version]
RETURNS [
PATH];
returns name with version substituted for name.lastComp.version.
ReplaceShortName:
PROC [name:
PATH, newShortName: Component]
RETURNS [
PATH];
returns name with newShortName substituted for name.lastComp
ReplaceComponent:
PROC [name:
PATH, index:
NAT, new: Component]
RETURNS [
PATH];
In absolute names, returns name with new substituted for the position-th component.
InASubdirectory:
PROC [parent:
PATH, name:
PATH]
RETURNS [
BOOL];
IsAPrefix[parent, name].isa AND ComponentCount[Directory[IsAPrefix[parent, name].suffix]]#0
FirstSubdirectory:
PROC [parent:
PATH, name:
PATH]
RETURNS [
PATH];
If NOT InASubdirectory[parent, name] then returns NoWDir. Otherwise, returns the part of name up to and including the first subdirectory after the end of parent.
Directory:
PROC [name:
PATH]
RETURNS [
PATH];
Return the directory part of the name.
Parent:
PROC [name:
PATH]
RETURNS [
PATH];
If name is a directory, then returns the parent directory. If name is a file, then returns the containing directory. In either case, this means that Parent returns the directory which contains the object denoted by name.
ConstructComponent:
PROC [name: ComponentNamePart, version: Version ¬ [none]]
RETURNS [Component];
VersionToRope:
PROC [Version]
RETURNS [
ROPE];
Replace:
PROC [base:
PATH, start:
INT ¬ 0, len:
NAT ¬
NAT.
LAST, with:
PATH]
RETURNS [
PATH];
ComponentProc: TYPE = PROC[comp: Component, ref: REF];
SeparatorProc: TYPE = PROC[separatorPresent: BOOL, ref: REF];
Map:
PROC [name:
PATH, componentProc: ComponentProc,
separatorProc: SeparatorProc, ref:
REF ¬
NIL];
alternately calls separatorProc and componentProc (beginning and ending with separatorProc). separatorPresent is name.absolute for the first call, name.directory for the last and TRUE for all others.
NonNIL:
PROC [p:
PATH]
RETURNS [
PATH] ~
INLINE {
RETURN[IF p=NIL THEN EmptyPath ELSE p];
};
Rather than forever testing whether or not a path is NIL, it is better to convert NIL to an explicit empty path for some operations.
Operations on Components
CompareComponents: PROC [c1, c2: Component, case: BOOL ¬ FALSE] RETURNS [Comparison];
EqualComponents:
PROC [c1, c2: Component, case:
BOOL ¬
FALSE]
RETURNS [
BOOL] ~
INLINE {
RETURN[CompareComponents[c1, c2, case]=equal];
};