home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / futils / futils~1 / src / misc1s.zoo / misc1 / combine / pass3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-23  |  5.0 KB  |  186 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "util.h"
  4. #include "combine.h"
  5. /*
  6.  * pass3: Expand anchors to non-unique records.
  7.  *
  8.  * If in a pair of files immediately adjacent to an anchor point
  9.  * there are lines which are identical to each other, these lines
  10.  * are then considered to be anchor points. Repeated application of this
  11.  * principle on each possible pair of files and in each possible direction
  12.  * results in all matched lines being found.
  13.  *
  14.  * This routine calls the 'pass3_scan' routine once for each combination of
  15.  * file pairs and directions.
  16.  *
  17.  * Possible design flaw: If a particular anchor exists in all three files,
  18.  * should adjacent records be considered to be an anchor only if all
  19.  * three adjacent records are identical.
  20.  *
  21.  * Return value:
  22.  *      This procedure has no return value.
  23.  */
  24.  
  25. void pass3 () {
  26.  
  27.     int     i;        /* Misc. variable */
  28.  
  29.     int     j;        /* Misc. variable */
  30.  
  31.     /*
  32.      * Scan each pair of files in the forward direction.
  33.      */
  34.  
  35.     for (j = 0; j < UNIQUE_MATCH_COUNT; ++j) {
  36.  
  37.         i = unique_match[j];
  38.  
  39.         if (files[curr_file[i]].record != 0 &&
  40.                 files[corres_file[i]].record != 0) {
  41.  
  42.             pass3_scan (i, 1);
  43.  
  44.         }
  45.  
  46.     }
  47.  
  48.     /*
  49.      * Scan each pair of files in the reverse direction.
  50.      */
  51.     for (j = 0; j < UNIQUE_MATCH_COUNT; ++j) {
  52.  
  53.         i = unique_match[j];
  54.  
  55.         if (files[curr_file[i]].record != 0 &&
  56.                 files[corres_file[i]].record != 0) {
  57.  
  58.             pass3_scan (i, -1);
  59.  
  60.         }
  61.  
  62.     }
  63.  
  64. }
  65. /*
  66.  * pass3_scan: Expand anchors to non-unique records.
  67.  *
  68.  * This routine scans the record arrays for a pair of files in one
  69.  * direction expanding anchors. For each record in the first file,
  70.  * if the current record is an anchor, and the next record in each file
  71.  * is a hash code (i.e. not an anchor), and the hash codes are the same,
  72.  * then the next records are considered to be anchors.
  73.  *
  74.  * Return value:
  75.  *      This procedure has no return value.
  76.  */
  77. void pass3_scan (match_no, direction)
  78. int     match_no;        /* input */
  79.                 /* Which relationship is being scanned */
  80.  
  81. int     direction;        /* This is the direction to scan the file.
  82.                    Valid values are 1 for forward and -1 for
  83.                    backward. */
  84.  
  85. {
  86.  
  87.     int     end_index1;    /* Index into record array of file1 of end of
  88.                    the record array. (e.g. the first record to
  89.                    not process when going in 'direction') */
  90.  
  91.     file_type * file1_ptr;    /* First file - current_file */
  92.  
  93.     file_type * file2_ptr;    /* Second file - corresponding file */
  94.  
  95.     int     file1_sub;    /* For each record of the first file, this is a
  96.                    subscript of the 'value' array of the
  97.                    relationship between file1 and file2 */
  98.  
  99.     int     file2_sub;    /* For each record of the second file, this is
  100.                    a subscript of the 'value' array of the
  101.                    relationship between file2 and file1 */
  102.  
  103.     int     index1;        /* Index into record array of file1 of the
  104.                    record currently being processed */
  105.  
  106.     int     index2;        /* Index into record array of file2 of the
  107.                    record anchored to the 'index1' record */
  108.  
  109.     record_type * record1;    /* Pointer to record array of file1 */
  110.  
  111.     record_type * record2;    /* Pointer to record array of file2 */
  112.  
  113.     int    *val1_ptr;    /* Pointer to the 'value' field in 'next'
  114.                    record on file1. This is the 'value' which
  115.                    indicates the relationship to file2. */
  116.  
  117.     int    *val2_ptr;    /* Pointer to the 'value' field in 'next'
  118.                    record on file2. This is the 'value' which
  119.                    indicates the relationship to file1. */
  120.  
  121.  
  122.     /*
  123.      * Initialize indexes to first and last record of the files.
  124.      */
  125.     file1_ptr = &files[curr_file[match_no]];
  126.     file2_ptr = &files[corres_file[match_no]];
  127.     file1_sub = value_sub[match_no];
  128.     file2_sub = rev_value_sub[match_no];
  129.  
  130.     record1 = file1_ptr -> record;
  131.     record2 = file2_ptr -> record;
  132.  
  133.     if (direction == 1) {
  134.         index1 = BEGIN_INDEX;
  135.         end_index1 = file1_ptr -> record_array_size - 1;
  136.     } else {
  137.         index1 = file1_ptr -> record_array_size - 1;
  138.         end_index1 = BEGIN_INDEX;
  139.     }
  140.  
  141.     /*
  142.      * For each record in the first file.
  143.      *
  144.      * Note: given the existence of the 'begin' and 'end' record on each
  145.      * end of the record array, and given the way the 'end_index1'
  146.      * was set up above (so as to not process the last record
  147.      * on the opposite end of the file from which the scan started),
  148.      * we can convince ourselves that the tests below won't ever index
  149.      * off the end of the arrays.
  150.      */
  151.     for (; index1 != end_index1; index1 += direction) {
  152.  
  153.         /*
  154.          * If the current record in file1 is an anchor point,
  155.          *     Compute the index into file2 of the corresponding record.
  156.          *     Compute a pointer to value field of the next record in each file.
  157.          */
  158.  
  159.         index2 = record1[index1].value[file1_sub];
  160.         if (!is_hash_code (index2)) {
  161.  
  162.             val1_ptr = &(record1[index1 + direction].
  163.                 value[file1_sub]);
  164.             val2_ptr = &(record2[index2 + direction].
  165.                 value[file2_sub]);
  166.  
  167.             /*
  168.              * If the neither of the next records are anchor points and
  169.              *     the records are identical,
  170.              *     consider these records to be anchors.
  171.              */
  172.             if (is_hash_code (*val1_ptr) &&
  173.                     is_hash_code (*val2_ptr) &&
  174.                     *val1_ptr == *val2_ptr) {
  175.  
  176.                 link_records (match_no, index1 + direction,
  177.                     index2 + direction);
  178.  
  179.             }
  180.  
  181.         }
  182.  
  183.     }
  184.  
  185. }
  186.