home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / PNL Libraries / MyLists.p < prev    next >
Encoding:
Text File  |  1995-10-03  |  10.2 KB  |  416 lines  |  [TEXT/CWIE]

  1. unit MyLists;
  2.  
  3. interface
  4.  
  5.     uses
  6.         Types;
  7.         
  8. { Some types have been changed to avoid clashing with the list manager }
  9.     type
  10.         listHead = ^listNode;            { Was listHeadHandle }
  11.         listItem = ^listNode;            { Was listHandle }
  12.         listNode = record
  13.                 head: boolean;
  14.                 next: listItem;
  15.                 prev: listItem;
  16.                 this: handle;
  17.             end;
  18.  
  19.     var
  20.         listError: boolean;
  21.  
  22.     procedure CreateList (var l: listHead);
  23.     procedure DestroyList (var l: listHead; dispose: boolean);
  24.  
  25.     procedure ReturnHead (lh: listHead; var l: listItem);
  26.     (* <a> b c / <a> b c / <a> b c / <a> / <a> / <> *)
  27.     procedure ReturnTail (lh: listHead; var l: listItem);
  28.     (* a b c <> / a b c <> / a b c <> / a b c <> / a <> / a <> / <> *)
  29.  
  30.     procedure MoveToHead (var l: listItem);
  31.     (* <a> b c / <a> b c / <a> b c / <a> b c / <a> / <a> / <> *)
  32.     procedure MoveToTail (var l: listItem);
  33.     (* a b c <> / a b c <> / a b c <> / a b c <> / a <> / a <> / <> *)
  34.     procedure MoveToNext (var l: listItem);
  35.     (* a <b> c / a b <c> / a b c <> / error / a <> / error / error *)
  36.     procedure MoveToPrev (var l: listItem);
  37.     (* error / <a> b c / a <b> c / a b <c> / error / <a> / error *)
  38.  
  39.     function FindItem (lh: listHead; it: univ handle; var l: listItem): boolean;
  40.  
  41.     procedure AddHead (l: listHead; it: univ handle);
  42.     (* x <a> b c / x a <b> c / x a b <c> / x a b c <> / x <a> / x a <> / x <>*)
  43.     procedure AddTail (l: listHead; it: univ handle);
  44.     (* <a> b c x / a <b> c x / a b <c> x / a b c x <> / <a> x / a x <> / x <>*)
  45.     procedure AddBefore (l: listItem; it: univ handle);
  46.     (* x <a> b c / a x <b> c / a b x <c> / a b c x <> / x <a> / a x <> / x <>*)
  47.     procedure AddAfter (l: listItem; it: univ handle);
  48.     (* <a> x b c / a <b> x c / a b <c> x / error / <a> x / error / error *)
  49.  
  50.     procedure DeleteHead (l: listHead; var it: univ handle);
  51.     (* <?> b c / <b> c / b <c> / b c <> / <?> / <> / error *)
  52.     procedure DeleteTail (l: listHead; var it: univ handle);
  53.     (* <a> b / a <b> / a b <?> / a b <> / <?> / <> / error *)
  54.     procedure DeletePrev (l: listItem; var it: univ handle);
  55.     (* error / <b> c / a <c> / a b <> / error / <> / error *)
  56.     procedure DeleteNext (l: listItem; var it: univ handle);
  57.     (* <a> c / a <b> / error / error / error / error / error *)
  58.     procedure DeleteItem (var l: listItem; var it: univ handle);
  59.     (* <b> c / a <c> / a b <> / error / <> / error / error *)
  60.  
  61.     procedure FetchHead (l: listHead; var it: univ handle);
  62.     (* a / a / a / a / a / a / error  *)
  63.     procedure FetchTail (l: listHead; var it: univ handle);
  64.     (* c / c / c / c / a / a / error  *)
  65.     procedure FetchNext (l: listItem; var it: univ handle);
  66.     (* b / c / error / error / error / error / error *)
  67.     procedure FetchPrev (l: listItem; var it: univ handle);
  68.     (* error / a / b / c / error / a / error *)
  69.     procedure Fetch (l: listItem; var it: univ handle);
  70.     (* a / b / c / error / a / error / error *)
  71.  
  72.     function IsHead (l: listItem): boolean;
  73.     (* T / F / F / F / T / F / T *)
  74.     function IsTail (l: listItem): boolean;
  75.     (* F / F / F / T / F / T / T *)
  76.     function IsEmpty (l: listHead): boolean;
  77.     (* F / F / F / F / F / F / T *)
  78.  
  79.     procedure DisplayList (lh: listHead);
  80.    (* To the Text Screen *)
  81.     procedure ValidateList (lh: listHead; maxlen: longint);
  82.     (* Check the list for validity, maxlen is the maximum valid length *)
  83.  
  84. implementation
  85.  
  86.     uses
  87.         Memory;
  88. { Internal Routines }
  89.  
  90.     procedure DestroyListPtr (var l: univ listItem);
  91.     begin
  92. {    l^^.next := nil;                These dont do any good }
  93. {    l ^ ^ . prev := nil;            cause DisposHandle }
  94. {    l  ^ ^ . this := nil;            destroys the data }
  95.         DisposePtr(Ptr(l));
  96.         l := nil;
  97.     end;
  98.  
  99.     procedure CreateListPtr (var l: univ listItem);
  100.     begin
  101.         l := listItem(NewPtr(SizeOf(listNode)));
  102.         if l = nil then begin
  103.             listError := true;
  104.             DebugStr('CreateListPtr Failed!');
  105.         end;
  106.     end;
  107.  
  108.     procedure MoveToStart (var l: univ listItem);
  109.         var
  110.             tmp: listItem;
  111.     begin
  112.         if not l^.head then begin
  113.             tmp := l;
  114.             repeat
  115.                 l := l^.next;
  116.             until (tmp = l) or l^.head;
  117.             if tmp = l then begin
  118.                 listError := true;
  119.             end;
  120.         end;
  121.     end;
  122.  
  123.     procedure InsertBefore (l: univ listItem; var it: univ handle);
  124.         var
  125.             tmp: listItem;
  126.     begin
  127.         CreateListPtr(tmp);
  128.         if tmp <> nil then begin
  129.             tmp^.head := false;
  130.             tmp^.this := it;
  131.             tmp^.next := l;
  132.             tmp^.prev := l^.prev;
  133.             l^.prev^.next := tmp;
  134.             l^.prev := tmp;
  135.         end;
  136.     end;
  137.  
  138.     procedure DeleteNode (l: listItem; var it: univ handle);
  139.     begin
  140.         if l^.head then begin
  141.             listError := true;
  142.         end else begin
  143.             it := l^.this;
  144.             l^.prev^.next := l^.next;
  145.             l^.next^.prev := l^.prev;
  146.             DestroyListPtr(l);
  147.         end;
  148.     end;
  149.  
  150.     procedure FetchNode (l: listItem; var it: univ handle);
  151.     begin
  152.         if l^.head then begin
  153.             listError := true;
  154.         end;
  155.         it := l^.this;
  156.     end;
  157.  
  158. { External Routines }
  159.  
  160.     procedure CreateList (var l: listHead);
  161.     begin
  162.         CreateListPtr(l);
  163.         if l <> nil then begin
  164.             l^.head := true;
  165.             l^.next := listItem(l);
  166.             l^.prev := listItem(l);
  167.             l^.this := nil;
  168.         end;
  169.     end;
  170.  
  171.     procedure DestroyList (var l: listHead; dispose: boolean);
  172.         var
  173.             tmp, tmp2: listItem;
  174.     begin
  175.         tmp := l^.next;
  176.         while tmp <> listItem(l) do begin
  177.             tmp2 := tmp;
  178.             tmp := tmp^.next;
  179.             if dispose then begin
  180.                 DisposeHandle(tmp2^.this);
  181.             end;
  182.             DestroyListPtr(tmp2);
  183.         end;
  184.         if dispose then begin
  185.             DisposeHandle(l^.this);
  186.         end;
  187.         DestroyListPtr(l);
  188.     end;
  189.  
  190.     procedure ReturnHead (lh: listHead; var l: listItem);
  191.     (* <a> b c / <a> b c / <a> b c / <a> / <a> / <> *)
  192.     begin
  193.         l := lh^.next;
  194.     end;
  195.  
  196.     procedure ReturnTail (lh: listHead; var l: listItem);
  197.     (* a b c <> / a b c <> / a b c <> / a b c <> / a <> / a <> / <> *)
  198.     begin
  199.         l := listItem(lh);
  200.     end;
  201.  
  202.     function FindItem (lh: listHead; it: univ handle; var l: listItem): boolean;
  203.     begin
  204.         l := listItem(lh)^.next;
  205.         while (not l^.head) and (it <> l^.this) do begin
  206.             l := l^.next;
  207.         end;
  208.         FindItem := (not l^.head) and (it = l^.this);
  209.     end;
  210.  
  211.     procedure MoveToHead (var l: listItem);
  212.     (* <a> b c / <a> b c / <a> b c / <a> b c / <a> / <a> / <> *)
  213.     begin
  214.         MoveToStart(l);
  215.         l := l^.next;
  216.     end;
  217.  
  218.     procedure MoveToTail (var l: listItem);
  219.     (* a b c <> / a b c <> / a b c <> / a b c <> / a <> / a <> / <> *)
  220.     begin
  221.         MoveToStart(l);
  222.     end;
  223.  
  224.     procedure MoveToNext (var l: listItem);
  225.     (* a <b> c / a b <c> / a b c <> / error / a <> / error / error *)
  226.     begin
  227.         if l^.head then begin
  228.             listError := true;
  229.         end else begin
  230.             l := l^.next;
  231.         end;
  232.     end;
  233.  
  234.     procedure MoveToPrev (var l: listItem);
  235.     (* error / <a> b c / a <b> c / a b <c> / error / <a> / error *)
  236.     begin
  237.         if l^.prev^.head then begin
  238.             listError := true;
  239.         end else begin
  240.             l := l^.prev;
  241.         end;
  242.     end;
  243.  
  244.     procedure AddHead (l: listHead; it: univ handle);
  245.     (* x <a> b c / x a <b> c / x a b <c> / x a b c <> / x <a> / x a <> / x <>*)
  246.     begin
  247.         InsertBefore(l^.next, it);
  248.     end;
  249.  
  250.     procedure AddTail (l: listHead; it: univ handle);
  251.     (* <a> b c x / a <b> c x / a b <c> x / a b c x <> / <a> x / a x <> / x <>*)
  252.     begin
  253.         InsertBefore(l, it);
  254.     end;
  255.  
  256.     procedure AddBefore (l: listItem; it: univ handle);
  257.     (* x <a> b c / a x <b> c / a b x <c> / a b c x <> / x <a> / a x <> / x <>*)
  258.     begin
  259.         InsertBefore(l, it);
  260.     end;
  261.  
  262.     procedure AddAfter (l: listItem; it: univ handle);
  263.     (* <a> x b c / a <b> x c / a b <c> x / error / <a> x / error / error *)
  264.     begin
  265.         if l^.head then begin
  266.             listError := true;
  267.         end else begin
  268.             InsertBefore(l^.next, it);
  269.         end;
  270.     end;
  271.  
  272.     procedure DeleteHead (l: listHead; var it: univ handle);
  273.     (* <?> b c / <b> c / b <c> / b c <> / <?> / <> / error *)
  274.     begin
  275.         DeleteNode(l^.next, it);
  276.     end;
  277.  
  278.     procedure DeleteTail (l: listHead; var it: univ handle);
  279.     (* <a> b / a <b> / a b <?> / a b <> / <?> / <> / error *)
  280.     begin
  281.         DeleteNode(l^.prev, it);
  282.     end;
  283.  
  284.     procedure DeletePrev (l: listItem; var it: univ handle);
  285.     (* error / <b> c / a <c> / a b <> / error / <> / error *)
  286.     begin
  287.         DeleteNode(l^.prev, it);
  288.     end;
  289.  
  290.     procedure DeleteNext (l: listItem; var it: univ handle);
  291.     (* <a> c / a <b> / error / error / error / error / error *)
  292.     begin
  293.         if l^.head then begin
  294.             listError := true;
  295.             it := nil;
  296.         end
  297.         else
  298.             DeleteNode(l^.next, it);
  299.     end;
  300.  
  301.     procedure DeleteItem (var l: listItem; var it: univ handle);
  302.     (* <b> c / a <c> / a b <> / error / <> / error / error *)
  303.         var
  304.             tmp: listItem;
  305.     begin
  306.         if l^.head then begin
  307.             listError := true;
  308.             it := nil;
  309.         end
  310.         else begin
  311.             tmp := l^.next;
  312.             DeleteNode(l, it);
  313.             l := tmp;
  314.         end;
  315.     end;
  316.  
  317.     procedure FetchHead (l: listHead; var it: univ handle);
  318.     (* a / a / a / a / a / a / error  *)
  319.     begin
  320.         FetchNode(l^.next, it);
  321.     end;
  322.  
  323.     procedure FetchTail (l: listHead; var it: univ handle);
  324.     (* c / c / c / c / a / a / error  *)
  325.     begin
  326.         FetchNode(l^.prev, it);
  327.     end;
  328.  
  329.     procedure FetchNext (l: listItem; var it: univ handle);
  330.     (* b / c / error / error / error / error / error *)
  331.     begin
  332.         if l^.head then begin
  333.             listError := true;
  334.             it := nil;
  335.         end
  336.         else
  337.             FetchNode(l^.next, it);
  338.     end;
  339.  
  340.     procedure FetchPrev (l: listItem; var it: univ handle);
  341.     (* error / a / b / c / error / a / error *)
  342.     begin
  343.         FetchNode(l^.prev, it);
  344.     end;
  345.  
  346.     procedure Fetch (l: listItem; var it: univ handle);
  347.     (* a / b / c / error / a / error / error *)
  348.     begin
  349.         FetchNode(l, it);
  350.     end;
  351.  
  352.     function IsHead (l: listItem): boolean;
  353.     (* T / F / F / F / T / F / T *)
  354.     begin
  355.         IsHead := l^.prev^.head;
  356.     end;
  357.  
  358.     function IsTail (l: listItem): boolean;
  359.     (* F / F / F / T / F / T / T *)
  360.     begin
  361.         IsTail := l^.head;
  362.     end;
  363.  
  364.     function IsEmpty (l: listHead): boolean;
  365.     (* F / F / F / F / F / F / T *)
  366.     begin
  367.         IsEmpty := l^.next = listItem(l);
  368.     end;
  369.  
  370.     procedure DisplayList (lh: listHead);
  371.         var
  372.             l: listItem;
  373.             hhhh: handle;
  374.     begin
  375.         ReturnHead(lh, l);
  376.         write('(');
  377.         while not IsTail(l) do begin
  378.             Fetch(l, hhhh);
  379.             MoveToNext(l);
  380.             write(hhhh);
  381.             if not IsTail(l) then begin
  382.                 write(',');
  383.             end;
  384.         end;
  385.         writeln('  )');
  386.     end;
  387.  
  388.     procedure ValidateList (lh: listHead; maxlen: longint);
  389.         var
  390.             item: listItem;
  391.             count: integer;
  392.             data: handle;
  393.     begin
  394.         if lh = nil then begin
  395.             DebugStr('ValidateList: lh = nil');
  396.         end;
  397.         count := 0;
  398.         ReturnHead(lh, item);
  399.         if item = nil then begin
  400.             DebugStr('ValidateList: first item = nil');
  401.         end;
  402.         while not IsTail(item) do begin
  403.             Fetch(item, data);
  404.             MoveToNext(item);
  405.             if item = nil then begin
  406.                 DebugStr('ValidateList: list item = nil');
  407.             end;
  408.             count := count + 1;
  409.             if count > maxlen then begin
  410.                 DebugStr('ValidateList: List too long - probably bad');
  411.                 leave;
  412.             end;
  413.         end;
  414.     end;
  415.  
  416. end.