! Directory and file information routines. J. Butler Nov 84
! DIRS LIST returns a list of all directories which match MASK
! FILES LIST returns a list of all files in a directory which match MASK.
! This include file is one of a number of files comprising a source "library".
! It does not have any defined level of support.
! you'll need these...
!%include "inc:fs.imp"
!%include "inc:util.imp"
!%include "inc:fsutil.imp"
recordformat cell fm(string (31) datum, record (cell fm) name link)
conststring (1) pathseps = ":"
constinteger max partition = 7
externalroutinespec smove block(integer len, from, to)
record (cell fm) map dir list(string (255) mask)
!Grab the list of directories on this FS matching MASK and return it as a
!linked list on the heap. A pointer to the head of the list is returned
!Via %result. NIL indicates no matches. Failure conditions will generate
!Events.
record (cell fm) head
record (cell fm) name tail
integer part, dirtot
routine do part(integer part)
string (255) s
string (31) name
integer i, l
bytearray buff(0:511)
on 3 start ; return ; finish {for filestores with fewer partitions}
s = tostring(part+'0')
l = fcommr('¬'<<8,s,buff(0),512)
for i = 0, 8, 504 cycle
smove block(8, addr(buff(i)), addr(name)+1)
length(name) = 8
length(name) = length(name)-1 while name # "" and charno(name, length(name)) <= ' '
unless name = "---" start
!??! length(name) = 31 %if length(name) > 31
if matches(name, mask) start
tail_link == new(head); tail == tail_link; tail_link == nil
tail_datum = name
finish
finish
repeat
end
head = 0; tail == head
for part = 0, 1, MAX PARTITION cycle
do part(part<<1); do part(part<<1+1)
repeat
result == head_link
end
record (cell fm) map files list(string (31) mask)
!Grab the list of accessible files in this directory which match MASK and
!return it on the heap.
!A pointer to the head of the list is returned via %result. NIL indicates
!no matches. Failures will generate events.
!MASK is of form <pathname> <pathsep> <filename>. Both may be wild.
integer i
record (cell fm) head
record (cell fm) name tail, dirs, old
string (31) dir
routine get files(string (31) dir)
integer ad, ptr, len
string (31) name
predicate open directory(string (31) dir)
on 3,9 start ; false ; finish
dir = dir.pathseps if dir # ""
connect file(dir."directory", 0, ad, len)
ptr = 0
true
end
routine close directory
heapput(ad)
end
predicate next line(string (*) name s)
integer c
s = ""
false if ptr = len
cycle
c = byteinteger(ad+ptr)
s = s.tostring(c); ptr = ptr+1
repeatuntil c = nl
length(s) = length(s) - 1
true
end
if open directory(dir) start
while next line(name) cycle
if matches(name, mask) start
tail_link == new(head); tail == tail_link; tail_link == nil
name = dir.pathseps.name if dir # ""
tail_datum = name
finish
repeat
close directory
finish
end
!Resolve MASK on last instance of pathsep
i = length(mask)
i=i-1 while i # 0 and substring(mask,i,i) # pathseps
if i > 0 start
dir = substring(mask,1,i); length(dir) = length(dir) - 1
mask = substring(mask,i+1,length(mask))
finishelse dir = ""
head = 0; tail == head
if wildness(dir) = 0 then get files(dir) elsestart
dirs == dir list(dir)
while dirs ## nil cycle
get files(dirs_datum) unless mask = ""
old == dirs
dirs == dirs_link
dispose(old)
repeat
finish
result == head_link
end
endoffile