home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / LSTS20.ZIP / LISTS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-07-16  |  8.9 KB  |  351 lines

  1. (*****************************************************************************
  2.    Program:  Lists.Pas
  3.    Author:   Mark Addleman
  4.    Version:  2.0
  5.    Date:     July 14, 1988
  6.    Note:     Public domain software
  7.              Please distribute in complete form
  8.  
  9.  
  10. VERSION RECORD
  11. 1.0 - Gosh, I thought everything was right!
  12.  
  13. 1.1 - Minor bug found in DisposeOfList routine
  14.       If no items were added, DisposeOfList would try to dispose of
  15.       a NIL variable (List.FirstItem).  This is a no-no
  16.  
  17. 1.2 - Bug in DeleteItemFromList routine
  18.       If list contained only 1 item, the routine would not properly
  19.       reclaim the used memory
  20.  
  21. 2.0 - Revision to make life easier
  22.       - Renames of procedures/variables
  23.         - AddToList              becomes   AddItem
  24.         - InsertInList           becomes   InsertItem
  25.         - DeleteItemFromList     becomes   DeleteItem
  26.         - ListOK                 becomes   OK
  27.       - Replaced routines
  28.         - MoveTo______ routines replaced with MoveToItem
  29.         - _____ItemPtr routines replaced with Item
  30.       - New routines to process Stacks and Queues
  31.         - PUSH and POP provided to act as a Last In First Out stack
  32.         - Queue and Dequeue provided to act as a First In Last Out queue
  33.       - No external routines are needed to process lists
  34.         - Size of the Item is now taken as an argument
  35.         - DeleteItem now truly deletes the item and its reference in the list
  36.         - Pointers no longer necessary as arguments to AddItem and InsertItem
  37.       - The name of the list ALWAYS comes first in the arguments
  38.       - ItemInList is no longer implemented
  39. ******************************************************************************)
  40.  
  41.  
  42.  
  43. {$R-,S-,I-,D-,T-,F-,V+,B-,N-,L- }
  44. {$M 16384,0,655360 }
  45. Unit Lists;
  46.  
  47. INTERFACE
  48. Type
  49.    ItemPtr                   =   ^ItemRec;
  50.    ItemRec                   =   Record
  51.                                     PrevItem   :   ItemPtr;
  52.                                     NextItem   :   ItemPtr;
  53.                                     Ptr        :   Pointer;
  54.                                     Size       :   Word;
  55.                                  End;
  56.  
  57.    ListRec                   =   Record
  58.                                     FirstItem  :   ItemPtr;
  59.                                     LastItem   :   ItemPtr;
  60.                                     Item       :   ItemPtr;
  61.                                     OK         :   Boolean;
  62.                                  End;
  63.  
  64. Procedure InitList(Var List:ListRec);
  65. Procedure AddItem(Var List:ListRec; Var _Item; _Size:Word);
  66. Procedure InsertItem(Var List:ListRec; Var _Item; _Size:Word;Location:Pointer);
  67.  
  68. Procedure DeleteItem(Var List:ListRec; _Item:Pointer);
  69. Procedure DeleteList(Var List:ListRec);
  70.  
  71. Function Item(List:ListRec; Location:ItemPtr):Pointer;
  72.  
  73. Procedure GetItem(Var List:ListRec; Location:ItemPtr; Var _Item);
  74.  
  75. Procedure MoveToItem(Var List:ListRec; Location:ItemPtr);
  76.  
  77. Function CurrentItem(List:ListRec):Pointer;
  78. Function FirstItem(List:ListRec):Pointer;
  79. Function LastItem(List:ListRec):Pointer;
  80. Function NextItem(_Item:Pointer):Pointer;
  81. Function PrevItem(_Item:Pointer):Pointer;
  82.  
  83. Procedure InitStack(Var Stack:ListRec);
  84. Procedure Push(Var Stack:ListRec; Var Item; Size:Word);
  85. Procedure Pop(Var Stack:ListRec; Var Item);
  86. Procedure Queue(Var Stack:ListRec; Var Item; Size:Word);
  87. Procedure DeQueue(Var Stack:ListRec; Var Item);
  88.  
  89.  
  90. IMPLEMENTATION
  91.  
  92. Procedure InitList(Var List:ListRec);
  93. Begin
  94.    With List Do Begin
  95.       FirstItem:=nil; FirstItem^.PrevItem:=nil;
  96.       LastItem:=nil;  LastItem^.NextItem:=nil;
  97.       Item:=nil;
  98.       With Item^ Do Begin
  99.          NextItem:=nil;
  100.          PrevItem:=nil;
  101.          Ptr:=nil;
  102.       End;
  103.       OK:=True;
  104.    End;
  105. End;
  106.  
  107. Procedure AddItem(Var List:ListRec; Var _Item; _Size:Word);
  108. Begin
  109.    With List Do
  110.    If FirstItem=nil Then Begin
  111.       New(FirstItem);
  112.  
  113.       With FirstItem^ Do Begin
  114.          NextItem:=nil;
  115.          PrevItem:=nil;
  116.  
  117.          GetMem(Ptr, _Size);
  118.          Move(_Item, Ptr^, _Size);
  119.  
  120.          Size:=_Size;
  121.       End;
  122.       Item:=FirstItem;
  123.       LastItem:=FirstItem;
  124.    End
  125.    Else Begin
  126.       New(LastItem^.NextItem);
  127.  
  128.       LastItem^.NextItem^.PrevItem:=LastItem;
  129.  
  130.       LastItem:=LastItem^.NextItem;
  131.       LastItem^.NextItem:=nil;
  132.  
  133.       GetMem(LastItem^.Ptr, _Size);
  134.       Move(_Item, LastItem^.Ptr^, _Size);
  135.  
  136.       LastItem^.Size:=_Size;
  137.    End;
  138. End;
  139.  
  140. Procedure InsertItem(Var List:ListRec; Var _Item; _Size:Word;
  141.                      Location:Pointer);
  142. Var
  143.    NewItem                   :   ItemPtr;
  144.  
  145. Begin
  146.    If Location=nil Then Begin
  147.       List.OK:=False;
  148.       Exit;
  149.    End
  150.    Else List.OK:=True;
  151.  
  152.    With List Do Begin
  153.       New(NewItem);
  154.       With NewItem^ Do Begin
  155.          GetMem(Ptr, _Size);
  156.          Move(_Item, Ptr^, _Size);
  157.          Size:=_Size;
  158.  
  159.          NextItem:=Location;
  160.          PrevItem:=ItemRec(Location^).PrevItem;
  161.       End;
  162.  
  163.       With ItemRec(Location^) Do Begin
  164.          PrevItem^.NextItem:=NewItem;
  165.          PrevItem:=NewItem;
  166.       End;
  167.  
  168.       If FirstItem=nil Then Begin
  169.          FirstItem:=NewItem;
  170.          Item:=FirstItem;
  171.       End;
  172.  
  173.       If LastItem=nil Then Begin
  174.          LastItem:=NewItem;
  175.          Item:=LastItem;
  176.       End;
  177.  
  178.       If Location=FirstItem Then FirstItem:=NewItem;
  179.    End;
  180. End;
  181.  
  182.  
  183. Procedure GetItem(Var List:ListRec; Location:ItemPtr; Var _Item);
  184. Begin
  185.    With Location^ Do Begin
  186.       List.OK:=Not (Location=nil);
  187.       If List.OK Then Move(Ptr^, _Item, Size);
  188.    End;
  189. End;
  190.  
  191.  
  192.  
  193. Function Item(List:ListRec; Location:ItemPtr):Pointer;
  194. Begin
  195.    Item:=ItemRec(Location^).Ptr;
  196. End;
  197.  
  198. Function PrevItemPtr(List:ListRec):Pointer;
  199. Begin
  200.    With List Do
  201.    If Item^.PrevItem=nil Then PrevItemPtr:=nil
  202.    Else PrevItemPtr:=Item^.PrevItem^.Ptr;
  203. End;
  204.  
  205. Function FirstItemPtr(List:ListRec):Pointer;
  206. Begin
  207.    FirstItemPtr:=List.FirstItem^.Ptr;
  208. End;
  209.  
  210. Function LastItemPtr(List:ListRec):Pointer;
  211. Begin
  212.    LastItemPtr:=List.LastItem^.Ptr;
  213. End;
  214.  
  215. Function CurrentItemPtr(List:ListRec):Pointer;
  216. Begin
  217.    With List,List.Item^ Do
  218.    If Not (Item=nil) Then CurrentItemPtr:=Ptr
  219.    Else OK:=False;
  220. End;
  221.  
  222.  
  223.  
  224.  
  225. Procedure MoveToItem(Var List:ListRec; Location:ItemPtr);
  226. Begin
  227.    With List Do Begin
  228.       OK:=Not (Location=nil);
  229.       If OK Then Item:=Location;
  230.    End;
  231. End;
  232.  
  233. Function CurrentItem(List:ListRec):Pointer;
  234. Begin
  235.    CurrentItem:=List.Item;
  236. End;
  237.  
  238. Function PrevItem(_Item:Pointer):Pointer;
  239. Begin
  240.    PrevItem:=ItemRec(_Item^).PrevItem;
  241. End;
  242.  
  243. Function NextItem(_Item:Pointer):Pointer;
  244. Begin
  245.    NextItem:=ItemRec(_Item^).NextItem;
  246. End;
  247.  
  248. Function FirstItem(List:ListRec):Pointer;
  249. Begin
  250.    FirstItem:=List.FirstItem;
  251. End;
  252.  
  253. Function LastItem(List:ListRec):Pointer;
  254. Begin
  255.    LastItem:=List.LastItem;
  256. End;
  257.  
  258. Procedure DeleteItem(Var List:ListRec; _Item:Pointer);
  259. Var
  260.    TempItem                  :   Pointer;
  261.  
  262. Begin
  263.    If (_Item=nil) or Not (List.OK) Then Begin
  264.       List.OK:=False;
  265.       Exit;
  266.    End;
  267.  
  268.    With List Do
  269.    If LastItem=FirstItem Then Begin
  270.       FreeMem(LastItem^.Ptr, LastItem^.Size);
  271.       Dispose(LastItem);
  272.       InitList(List);
  273.       TempItem:=nil;
  274.    End
  275.    Else Begin
  276.       If (_Item=LastItem) or (_Item=FirstItem) Then Begin
  277.          If _Item=LastItem Then Begin
  278.             LastItem:=LastItem^.PrevItem;
  279.             Dispose(LastItem^.NextItem);
  280.             LastItem^.NextItem:=nil;
  281.             TempItem:=LastItem;
  282.          End;
  283.  
  284.          If _Item=FirstItem Then Begin
  285.             FirstItem:=FirstItem^.NextItem;
  286.             Dispose(FirstItem^.PrevItem);
  287.             FirstItem^.PrevItem:=nil;
  288.             TempItem:=FirstItem;
  289.          End;
  290.       End
  291.       Else Begin
  292.          With ItemRec(_Item^) Do Begin
  293.             PrevItem^.NextItem:=NextItem;
  294.             NextItem^.PrevItem:=PrevItem;
  295.             TempItem:=PrevItem;
  296.          End;
  297.       End;
  298.  
  299.       FreeMem(_Item, SizeOf(ItemRec));
  300.       FreeMem(ItemRec(_Item^).Ptr, ItemRec(_Item^).Size);
  301.       OK:=True;
  302.    End;
  303.  
  304.    If List.Item=_Item Then List.Item:=TempItem;
  305. End;
  306.  
  307. Procedure DeleteList(Var List:ListRec);
  308. Begin
  309.    MoveToItem(List, FirstItem(List));
  310.  
  311.    With List Do
  312.    While OK Do Begin
  313.        FreeMem(Item^.Ptr, Item^.Size);
  314.        Dispose(Item);
  315.        MoveToItem(List, PrevItem(CurrentItem(List)));
  316.    End;
  317.  
  318.    InitList(List);
  319. End;
  320.  
  321.  
  322.  
  323. Procedure InitStack(Var Stack:ListRec);
  324. Begin
  325.    InitList(Stack);
  326. End;
  327.  
  328. Procedure Push(Var Stack:ListRec; Var Item; Size:Word);
  329. Begin
  330.    AddItem(Stack, Item, Size);
  331. End;
  332.  
  333. Procedure Pop(Var Stack:ListRec; Var Item);
  334. Begin
  335.    GetItem(Stack, LastItem(Stack), Item);
  336.    DeleteItem(Stack, Pointer(Stack.Item));
  337. End;
  338.  
  339. Procedure Queue(Var Stack:ListRec; Var Item; Size:Word);
  340. Begin
  341.    InsertItem(Stack, Item, Size, FirstItem(Stack));
  342. End;
  343.  
  344. Procedure DeQueue(Var Stack:ListRec; Var Item);
  345. Begin
  346.    GetItem(Stack, FirstItem(Stack), Item);
  347.    DeleteItem(Stack, Pointer(Stack.Item));
  348. End;
  349.  
  350. END.
  351.