Category : Pascal Source Code
Archive   : TJOCKOT1.ZIP
Filename : TOTLINK.PAS

 
Output of file : TOTLINK.PAS contained in archive : TJOCKOT1.ZIP
{ Copyright 1991 TechnoJock Software, Inc. }
{ All Rights Reserved }
{ Restricted by License }

{ Build # 1.00 }

Unit totLINK;
{$I TOTFLAGS.INC}

{
Development Notes:

}

INTERFACE

Uses DOS,CRT,
totSTR;

Const
NoFiles: string[20] = 'No Files';

Type

tFileInfo = record
FileName: string[12];
Attr: byte;
Time: longint;
Size: longint;
LoadID: longint;
end; {tFileInfo}

DLLNodePtr = ^DLLNodeObj;
pDLLNodeOBJ = ^DLLNodeOBJ;
DLLNodeOBJ = Object {this object is not extensible}
vNextPtr: DLLNodePtr;
vPrevPtr: DLLNodePtr;
vDataPtr: pointer;
vSize: longint;
vStatus: byte; {selectable, selected}
{methods...}
procedure FreeData;
function NextPtr: DLLNodePtr;
function PrevPtr: DLLNodePtr;
function GetStatus(BitPos:byte): boolean;
procedure SetStatus(BitPos:byte;On:boolean);
function GetStatusByte: byte;
procedure SetStatusByte(Val:byte);
end; {DLLNodeOBJ}

DLLPtr = ^DLLOBJ;
pDLLOBJ = ^DLLOBJ;
DLLOBJ = Object
vStartNodePtr: DLLNodePtr;
vEndNodePtr: DLLNodePtr;
vActiveNodePtr: DLLNodePtr;
vTotalNodes: longint;
vActiveNodeNumber: longint;
vSortID: shortInt;
vSortAscending: boolean;
vSorted: boolean;
vMaxNodeSize : longint;
{methods...}
constructor Init;
function Add(var TheData;Size:longint): integer;
function Change(Node:DLLNodePtr;var TheData;Size:longint): integer;
function InsertBefore(Node:DLLNodePtr;var TheData;Size:longint): integer;
procedure Get(var TheData);
procedure GetNodeData(Node:DLLNodePtr;Var TheData);
function GetNodeDataSize(Node:DLLNodePtr):longint;
function GetMaxNodeSize: longint;
procedure Advance(Amount:longint);
procedure Retreat(Amount:longint);
function NodePtr(NodeNumber:longint): DLLNodePtr;
procedure Jump(NodeNumber:longint);
procedure ShiftActiveNode(NewNode: DLLNodePtr; NodeNumber: longint);
procedure DelNode(Node:DLLNodePtr);
procedure DelAllStatus(BitPos:byte;On:boolean);
function TotalNodes: longint;
function ActiveNodeNumber: longint;
function ActiveNodePtr: DLLNodePtr;
function StartNodePtr: DLLNodePtr;
function EndNodePtr: DLLNodePtr;
procedure EmptyList;
procedure Sort(SortID:shortint;Ascending:boolean);
function WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean; VIRTUAL;
procedure SwapNodes(Node1,Node2:DLLNodePtr); VIRTUAL;
function GetStr(Node:DLLNodePtr;Start,Finish: longint):string; VIRTUAL;
destructor Done;
end; {DLLOBJ}

StrDLLPtr = ^StrDLLOBJ;
pStrDLLOBJ = ^StrDLLOBJ;
StrDLLOBJ = object (DLLOBJ)
{methods ...}
constructor Init;
function Add(Str:string): integer;
function Change(Node:DLLNodePtr;Str: string): integer;
function InsertBefore(Node:DLLNodePtr;Str:string): integer;
function WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean; VIRTUAL;
function GetStr(Node:DLLNodePtr;Start,Finish: longint):string; VIRTUAL;
destructor Done;
end; {StrDLLOBJ}

FileDLLPtr = ^FileDLLOBJ;
pFileDLLOBJ = ^FileDLLOBJ;
FileDLLOBJ = object (DLLOBJ)
vFileMasks: string;
vFileAttrib: word;
{methods ...}
constructor Init;
procedure FillList;
procedure SetFileDetails(FileMasks:string; FileAttrib: word);
procedure FillNewMask(FileMasks:string);
function GetLongStr(Node:DLLNodePtr):string;
procedure GetFileRecord(var FileInfo:tFileInfo; Item:longint);
function GetFileMask:string;
function WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean; VIRTUAL;
procedure SwapNodes(Node1,Node2:DLLNodePtr); VIRTUAL;
function GetStr(Node:DLLNodePtr;Start,Finish: longint):string; VIRTUAL;
destructor Done;
end; {FileDLLOBJ}

function Subdirectory(B : byte):boolean;
function FileAttribs(B:byte):string;
function LongName(Info: tFileInfo):string;
procedure LINKInit;

IMPLEMENTATION
{|||||||||||||||||||||||||||||||||||||||||||||}
{ }
{ M i s c. P r o c s & F u n c s }
{ }
{|||||||||||||||||||||||||||||||||||||||||||||}
function Subdirectory(B : byte):boolean;
begin
Subdirectory := ((B and Directory) = Directory);
end; {Subdirectory}

function FileAttribs(B:byte):string;
var
S : string;
begin
S := ' ';
If ((B and ReadOnly) = Readonly) then
S[1] := 'R';
If ((B and Hidden) = Hidden) then
S[2] := 'H';
If ((B and SysFile) = SysFile) then
S[3] := 'S';
If ((B and Archive) = Archive) then
S[4] := 'A';
FileAttribs := S;
end; {FileAttribs}

function LongName(Info: tFileInfo):string;
{}
var
DT :datetime;
S: String;
begin
S := padleft(Info.FileName,12,' ');
UnPackTime(Info.Time,DT);
if Subdirectory(Info.Attr) then {add file size}
S := S + Padright('',8,' ')
else
S := S + Padright(InttoStr(Info.Size),8,' ');
S := S + ' ';
with DT do
begin
Case Month of
1 : S := S + 'Jan ';
2 : S := S + 'Feb ';
3 : S := S + 'Mar ';
4 : S := S + 'Apr ';
5 : S := S + 'May ';
6 : S := S + 'Jun ';
7 : S := S + 'Jul ';
8 : S := S + 'Aug ';
9 : S := S + 'Sep ';
10: S := S + 'Oct ';
11: S := S + 'Nov ';
12: S := S + 'Dec ';
end; {case}
S := S + Padright(InttoStr(Day),2,'0')+','+IntToStr(Year)+' ';
if Hour > 12 then
S := S + Padright(IntToStr(Hour-12),2,' ')+':'+Padright(IntToStr(min),2,'0')+'p'
else
S := S + Padright(IntToStr(Hour),2,' ')+':'+Padright(IntToStr(min),2,'0')+'a';
S := S + ' '+FileAttribs(Info.Attr);
end;
LongName := S;
end; {LongName}
{||||||||||||||||||||||||||||||||||||||||||||||}
{ }
{ D L L N o d e O b j M E T H O D S }
{ }
{||||||||||||||||||||||||||||||||||||||||||||||}
procedure DLLNodeObj.FreeData;
{}
begin
if (vDataPtr <> Nil) and (vSize > 0) then
begin
Freemem(vDataPtr,vSize);
vDataPtr := nil;
vSize:= 0;
end;
end; {DLLNodeObj.FreeData}

function DLLNodeObj.NextPtr: DLLNodePtr;
{}
begin
NextPtr := vNextPtr;
end; {DLLNodeOBJ.NextPtr}

function DLLNodeObj.PrevPtr: DLLNodePtr;
{}
begin
PrevPtr := vPrevPtr;
end; {DLLNodeOBJ.PrevPtr}

function DLLNodeObj.GetStatus(BitPos:byte): boolean;
{}
var TestByte: Byte;
begin
if BitPos > 7 then
GetStatus := false
else
begin
Testbyte := vStatus;
TestByte := TestByte SHR BitPos; {move to end bit}
GetStatus := odd(TestByte);
end;
end; {DLLNodeOBJ.GetStatus}

procedure DLLNodeObj.SetStatus(BitPos:byte; On:boolean);
{}
var
Test : integer;
begin
if BitPos <= 7 then
begin
if On then
begin
Test := 1 SHL BitPos;
vStatus := vStatus or Test
end
else
begin
Test := not (1 SHL BitPos);
vStatus := vStatus and Test;
end;
end;
end; { DLLNodeObj.SetStatus }

function DLLNodeObj.GetStatusByte: byte;
{}
begin
GetStatusByte := vStatus;
end; {DLLNodeObj.GetStatusByte}

procedure DLLNodeObj.SetStatusByte(Val:byte);
{}
begin
vStatus := Val;
end; {DLLNodeObj.SetStatusByte}
{|||||||||||||||||||||||||||||||||||||}
{ }
{ D L L O b j M E T H O D S }
{ }
{|||||||||||||||||||||||||||||||||||||}
constructor DLLOBJ.Init;
{}
begin
vStartNodePtr := nil;
vEndNodePtr := nil;
vActiveNodePtr := nil;
vTotalNodes := 0;
vActiveNodeNumber := 0;
vSortID := 0;
vSortAscending := true;
vSorted := true;
vMaxNodeSize := 0;
end; {DLLOBJ.Init}

function DLLOBJ.Add(var TheData; Size:Longint): integer;
{ Adds node after the ActiveNodePtr, and increments the
ActiveNodePtr.

Returns status indicating result of attemp to add.
Codes: 0 Success
1 Not enough memory
2 Not enough memory for data
}
var
Temp: DLLNodePtr;
begin
if MaxAvail < sizeOf(vStartNodePtr^) then
begin
Add := 1; {not enough memory}
exit;
end;
if vStartNodePtr = nil then
begin
getmem(vStartNodePtr,sizeof(vStartNodePtr^));
vStartNodePtr^.vPrevPtr := nil;
vActiveNodePtr := vStartNodePtr;
vActiveNodePtr^.vNextPtr := nil;
vActiveNodeNumber := 1;
vEndNodePtr := vActiveNodePtr;
end
else
begin
if vActiveNodePtr^.vNextPtr = nil then
begin
getmem(vActiveNodePtr^.vNextPtr,sizeof(vActiveNodePtr^));

vActiveNodePtr^.vNextPtr^.vPrevPtr := vActiveNodePtr;
vActiveNodePtr := vActiveNodePtr^.vNextPtr;
vActiveNodePtr^.vNextPtr := nil;
inc(vActiveNodeNumber);
vEndNodePtr := vActiveNodePtr;
end
else {insert a node}
begin
getmem(Temp,sizeof(temp^));
vActiveNodePtr^.vNextPtr^.vPrevPtr := Temp;
Temp^.vNextPtr := vActiveNodePtr^.vNextPtr;
Temp^.vPrevPtr := vActiveNodePtr;
vActiveNodePtr^.vNextPtr := Temp;
vActiveNodePtr := Temp;
inc(vActiveNodeNumber);
end;
end;
inc(vTotalNodes);
{now add the data to the node data pointer}
if MemAvail < Size then
begin
Add := 2; {not enough memory for data}
vActiveNodePtr^.vSize := 0;
vActiveNodePtr^.vDataPtr := nil;
exit;
end;
if Size > 0 then
begin
getmem(vActiveNodePtr^.vDataPtr,Size);
move(TheData,vActiveNodePtr^.vDataPtr^,Size);
if Size > vMaxNodeSize then
vMaxNodeSize := Size;
end
else
vActiveNodePtr^.vDataPtr := nil;
vActiveNodePtr^.vSize := Size;
vActiveNodePtr^.vStatus := 0;
Add := 0;
end; {DLLOBJ.Add}

function DLLOBJ.Change(Node:DLLNodePtr;var TheData; Size:Longint): integer;
{ Returns status indicating result of attemp to add.
Codes: 0 Success
2 Not enough memory for data
3 Invalid Node Ptr
}
begin
if node = nil then
Change := 3
else
begin
Node^.FreeData;
if MaxAvail < Size then
Change := 2
else
begin
Change := 0;
getmem(Node^.vDataPtr,Size);
move(TheData,Node^.vDataPtr^,Size);
Node^.vSize := Size;
end;
end;
end; {DLLOBJ.Change}

function DLLOBJ.InsertBefore(Node:DLLNodePtr;var TheData;Size:longint): integer;
{ Returns status indicating result of attemp to add.
Codes: 0 Success
1 Not enough memory
2 Not enough memory for data
3 Invalid Node Ptr
}
var
Temp: DLLNodePtr;
begin
if node = nil then
InsertBefore := 3
else if MaxAvail < sizeOf(Node^) then
InsertBefore:= 1 {not enough memory}
else
begin
if Node = vStartNodePtr then {add to head of list}
begin
getmem(Node^.vPrevPtr,sizeof(Node^));
Node^.vPrevPtr^.vNextPtr := Node;
Node := Node^.vPrevPtr;
Node^.vPrevPtr := nil;
vStartNodePtr := Node;
end
else
begin
getmem(Temp,sizeof(Temp^));
Node^.vPrevPtr^.vNextPtr := Temp;
Temp^.vPrevPtr := Node^.PrevPtr;
Node^.vPrevPtr := Temp;
Temp^.vNextPtr := Node;
Node := Temp;
end;
inc(vTotalNodes);
vActiveNodeNumber := 1;
vActiveNodePtr := vStartNodePtr;
if MemAvail < Size then
begin
InsertBefore := 2; {not enough memory for data}
Node^.vSize := 0;
Node^.vDataPtr := nil;
end
else
begin
if Size > 0 then
begin
getmem(Node^.vDataPtr,Size);
move(TheData,Node^.vDataPtr^,Size);
end
else
Node^.vDataPtr := nil;
Node^.vSize := Size;
InsertBefore := 0;
end;
end;
end; {DLLOBJ.InsertBefore}

procedure DLLOBJ.Get(Var TheData);
{}
begin
with vActiveNodePtr^ do
if vDataPtr <> Nil then
move(vDataPtr^,TheData,vSize);
end; {DLLOBJ.Get}

procedure DLLOBJ.GetNodeData(Node:DLLNodePtr;Var TheData);
{}
begin
with Node^ do
if vDataPtr <> Nil then
move(vDataPtr^,TheData,vSize);
end; {DLLOBJ.GetNodedata}

function DLLOBJ.GetNodeDataSize(Node:DLLNodePtr):longint;
{}
begin
with Node^ do
begin
if vDataPtr = Nil then
GetNodeDataSize := 0
else
GetNodeDataSize := vSize;
end;
end; {DLLOBJ.GetNodeDataSize}

function DLLOBJ.GetMaxNodeSize: longint;
{}
begin
GetMaxNodeSize := vMaxNodeSize;
end; {DLLOBJ.GetMaxNodeSize}

function DLLOBJ.GetStr(Node:DLLNodePtr;Start,Finish:longint): String;
{generic method..usually in descendant object}
var temp: string;
begin
if Start < 0 then Start := 0;
if Finish < 0 then Finish := 0;
{validate Start and Finish Parameters}
if ((Finish = 0) and (Start = 0))
or (Start > Finish) then {get full string}
begin
Start := 1;
Finish := 255;
end
else if Finish - Start > 254 then {too long to fit in string}
Finish := Start + 254;

if (Node = Nil)
or (Node^.vDataPtr = Nil)
or (Node^.vSize = 0)
or (Start > Node^.vSize) then
GetStr := ''
else
begin
if Finish > Node^.vSize then
Finish := Node^.vSize;
if Start = 0 then
inc(Start);
Move(mem[seg(Node^.vDataPtr^):ofs(Node^.vDataPtr^)+pred(Start)],Temp[1],succ(Finish-Start));
Temp [0] := chr(succ(Finish-Start));
GetStr := Temp;
end;
end; {DLLOBJ.GetStr}

procedure DLLOBJ.Advance(Amount:longint);
{}
var
I : longint;
begin
for I := 1 to Amount do
if vActiveNodePtr^.vNextPtr <> nil then
begin
vActiveNodePtr := vActiveNodePtr^.vNextPtr;
inc(vActiveNodeNumber);
end;
end; {DLLOBJ.Advance}

procedure DLLOBJ.Retreat(Amount:longint);
{}
var
I : longint;
begin
for I := 1 to Amount do
if vActiveNodePtr^.vPrevPtr <> nil then
begin
vActiveNodePtr := vActiveNodePtr^.vPrevPtr;
dec(vActiveNodeNumber);
end;
end; {DLLOBJ.Retreat}

procedure DLLOBJ.Jump(NodeNumber:longint);
{}
begin
if NodeNumber = 1 then
begin
vActiveNodePtr := vStartNodePtr;
vActiveNodeNumber := 1;
end
else
begin
if NodeNumber < vActiveNodeNumber then
Retreat(vActiveNodeNumber - NodeNumber)
else
Advance(NodeNumber - vActiveNodeNumber);
end;
end; {DLLOBJ.Jump}

procedure DLLOBJ.ShiftActiveNode(NewNode: DLLNodePtr; NodeNumber: longint);
{}
begin
vActiveNodePtr := NewNode;
vActiveNodeNumber := NodeNumber;
end; {DLLOBJ.ShiftActiveNode}

function DLLOBJ.NodePtr(NodeNumber:longint): DLLNodePtr;
{}
var
StartNode: DLLNodePtr;
DistanceA,
DistanceB,
DistanceC,
Counter,
I: LongInt;
Forwards : boolean;
Indicator : byte;
begin
if (NodeNumber < 1) or (NodeNumber > vTotalNodes) then
NodePtr := nil
else
begin
if NodeNumber = 1 then
NodePtr := vStartNodePtr
else if NodeNumber = vTotalNodes then
NodePtr := vEndNodePtr
else if NodeNumber = vActiveNodeNumber then
NodePtr := vActiveNodePtr
else
begin
{check for the nearest node ptr, and jump from there}
DistanceA := abs(NodeNumber - vActiveNodeNumber);
DistanceB := NodeNumber;
DistanceC := vTotalNodes - NodeNumber;
if DistanceA < DistanceB then
begin
if DistanceA < DistanceC then
begin
StartNode := vActiveNodePtr;
Forwards := (vActiveNodeNumber < NodeNumber);
Counter := DistanceA;
end
else
begin
StartNode := vEndNodePtr;
Forwards := false;
Counter := DistanceC;
end;
end
else {DA > DB}
begin
if DistanceB < DistanceC then
begin
StartNode := vStartNodePtr;
Forwards := true;
Counter := pred(DistanceB);
end
else
begin
StartNode := vEndNodePtr;
Forwards := false;
Counter := DistanceC;
end;
end;
if Forwards then
for I := 1 to Counter do
StartNode := StartNode^.NextPtr
else
for I := 1 to Counter do
StartNode := StartNode^.PrevPtr;
NodePtr := StartNode;

end;
end;
end; {DLLOBJ.NodePtr}

function DLLOBJ.TotalNodes: longint;
{}
begin
TotalNodes := vTotalNodes;
end;

function DLLOBJ.ActiveNodeNumber: longint;
{}
begin
ActiveNodeNumber := vActiveNodeNumber;
end;

function DLLOBJ.StartNodePtr: DLLNodePtr;
{}
begin
StartNodePtr := vStartNodePtr;
end; {DLLOBJ.StartNodePtr}

function DLLOBJ.EndNodePtr: DLLNodePtr;
{}
begin
EndNodePtr := vEndNodePtr;
end; {DLLOBJ.EndNodePtr}

function DLLOBJ.ActiveNodePtr: DLLNodePtr;
{}
begin
ActiveNodePtr := vActiveNodePtr;
end; {DLLOBJ.ActiveNodePtr}

(* The following procedure requires only 8 bytes on the
stack but damn it's slow!
procedure DLLOBJ.SwapNodes(Node1,Node2:DLLNodePtr);
{swaps the position of two nodes in the tree}
var
TempPrevPtr,
TempNextPtr : DLLNodePtr;
begin
if vStartNodePtr = Node1 then
vStartNodePtr := Node2
else if vStartNodePtr = Node2 then
vStartNodePtr := Node1;
if vEndNodePtr = Node1 then
vEndNodePtr := Node2
else if vEndNodePtr = Node2 then
vEndNodePtr := Node1;
if vActiveNodePtr = Node1 then
vActiveNodePtr := Node2
else if vActiveNodePtr = Node2 then
vActiveNodePtr := Node1;
if (Node1^.vNextPtr = Node2) then {nodes next to each other}
begin
TempNextPtr := Node2^.vNextPtr;
{move Node2 into Node1's place}
Node2^.vPrevPtr := Node1^.vPrevPtr;
Node2^.vNextPtr := Node1;
if Node2^.vPrevPtr <> nil then
Node2^.vPrevPtr^.vNextPtr := Node2;
if Node2^.vNextPtr <> nil then
Node2^.vNextPtr^.vPrevPtr := Node2;
{move Node1 into Node2's place}
Node1^.vPrevPtr := Node2;
Node1^.vNextPtr := TempNextPtr;
if Node1^.vNextPtr <> nil then
Node1^.vNextPtr^.vPrevPtr := Node1;
end
else
if (Node1^.vPrevPtr = Node2) then {nodes next to each other}
begin
TempPrevPtr := Node2^.vPrevPtr;
{move Node2 into Node1's place}
Node2^.vPrevPtr := Node1;
Node2^.vNextPtr := Node1^.vNextPtr;
if Node2^.vNextPtr <> nil then
Node2^.vNextPtr^.vPrevPtr := Node2;
{move Node1 into Node2's place}
Node1^.vPrevPtr := TempPrevPtr;
Node1^.vNextPtr := Node2;
if Node1^.vPrevPtr <> nil then
Node1^.vPrevPtr^.vNextPtr := Node1;
end
else {the nodes are not adjacent to each other}
begin
TempPrevPtr := Node2^.vPrevPtr;
TempNextPtr := Node2^.vNextPtr;
{move Node2 into Node1's place}
Node2^.vPrevPtr := Node1^.vPrevPtr;
Node2^.vNextPtr := Node1^.vNextPtr;
if Node2^.vPrevPtr <> nil then
Node2^.vPrevPtr^.vNextPtr := Node2;
if Node2^.vNextPtr <> nil then
Node2^.vNextPtr^.vPrevPtr := Node2;
{move Node1 into Node2's place}
Node1^.vPrevPtr := TempPrevPtr;
Node1^.vNextPtr := TempNextPtr;
if Node1^.vPrevPtr <> nil then
Node1^.vPrevPtr^.vNextPtr := Node1;
if Node1^.vNextPtr <> nil then
Node1^.vNextPtr^.vPrevPtr := Node1;
end;
end; {DLLOBJ.SwapNodes}
*)

procedure DLLOBJ.SwapNodes(Node1,Node2:DLLNodePtr);
{}
var
Ptr1: pointer;
Size1,Size2: longint;
Status1: byte;
Ecode: integer;
begin
Status1 := Node1^.GetStatusByte;
Node1^.SetStatusByte(Node2^.GetStatusByte);
Node2^.SetStatusByte(Status1);
Size1 := GetNodeDataSize(Node1);
if Size1 > 0 then
begin
getmem(Ptr1,size1);
GetNodeData(Node1,Ptr1^);
end;
Size2 := GetNodeDataSize(Node2);
Ecode := Change(Node1,Node2^.vDataPtr^,Size2);
Ecode := Change(Node2,Ptr1^,Size1);
if Size1 > 0 then
freemem(Ptr1,Size1);
end; {DLLOBJ.SwapNodes}

procedure DLLOBJ.DelNode(Node: DLLNodePtr);
{}
begin
if vActiveNodePtr = Node then {move active ptr to next entry in list}
begin
if vActiveNodePtr^.vNextPtr = nil then
begin
dec(vActiveNodeNumber);
vActiveNodePtr := vActiveNodePtr^.vPrevPtr;
end
else
vActiveNodePtr := vActiveNodePtr^.vNextPtr;
end;
if Node = vStartNodePtr then
begin
if Node^.vNextPtr = nil then {only node in list}
begin
Node^.FreeData;
Freemem(vStartNodePtr,sizeof(vStartNodePtr^));
vStartNodePtr := nil;
vEndNodePtr := nil;
end
else
begin
vStartNodePtr := vStartNodePtr^.vNextPtr;
vStartNodePtr^.vPrevPtr := nil;
Node^.FreeData;
Freemem(Node,sizeof(Node^));
end;
end
else
begin
Node^.vPrevPtr^.vNextPtr := Node^.vNextPtr;
if Node = vEndNodePtr then
vEndNodePtr := vEndNodePtr^.vPrevPtr
else
Node^.vNextPtr^.vPrevPtr := Node^.vPrevPtr;
Node^.FreeData;
Freemem(Node,sizeof(Node^));
end;
dec(vTotalNodes);
end; {DLLOBJ.DelNode}

procedure DLLOBJ.DelAllStatus(BitPos:byte;On:boolean);
{}
var
TempPtr,TempNextPtr: DLLNodePtr;
begin
if vStartNodePtr <> nil then
begin
TempPtr := vStartNodePtr;
TempNextPtr := TempPtr^.NextPtr;
while TempNextPtr <> nil do
begin
if TempNextPtr^.GetStatus(BitPos) = On then
DelNode(TempNextPtr)
else
TempPtr := TempPtr^.NextPtr;
TempNextPtr := TempPtr^.NextPtr;
end;
if vStartNodePtr^.GetStatus(BitPos) = On then
DelNode(vStartNodePtr)
end;
end; {DLLOBJ.DelAllStatus}

function DLLOBJ.WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean):boolean;
{abstract}
begin
WrongOrder := false;
end; {DLLOBJ.WrongOrder}

procedure DLLOBJ.Sort(SortID:shortint;Ascending:boolean);
{Shell sort}
var
I,J,Delta : longint;
Swapped : boolean;
Ptr1,Ptr2 : DLLNodePtr;
begin
if ((vSortID <> SortID) or (vSortAscending <> Ascending) or (vSorted = false))
and (vTotalNodes >= 2) then
begin
vSortID := SortID;
vSortAscending := Ascending;
Delta := vTotalNodes div 2;
repeat
Repeat
Swapped := false;
Ptr1 := vStartNodePtr;
Ptr2 := Ptr1;
for I := 1 to Delta do
Ptr2 := Ptr2^.vNextPtr;
for I := 1 to vTotalNodes - Delta do
begin
if I > 1 then
begin
Ptr1 := Ptr1^.vNextPtr;
Ptr2 := Ptr2^.vNextPtr;
end;
if WrongOrder(Ptr1,Ptr2,vSortAscending) then
begin
SwapNodes(Ptr1,Ptr2);
Swapped := true;
end;
end;
Until (not Swapped);
Delta := Delta div 2;
Until Delta = 0;
end;
vSorted := true;
end; {DLLOBJ.Sort}

procedure DLLOBJ.EmptyList;
{removes all the memory allocated on the heap by chaining back
through the list and disposing of each node.}
var TempPtr: DLLNodePtr;
begin
TempPtr := vEndNodePtr;
if vEndNodePtr <> nil then
while TempPtr^.vPrevPtr <> nil do
begin
TempPtr^.FreeData;
TempPtr := TempPtr^.vPrevPtr;
Freemem(TempPtr^.vNextPtr,sizeof(TempPtr^));
end;
if vStartNodePtr <> Nil then
begin
vStartNodePtr^.FreeData;
Freemem(vStartNodePtr,sizeof(vStartNodePtr^));
vStartNodePtr := Nil;
end;
vEndNodePtr := nil;
vActiveNodePtr := nil;
vTotalNodes := 0;
vActiveNodeNumber := 0;
end; {DLLOBJ.EmptyList}

destructor DLLOBJ.Done;
{}
begin
EmptyList;
end; {of dest DLLOBJ.Done}

{|||||||||||||||||||||||||||||||||||||||||||}
{ }
{ S t r D L L O b j M E T H O D S }
{ }
{|||||||||||||||||||||||||||||||||||||||||||}

{The StrDLLOBJ object is a descendant of the DLLOBJ object, and
it is designed to specifically manipulate strings}

constructor StrDLLOBJ.Init;
{}
begin
DLLOBJ.Init;
end; {StrDLLOBJ.Init}

function StrDLLOBJ.Add(Str: string): integer;
{}
var
Len : byte;
begin
Len := Length(Str);
Add := DLLOBJ.Add(Str[1],Len);
end; {StrDLLOBJ.Add}

function StrDLLOBJ.GetStr(Node:DLLNodePtr;Start,Finish:longint): String;
{}
begin
GetStr := DLLOBJ.GetStr(Node,Start,Finish);
end; {StrDLLOBJ.GetStr}

function StrDLLOBJ.Change(Node:DLLNodePtr;Str: string): integer;
{}
var
Len:byte;
begin
Len := length(Str);
Change := DLLOBJ.Change(Node,Str[1],Len);
end; {StrDLLOBJ.Change}

function StrDLLOBJ.InsertBefore(Node:DLLNodePtr;Str:string): integer;
{}
var
Len:byte;
begin
Len := length(Str);
InsertBefore := DLLOBJ.InsertBefore(Node,Str[1],Len);
end; {StrDLLOBJ.InsertBefore}

function StrDLLOBJ.WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean;
{}
var S1,S2: string;
begin
(*
if Asc then
begin
GetNodeData(Node1,S1);
GetNodeData(Node2,S2);
end
else
begin
GetNodeData(Node1,S2);
GetNodeData(Node2,S1);
end;
*)
if Asc then
begin
S1 := GetStr(Node1,1,255);
S2 := GetStr(Node2,1,255);
end
else
begin
S1 := GetStr(Node2,1,255);
S2 := GetStr(Node1,1,255);
end;
WrongOrder := (S1 > S2);
end; {StrDLLOBJ.WrongOrder}

destructor StrDLLOBJ.Done;
{}
begin
DLLOBJ.Done;
end; {StrDLLOBJ.Done}
{|||||||||||||||||||||||||||||||||||||||||||||}
{ }
{ F i l e D L L O b j M E T H O D S }
{ }
{|||||||||||||||||||||||||||||||||||||||||||||}
constructor FileDLLOBJ.Init;
{}
begin
DLLOBJ.Init;
vFileMasks := '*.*';
vFileAttrib := archive + readonly;
end; {FileDLLOBJ.Init}

function FileDLLOBJ.GetStr(Node:DLLNodePtr;Start,Finish: longint):string;
{ignores Start and Finish parameters - first 13 bytes of the Data is
the filename.}
var temp : string;
begin
if (Node = Nil)
or (Node^.vDataPtr = Nil)
or (Node^.vSize = 0) then
GetStr := ''
else
begin
Move(mem[seg(Node^.vDataPtr^):ofs(Node^.vDataPtr^)],Temp[0],13);
GetStr := Temp;
end;
end; {FileDLLOBJ.GetStr}

function FileDLLOBJ.GetLongStr(Node:DLLNodePtr):string;
{}
var Info: tFileInfo;
begin
if (Node = Nil)
or (Node^.vDataPtr = Nil)
or (Node^.vSize = 0) then
GetLongStr := ''
else
begin
Move(mem[seg(Node^.vDataPtr^):ofs(Node^.vDataPtr^)],Info,sizeof(Info));
if Info.FileName = NoFiles then
GetLongStr := 'No matching files found'
else
GetLongStr := LongName(Info);
end;
end; {FileDLLOBJ.GetLongStr}

procedure FileDLLOBJ.GetFileRecord(var FileInfo:tFileInfo; Item:longint);
{}
var
Node:DLLNodePtr;
begin
Node := NodePtr(Item);
if (Node = Nil)
or (Node^.vDataPtr = Nil)
or (Node^.vSize = 0) then
FileInfo.FileName := ''
else
Move(mem[seg(Node^.vDataPtr^):ofs(Node^.vDataPtr^)],FileInfo,sizeof(FileInfo));
end; {FileDLLOBJ.GetFileRecord}

function FileDLLOBJ.GetFileMask:string;
{}
begin
GetFileMask := vFileMasks;
end; {FileDLLOBJ.GetFileMask}

procedure FileDLLOBJ.SetFileDetails(FileMasks:string; FileAttrib: word);
{}
begin
if FileMasks = '' then
FileMasks := '*.*';
vFileMasks := FileMasks;
vFileAttrib := FileAttrib;
end; {FileDLLOBJ.SetFileDetails}

procedure FileDLLOBJ.FillList;
{}
var
FileDetails: SearchRec;
FileInfo: tFileInfo;
TotMasks: byte;
Mask: string;
RecSize: byte;
ECode : integer;

procedure SaveFileDetails(IsDir:boolean);
begin
if FileDetails.Name <> '.' then
begin
with FileInfo do
begin
FileName := FileDetails.Name;
Attr := FileDetails.Attr;
Time := FileDetails.Time;
Size := FileDetails.Size;
LoadID := succ(vTotalNodes);
end; {with}
Ecode := Add(FileInfo,RecSize);
if Ecode = 0 then
vActiveNodePtr^.SetStatus(1,IsDir);
end;
end; {SaveFileDetails}

procedure ProcessFiles(Attrib:word);
{}
var I : integer;
begin
for I := 1 to TotMasks do
begin
Mask := ExtractWords(I,1,vFileMasks);
FindFirst(Mask,Attrib,FileDetails);
while DOSError = 0 do
begin
if (Attrib <> Directory) then
SaveFileDetails(false)
else if ((Attrib = Directory) and (FileDetails.Attr = Directory)) then
SaveFileDetails(true);
FindNext(FileDetails);
end;
end;
end; {ProcessFiles}

begin
RecSize := sizeof(FileInfo);
if vStartNodePtr <> Nil then
EmptyList;
TotMasks := WordCnt(vFilemasks);
if ((vFileAttrib and Directory) = Directory) then
begin
ProcessFiles(Directory);
ProcessFiles(vFileAttrib and (Anyfile-Directory-VolumeID));
end
else
ProcessFiles(vFileAttrib);
if vTotalNodes = 0 then
begin
FileInfo.Filename := NoFiles;
FileInfo.Time := 0;
Ecode := Add(FileInfo,RecSize);
end;
vSorted := (vSortID = 0) and (vSortAscending = true);
end; {FileDLLOBJ.FillList}

procedure FileDLLOBJ.FillNewMask(FileMasks:string);
{}
begin
SetFileDetails(FileMasks,vFileAttrib);
FillList;
end; {FileDLLOBJ.FillNewMask}

function FileDLLOBJ.WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean;
{}
var F1,F2: tFileInfo;
P: integer;
Name1,Name2: string[8];
Ext1,Ext2: string[3];

function Name(F:tFileInfo):string;
{}
begin
P := pos('.',F.FileName);
if P = 0 then
Name := F.FileName
else
Name := copy(F.FileName,1,pred(P));
end;{Name}

function Ext(F:tFileInfo):string;
{}
begin
P:= pos('.',F.FileName);
if P = 0 then
Ext := ''
else
Ext := copy(F.FileName,succ(P),3);
end; {Ext}

begin
fillchar(F1,sizeof(F1),#0);
fillchar(F2,sizeof(F2),#0);
if Asc then
begin
GetNodeData(Node1,F1);
GetNodeData(Node2,F2);
end
else
begin
GetNodeData(Node1,F2);
GetNodeData(Node2,F1);
end;
case vSortID of
0: WrongOrder := (F1.LoadID > F2.LoadID); {DOS}
1: begin {NAME}
Name1 := Name(F1);
Name2 := Name(F2);
if (Name1 = Name2) then
WrongOrder := (Ext(F1) > Ext(F2))
else
WrongOrder := (Name1 > Name2);
end;
2: begin {EXT}
Ext1 := Ext(F1);
Ext2 := Ext(F2);
if Ext1 = Ext2 then
WrongOrder := (Name(F1) > Name(F2))
else
WrongOrder := (Ext1 > Ext2);
end;
3: WrongOrder := (F1.Size > F2.Size); {SIZE}
4: WrongOrder := (F1.Time > F2.Time); {TIME}
else WrongOrder := false;
end; {case}
end; {FileDLLOBJ.WrongOrder}

procedure FileDLLOBJ.SwapNodes(Node1,Node2:DLLNodePtr);
{}
var
FileInfo: tFileInfo;
Size: longint;
Status1: byte;
begin
Status1 := Node1^.GetStatusByte;
Node1^.SetStatusByte(Node2^.GetStatusByte);
Node2^.SetStatusByte(Status1);
GetNodeData(Node1,FileInfo);
Size := sizeof(FileInfo);
Move(Node2^.vDataPtr^,Node1^.vDataPtr^,size);
Move(FileInfo,Node2^.vDataPtr^,size);
end; {FileDLLOBJ.SwapNodes}

destructor FileDLLOBJ.Done;
{}
begin
DLLOBJ.Done;
end; {FileDLLOBJ.Done}
{|||||||||||||||||||||||||||||||||||||||||||||||}
{ }
{ U N I T I N I T I A L I Z A T I O N }
{ }
{|||||||||||||||||||||||||||||||||||||||||||||||}
procedure LinkInit;
{initilizes objects and global variables}
begin
end;

{end of unit}
{$ifNDEF OVERLAY}
begin
LINKInit;
{$ENDif}
end.


  3 Responses to “Category : Pascal Source Code
Archive   : TJOCKOT1.ZIP
Filename : TOTLINK.PAS

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/