home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / VIDEOTEXT.LZX / VTsrc / pagelist.p < prev    next >
Encoding:
Text File  |  1996-02-19  |  6.4 KB  |  204 lines

  1. UNIT pagelist; {$project vt}
  2. { Verwaltung der verketteten Seitenliste zum Programm VideoText }
  3. { Es wird darauf geachtet, daß die Auswahlzeiger <thispage> und <visblpage> }
  4. { immer einen sinnvollen Inhalt haben und daß <thispage> nur bei leerer }
  5. { Liste NIL ist. }
  6.  
  7. INTERFACE; FROM vt USES global;
  8.  
  9. VAR root,thispage,visblpage: p_onepage;
  10.     listsize: Word;
  11.  
  12. PROCEDURE kill_list;
  13. PROCEDURE del_from_list(target: p_onepage);
  14. PROCEDURE ins_to_list(item: p_onepage);
  15. PROCEDURE add_to_list(item: p_onepage);
  16. FUNCTION hunt_in_list(pg,sp: Integer; exact: Boolean): p_onepage;
  17. FUNCTION next_magazine(item: p_onepage): p_onepage;
  18. FUNCTION prev_magazine(item: p_onepage): p_onepage;
  19. FUNCTION posn_in_list(item: p_onepage): Integer;
  20. FUNCTION page_on_posn(n: Integer): p_onepage;
  21.  
  22. { ---------------------------------------------------------------------- }
  23.  
  24. IMPLEMENTATION;
  25.  
  26. {$opt q,s+,i+ } { keine Laufzeitprüfungen außer Stack und Feldindizes }
  27.  
  28. PROCEDURE kill_list;
  29. { Alle Seiten wegwerfen. }
  30. VAR hilf: p_onepage;
  31. BEGIN
  32.   hilf := root;
  33.   WHILE root<>Nil DO BEGIN
  34.     root := root^.next;
  35.     Dispose(hilf);
  36.     hilf := root;
  37.   END;
  38.   thispage := root; visblpage := Nil;
  39.   listsize := 0;
  40. END;
  41.  
  42. PROCEDURE del_from_list{(target: p_onepage)};
  43. { Die bezeichnete Seite aus der Liste herauslösen UND löschen (Dispose). }
  44. { Falls <thispage> auf die gelöschte Seite zeigt, wird sichergestellt, daß }
  45. { <thispage> anschließend wieder auf einen sinnvollen Inhalt zeigt: }
  46. {  - auf den Nachfolger der gelöschten Seite, falls sie einen hat, sonst }
  47. {  - auf ihren Vorgänger (d. h. Listenende oder Nil) }
  48. BEGIN
  49.   IF target^.prev<>Nil THEN
  50.     target^.prev^.next := target^.next  ELSE  root := target^.next;
  51.   IF target^.next<>Nil THEN
  52.     target^.next^.prev := target^.prev;
  53.   IF target=visblpage THEN visblpage := Nil;
  54.   IF target=thispage THEN BEGIN
  55.     thispage := target^.next;
  56.     IF thispage = Nil THEN thispage := target^.prev;
  57.   END;
  58.   Dispose(target);
  59.   Dec(listsize);
  60. END;
  61.  
  62. FUNCTION hunt_in_list{(pg,sp: Integer; exact: Boolean): p_onepage};
  63. { Liefert einen Zeiger auf die durch <pg>, <sp> beschriebene Seite in der }
  64. { Liste. Falls eine entsprechende Seite nicht gefunden wird, ist das }
  65. { Resultat für exact=False der nächsthöhere existierende Eintrag (bzw. das }
  66. { Listenende, wenn es keinen höheren Eintrag gibt), für exact=True einfach }
  67. { Nil. Letztere Variante funktioniert dafür auch auf unsortierten Listen, }
  68. { d. h. solchen, die mit add_to_list() statt ins_to_list() aufgebaut wurden. }
  69. VAR hilf: p_onepage;
  70. BEGIN
  71.   hilf := root;
  72.   IF hilf<>Nil THEN
  73.     IF exact THEN BEGIN
  74.       { richtige Seitennummer finden }
  75.       WHILE ((hilf^.pg<>pg) OR (hilf^.sp<>sp)) AND (hilf^.next<>Nil) DO
  76.         hilf := hilf^.next;
  77.       IF ((hilf^.pg<>pg) OR (hilf^.sp<>sp)) THEN
  78.         hilf := Nil; {=hilf^.next}
  79.     END ELSE BEGIN
  80.       { richtige oder nächsthöhere Seitennummer finden }
  81.       WHILE (hilf^.pg<pg) AND (hilf^.next<>Nil) DO
  82.         hilf := hilf^.next;
  83.       { Wenn die Seitennummer stimmt, noch die Unterseite finden }
  84.       WHILE (hilf^.pg=pg) AND (hilf^.sp<sp) AND (hilf^.next<>Nil) DO
  85.         hilf := hilf^.next;
  86.     END;
  87.   hunt_in_list := hilf;
  88. END;
  89.  
  90. PROCEDURE ins_to_list{(item: p_onepage)};
  91. { Neue Seite nach Seiten- und Unterseitennummer in die Liste einsortieren. }
  92. { Wenn bereits gleichartige Einträge existieren, wird die neue Seite hinter }
  93. { diesen eingefügt. }
  94. VAR hilf: p_onepage;
  95. BEGIN
  96.   IF root=Nil THEN BEGIN
  97.     root := item;
  98.     item^.next := Nil;
  99.     item^.prev := Nil;
  100.   END ELSE BEGIN
  101.     hilf := hunt_in_list(item^.pg,item^.sp,False);
  102.     WHILE (hilf^.pg=item^.pg) AND (hilf^.sp=item^.sp) AND (hilf^.next<>Nil) DO
  103.       hilf := hilf^.next;
  104.     { hilf zeigt jetzt auf die Seite, vor der eingefügt werden sollte, bzw. }
  105.     { auf das Listenende, falls die neue Seite die höchste aller Nummern hat. }
  106.     IF (hilf^.pg>item^.pg) OR ((hilf^.pg=item^.pg) AND (hilf^.sp>item^.sp))
  107.     THEN BEGIN    { Normalfall, vor hilf einfügen }
  108.       item^.prev := hilf^.prev;
  109.       item^.next := hilf;
  110.       IF hilf^.prev<>Nil THEN hilf^.prev^.next := item  ELSE  root := item;
  111.       hilf^.prev := item;
  112.     END ELSE BEGIN    { Sonderfall, hinter hilf anhängen }
  113.       item^.prev := hilf;
  114.       item^.next := hilf^.next;
  115.       IF hilf^.next<>Nil THEN hilf^.next^.prev := item;
  116.       hilf^.next := item;
  117.     END;
  118.   END;
  119.   IF thispage=Nil THEN thispage := item;
  120.   Inc(listsize);
  121. END;
  122.  
  123. PROCEDURE add_to_list{(item: p_onepage)};
  124. { Hängt eine Seite ans Ende der Liste an. }
  125. VAR hilf: p_onepage;
  126. BEGIN
  127.   IF root=Nil THEN BEGIN
  128.     root := item
  129.     item^.next := Nil;
  130.     item^.prev := Nil;
  131.   END ELSE BEGIN
  132.     hilf := root;
  133.     WHILE hilf^.next<>Nil DO
  134.       hilf := hilf^.next;
  135.     { Hinter hilf anhängen: }
  136.     hilf^.next := item;
  137.     item^.prev := hilf;
  138.     item^.next := Nil;
  139.   END;
  140.   IF thispage=Nil THEN thispage := item;
  141.   Inc(listsize);
  142. END;
  143.  
  144. FUNCTION next_magazine{(item: p_onepage): p_onepage};
  145. { Erste Seite finden, die hinter <item> in der Liste steht und eine andere }
  146. { Magazinnummer trägt. Absichtlich so vorsichtig formuliert, damit das auch }
  147. { auf unsortierten Listen sinnvolle Resultate liefert. }
  148. VAR mag: integer;
  149. BEGIN
  150.   IF item<>Nil THEN BEGIN
  151.     mag := item^.pg SHR 8;
  152.     { zum nächsten Magazin vorrücken }
  153.     WHILE (item^.next<>Nil) AND (item^.pg SHR 8 = mag) DO
  154.       item := item^.next;
  155.   END;
  156.   next_magazine := item;
  157. END;
  158.  
  159. FUNCTION prev_magazine{(item: p_onepage): p_onepage};
  160. { Die in Richtung Listenanfang nächstliegende Seite, die einen Magazinanfang }
  161. { markiert und nicht <item> selbst ist. }
  162. VAR mag: integer;
  163. BEGIN
  164.   IF item<>Nil THEN IF item^.prev<>Nil THEN BEGIN
  165.     item := item^.prev;
  166.     mag := item^.pg SHR 8;
  167.     { zum vorigen Magazin }
  168.     WHILE (item^.prev<>Nil) AND (item^.pg SHR 8 = mag) DO
  169.       item := item^.prev;
  170.     { Hoppla, eins zu weit ... }
  171.     IF (item^.next<>Nil) AND (item^.pg SHR 8 <> mag) THEN
  172.       item := item^.next;
  173.   END;
  174.   prev_magazine := item;
  175. END;
  176.  
  177. FUNCTION posn_in_list{(item: p_onepage): Integer};
  178. { herausfinden, die wievielte in der Liste <seite> ist (ab 0 gezählt) }
  179. VAR n: Integer;
  180.     hilf: p_onepage;
  181. BEGIN
  182.   hilf := root; n := 0;
  183.   WHILE (hilf<>Nil) AND (hilf<>item) DO BEGIN
  184.     hilf := hilf^.next; Inc(n);  END;
  185.   posn_in_list := n;
  186. END;
  187.  
  188. FUNCTION page_on_posn{(n: Integer): p_onepage};
  189. { Zeiger auf die <n>-te Seite besorgen }
  190. VAR i: Integer;
  191.     hilf: p_onepage;
  192. BEGIN
  193.   hilf := root;
  194.   FOR i := 1 TO n DO
  195.     IF hilf<>Nil THEN hilf := hilf^.next;
  196.   page_on_posn := hilf;
  197. END;
  198.  
  199. BEGIN   { Intialisierungsteil }
  200.   root := Nil; thispage := Nil; visblpage := Nil;
  201.   listsize := 0;
  202. END.
  203.  
  204.