home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c160 / 1.ddi / SOURCE / M4WRITE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-22  |  8.4 KB  |  322 lines

  1.  
  2. /* m4write.c   (c)Copyright Sequiter Software Inc., 1987-1990.  All rights reserved. */
  3.  
  4. #include "p4misc.h"
  5. #include "d4all.h"
  6. #include "u4error.h"
  7. #include "m4.h"
  8.  
  9. #include <string.h>
  10.  
  11. #ifndef UNIX
  12. #include <process.h>
  13. #include <io.h>
  14. #endif
  15.  
  16. #ifdef __WATCOMC__
  17. #include <stdio.h>
  18. #endif
  19.  
  20. extern  int  m4to_disk( FREE_AREA *, M *) ;
  21. extern  int  m4skip_area( M *) ;
  22. extern  int  v4lock_wait ;
  23.  
  24. extern  long m4write_do( M *, long, char *, int ) ;
  25.  
  26. extern  BASE *v4base ;
  27.  
  28. m4to_disk( FREE_AREA *free_area_ptr, M *m_ptr )
  29. {
  30.    int  rc ;
  31.  
  32.    if ( free_area_ptr->to_disk )
  33.    {
  34.       free_area_ptr->to_disk =  0 ;
  35.  
  36.       if ( free_area_ptr->num < 0xFFFFFL )
  37.       {
  38.      /* Not at end of file */
  39.      lseek( m_ptr->hand, free_area_ptr->block_no * m_ptr->block_size, 0 ) ;
  40.      rc =  write( m_ptr->hand, (char *) free_area_ptr, CHAIN_SIZE ) ;
  41.      if ( rc != CHAIN_SIZE )
  42.      {
  43.         u4error( E_WRITE, "Memo File:", m4name( m_ptr->base_ref), (char *) 0 ) ;
  44.         return -1 ;
  45.      }
  46.       }
  47.    }
  48.    return 0 ;
  49. }
  50.  
  51. /*  m4skip_area returns:  1 - Write Done;  0 - Continue;  -1 - Error
  52.  
  53.    m_ptr -  Memo Write Status Information Pointer 
  54. */
  55.  
  56. m4skip_area( M *m_ptr )
  57. {
  58.    int  rc ;
  59.  
  60.    if ( m4to_disk( &m_ptr->prev, m_ptr ) < 0 )  return -1 ;
  61.  
  62.    if ( m_ptr->write_done && m_ptr->free_done )
  63.    {
  64.       if ( m4to_disk( &m_ptr->cur, m_ptr ) < 0 )  return -1 ;
  65.       return 1 ;
  66.    }
  67.  
  68.    memcpy( (char *) &m_ptr->prev, (char *) &m_ptr->cur, sizeof(FREE_AREA) ) ;
  69.    m_ptr->cur.block_no =  m_ptr->cur.next ;
  70.    m_ptr->cur.to_disk  =  0 ;
  71.  
  72.    lseek( m_ptr->hand, m_ptr->block_size * m_ptr->cur.block_no, 0 ) ;
  73.    rc = read( m_ptr->hand, (char *) &m_ptr->cur, CHAIN_SIZE ) ;
  74.    if ( rc < 0 )
  75.    {
  76.       u4error( E_READ, "Reading Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
  77.       return -1 ;
  78.    }
  79.    if ( rc < CHAIN_SIZE )
  80.       m_ptr->cur.num =  0xFFFFFFFL ;   /* Unlimited number at the end of the memo file */
  81.  
  82.    return 0 ;
  83. }
  84.  
  85. long  m4write_do( M *m_ptr, long free_block, char *str, int str_len )
  86. {
  87.    MEMO_BLOCK   write_block ;  /* The Header Information on what is to be written */
  88.    int      no_to_write ;  /* The number of blocks to write */
  89.    long     write_block_no ; /* The actual block number which was written */
  90.  
  91.    MEMO_BLOCK   read_block ;   /* The header information on the block to be freed */
  92.    int      no_to_free ;   /* The number of blocks to free */
  93.    int      rc ;
  94.  
  95.    write_block.minus_one =  -1 ;
  96.    write_block.start_pos =  sizeof(MEMO_BLOCK) ;
  97.    write_block.num_chars =  str_len + sizeof(MEMO_BLOCK) ;
  98.    no_to_write    =  (int) ((write_block.num_chars + m_ptr->block_size -1) / m_ptr->block_size) ;
  99.    write_block_no =  0L ;
  100.  
  101.    if ( str_len == 0 )
  102.    {
  103.       no_to_write =  0 ;
  104.       m_ptr->write_done =  1 ;
  105.    }
  106.  
  107.    if ( free_block <= 0L )
  108.       m_ptr->free_done =  1 ;
  109.    else
  110.    {
  111.       /* Read the Memo Block to be freed and find out how many blocks to free */
  112.       lseek( m_ptr->hand, m_ptr->block_size * free_block, 0 ) ;
  113.       rc =  read( m_ptr->hand, (char *) &read_block, (unsigned int) sizeof(read_block)) ;
  114.       if ( rc <  (int) sizeof(read_block))
  115.       {
  116.      u4error( E_READ, "Reading Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
  117.      return -1L ;
  118.       }
  119.  
  120.       if ( read_block.minus_one == -1 )
  121.      no_to_free =  (int) ((read_block.num_chars + m_ptr->block_size -1) /
  122.               m_ptr->block_size) ;
  123.       else
  124.      no_to_free =  1 ;  /* dBASE III Block */
  125.    }
  126.  
  127.    /* Skip through the free chain; 
  128.       Add the free blocks at the appropriate point.
  129.       Write the new blocks as soon as a large enough area is located.
  130.    */
  131.  
  132.    for( rc = m4skip_area(m_ptr); rc == 0; rc = m4skip_area(m_ptr) )
  133.    {
  134.       /* Check to see if an area needs to be freed */
  135.       if ( m_ptr->cur.next > free_block  &&  ! m_ptr->free_done )
  136.       {
  137.      if ( m4to_disk( &m_ptr->prev, m_ptr ) < 0 )  return -1L ;
  138.      memcpy( (char *) &m_ptr->prev, (char *) &m_ptr->cur, sizeof(FREE_AREA) ) ;
  139.  
  140.      m_ptr->cur.next     =  m_ptr->prev.next ;
  141.      m_ptr->cur.num      =  no_to_free ;
  142.      m_ptr->cur.to_disk  =  1 ;
  143.      m_ptr->cur.block_no =  free_block ;
  144.  
  145.      m_ptr->prev.next    =  free_block ;
  146.      m_ptr->prev.to_disk =  1 ;
  147.  
  148.      m_ptr->free_done =  1 ;
  149.       }
  150.  
  151.       /* Check to see if the string information can be written in the current area */
  152.       if ( m_ptr->cur.num >= no_to_write  &&  ! m_ptr->write_done )
  153.       {
  154.      write_block_no =  m_ptr->cur.block_no ;
  155.  
  156.      /* First write the data */
  157.      lseek( m_ptr->hand, m_ptr->block_size * m_ptr->cur.block_no, 0 ) ;
  158.      if ( write(m_ptr->hand, (char *) &write_block, 
  159.         (unsigned int) sizeof(write_block)) != (int) sizeof(write_block) )
  160.      {
  161.         u4error( E_WRITE, "Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
  162.         return -1L ;
  163.      }
  164.      if ( write(m_ptr->hand, str, (unsigned int) str_len) != str_len )
  165.      {
  166.         u4error( E_WRITE, "Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
  167.         return -1L ;
  168.      }
  169.  
  170.      /* Now Fix the Chains */
  171.      if ( m_ptr->cur.num ==  no_to_write )
  172.      {
  173.         /* Complete Chain Used */
  174.         m_ptr->prev.next =  m_ptr->cur.next ;
  175.         memcpy( (char *) &m_ptr->cur, (char *) &m_ptr->prev, sizeof(FREE_AREA)) ;
  176.         m_ptr->prev.to_disk =  0 ;
  177.         m_ptr->cur.to_disk  =  1 ;
  178.      }
  179.      else
  180.      {
  181.         /* Only part of the free space was used */
  182.         m_ptr->cur.num      -=  no_to_write ;
  183.         m_ptr->cur.to_disk   =  1 ;
  184.         m_ptr->cur.block_no +=  no_to_write ;
  185.  
  186.         m_ptr->prev.next     =  m_ptr->cur.block_no ;
  187.         m_ptr->prev.to_disk  =  1 ;
  188.      }
  189.  
  190.      m_ptr->write_done =  1 ;
  191.       }
  192.    }
  193.    if ( rc < 0 )  return -1L ;
  194.  
  195.    return  write_block_no ;
  196. }
  197.  
  198. m4write( long field_ref, long rec_num, char *str, int str_len )
  199. {
  200.    M    m ;
  201.    int  old_base, rc ;
  202.    long free_block, new_block ;
  203.  
  204.    if ( str_len < 0 )
  205.       str_len =  0 ;
  206.  
  207.    memset( (char *) &m, 0, sizeof(m) ) ;
  208.    m.base_ref =  (int) (field_ref >> 16) ;
  209.  
  210.    if ( rec_num > d4reccount() )
  211.       d4blank() ;
  212.    else
  213.    {
  214.       old_base =  d4select( m.base_ref ) ;
  215.       rc =  d4go(rec_num) ;
  216.       d4select(old_base) ;
  217.       if ( rc < 0 )  return rc ;
  218.    }
  219.  
  220.    if ( m4open(m.base_ref) < 0 )   return -1 ;
  221.  
  222.    m.block_size =  v4base[m.base_ref].memo_size ;
  223.    m.hand       =  v4base[m.base_ref].memo_file ;
  224.  
  225.    free_block =   c4atol( f4ptr(field_ref),  f4width(field_ref) ) ;
  226.  
  227.    rc =  u4lock(m.hand, 0L, 0x7FFFFFFFL, v4lock_wait) ;
  228.    if ( rc < 0 )  return rc ;
  229.    new_block =  m4write_do( &m, free_block, str, str_len ) ;
  230.    if ( u4unlock( m.hand, 0L, 0x7FFFFFFFL ) < 0)  return -1 ;
  231.    if ( new_block < 0L )  return -1 ;
  232.  
  233.    if ( new_block == 0L ) 
  234.       memset( f4ptr(field_ref), (int) ' ', (size_t) f4width(field_ref) ) ;
  235.    else
  236.       c4ltoa( new_block, f4ptr(field_ref), -f4width(field_ref) ) ;
  237.  
  238.    old_base =  d4select( m.base_ref ) ;
  239.    if ( rec_num > d4reccount() )
  240.       rc = d4append() ;
  241.    else
  242.       rc = d4write( rec_num ) ;
  243.    d4select(old_base) ;
  244.    if ( rc < 0 )  return -1 ;
  245.  
  246.    return( str_len ) ;
  247. }
  248.  
  249. m4edit( long field_ref, long rec_num, char *editor_name, int max_size ) 
  250. {
  251. #ifndef NO_SPAWNL
  252.    char *ptr ;
  253.    int   hand, num_read ;
  254.    char  memoedit_ptr[14] ;
  255.  
  256.    if ( max_size <= 0 )  return -1 ;
  257.  
  258.    ptr =  h4alloc( max_size ) ;
  259.    if ( ptr == (char *) 0 )   return 1 ;
  260.  
  261.    if ((num_read = m4read( field_ref, rec_num, ptr, max_size))  < 0 ) 
  262.    {
  263.       h4free_memory(ptr) ;
  264.       return -1 ;
  265.    }
  266.  
  267.    strcpy( memoedit_ptr, "M4" ) ;
  268.    if ( (hand = u4temp_create(memoedit_ptr)) < 0 )  
  269.    {
  270.       h4free_memory(ptr) ;
  271.       return -1 ;
  272.    }
  273.  
  274.    lseek( hand, 0L, 0 ) ;
  275.    if ( write( hand, ptr, num_read ) != num_read ) 
  276.    {
  277.       h4free_memory(ptr) ;
  278.       close(hand) ;
  279.       u4error( E_WRITE, memoedit_ptr, (char *) 0 ) ;
  280.       return -1 ;
  281.    }
  282.  
  283.    close( hand ) ;
  284.  
  285.    if ( spawnl( P_WAIT, editor_name, "", memoedit_ptr, (char *) 0 )  < 0)
  286.    {
  287.       h4free_memory(ptr) ;
  288.       close(hand) ;
  289.       u4error( E_EDITOR, editor_name, (char *) 0 ) ;
  290.       return -1 ;
  291.    }
  292.  
  293.    if ( (hand = u4open(memoedit_ptr,0)) < 0 )  
  294.    {
  295.       h4free_memory(ptr) ;
  296.       return -1 ;
  297.    }
  298.  
  299.    lseek( hand, 0L, 0 ) ;
  300.    if ( (num_read = read(hand, ptr, max_size)) < 0 ) 
  301.    {
  302.       h4free_memory(ptr) ;
  303.       close(hand) ;
  304.       u4error( E_READ, memoedit_ptr, (char *) 0 ) ;
  305.       return -1 ;
  306.    }
  307.  
  308.    close(hand) ;
  309.  
  310.    u4remove( memoedit_ptr ) ;
  311.  
  312.    if ( m4write(field_ref, rec_num, ptr, num_read) < 0 )
  313.    {
  314.       h4free_memory(ptr) ;
  315.       return -1 ;
  316.    }
  317.  
  318.    h4free_memory( ptr ) ;
  319. #endif
  320.    return 0 ;
  321. }
  322.