home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
dskutl
/
swp-ms10.ark
/
TRAMDF.IF2
< prev
next >
Wrap
Text File
|
1989-09-27
|
9KB
|
300 lines
{* -------------------------------------------------------------------------
* F I L E L I S T M A N A G E M E N T
* ------------------------------------------------------------------------- *}
{*
* For the FileManger, a list of files on the source disk is maintained in
* memory. It is a double-linked circular list containing one special entry
* which serves as the sentinel for the EnterFileInList sort procedure.
*
* Most of the procedures work on the 'current' (file) list entry. It is the
* entry pointed to by the global variable FileEntry.
*}
function GetFileEntryName: FullFileNames ;
{*
* Fetch the name of the current (file) entry and insert the separator
* between the primary file name and the extension.
*}
begin
with FileEntry^ do
GetFileEntryName:= Copy( Name, 1, 8 ) + '.' + Copy( Name, 9, 3 ) ;
end ; { of GetFileEntryName }
function IsDirectory: Boolean ;
{*
* Determine whether the current file list entry contains a subdirectoryname,
* thus not a filename or a volumename.
*}
begin
IsDirectory:= ( SubDirectory in FileEntry^.Attr ) ;
end ; { of IsDirectory }
function IsFile: Boolean ;
{*
* Determine whether the current file list entry contains a filename, and
* thus not a volumename or a subdirectoryname.
*}
begin
IsFile:= ( FileEntry^.Attr*[Volume,SubDirectory] = [] ) ;
end ; { of IsFile }
procedure AdvanceFileEntry ;
{*
* Advance the pointer FileEntry to the next (file) entry in the list. If
* at the end of the list, wrap to the first entry in the list.
*}
begin
FileEntry:= FileEntry^.Next ;
FileIndex:= Succ( FileIndex ) ;
if FileEntry=TailFileList then
begin
FileEntry:= HeadFileList ;
FileIndex:= 1 ;
WriteLn ;
end ; { of if }
end ; { of AdvanceFileEntry }
procedure BackupFileEntry ;
{*
* Set the pointer FileEntry to the preceding entry in the filelist. If
* at the beginning of the list, wrap to the last entry in the list.
*}
begin
FileEntry:= FileEntry^.Prev ;
FileIndex:= Pred( FileIndex ) ;
if FileEntry=TailFileList then
begin
FileEntry:= FileEntry^.Prev ;
FileIndex:= SizeFileList ;
WriteLn ;
end ; { of if }
end ; { of BackupFileEntry }
procedure DeleteFileEntry ;
{*
* Remove the current entry from the filelist and select the logical next
* entry as the current entry. If the entry is marked, an implicit and
* silent UntagFileEntry is performed.
*}
var
FreeEntry: FileEntryPtr ; { Entry to be released }
begin
if FileEntry^.Mark then
SizeTaggedFiles:= SizeTaggedFiles - FileEntry^.Size ;
{*
* If the first entry in the list is to be deleted, move the head pointer
* to the next entry in the list.
*}
if HeadFileList=FileEntry then
HeadFileList:= HeadFileList^.Next ;
{*
* Detach the entry to be deleted from the filelist.
*}
FileEntry^.Prev^.Next:= FileEntry^.Next ;
FileEntry^.Next^.Prev:= FileEntry^.Prev ;
SizeFileList:= Pred( SizeFileList ) ;
{*
* Set the 'current' entry to the logical next entry in the list.
*}
FreeEntry:= FileEntry ; { Save pointer to the former entry }
FileEntry:= FileEntry^.Next ;
if FileEntry=TailFileList then
begin
FileEntry:= HeadFileList ;
FileIndex:= 1 ;
end ; { of if }
Dispose( FreeEntry ) ; { Finally, release the file entry }
end ; { of DeleteFileEntry }
procedure DisplayFileEntry ;
{*
* Display the name and the attributes of the current (file) entry.
*}
begin
with FileEntry^ do
begin
WriteLn ;
Write( FileIndex:3, ' : ', GetFileEntryName, ' ' ) ;
if ReadOnly in Attr then Write( 'R' ) else Write( '-' ) ;
if Hidden in Attr then Write( 'H' ) else Write( '-' ) ;
if System in Attr then Write( 'S' ) else Write( '-' ) ;
if Volume in Attr then Write( 'V' ) else Write( '-' ) ;
if SubDirectory in Attr then Write( 'D' ) else Write( '-' ) ;
if Archive in Attr then Write( 'A' ) else Write( '-' ) ;
Write( ' ', Size:5, 'K :' ) ;
if Mark then Write( '*' ) else Write( ' ' ) ;
end ; { of with }
end ; { of DisplayFileEntry }
procedure EnterFileInList ;
{*
* Enter the file, specified in FileEntry, in the filelist. If the
* filename is already in the list, the filesize is set to the larger
* of the two.
*
* Note that the last entry of the file list is a sentinel, containing
* the greatest possible file name.
*}
var
NextEntry: FileEntryPtr ; { Pointer to next element in list }
begin
NextEntry:= HeadFileList ;
while NextEntry<>Nil do
begin
if NextEntry^.Name=FileEntry^.Name then
{*
* The file name is already entered in the file list. This can happen
* in CP/M only. Save the biggest of the two file sizes and release the
* file-entry.
*}
begin
if NextEntry^.Size<FileEntry^.Size then
NextEntry^.Size:= FileEntry^.Size ;
NextEntry:= Nil ; { Terminate loop }
Dispose( FileEntry ) ;
end
else
if NextEntry^.Name>FileEntry^.Name then
{*
* The file name is not in the file list right now. Enter it in the list.
* Adjust the head pointer if necessary.
*}
begin
FileEntry^.Next := NextEntry ;
FileEntry^.Prev := NextEntry^.Prev ;
NextEntry^.Prev := FileEntry ;
FileEntry^.Prev^.Next:= FileEntry ;
if NextEntry=HeadFileList then
HeadFileList:= FileEntry ;
SizeFileList:= Succ( SizeFileList ) ;
NextEntry:= Nil ; { Terminate loop }
end
else
{*
* If the file name is in the list, it must after the entry in the list
* pointed to by NextEntry.
*}
NextEntry:= NextEntry^.Next ;
end ; { of while }
end ; { of EnterFileInList }
procedure PresetFileList ;
{*
* Remove all entries, if any, from the filelist and make sure that the
* filelist contains only the sentinel entry.
*}
var
NextEntry: FileEntryPtr ; { Next entry in filelist }
begin
{*
* Remove all but the sentinel entry in the filelist.
*}
NextEntry:= HeadFileList ;
while NextEntry<>Nil do
if NextEntry=TailFileList then
begin
HeadFileList:= NextEntry ; { Save ptr to sentinel entry }
NextEntry := Nil ; { Terminate loop }
end
else
begin
NextEntry:= NextEntry^.Next ; { Address of successor }
Dispose( NextEntry^.Prev ) ; { Release preceding entry }
end ; { of if/while }
{*
* The list contains now either zero or one entry. In the former case a
* sentinel entry is added to the list.
*}
if HeadFileList=Nil then
begin
New( HeadFileList ) ;
TailFileList:= HeadFileList ;
end ; { of if }
FileIndex := 0 ;
SizeFileList := 0 ;
SizeTaggedFiles:= 0 ;
with HeadFileList^ do
begin
Next:= HeadFileList ;
Prev:= HeadFileList ;
Name:= #$FF#$FF#$FF#$FF#$FF#$FF#$FF#$FF#$FF#$FF#$FF ;
Attr:= [] ;
Size:= 0 ;
Mark:= False ;
end ; { of with }
end ; { of PresetFileList }
procedure TagFileEntry ;
{*
* Mark the current (file) entry to be used in one of the 'mass' operations
* of the file manager. The aggregate size of the tagged files is displayed.
* An entry which does not correspond to a file cannot be marked!
*}
begin
if IsFile then
if not FileEntry^.Mark then
begin
FileEntry^.Mark:= True ;
SizeTaggedFiles:= SizeTaggedFiles + FileEntry^.Size ;
Write( 'Tagged size =', SizeTaggedFiles:4, 'K' ) ;
end ; { of if/if }
end ; { of TagFileEntry }
procedure TagMultipleFileEntries ;
{*
* Tag those file entries in the file list which match a user-specified
* wildcard mask.
*}
var
SavedFileEntry: FileEntryPtr ; { Save area for current file }
RawFileName : FullFileNames ; { Wildcard mask / file name }
FileNameMask : FileDescriptors ; { Expanded file name mask }
FileName : FileDescriptors ; { Filename to check against mask }
begin
SavedFileEntry:= FileEntry ;
Write( ' Enter mask : ' ) ;
ReadLn( RawFileName ) ;
SplitFileName( FileNameMask, RawFileName ) ;
FileEntry:= HeadFileList ;
while FileEntry<>TailFileList do
begin
if IsFile then
begin
RawFileName:= GetFileEntryName ;
SplitFileName( FileName, RawFileName ) ;
if SameName( FileName, FileNameMask, NE_Format ) then
begin
WriteLn ;
Write( 'Tagging --> ', RawFileName, ' : ' ) ;
TagFileEntry ;
end ; { of if }
end ; { of if }
FileEntry:= FileEntry^.Next ;
end ; { of while }
FileEntry:= SavedFileEntry ;
end ; { of TagMultipleFileEntries }
procedure UntagFileEntry ;
{*
* Remove the mark from the current (file) entry. The updated aggregate
* size of the remaining tagged files is displayed.
*}
begin
if FileEntry^.Mark then
begin
FileEntry^.Mark:= False ;
SizeTaggedFiles:= SizeTaggedFiles - FileEntry^.Size ;
Write( 'Tagged size =', SizeTaggedFiles:4, 'K' ) ;
end ; { of if }
end ; { of UntagFileEntry }