home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / sampler / 02 / listdata / list.pas
Encoding:
Pascal/Delphi Source File  |  1987-09-25  |  8.5 KB  |  290 lines

  1. unit addr_list;
  2.  
  3.   {Unit to hide a linked list data structure from the main
  4.    program.}
  5.  
  6.   {Marshall Brain   Box 37224 Raleigh, NC 27597  ver 1.0  9/13/87}
  7.  
  8.   INTERFACE
  9.     {This portion of the unit is used to describe the type of
  10.      objects used by the unit and the operations available to
  11.      manipulate those objects. This section is visible to any
  12.      program using this unit.}
  13.  
  14.     TYPE
  15.       name_string=STRING[10];
  16.       Addr=RECORD
  17.         last_name,first_name:name_string;
  18.         street:STRING[40];
  19.         city:STRING[10];
  20.         state:STRING[2];
  21.         zip:STRING[10];
  22.         phone:STRING[15];
  23.         comment:STRING[40];
  24.       END;
  25.  
  26.     PROCEDURE load_file(filename:STRING; VAR error:Boolean);
  27.       {LOAD_FILE attempts to load the data structure from
  28.        the file name specified. If unsuccessful, ERROR will
  29.        be true. File is assumed to be in sorted order.}
  30.  
  31.     PROCEDURE create_file(filename:STRING);
  32.       {creates a new file of name FILENAME.}
  33.  
  34.     PROCEDURE save_file;
  35.       {SAVE_FILE saves the data structure back to the file it
  36.        was loaded from.}
  37.  
  38.     PROCEDURE find_first(lname,fname:name_string; VAR rec:Addr;
  39.                          no_match:Boolean);
  40.       {FIND_FIRST will find the first record with a name that
  41.        matches LNAME,FNAME. If a match is found, REC will contain
  42.        the record found. Otherwise, NO_MATCH will be true and REC
  43.        will contain garbage.}
  44.  
  45.     PROCEDURE find_next(lname,fname:name_string; VAR rec:Addr;
  46.                         no_match:Boolean);
  47.       {FIND_NEXT will find the next record matching LNAME,FNAME.
  48.        It is assumed that FIND_FIRST was used first. NO_MATCH
  49.        is set if there are no matches.}
  50.  
  51.     PROCEDURE add_rec(rec:Addr; VAR error:Boolean);
  52.       {ADD_REC will add REC to the data structure, maintaining
  53.        that data strucutre in sorted order by name. If the data
  54.        structure is full, ERROR will be set true.}
  55.  
  56.     PROCEDURE delete_rec;
  57.       {deletes the last record found using one of the FIND rtns.}
  58.  
  59.     PROCEDURE change_rec(rec:Addr);
  60.       {replaces the last record found using one of the find rtns
  61.        with rec. First and last name should not be changed, as this
  62.        will destroy the linked list order. If the name needs
  63.        to change, use DELETE_REC and ADD_REC instead.}
  64.  
  65.     FUNCTION size:word;
  66.       {SIZE will contain the number of records in the data
  67.        structure.}
  68.  
  69.     FUNCTION full:Boolean;
  70.       {FULL will be false if space remains in the data strucutre.}
  71.  
  72. IMPLEMENTATION
  73.     {This portion of the unit is invisible to the program, and
  74.      can be used to hide that data structure.}
  75.  
  76.     {The data structure is currently implemented as a linked list.}
  77.     TYPE
  78.       pntr=^ll_rec;
  79.       ll_rec=RECORD
  80.         a:Addr;
  81.         next,prev:pntr;
  82.       END;
  83.     VAR
  84.       first,last,curr:pntr;
  85.       f:FILE of Addr;
  86.       found:Boolean;
  87.  
  88.     PROCEDURE init;
  89.     {A hidden routine used to init variables.}
  90.     BEGIN
  91.       first:=NIL;
  92.       last:=NIL;
  93.       curr:=NIL;
  94.       found:=False;
  95.     END;
  96.  
  97.     PROCEDURE load_file{filename:STRING; VAR error:Boolean};
  98.       {LOAD_FILE attempts to load the data structure from
  99.        the file name specified. If unsuccessful, ERROR will
  100.        be true. File is assumed to be in sorted order.}
  101.     VAR temp:Addr; p:pntr; err:Boolean;
  102.     BEGIN
  103.       init;
  104.       {make sure that file exists.}
  105.       Assign(f,filename);
  106.       {$i-} Reset(f); {$i+}
  107.       IF IOResult=0 THEN
  108.       BEGIN
  109.         WHILE NOT EOF(f) DO
  110.         BEGIN
  111.           {append new records to the end of the linked list.}
  112.           Read(f,temp);
  113.           New(p);
  114.           {init p}
  115.           p^.a:=temp;
  116.           p^.next:=NIL;
  117.           p^.prev:=last;
  118.           {create the links.}
  119.           IF (first=NIL) THEN
  120.             first:=p
  121.           ELSE
  122.             last^.next:=p;
  123.           last:=p;
  124.         END;
  125.         Close(f);
  126.       END
  127.       ELSE
  128.         error:=True;
  129.     END;
  130.  
  131.     PROCEDURE create_file{filename:STRING};
  132.       {creates a new file of name FILENAME.}
  133.     BEGIN
  134.       Assign(f,filename);
  135.       init;
  136.     END;
  137.  
  138.     PROCEDURE save_file;
  139.       {SAVE_FILE saves the data structure back to the file it
  140.        was loaded from.}
  141.     VAR p:pntr;
  142.     BEGIN
  143.       Rewrite(f);
  144.       p:=first;
  145.       {loop to end of linked list.}
  146.       WHILE (p<>NIL) DO
  147.       BEGIN
  148.         {some I/O checking could be added.}
  149.         Write(f,p^.a);
  150.         {dispose of LL as it is saved.}
  151.         first:=first^.next;
  152.         dispose(p);
  153.         p:=first;
  154.       END;
  155.       init;
  156.       Close(f);
  157.     END;
  158.  
  159.     PROCEDURE find(lname,fname:name_string; VAR rec:Addr;
  160.                    VAR no_match:Boolean);
  161.     {This hidden routine loops through the LL looking for the
  162.      name passed.}
  163.     VAR stop:Boolean;
  164.     BEGIN
  165.       stop:=False;
  166.       no_match:=True;
  167.       {loop until end of list, match found, or past where name
  168.        should be.}
  169.       WHILE (curr<>NIL) AND no_match AND NOT stop DO
  170.       BEGIN
  171.         IF (lname>curr^.a.last_name) THEN {check next rec.}
  172.           curr:=curr^.next
  173.         ELSE IF (lname=curr^.a.last_name) THEN
  174.         {check for first name match.}
  175.         BEGIN
  176.           IF (fname>curr^.a.first_name) THEN {check next rec.}
  177.             curr:=curr^.next
  178.           ELSE IF (fname=curr^.a.first_name) THEN {match found.}
  179.           BEGIN
  180.             rec:=curr^.a;
  181.             no_match:=False;
  182.           END
  183.           ELSE {beyond where name can be.}
  184.             stop:=True;
  185.         END
  186.         ELSE {beyond where name can be.}
  187.           stop:=True;
  188.       END;
  189.     END;
  190.  
  191.     PROCEDURE find_first{lname,fname:name_string; VAR rec:Addr;
  192.                          no_match:Boolean};
  193.       {FIND_FIRST will find the first record with a name that
  194.        matches LNAME,FNAME. If a match is found, REC will contain
  195.        the record found. Otherwis, NO_MATCH will be true and REC
  196.        will contain garbage.}
  197.     BEGIN
  198.       curr:=first;
  199.       find(lname,fname,rec,no_match);
  200.       found:=NOT no_match;
  201.     END;
  202.  
  203.     PROCEDURE find_next{lname,fname:name_string; VAR rec:Addr;
  204.                         no_match:Boolean};
  205.       {FIND_NEXT will find the next record matching LNAME,FNAME.
  206.        It is assumed that FIND_FIRST was used first. NO_MATCH
  207.        is set if there are no matches.}
  208.     BEGIN
  209.       curr:=curr^.next;
  210.       find(lname,fname,rec,no_match);
  211.       found:=NOT no_match;
  212.     END;
  213.  
  214.     PROCEDURE add_rec{rec:Addr; VAR error:Boolean};
  215.       {ADD_REC will add REC to the data structure, maintaining
  216.        that data strucutre in sorted order by name. If the data
  217.        structure is full, ERROR will be set true.}
  218.     VAR temp:Addr; no_match:Boolean; p:pntr;
  219.     BEGIN
  220.       {check for heap overflow.}
  221.       IF (MemAvail>SizeOf(Addr)) THEN
  222.       BEGIN
  223.         {find where new rec should go.}
  224.         curr:=first;
  225.         find(rec.last_name,rec.first_name,temp,no_match);
  226.         {create new rec and link it in.}
  227.         New(p);
  228.         p^.a:=rec;
  229.         p^.next:=curr;
  230.         IF curr=NIL THEN p^.prev:=last ELSE p^.prev:=curr^.prev;
  231.         IF curr=first THEN first:=p
  232.           ELSE IF (curr=NIL) THEN last^.next:=p
  233.             ELSE curr^.prev^.next:=p;
  234.         IF curr=NIL THEN last:=p ELSE curr^.prev:=p;
  235.         error:=False;
  236.       END
  237.       ELSE
  238.         error:=True;
  239.     END;
  240.  
  241.     PROCEDURE delete_rec;
  242.       {deletes the last record found using one of the FIND rtns.}
  243.     VAR p:pntr;
  244.     BEGIN
  245.       IF found AND (curr<>NIL) THEN
  246.       BEGIN
  247.         WITH curr^ DO
  248.         BEGIN
  249.           {unlink rec and dispose of it.}
  250.           IF curr=first THEN first:=next ELSE prev^.next:=next;
  251.           IF curr=last THEN last:=prev ELSE next^.prev:=prev;
  252.           dispose(curr);
  253.         END;
  254.       END;
  255.     END;
  256.  
  257.     PROCEDURE change_rec{rec:Addr};
  258.       {replaces the last record found using one of the find rtns
  259.        with rec.}
  260.     BEGIN
  261.       IF found AND (curr<>NIL) THEN
  262.         curr^.a:=rec;
  263.     END;
  264.  
  265.     FUNCTION size{:word};
  266.       {SIZE will contain the number of records in the data
  267.        structure.}
  268.     VAR cnt:word; p:pntr;
  269.     BEGIN
  270.       p:=first;
  271.       cnt:=0;
  272.       WHILE (p<>NIL) DO
  273.       BEGIN
  274.         p:=p^.next;
  275.         cnt:=cnt+1;
  276.       END;
  277.       size:=cnt;
  278.     END;
  279.  
  280.     FUNCTION full{:Boolean};
  281.       {FULL will be false if space remains in the data structure.}
  282.     BEGIN
  283.       IF MemAvail<SizeOf(Addr) THEN full:=True ELSE full:=False;
  284.     END;
  285.  
  286. {initialization code for the unit.}
  287. BEGIN
  288.   init;
  289. END.
  290.