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