home *** CD-ROM | disk | FTP | other *** search
- (*****************************************************************************
- Program: Lists.Pas
- Author: Mark Addleman
- Version: 3.0
- Date: August 5, 1988
- Note: Public domain software
- Please distribute in complete form
-
-
- VERSION RECORD
- 1.0 - Gosh, I thought everything was right!
-
- 1.1 - Minor bug found in DisposeOfList routine
- If no items were added, DisposeOfList would try to dispose of
- a NIL variable (List.FirstItem). This is a no-no
-
- 1.2 - Bug in DeleteItemFromList routine
- If list contained only 1 item, the routine would not properly
- reclaim the used memory
-
- 2.0 - Revision to make life easier
- - Renames of procedures/variables
- - AddToList becomes AddItem
- - InsertInList becomes InsertItem
- - DeleteItemFromList becomes DeleteItem
- - ListOK becomes OK
- - Replaced routines
- - MoveTo______ routines replaced with MoveToItem
- - _____ItemPtr routines replaced with Item
- - New routines to process Stacks and Queues
- - PUSH and POP provided to act as a Last In First Out stack
- - Queue and Dequeue provided to act as a First In Last Out queue
- - No external routines are needed to process lists
- - Size of the Item is now taken as an argument
- - DeleteItem now truly deletes the item and its reference in the list
- - Pointers no longer necessary as arguments to AddItem and InsertItem
- - The name of the list ALWAYS comes first in the arguments
- - ItemInList is no longer implemented
-
- 3.0 - Complete revision of source code, less Procedures/Functions, more power
- - Renaming of routines/variables for easier understanding
- - Each Entry in the list contains an Item
- - Items are put into the list by the programmer
- - Renaming of routines/variables:
- - ItemRec and ItemPtr are now referred to as EntryRec and EntryPtr
- - AddItem becomes AddEntry
- - InsertItem becomes InsertEntry
- - DeleteItem becomes DeleteEntry
- - MoveToItem becomes MoveToEntry
- - PutItem(Location:EntryPtr; Var Item) added
- - Allows any item in list to be changed
- - SizeOf(Item) must be the same as the old item
- - Entry(Var List:ListRec; Location:EntryPtr) added
- - Allows programmer hooks into list to be used as arguments
- - EntryNumAbs(N:LongInt) added
- - Used as argument to Entry, allows access to the Nth entry in list
- - EntryNumRel(N:LongInt; Location:EntryPtr) added
- - Used as argument to Entry, allows relative access to entries in list
- - MoveItem(Source, Dest:EntryPtr) added
- - Allows shuffling of entries in list
- - New memory allocation for easier memory manipulation
- - Compiled code is about 20% smaller than version 2.0 !
- - Now ShareWare, $10 requested
- ******************************************************************************)
-
- {$R-,S-,I-,D-,T-,F-,V+,B-,N-,L+ }
- {$M 16384,0,655360 }
-
- Unit Lists;
-
- INTERFACE
- Type
- EntryPtr = ^EntryRec;
- EntryRec = Record
- P_Entry : EntryPtr;
- N_Entry : EntryPtr;
- Size : Word;
- Item : Byte;
- End;
-
- ListRec = Record
- OK : Boolean;
- F_Entry : EntryPtr; {First entry}
- L_Entry : EntryPtr; {Last entry}
- C_Entry : EntryPtr; {Current entry}
- End;
-
- Procedure InitList (Var List:ListRec);
- Procedure AddEntry (Var List:ListRec; Var _Item; _Size:Word);
- Procedure InsertEntry (Location:EntryPtr; Var _Item; _Size:Word);
-
- Procedure DeleteEntry (Location:EntryPtr);
- Procedure DeleteList (Var List:ListRec);
-
- Function Item (Location:EntryPtr):Pointer;
- Function Entry (Var List:ListRec; Location:EntryPtr):EntryPtr;
-
- Procedure GetItem (Location:EntryPtr; Var _Item);
- Procedure PutItem (Location:EntryPtr; Var _Item);
-
- Procedure MoveToEntry (Location:EntryPtr);
- Procedure MoveEntry (Source, Dest:EntryPtr);
-
- Function CurrentEntry (Var List:ListRec):EntryPtr;
- Function FirstEntry (Var List:ListRec):EntryPtr;
- Function LastEntry (Var List:ListRec):EntryPtr;
- Function NextEntry (Location:EntryPtr):EntryPtr;
- Function PrevEntry (Location:EntryPtr):EntryPtr;
- Function EntryNumAbs (Var List:ListRec; Num:LongInt):EntryPtr;
- Function EntryNumRel (Location:EntryPtr; Num:LongInt):EntryPtr;
-
- Procedure InitStack (Var Stack:ListRec);
- Procedure Push (Var Stack:ListRec; Var Item; Size:Word);
- Procedure Pop (Var Stack:ListRec; Var Item);
- Procedure Queue (Var Stack:ListRec; Var Item; Size:Word);
- Procedure DeQueue (Var Stack:ListRec; Var Item);
-
-
- IMPLEMENTATION
- Var
- GlobalList : ^ListRec;
-
- Procedure InitList(Var List:ListRec);
- Begin
- List.F_Entry:=nil; List.F_Entry^.P_Entry:=nil;
- List.L_Entry:=nil; List.L_Entry^.N_Entry:=nil;
-
- List.C_Entry:=nil;
- List.C_Entry^.N_Entry:=nil;
- List.C_Entry^.P_Entry:=nil;
-
- List.OK:=True;
- End;
-
-
- Procedure AddEntry(Var List:ListRec; Var _Item; _Size:Word);
- Begin
- GetMem(List.L_Entry^.N_Entry, _Size+SizeOf(List.L_Entry^.N_Entry^));
-
- List.L_Entry^.N_Entry^.Size:=_Size;
- List.L_Entry^.N_Entry^.N_Entry:=nil;
- List.L_Entry^.N_Entry^.P_Entry:=List.L_Entry;
-
- PutItem(List.L_Entry^.N_Entry, _Item);
-
- If List.F_Entry=nil Then Begin
- List.F_Entry:=List.L_Entry^.N_Entry;
- List.F_Entry^.P_Entry:=nil;
- List.C_Entry:=List.L_Entry;
- End;
-
- List.L_Entry:=List.L_Entry^.N_Entry;
- List.L_Entry^.N_Entry:=nil;
- End;
-
-
- Procedure InsertEntry(Location:EntryPtr; Var _Item; _Size:Word);
- Var
- NewEntry : EntryPtr;
-
- Begin
- If Location=nil Then Begin
- AddEntry(GlobalList^, _Item, _Size);
- Exit;
- End;
-
-
- GetMem(NewEntry, _Size+SizeOf(NewEntry^));
-
- NewEntry^.Size:=_Size;
- NewEntry^.N_Entry:=Location;
- NewEntry^.P_Entry:=Location^.P_Entry;
- PutItem(NewEntry, _Item);
-
- Location^.P_Entry^.N_Entry:=NewEntry;
- Location^.P_Entry:=NewEntry;
-
- If Location=GlobalList^.F_Entry Then
- GlobalList^.F_Entry:=Location^.P_Entry;
- End;
-
-
- Procedure GetItem(Location:EntryPtr; Var _Item);
- Begin
- Move(Location^.Item, _Item, Location^.Size);
- End;
-
-
- Procedure PutItem(Location:EntryPtr; Var _Item);
- Begin
- Move(_Item, Location^.Item, Location^.Size);
- End;
-
-
- Function Item(Location:EntryPtr):Pointer;
- Begin
- Item:=@Location^.Item;
- End;
-
-
- Function PrevEntry(Location:EntryPtr):EntryPtr;
- Begin
- If Location^.P_Entry=nil Then PrevEntry:=nil
- Else PrevEntry:=Location^.P_Entry;
- End;
-
-
- Function NextEntry(Location:EntryPtr):EntryPtr;
- Begin
- If Location^.N_Entry=nil Then NextEntry:=nil
- Else NextEntry:=Location^.N_Entry;
- End;
-
-
- Function EntryNumAbs(Var List:ListRec; Num:LongInt):EntryPtr;
- Var
- TempEntry : EntryPtr;
- I : LongInt;
-
- Label
- Finish;
-
- Begin
- GlobalList:=@List;
- TempEntry:=GlobalList^.F_Entry;
-
- With TempEntry^ Do
- For I:=1 To Pred(Num) Do Begin
- If TempEntry=nil Then Goto Finish;
- TempEntry:=N_Entry;
- End;
-
- Begin Finish:
- EntryNumAbs:=TempEntry;
- End;
- End;
-
-
- Function EntryNumRel(Location:EntryPtr; Num:LongInt):EntryPtr;
- Var
- TempEntry : EntryPtr;
- I : LongInt;
-
- Label
- Finish;
-
- Begin
- TempEntry:=Location;
-
- With TempEntry^ Do
- If Num < 0 Then
- For I:=0 DownTo Succ(Num) Do Begin
- If TempEntry=nil Then Goto Finish;
- TempEntry:=P_Entry;
- End
- Else
- For I:=1 To Pred(Num) Do Begin
- If TempEntry=nil Then Goto Finish;
- TempEntry:=N_Entry;
- End;
-
- Begin Finish:
- EntryNumRel:=TempEntry;
- End;
- End;
-
-
- Function CurrentEntry(Var List:ListRec):EntryPtr;
- Begin
- CurrentEntry:=List.C_Entry;
- GlobalList:=@List;
- End;
-
-
- Function FirstEntry(Var List:ListRec):EntryPtr;
- Begin
- FirstEntry:=List.F_Entry;
- GlobalList:=@List;
- End;
-
-
- Function LastEntry(Var List:ListRec):EntryPtr;
- Begin
- LastEntry:=List.L_Entry;
- GlobalList:=@List;
- End;
-
-
- Function Entry(Var List:ListRec; Location:EntryPtr):EntryPtr;
- Begin
- Entry:=Location;
- GlobalList:=@List;
- End;
-
-
- Procedure MoveToEntry(Location:EntryPtr);
- Begin
- GlobalList^.OK:=Not (Location=nil);
- If GlobalList^.OK Then GlobalList^.C_Entry:=Location;
- End;
-
-
- Procedure MoveEntry(Source, Dest:EntryPtr);
- Begin
- If Source=GlobalList^.F_Entry Then
- GlobalList^.F_Entry:=GlobalList^.F_Entry^.N_Entry
- Else
- If Source=GlobalList^.L_Entry Then
- GlobalList^.L_Entry:=GlobalList^.L_Entry^.P_Entry;
-
- If Dest=GlobalList^.F_Entry Then
- GlobalList^.F_Entry:=Source;
-
- Source^.P_Entry^.N_Entry:=Source^.N_Entry;
- Source^.N_Entry^.P_Entry:=Source^.P_Entry;
-
- Source^.P_Entry:=Dest^.P_Entry;
- Source^.N_Entry:=Dest;
-
- If Dest=nil Then Begin
- GlobalList^.L_Entry^.N_Entry:=Source;
- GlobalList^.L_Entry:=GlobalList^.L_Entry^.N_Entry;
- End
- Else Begin
- Dest^.P_Entry^.N_Entry:=Source;
- Dest^.P_Entry:=Source;
- End;
- End;
-
-
- Procedure DeleteEntry(Location:EntryPtr);
- Begin
- If Location=nil Then Begin
- GlobalList^.OK:=False;
- Exit;
- End;
-
- Location^.P_Entry^.N_Entry:=Location^.N_Entry;
- Location^.N_Entry^.P_Entry:=Location^.P_Entry;
-
- If Location=GlobalList^.F_Entry Then
- GlobalList^.F_Entry:=Location^.N_Entry;
- If Location=GlobalList^.L_Entry Then
- GlobalList^.L_Entry:=Location^.P_Entry;
-
- If Location^.N_Entry=nil Then
- GlobalList^.C_Entry:=Location^.P_Entry
- Else
- GlobalList^.C_Entry:=Location^.N_Entry;
-
- If GlobalList^.C_Entry=nil Then GlobalList^.OK:=False;
-
- FreeMem(Location, Location^.Size+SizeOf(Location^));
- End;
-
-
- Procedure DeleteList(Var List:ListRec);
- Begin
- MoveToEntry(FirstEntry(List));
-
- With List Do
- While OK Do Begin
- FreeMem(C_Entry, C_Entry^.Size+SizeOf(C_Entry^));
- MoveToEntry(NextEntry(CurrentEntry(List)));
- End;
-
- InitList(List);
- End;
-
-
-
-
-
- Procedure InitStack(Var Stack:ListRec);
- Begin
- InitList(Stack);
- End;
-
- Procedure Push(Var Stack:ListRec; Var Item; Size:Word);
- Begin
- AddEntry(Stack, Item, Size);
- End;
-
- Procedure Pop(Var Stack:ListRec; Var Item);
- Begin
- GetItem(LastEntry(Stack), Item);
- DeleteEntry(LastEntry(Stack));
- End;
-
- Procedure Queue(Var Stack:ListRec; Var Item; Size:Word);
- Begin
- InsertEntry(FirstEntry(Stack), Item, Size);
- End;
-
- Procedure DeQueue(Var Stack:ListRec; Var Item);
- Begin
- GetItem(FirstEntry(Stack), Item);
- DeleteEntry(FirstEntry(Stack));
- End;
-
-
- End.