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 / X4.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-14  |  12.0 KB  |  624 lines

  1. /*  x4.c    (c)Copyright Sequiter Software Inc., 1987, 1988, 1989.  All rights reserved. */
  2.  
  3. #include  "d4base.h"
  4. #include  "u4error.h"
  5.  
  6. #include  <stdlib.h>
  7. #include  <string.h>
  8.  
  9. typedef struct
  10. {
  11.    int    next,prev ;
  12.  
  13.    int    (*filter_routine)() ;
  14.  
  15. }  FILTER ;
  16.  
  17. static FILTER  *filter =  (FILTER *) 0 ;
  18.  
  19. extern BASE   *v4base ;
  20. extern INDEX  *v4index ;
  21. extern int     v4cur_base ;
  22.  
  23. typedef struct
  24. {
  25.    int      next,prev ;
  26.  
  27.    int      control_base_ref ;
  28.  
  29.    char  *compile ;
  30.  
  31.    /* Identify the database and index file to be repositioned */
  32.    int      base_ref, index_ref ;
  33.  
  34.    long   miss_code ;
  35.  
  36. }  RELATE ;
  37.  
  38. static RELATE  *relate =  (RELATE *) 0 ;
  39.  
  40.  
  41.  
  42. int  x4filter( filter_routine )
  43. int  (*filter_routine)(void) ;
  44. {
  45.    BASE  *base_ptr ;
  46.  
  47.    base_ptr =  d4ptr() ;
  48.    if ( base_ptr == (BASE *) 0 )  return -1 ;  /* No Database is Selected */
  49.  
  50.    if ( filter ==  (FILTER *) 0 )
  51.       if ( h4create( (char **) &filter, 5, sizeof(FILTER), 3 ) < 0 )  return -1 ;
  52.  
  53.    base_ptr->filter_ref =  h4get( (char **) &filter, base_ptr->filter_ref ) ;
  54.    if ( base_ptr->filter_ref < 0 )   return -1 ; 
  55.  
  56.    filter[base_ptr->filter_ref].filter_routine =  filter_routine ;
  57.  
  58.    return 0 ;
  59. }
  60.  
  61.  
  62. x4blank()  /* Returns TRUE if the record is blank */
  63. {
  64.    char *ptr ;
  65.    int     i ;
  66.  
  67.    for ( i= 1; i<= f4num_fields(); i++ )
  68.    {
  69.       ptr =  f4str( f4j_ref(i) ) ;
  70.       while ( *ptr !=  (char) 0 )
  71.      if ( *ptr++ != ' ' )  return 0 ;
  72.    }
  73.  
  74.    return 1 ;
  75. }
  76.  
  77.  
  78. int  x4filter_pop()
  79. {
  80.    BASE *base_ptr ;
  81.  
  82.    base_ptr =  d4ptr() ;
  83.    if ( filter == (FILTER *) 0    ||  base_ptr == (BASE *) 0 )  return -1;
  84.    if ( base_ptr->filter_ref < 0 )  return -1 ;
  85.  
  86.    base_ptr->filter_ref = h4free((char **) &filter, base_ptr->filter_ref);
  87.  
  88.    return 0 ;
  89. }
  90.  
  91.  
  92. void  x4filter_reset()
  93. {
  94.    while ( x4filter_pop() == 0 ) ;
  95. }
  96.  
  97.  
  98. int  x4filter_do()
  99. {
  100.    int    on, rc ;
  101.    BASE  *base_ptr ;
  102.  
  103.    if (filter == (FILTER *) 0)    return 0 ;
  104.  
  105.    base_ptr =  d4ptr() ;
  106.    if ( base_ptr == (BASE *) 0)  return -1 ;
  107.  
  108.    for ( on = base_ptr->filter_ref; on >= 0; on = filter[on].prev)
  109.    {
  110.       rc = (*filter[on].filter_routine)() ;
  111.       if ( rc < 0 )  return  -1 ;
  112.       if ( rc > 0 )  return   1 ;
  113.    }
  114.  
  115.    return 0 ;
  116. }
  117.  
  118.  
  119. x4relate( expr, base_ref, index_ref, miss_code )
  120. char *expr ;
  121. int   base_ref, index_ref ;
  122. long  miss_code ;
  123. {
  124.    BASE     *base_ptr ;
  125.    RELATE   *relate_ptr ;
  126.    char     *compile_ptr ;
  127.  
  128.    base_ptr =  d4ptr() ;
  129.    if ( base_ptr == (BASE *) 0 )
  130.    {
  131.       u4error( E_CONTROL, (char *) 0 ) ;
  132.       return -1 ;  /* No Database is Selected */
  133.    }
  134.  
  135.    if ( base_ref == v4cur_base )
  136.    {
  137.       u4error( E_RELATED, (char *) 0 ) ;
  138.       return -1 ;  /* No Database is Selected */
  139.    }
  140.  
  141.    if ( e4parse( expr, &compile_ptr ) < 0 )   return -1 ;
  142.    if ( e4exec( compile_ptr ) == (char *) 0 )
  143.    {
  144.       h4free_memory( compile_ptr ) ;
  145.       return -1 ;
  146.    }
  147.  
  148.    if ( relate == (RELATE *) 0 )
  149.       if ( h4create( (char **) &relate, 5, sizeof(RELATE), 3 )  < 0 )  return -1 ;
  150.  
  151.    base_ptr->relate_ref = h4get( (char **) &relate, base_ptr->relate_ref);
  152.    if ( base_ptr->relate_ref < 0 )  return -1 ;
  153.  
  154.    relate_ptr =  relate + base_ptr->relate_ref ;
  155.  
  156.    relate_ptr->control_base_ref =  d4select( -1 ) ;
  157.  
  158.    if ( index_ref >= 0 )
  159.       base_ref =  v4index[index_ref].base_ref ;
  160.  
  161.    relate_ptr->compile     =  compile_ptr ;
  162.    relate_ptr->base_ref  =  base_ref ;
  163.    relate_ptr->index_ref =  index_ref ;
  164.    relate_ptr->miss_code =  miss_code ;
  165.  
  166.    return 0 ;
  167. }
  168.  
  169.  
  170. x4relate_reset()
  171. {
  172.    int     relate_ref ;
  173.    BASE *base_ptr ;
  174.  
  175.    base_ptr =  d4ptr() ;
  176.    if ( base_ptr == (BASE *) 0 )  return -1 ;
  177.  
  178.    relate_ref =  base_ptr->relate_ref ;
  179.  
  180.    while ( relate_ref >= 0 )
  181.    {
  182.       h4free_memory( relate[relate_ref].compile ) ;
  183.       relate_ref =  h4free( (char **) &relate, relate_ref ) ;
  184.    }
  185.  
  186.    base_ptr->relate_ref =  -1 ;
  187.  
  188.    return 0 ;
  189. }
  190.  
  191. static  void  x4relate_error( RELATE *, char *) ;
  192.  
  193. static void  x4relate_error( relate_ptr, msg )
  194. RELATE *relate_ptr ;
  195. char   *msg ;
  196. {
  197.    char  rec_str[34], *index_file ;
  198.  
  199.    d4select( relate_ptr->control_base_ref ) ;
  200.  
  201.    ltoa( d4recno(), rec_str, 10 ) ;
  202.  
  203.    if ( relate_ptr->index_ref >= 0 )
  204.       index_file =  v4index[relate_ptr->index_ref].name ;
  205.    else
  206.       index_file =  "No Index File" ;
  207.  
  208.    u4error( E_RELATING, msg,
  209.              "Controlling Database:",
  210.              v4base[relate_ptr->control_base_ref].name,
  211.              "On Record Number: ", rec_str,
  212.              "Related Database:", d4ptr()->name,
  213.              "Index File:", index_file,
  214.              (char *) 0 ) ;
  215. }
  216.  
  217. static  int  x4miss( RELATE * ) ;
  218.  
  219. static    x4miss( relate_ptr )
  220. RELATE    *relate_ptr ;
  221. {
  222.    if ( relate_ptr->miss_code >= 1 )
  223.    {
  224.       if ( d4go( relate_ptr->miss_code ) < 0)
  225.       {
  226.      d4select( relate_ptr->control_base_ref ) ;
  227.      return -1 ;
  228.       }
  229.       return 0 ;
  230.    }
  231.  
  232.    memset( v4base[relate_ptr->base_ref].buffer, (int) ' ',
  233.        (size_t) v4base[relate_ptr->base_ref].buffer_len ) ;
  234.    v4base[relate_ptr->base_ref].rec_num =  -1L ;
  235.    if ( relate_ptr->miss_code != 0 )
  236.    {
  237.       x4relate_error( relate_ptr, "(No Record Located)" ) ;
  238.       return -1 ;
  239.    }
  240.  
  241.    return 0 ;
  242. }
  243.  
  244.  
  245. x4relate_do()
  246. {
  247.    int      on, old_base, rc, old_index ;
  248.    long   rec_num ;
  249.    char  *ptr ;
  250.    RELATE  *relate_ptr ;
  251.  
  252.    old_base =  d4select( -1 ) ;
  253.  
  254.    for ( on =  d4ptr()->relate_ref; on >= 0; on =  relate_ptr->prev )
  255.    {
  256.       relate_ptr =  relate +  on ;
  257.  
  258.       if ( (ptr = e4exec(relate_ptr->compile)) == (char *) 0 )
  259.       {
  260.      d4select(old_base) ;
  261.      return -1 ;
  262.       }
  263.  
  264.       d4select( relate_ptr->base_ref ) ;
  265.       if ( relate_ptr->base_ref != v4cur_base )
  266.       {
  267.      x4relate_error( relate_ptr, "(Could not Select Related Database)");
  268.      d4select(old_base) ;
  269.      return -1 ;
  270.       }
  271.  
  272.       if ( relate_ptr->index_ref >= 0 )
  273.       {
  274.      old_index =  d4ptr()->current_index ;
  275.  
  276.      i4select( relate_ptr->index_ref ) ;
  277.      if ( i4seek_ref() != relate_ptr->index_ref)
  278.      {
  279.         x4relate_error( relate_ptr, "(Could not Select Related Index File)" ) ;
  280.         d4select(old_base) ;
  281.         return -1 ;
  282.      }
  283.      rc =  d4seek( ptr ) ;
  284.      i4select( old_index ) ;
  285.  
  286.      if ( rc < 0 )
  287.      {
  288.         d4select(old_base) ;
  289.         return -1 ;
  290.      }
  291.  
  292.      if ( rc > 1 )
  293.         if ( x4miss( relate_ptr ) < 0)
  294.         {
  295.            d4select(old_base) ;
  296.            return -1 ;
  297.         }
  298.       }
  299.       else
  300.       {
  301.      if ( e4type() != 'N' && e4type() != 'F' )
  302.      {
  303.         x4relate_error( relate_ptr, "(Relation Expression did not Return a Record Number)");
  304.         d4select(old_base) ;
  305.         return -1 ;
  306.      }
  307.  
  308.      rec_num =  (long) *((double *) ptr) ;
  309.  
  310.      rc =  d4go(rec_num) ;
  311.      if ( rc > 0 )
  312.         if ( x4miss( relate_ptr ) < 0)
  313.         {
  314.            d4select(old_base) ;
  315.            return -1 ;
  316.         }
  317.  
  318.      if ( rc < 0 )
  319.      {
  320.         d4select( old_base ) ;
  321.         return -1 ;
  322.      }
  323.       }
  324.    }
  325.  
  326.    d4select( old_base ) ;
  327.    return 0 ;
  328. }
  329.  
  330.  
  331.  
  332. x4go( record_number )
  333. long  record_number ;
  334. {
  335.    int rc ;
  336.  
  337.    if ( (rc =  d4go(record_number)) < 0 )  return -1 ;
  338.    if ( x4relate_do() < 0 )  return -1 ;
  339.  
  340.    return rc ;
  341. }
  342.  
  343.  
  344. x4seek( search_string )
  345. char *search_string ;
  346. {
  347.    int     rc1, rc, index_ref, len ;
  348.    char *ptr ;
  349.  
  350.    if ( (rc1 = d4seek(search_string)) < 0 )  return -1 ;
  351.    if ( rc1 == 3 )
  352.    {
  353.       if ( x4relate_do() < 0 )    return -1 ;
  354.       return 3 ;
  355.    }
  356.  
  357.    if ( (rc = x4filter_do()) < 0 )  return -1 ;
  358.    if ( rc == 0 )
  359.    {
  360.       if ( x4relate_do() < 0 )    return -1 ;
  361.       return rc1 ;
  362.    }
  363.  
  364.    if ( (rc =  x4skip(1L)) != 0)  return rc ;  /* EOF or Error */
  365.  
  366.    /* Determine the Return Code */
  367.    index_ref =    d4ptr()->current_index ;
  368.    if ( index_ref < 0 )
  369.       index_ref =  d4ptr()->index_ref ;
  370.  
  371.    if ( (ptr =    i4eval( index_ref )) == (char *) 0 )  return -1 ;
  372.  
  373.    if ( e4type() == 'C' )
  374.    {
  375.       len =  strlen(search_string) ;
  376.       if ( len > v4index[index_ref].key_len)  len = v4index[index_ref].key_len ;
  377.  
  378.       if ( memcmp(search_string, ptr, len) != 0 )
  379.      rc =  2 ;
  380.       else
  381.       {
  382.       if ( len == v4index[index_ref].key_len )
  383.          rc =  0 ;
  384.       else
  385.          rc =  1 ;
  386.       }
  387.    }
  388.    else
  389.    {
  390.       if ( memcmp( ptr, search_string, v4index[index_ref].key_len ) == 0 )
  391.      rc =  0 ;
  392.       else
  393.      rc =  2 ;
  394.    }
  395.  
  396.    return rc ;
  397. }
  398.  
  399. x4skip( num_records )
  400. long  num_records ;
  401. {
  402.    int     rc, rc2 ;
  403.    long  sign, good_rec ;
  404.  
  405.    good_rec =  d4recno() ;
  406.  
  407.    if ( num_records < 0 )
  408.    {
  409.       sign =  -1L ;
  410.       num_records =  -num_records ;
  411.    }
  412.    else
  413.       sign =  1L ;
  414.  
  415.    rc =  0 ;
  416.  
  417.    while ( num_records--  &&  rc == 0 )
  418.    {
  419.       /* Skip One Record */
  420.       rc = d4skip(sign) ;
  421.       if ( rc < 0 )   return -1 ;
  422.       if ( rc == 3 )  break ;
  423.       if ( rc == 1 )
  424.       {
  425.      if ((rc2 = x4filter_do()) < 0)  return -1 ;
  426.      if ( rc2 )
  427.      {
  428.         if ( good_rec > 0L )  
  429.         {
  430.            if ( x4go(good_rec) )  return -1 ;
  431.            rc =  1 ;
  432.         }
  433.         else
  434.            rc =  3 ;
  435.         break ;
  436.      }
  437.      else
  438.         break ;
  439.       }
  440.  
  441.       for (;;)
  442.       {
  443.      if ((rc = x4filter_do()) < 0)    return -1 ;
  444.      if ( rc == 0 )
  445.      {
  446.         good_rec =    d4recno() ;
  447.         break ;
  448.      }
  449.  
  450.      if ( (rc = d4skip(sign)) != 0)
  451.      {
  452.         if ( rc < 0 )  return -1 ;
  453.         if ( rc == 3 )  break ;
  454.         if ( rc == 1 )
  455.         {
  456.            if ( good_rec > 0L )
  457.            {
  458.           if ( x4go(good_rec) )  return -1 ;
  459.           rc =  1 ;
  460.            }
  461.            else
  462.           rc =  3 ;
  463.            break ;
  464.         }
  465.      }
  466.       }
  467.    }
  468.  
  469.    if ( x4relate_do() < 0 )  return -1 ;
  470.  
  471.    return rc ;
  472. }
  473.  
  474.  
  475. x4bottom()
  476. {
  477.    int    rc ;
  478.  
  479.    if ( (rc =  d4bottom()) < 0 )  return -1 ;
  480.    if ( rc == 0 )
  481.    {
  482.       if ((rc = x4filter_do()) < 0)  return -1 ;
  483.       if ( rc )
  484.       {
  485.      if ((rc = x4skip(-1L)) < 0)  return -1 ;
  486.      if ( rc )  return( x4skip(1L) ) ;
  487.       }
  488.    }
  489.  
  490.    if ( x4relate_do() < 0 )  return -1 ;
  491.  
  492.    return  rc ;
  493. }
  494.  
  495.  
  496. x4top()
  497. {
  498.    int    rc ;
  499.  
  500.    if ( (rc =  d4top()) < 0)  return -1 ;
  501.    if ( rc == 0 )
  502.    {
  503.       if ((rc = x4filter_do()) < 0)  return -1 ;
  504.       if ( rc )  return( x4skip(1L) ) ;
  505.    }
  506.  
  507.    if ( x4relate_do() < 0 )  return -1 ;
  508.  
  509.    return  rc ;
  510. }
  511.  
  512.  
  513. double    x4sum( field_ref )
  514. long  field_ref ;
  515. {
  516.    double  total ;
  517.    int       rc, old_base ;
  518.  
  519.    total =  0.0 ;
  520.  
  521.    old_base =  d4select( -1 ) ;
  522.    d4select( (int) (field_ref >> 16) ) ;
  523.  
  524.    if ( (rc= x4top()) < 0 )
  525.    {
  526.       d4select( old_base ) ;
  527.       return 0.0 ;
  528.    }
  529.  
  530.    while ( rc != 3 )
  531.    {
  532.       total +=    f4value(field_ref) ;
  533.  
  534.       if ( (rc= x4skip(1L)) < 0 )
  535.       {
  536.      d4select( old_base ) ;
  537.      return 0.0 ;
  538.       }
  539.    }
  540.  
  541.    d4select( old_base ) ;
  542.  
  543.    return  total ;
  544. }
  545.  
  546.  
  547. int  x4insert( rec_num )
  548. long  rec_num ;
  549. {
  550.    long  i_rec ;
  551.    BASE *base_ptr ;
  552.    int     index_ref ;
  553.  
  554.    if ( (base_ptr =  d4ptr()) == (BASE *) 0)  return -1 ;
  555.  
  556.    /* Temporarily Disable the Index Files */
  557.    index_ref =    base_ptr->index_ref ;
  558.    base_ptr->index_ref =  -1 ;
  559.  
  560.    /* Save the Current Record */
  561.    memcpy( base_ptr->old_buf,  base_ptr->buffer, base_ptr->buffer_len ) ;
  562.  
  563.    for ( i_rec = d4reccount(); i_rec >= rec_num; i_rec-- )
  564.    {
  565.       if ( d4go(i_rec) < 0 )
  566.       {
  567.      base_ptr->index_ref =    index_ref ;
  568.      return -1 ;
  569.       }
  570.       if ( d4write( i_rec+1 ) < 0 )
  571.       {
  572.      base_ptr->index_ref =    index_ref ;
  573.      return -1 ;
  574.       }
  575.    }
  576.  
  577.    /* Restore the Saved Record */
  578.    memcpy ( base_ptr->buffer, base_ptr->old_buf, base_ptr->buffer_len ) ;
  579.  
  580.    if ( d4write( rec_num ) < 0 )
  581.    {
  582.       base_ptr->index_ref =  index_ref ;
  583.       return -1 ;
  584.    }
  585.  
  586.    base_ptr->index_ref =  index_ref ;
  587.  
  588.    /* Reindex All of the Index Files */
  589.    if ( i4reindex( -1 ) < 0 )  return -1 ;
  590.  
  591.    if ( x4go(rec_num) < 0 )  return -1 ;
  592.  
  593.    return 0 ;
  594. }
  595.  
  596.  
  597. x4replace( field_ref, rec_num, value )
  598. long  field_ref, rec_num ;
  599. void *value ;
  600. {
  601.    int       rc, old_base ;
  602.  
  603.    old_base =  d4select( -1 ) ;
  604.    d4select( (int) (field_ref >> 16) ) ;
  605.  
  606.    if ( d4go(rec_num) < 0 )
  607.    {
  608.       d4select( old_base ) ;
  609.       return -1 ;
  610.    }
  611.  
  612.    if ( (rc = f4replace( field_ref, value)) != 0 )
  613.    {
  614.       d4select( old_base ) ;
  615.       return rc ;
  616.    }
  617.  
  618.    rc =  d4write( rec_num ) ;
  619.    d4select( old_base ) ;
  620.    if ( rc != 0 )   return -1 ;
  621.  
  622.    return 0 ;
  623. }
  624.