home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / CODE4-1.ZIP / SOURCE.ZIP / I4CHECK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-11  |  5.1 KB  |  227 lines

  1.  
  2. /* i4check.c   (C)Copyright Sequiter Software Inc., 1987, 1988, 1989.  All rights reserved.
  3.  
  4.    Check Index checks to see if an index file is accurate.
  5. */
  6.  
  7.  
  8. #include "d4base.h"
  9. #include <string.h>
  10.  
  11. extern  INDEX  *v4index ;
  12. extern  BLOCK  *v4block ;
  13.  
  14. static unsigned char  *rec_flags ;
  15.  
  16. static  int  set_flag(long), check_record(void) ;
  17. static  unsigned int  test_set(long) ;
  18. #ifndef CLIPPER
  19.    i4blk_ptr_chk(void) ;
  20. #endif
  21.  
  22.  
  23. static  char  old_key[260], new_key[260] ;
  24. static  long  old_rec ;
  25. static  int   do_compare ;  /* Do not compare the first time */
  26. static  int   entry_num, i_ref  ;
  27. static  INDEX  *i_ptr =  (INDEX *) 0 ;
  28.  
  29.  
  30. static int  set_flag( r_num)
  31. long r_num ;
  32. {
  33.    unsigned int  low_val, set_val, high_val  ;
  34.  
  35.    if ( r_num < 1) return( -1) ;
  36.  
  37.    low_val  =  (unsigned int) (r_num & 0x7) ;
  38.    high_val =  (unsigned int) (r_num >> 3) ;
  39.  
  40.    set_val  =  1 << low_val ;
  41.  
  42.    rec_flags[high_val] = (unsigned char)  (set_val | (unsigned int) rec_flags[high_val]) ;
  43.  
  44.    return( 0) ;
  45. }
  46.  
  47. static unsigned int  test_set( r_num)
  48. long r_num ;
  49. {
  50.    unsigned int  ret_val, low_val, high_val  ;
  51.  
  52.    low_val  =  (unsigned int) (r_num & 0x7) ;
  53.    high_val =  (unsigned int) (r_num >> 3) ;
  54.  
  55.    ret_val =  (1 << low_val) &  (unsigned int) rec_flags[high_val]  ;
  56.  
  57.    return( ret_val )  ;
  58. }
  59.  
  60.  
  61. static int  check_record()
  62. {
  63.    char *ptr ;
  64.    int   key_len, rc ;
  65.    long   rec ;
  66.  
  67.    entry_num++ ;
  68.  
  69.    /* Check for Missing Key */
  70.    if ( b4key(i_ref) == (KEY *) 0)  return( -1 ) ;
  71.  
  72.    rec =  b4key(i_ref)->rec_num ;
  73.    if ( rec < 1 ||      rec > d4reccount() )
  74.       return( -3 ) ;
  75.  
  76.    if ( d4go( rec ) < 0)  return( -1) ;
  77.  
  78.    if ( test_set(rec) )
  79.       return( -4 ) ;
  80.    else
  81.       set_flag( rec ) ;
  82.  
  83.    ptr =  i4eval( i_ref ) ;
  84.    if ( ptr == (char *) 0)  return( -1 ) ;
  85.  
  86.    key_len =  i_ptr->key_len ;
  87.    memcpy( new_key, ptr,  key_len) ;
  88.  
  89.    if ( memcmp( b4key(i_ref)->value, ptr, key_len) != 0 )
  90.       return( -5 ) ;
  91.  
  92.    if ( do_compare )
  93.    {
  94.       if ( (rc = i4keycmp( i_ref, old_key, new_key)) > 0 ) 
  95.          return( -6 ) ;
  96.  
  97.       if ( rc == 0 && old_rec >= rec ) ;
  98.       /*   return( -6 ) ; */
  99.    }
  100.    else
  101.       do_compare =  1 ;
  102.  
  103.    old_rec =  rec ;
  104.    memcpy( old_key, new_key, key_len ) ;
  105.  
  106.    return( 0 ) ;
  107. }
  108.  
  109.  
  110. long  i4check( index_ref )
  111. int  index_ref ;
  112. {
  113.    int           rc ;
  114.    unsigned int  len_flags ;
  115.    long          base_size, on_rec ;
  116.  
  117.    do_compare = 0 ;
  118.    entry_num  = 0 ;
  119.    i_ref =  index_ref ;
  120.    i_ptr =  v4index+ i_ref ;
  121.  
  122.    d4select( i_ptr->base_ref ) ;
  123.    i4select( i_ref ) ;
  124.    if ( d4lock(-1L, 1) != 0 )  return( -1 ) ;
  125.    if ( i4lock( i_ref, 1 ) < 0 )  return -1 ;
  126.  
  127.    base_size =  d4reccount() ;
  128.    if ( base_size < 0 )  return( -1 ) ;
  129.  
  130.    if ( base_size > 0x7FF00L)  return( -2 ) ;
  131.  
  132.    len_flags =  (unsigned int) ((base_size-1)/8 + 2) ;
  133.  
  134.    if ( d4top() < 0 )  return( -1 ) ;
  135.  
  136.    if ( base_size == 0L )
  137.       if ( i4skip( i_ref, 1L ) == 0 )
  138.      return( 0 ) ;
  139.       else
  140.      return( -3 ) ;
  141.  
  142.    rec_flags =  (unsigned char *)  h4alloc( (int) len_flags ) ;
  143.    if ( rec_flags == (unsigned char *) 0 )   return( -2 ) ;
  144.  
  145.    rc = 1 ;
  146.    while ( rc == 1 )
  147.    {
  148.       if ( (rc=check_record()) != 0 )
  149.       {
  150.          h4free_memory( (char *) rec_flags ) ;
  151.          return( rc ) ;
  152.       }
  153.       rc =  (int) i4skip( i_ref, 1L) ;
  154.    }
  155.    if ( rc < 0 )  
  156.    {
  157.       h4free_memory( (char *) rec_flags ) ;
  158.       return( -1 ) ;
  159.    }
  160.  
  161.    /* Now Test for Duplication */
  162.    for ( on_rec = 1;  on_rec <= base_size; on_rec++)
  163.    {
  164.       if ( ! test_set( on_rec) )  
  165.       {
  166.          h4free_memory( (char *) rec_flags ) ;
  167.          return( on_rec ) ;
  168.       }
  169.    }
  170.  
  171.    h4free_memory( (char *) rec_flags ) ;
  172.  
  173.    /* Now make sure the block key pointers match the blocks they point to.
  174.       This needs to be true for d4seek to function perfectly.
  175.    */
  176.  
  177.    #ifdef CLIPPER
  178.       return 0 ;
  179.    #else
  180.       return( i4blk_ptr_chk() ) ;
  181.    #endif
  182. }
  183.  
  184. #ifndef CLIPPER
  185.    i4blk_ptr_chk()
  186.    {
  187.       int    rc, keys_skip ;
  188.       BLOCK *block_ptr ;
  189.       char  *bot_ptr, *up_ptr ;
  190.  
  191.       if ( (rc = i4bottom(i_ref)) == -1)  return -1 ;
  192.       if ( rc == 3 )  return 0 ;
  193.  
  194.       for(;;)
  195.       {
  196.          block_ptr =  v4block + i_ptr->block_ref ;
  197.          keys_skip = -block_ptr->num_keys ;
  198.          rc =  (int) i4skip( i_ref, (long) keys_skip ) ;
  199.          if ( rc == -keys_skip )  return -1 ;
  200.          if ( rc !=  keys_skip )  return  0 ;  /* Top of File */
  201.  
  202.          block_ptr =  v4block + i_ptr->block_ref ;
  203.          for(;;)
  204.          {
  205.             if ( block_ptr->prev < 0 )
  206.            {
  207.            rc = 0 ;
  208.            return -8 ;
  209.         }
  210.             block_ptr =  v4block + block_ptr->prev ;
  211.  
  212.             if ( block_ptr->key_on < block_ptr->num_keys )
  213.             {
  214.                bot_ptr =  b4key(i_ref)->value ;
  215.                up_ptr  =  block_ptr->key.value + i_ptr->group_len*block_ptr->key_on ;
  216.            if ( memcmp( bot_ptr, up_ptr, i_ptr->key_len) != 0 )
  217.            {
  218.               rc = 0 ;
  219.               return -8 ;
  220.            }
  221.            break ;
  222.         }
  223.        }
  224.       }
  225.    }
  226. #endif
  227.