home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / useful / dev / obero / oberon-a / source / library / lists.mod < prev    next >
Encoding:
Text File  |  1994-08-08  |  5.1 KB  |  212 lines

  1. (***************************************************************************
  2.  
  3.      $RCSfile: Lists.mod $
  4.   Description: Doubly-linked lists similar to Exec lists
  5.  
  6.    Created by: fjc (Frank Copeland)
  7.     $Revision: 1.5 $
  8.       $Author: fjc $
  9.         $Date: 1994/08/08 16:25:10 $
  10.  
  11.   Copyright © 1994, Frank Copeland.
  12.   This file is part of the Oberon-A Library.
  13.   See Oberon-A.doc for conditions of use and distribution.
  14.  
  15. ***************************************************************************)
  16.  
  17. MODULE Lists;
  18.  
  19. (*
  20. ** $C= CaseChk       $I= IndexChk  $L+ LongAdr   $N= NilChk
  21. ** $P= PortableCode  $R= RangeChk  $S= StackChk  $T= TypeChk
  22. ** $V= OvflChk       $Z= ZeroVars
  23. *)
  24.  
  25. IMPORT E := Exec, Str := Strings, SYSTEM;
  26.  
  27. TYPE
  28.  
  29.   (* A simple doubly linked node *)
  30.  
  31.   NodePtr * = POINTER TO Node;
  32.   Node * = RECORD
  33.     succ * : NodePtr;
  34.     pred * : NodePtr;
  35.   END; (* Node *)
  36.  
  37.   (* An extended node with name and ordering information *)
  38.  
  39.   ExtNodePtr * = POINTER TO ExtNode;
  40.   ExtNode * = RECORD (Node)
  41.     name * : E.STRPTR;
  42.     key *  : LONGINT;
  43.   END; (* ExtNode *)
  44.  
  45.   (* A list header *)
  46.  
  47.   ListPtr * = POINTER TO List;
  48.   List * = RECORD
  49.     head * : NodePtr;
  50.     tail * : NodePtr;
  51.   END; (* List *)
  52.  
  53.  
  54. (* --- ExtNode procedures ----------------------------------------------- *)
  55.  
  56.  
  57. (*------------------------------------*)
  58. (* $D- disable copying of open arrays *)
  59. PROCEDURE AttachName * (VAR node : ExtNode; name : ARRAY OF CHAR);
  60.  
  61. BEGIN (* AttachName *)
  62.   SYSTEM.NEW (node.name, SYSTEM.STRLEN (name) + 1);
  63.   COPY (name, node.name^)
  64. END AttachName;
  65.  
  66.  
  67. (* --- List procedures -------------------------------------------------- *)
  68.  
  69.  
  70. (*------------------------------------*)
  71. PROCEDURE NewList * (VAR list : List);
  72.  
  73. BEGIN (* NewList *)
  74.   list.head := NIL; list.tail := NIL
  75. END NewList;
  76.  
  77. (*------------------------------------*)
  78. PROCEDURE AddHead * (VAR list : List; node : NodePtr);
  79.  
  80. BEGIN (* AddHead *)
  81.   node.succ := list.head; node.pred := NIL;
  82.   IF list.head # NIL THEN list.head.pred := node END;
  83.   list.head := node;
  84.   IF list.tail = NIL THEN list.tail := node END
  85. END AddHead;
  86.  
  87. (*------------------------------------*)
  88. PROCEDURE AddTail * (VAR list : List; node : NodePtr);
  89.  
  90. BEGIN (* AddTail *)
  91.   node.succ := NIL; node.pred := list.tail;
  92.   IF list.tail # NIL THEN list.tail.succ := node END;
  93.   list.tail := node;
  94.   IF list.head = NIL THEN list.head := node END
  95. END AddTail;
  96.  
  97. (*------------------------------------*)
  98. PROCEDURE Insert * (VAR list : List; node, prevNode : NodePtr);
  99.  
  100. BEGIN (* Insert *)
  101.   IF prevNode = NIL THEN AddHead (list, node)
  102.   ELSIF prevNode = list.tail THEN AddTail (list, node)
  103.   ELSE
  104.     node.succ := prevNode.succ;
  105.     IF node.succ # NIL THEN node.succ.pred := node END;
  106.     node.pred := prevNode; prevNode.succ := node
  107.   END; (* ELSE *)
  108. END Insert;
  109.  
  110. (*------------------------------------*)
  111. PROCEDURE IsListEmpty * (VAR list : List) : BOOLEAN;
  112.  
  113. BEGIN (* IsListEmpty *)
  114.   RETURN (list.head = NIL)
  115. END IsListEmpty;
  116.  
  117.  
  118. (*------------------------------------*)
  119. PROCEDURE RemHead * (VAR list : List) : NodePtr;
  120.  
  121.   VAR node : NodePtr;
  122.  
  123. BEGIN (* RemHead *)
  124.   node := list.head;
  125.   IF node # NIL THEN
  126.     list.head := node.succ;
  127.     IF list.tail = node THEN list.tail := NIL END;
  128.     node.pred := NIL; node.succ := NIL
  129.   END; (* IF *)
  130.   RETURN node
  131. END RemHead;
  132.  
  133. (*------------------------------------*)
  134. PROCEDURE RemTail * (VAR list : List) : NodePtr;
  135.  
  136.   VAR node : NodePtr;
  137.  
  138. BEGIN (* RemTail *)
  139.   node := list.tail;
  140.   IF node # NIL THEN
  141.     list.tail := node.pred;
  142.     IF list.head = node THEN list.head := NIL END;
  143.     node.pred := NIL; node.succ := NIL
  144.   END; (* IF *)
  145.   RETURN node
  146. END RemTail;
  147.  
  148.  
  149. (*------------------------------------*)
  150. PROCEDURE Remove * (VAR list : List; node : NodePtr);
  151.  
  152. BEGIN (* Remove *)
  153.   IF node.succ # NIL THEN node.succ.pred := node.pred END;
  154.   IF node.pred # NIL THEN node.pred.succ := node.succ END;
  155.   IF list.head = node THEN list.head := node.succ END;
  156.   IF list.tail = node THEN list.tail := node.pred END;
  157.   node.succ := NIL; node.pred := NIL
  158. END Remove;
  159.  
  160.  
  161. (* --- List procedures requiring ExtNodes ------------------------------- *)
  162.  
  163.  
  164. (*------------------------------------*)
  165. PROCEDURE Enqueue * (VAR list : List; node : ExtNodePtr);
  166.  
  167.   VAR next : NodePtr;
  168.  
  169. BEGIN (* Enqueue *)
  170.   next := list.head;
  171.   WHILE (next # NIL) & (next (ExtNodePtr).key >= node.key) DO
  172.     next := next.succ
  173.   END; (* WHILE *)
  174.   IF next = NIL THEN AddTail (list, node)
  175.   ELSE Insert (list, node, next.pred)
  176.   END;
  177. END Enqueue;
  178.  
  179. (*------------------------------------*)
  180. (* $D- disable copying of open arrays *)
  181. PROCEDURE FindName * (VAR list : List; name : ARRAY OF CHAR) : NodePtr;
  182.  
  183.   VAR next : NodePtr;
  184.  
  185. BEGIN (* FindName *)
  186.   next := list.head;
  187.   WHILE (next # NIL) & (next (ExtNodePtr).name^ # name) DO
  188.     next := next.succ
  189.   END; (* WHILE *)
  190.   RETURN next
  191. END FindName;
  192.  
  193. (*------------------------------------*)
  194. (* $D- disable copying of open arrays *)
  195. PROCEDURE FindNameNoCase *
  196.   (VAR list : List; name : ARRAY OF CHAR)
  197.   : NodePtr;
  198.  
  199.   VAR next : NodePtr;
  200.  
  201. BEGIN (* FindNameNoCase *)
  202.   next := list.head;
  203.   WHILE
  204.     (next # NIL) & (Str.CompareCAP (next (ExtNodePtr).name^, name) # 0)
  205.   DO
  206.     next := next.succ
  207.   END;
  208.   RETURN next
  209. END FindNameNoCase;
  210.  
  211. END Lists.
  212.