which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			866 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			866 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* f4file.c (c)Copyright Sequiter Software Inc., 1990-1994.  All rights reserved. */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifndef S4UNIX
 | 
						|
#ifdef __TURBOC__
 | 
						|
#pragma hdrstop
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4TEMP
 | 
						|
#include "t4test.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#include <time.h>
 | 
						|
 | 
						|
#ifndef S4UNIX
 | 
						|
#ifndef S4IBMOS2
 | 
						|
#ifndef __TURBOC__
 | 
						|
#include <sys\locking.h>
 | 
						|
#define S4LOCKING
 | 
						|
#endif
 | 
						|
#ifdef __ZTC__
 | 
						|
extern int  errno ;
 | 
						|
#endif
 | 
						|
#ifdef _MSC_VER
 | 
						|
#include <sys\types.h>
 | 
						|
#include <sys\locking.h>
 | 
						|
#endif
 | 
						|
#ifdef __TURBOC__
 | 
						|
/*      extern int cdecl errno ; */
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#include <sys\stat.h>
 | 
						|
#include <share.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <fcntl.h>
 | 
						|
#include <errno.h>
 | 
						|
 | 
						|
#ifdef __SC__
 | 
						|
#include <dos.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4ERRNO
 | 
						|
extern int errno ;
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
#ifdef S4NO_FILELENGTH
 | 
						|
#ifdef S4MACINTOSH
 | 
						|
long filelength( int hand )
 | 
						|
{
 | 
						|
  long filelen ;
 | 
						|
 | 
						|
  if ( GetEOF(hand, &filelen) != 0 )
 | 
						|
    e4severe( e4result, "filelength(): GetEOF()" ) ;
 | 
						|
 | 
						|
  return filelen ;
 | 
						|
}
 | 
						|
#else
 | 
						|
#ifdef S4WIN32
 | 
						|
long filelength( int hand )
 | 
						|
{
 | 
						|
  long rc ;
 | 
						|
 | 
						|
  rc = (long)GetFileSize( (HANDLE)hand, NULL ) ;
 | 
						|
 | 
						|
  if ( rc == -1L )
 | 
						|
    e4severe( e4result, "filelength()" ) ;
 | 
						|
 | 
						|
  return rc ;
 | 
						|
}
 | 
						|
#else
 | 
						|
#include  <sys/types.h>
 | 
						|
#include  <sys/stat.h>
 | 
						|
 | 
						|
long filelength( hand )
 | 
						|
  int hand  ;
 | 
						|
{
 | 
						|
  struct stat   str_stat ;
 | 
						|
 | 
						|
  if (fstat( hand, &str_stat ) )
 | 
						|
    e4severe( e4result, "filelength()" ) ;
 | 
						|
 | 
						|
  return( (long) str_stat.st_size ) ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4MACINTOSH
 | 
						|
long MAClseek(int hand, long offset, int fromwhere, int extend )
 | 
						|
{
 | 
						|
  long filelen ;
 | 
						|
  if ( offset != 0 )
 | 
						|
  {
 | 
						|
    filelen = filelength( hand ) ;
 | 
						|
 | 
						|
    if (extend)
 | 
						|
    {
 | 
						|
      if ( filelen < offset )
 | 
						|
        SetEOF( hand, offset ) ;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      if ( filelen < offset )
 | 
						|
      {
 | 
						|
        if ( SetFPos(hand, fsFromStart, filelen ) == 0 )
 | 
						|
          return offset ;
 | 
						|
        else
 | 
						|
          return -1L ;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  if ( SetFPos(hand, fsFromStart, offset ) == 0 )
 | 
						|
    return offset ;
 | 
						|
  else
 | 
						|
    return -1L ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4LSEEK
 | 
						|
/* if extend is set, file is extended, else lseek to EOF */
 | 
						|
long f4lseek(FILE4 *file, long offset, int fromwhere, int extend )
 | 
						|
{
 | 
						|
  long filelen ;
 | 
						|
  if ( offset != 0 )
 | 
						|
  {
 | 
						|
    filelen = filelength( file->hand ) ;
 | 
						|
 | 
						|
    if (extend)
 | 
						|
    {
 | 
						|
      if ( filelen < offset )
 | 
						|
        file4change_size( file, offset ) ;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      if ( filelen < offset )
 | 
						|
      {
 | 
						|
        if ( lseek( file->hand, filelen, 0 ) )
 | 
						|
          return offset ;
 | 
						|
        else
 | 
						|
          return -1L ;
 | 
						|
      }
 | 
						|
  }
 | 
						|
  return lseek( file->hand, offset, fromwhere ) ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4NO_CHSIZE
 | 
						|
 | 
						|
#define E4MAXLINE 129   /* maximum file path length */
 | 
						|
 | 
						|
#ifdef S4MACINTOSH
 | 
						|
int S4FUNCTION file4change_size( FILE4 *f4, long size )
 | 
						|
{
 | 
						|
  if ( SetEOF( f4->hand, size ) != 0 )
 | 
						|
    e4severe( e4result, "file4change_size(): SetEOF" ) ;
 | 
						|
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
#else
 | 
						|
int S4FUNCTION file4change_size( FILE4 *f4, long size )
 | 
						|
{
 | 
						|
  char *buffer ;
 | 
						|
  char temp_name[E4MAXLINE], file_name[E4MAXLINE] ;
 | 
						|
  long buffer_size, filelen, amount_read = 0, extra_size = 0 ;
 | 
						|
  CODE4 *c4 ;
 | 
						|
  FILE4 temp ;
 | 
						|
  FILE4SEQ_WRITE seq_write ;
 | 
						|
  FILE4SEQ_READ seq_read ;
 | 
						|
 | 
						|
  if ( f4->is_read_only )
 | 
						|
    return e4( f4->code_base, e4parm, E4_PARM_SIZ ) ;
 | 
						|
 | 
						|
  filelen = filelength( f4->hand ) ;
 | 
						|
  if ( size == filelen )
 | 
						|
    return 0 ;
 | 
						|
 | 
						|
  if ( size > filelen )    /* pad file to increase size */
 | 
						|
  {
 | 
						|
    file4seq_write_init( &seq_write, f4, filelen, 0, 0 ) ;
 | 
						|
    file4seq_write_repeat( &seq_write, size - filelen, '\0' ) ;
 | 
						|
    return 0 ;
 | 
						|
  }
 | 
						|
 | 
						|
  c4 = f4->code_base ;
 | 
						|
 | 
						|
  memcpy( file_name, f4->name, E4MAXLINE ) ;
 | 
						|
  u4name_piece( temp_name, E4MAXLINE, f4->name, 1, 0 ) ;
 | 
						|
  u4name_ext( temp_name, E4MAXLINE, "TMP", 1 ) ;
 | 
						|
 | 
						|
  if ( file4create( &temp, c4, temp_name, 0 ) < 0 )
 | 
						|
  {
 | 
						|
    e4( c4, e4create, temp_name ) ;
 | 
						|
    return -1 ;
 | 
						|
  }
 | 
						|
 | 
						|
  buffer_size = c4->mem_size_buffer ;
 | 
						|
  buffer = (char *)u4alloc_free( c4, buffer_size ) ;
 | 
						|
 | 
						|
  while ( !buffer )
 | 
						|
  {
 | 
						|
    buffer_size -= 0x400 ;
 | 
						|
 | 
						|
    if ( buffer_size <= 0 )
 | 
						|
    {
 | 
						|
      e4( c4, e4memory, 0 ) ;
 | 
						|
      return -1 ;
 | 
						|
    }
 | 
						|
 | 
						|
    buffer = (char *)u4alloc_free( c4, buffer_size ) ;
 | 
						|
  }
 | 
						|
 | 
						|
  file4seq_write_init( &seq_write, &temp, 0, 0, buffer_size ) ;
 | 
						|
  file4seq_read_init( &seq_read, f4, 0, 0, buffer_size ) ;
 | 
						|
 | 
						|
  /* copy the old file contents to the temp file */
 | 
						|
  while ( size > 0 )
 | 
						|
  {
 | 
						|
    if ( size < buffer_size )
 | 
						|
      amount_read = file4seq_read( &seq_read, buffer, size ) ;
 | 
						|
    else
 | 
						|
      amount_read = file4seq_read( &seq_read, buffer, buffer_size ) ;
 | 
						|
 | 
						|
    file4seq_write( &seq_write, buffer, amount_read ) ;
 | 
						|
    size -= amount_read ;
 | 
						|
  }
 | 
						|
 | 
						|
  file4seq_write_flush( &seq_write ) ;
 | 
						|
 | 
						|
  u4free( buffer ) ;
 | 
						|
 | 
						|
  file4close( f4 ) ;
 | 
						|
  file4close( &temp ) ;
 | 
						|
 | 
						|
  if ( u4remove( file_name ) )
 | 
						|
  {
 | 
						|
    e4( c4, e4info, file_name ) ;
 | 
						|
    return -1 ;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( u4rename( temp_name, file_name ) )
 | 
						|
  {
 | 
						|
    e4( c4, e4rename, temp_name ) ;
 | 
						|
    return -1 ;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( file4open( f4, c4, file_name, 1 ) < 0 )
 | 
						|
  {
 | 
						|
    e4( c4, e4open, file_name ) ;
 | 
						|
    return -1 ;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( file4lock( f4, L4LOCK_POS, L4LOCK_POS ) < 0 )
 | 
						|
  {
 | 
						|
    e4( c4, e4lock, file_name ) ;
 | 
						|
    return -1 ;
 | 
						|
  }
 | 
						|
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
#endif  /* ifdef S4MACINTOSH */
 | 
						|
#endif   /* ifdef S4NO_CHSIZE */
 | 
						|
 | 
						|
long S4FUNCTION file4len( FILE4 *file )
 | 
						|
{
 | 
						|
  long lrc ;
 | 
						|
 | 
						|
#ifdef S4DEBUG
 | 
						|
  if ( file == 0 )
 | 
						|
    e4severe( e4parm, E4_FILE4LEN ) ;
 | 
						|
  if ( file->hand < 0 && file->file_created != 0 )
 | 
						|
    e4severe( e4parm, E4_FILE4LEN ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
  if ( file->is_temp == 1 && file->file_created == 0 && file->len == -1 )
 | 
						|
    return 0 ;
 | 
						|
  if ( file->do_buffer && file->len >= 0 )
 | 
						|
    lrc = file->len ;
 | 
						|
  else
 | 
						|
#endif
 | 
						|
    lrc = filelength( file->hand ) ;
 | 
						|
  if ( lrc < 0L )
 | 
						|
    e4( file->code_base, e4len, file->name ) ;
 | 
						|
  return lrc ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION file4len_set( FILE4 *file, long new_len )
 | 
						|
{
 | 
						|
  int rc ;
 | 
						|
#ifdef __SC__
 | 
						|
  union REGS dos_flush ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4DEBUG
 | 
						|
  if ( file == 0 || new_len < 0 )
 | 
						|
    e4severe( e4parm, E4_FILE4LEN_SET ) ;
 | 
						|
  if ( file->hand < 0 && file->file_created != 0 )
 | 
						|
    e4severe( e4parm, E4_FILE4LEN_SET ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( file->code_base->error_code > 0 && file->code_base->error_code < 200 )  /* file error */
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
  if ( file->is_read_only )
 | 
						|
    return e4( file->code_base, e4parm, E4_PARM_SIZ ) ;
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
  if ( file->do_buffer )
 | 
						|
  {
 | 
						|
    if ( file->len > new_len )   /* must do a partial delete of memory */
 | 
						|
      opt4file_delete( file, new_len, file->len ) ;
 | 
						|
    if ( file->buffer_writes )
 | 
						|
      file->len = new_len ;
 | 
						|
#ifdef S4DEBUG
 | 
						|
    else
 | 
						|
      if ( file->len != -1L )
 | 
						|
        e4severe( e4opt, E4_FILE4LEN_SET ) ;
 | 
						|
#endif
 | 
						|
  }
 | 
						|
#ifndef S4SAFE
 | 
						|
  if ( file->do_buffer == 0 || file->buffer_writes == 0 )
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4NO_CHSIZE
 | 
						|
    rc = file4change_size( file, new_len ) ;
 | 
						|
#else
 | 
						|
#ifdef S4WIN32
 | 
						|
  if ( SetFilePointer( (HANDLE)file->hand, new_len, NULL, FILE_BEGIN ) == (DWORD)-1 )
 | 
						|
    return e4( file->code_base, e4len_set, file->name ) ;
 | 
						|
  if ( SetEndOfFile( (HANDLE)file->hand ) )
 | 
						|
    rc = 0 ;
 | 
						|
  else
 | 
						|
    rc = -1 ;
 | 
						|
#else
 | 
						|
#ifdef __SC__
 | 
						|
  dos_flush.x.ax = 0x4200;
 | 
						|
  dos_flush.x.bx = file->hand ;
 | 
						|
  memcpy((void *)&dos_flush.x.dx,(void *)&new_len,2);
 | 
						|
  memcpy((void *)&dos_flush.x.cx,((char *)&new_len)+2,2);
 | 
						|
  intdos( &dos_flush, &dos_flush ) ;
 | 
						|
  if ( dos_flush.x.cflag != 0 )
 | 
						|
    return e4( file->code_base, e4len_set, 0 ) ;
 | 
						|
  dos_flush.h.ah = 0x40;
 | 
						|
  dos_flush.x.bx = file->hand ;
 | 
						|
  dos_flush.x.cx = 0x00;
 | 
						|
  intdos( &dos_flush, &dos_flush ) ;
 | 
						|
  if ( dos_flush.x.cflag != 0 )
 | 
						|
    return e4( file->code_base, e4len_set, 0 ) ;
 | 
						|
#else
 | 
						|
  rc = chsize( file->hand, new_len ) ;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
  if ( rc < 0 )
 | 
						|
  {
 | 
						|
    e4describe( file->code_base, e4len_set, E4_CREATE_FIL, file->name, (char *)0 ) ;
 | 
						|
    return -1 ;
 | 
						|
  }
 | 
						|
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
unsigned S4FUNCTION file4read( FILE4 *file, long pos, void *ptr, unsigned ptr_len )
 | 
						|
{
 | 
						|
  long rc ;
 | 
						|
  unsigned urc ;
 | 
						|
 | 
						|
#ifdef S4DEBUG
 | 
						|
  if ( file == 0 || pos < 0 || ptr == 0  )
 | 
						|
    e4severe( e4parm, E4_F4READ ) ;
 | 
						|
  if ( file->hand < 0 && file->file_created != 0 )
 | 
						|
    e4severe( e4parm, E4_F4READ ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( file->code_base->error_code < 0 )
 | 
						|
    return 0 ;
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
  if ( file->do_buffer )
 | 
						|
    urc = (unsigned)opt4file_read( file, pos, ptr, ptr_len )  ;
 | 
						|
  else
 | 
						|
  {
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4WINDOWS
 | 
						|
    rc = _llseek( file->hand, pos, 0 ) ;
 | 
						|
#else
 | 
						|
#ifdef S4MACINTOSH
 | 
						|
    rc = MAClseek( file->hand, pos, 0, 0 ) ;
 | 
						|
#else
 | 
						|
#ifdef S4WIN32
 | 
						|
    if ( rc = SetFilePointer( (HANDLE)file->hand, pos, NULL, FILE_BEGIN ) != (DWORD)-1 )
 | 
						|
      rc = pos ;
 | 
						|
#else
 | 
						|
#ifdef S4LSEEK
 | 
						|
    rc = f4lseek( file, pos, 0, 0 ) ;
 | 
						|
#else
 | 
						|
    rc = lseek( file->hand, pos, 0 ) ;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
    if ( rc != pos )
 | 
						|
    {
 | 
						|
      file4read_error( file ) ;
 | 
						|
      return 0 ;
 | 
						|
    }
 | 
						|
 | 
						|
#ifdef S4WINDOWS
 | 
						|
    urc = (unsigned)_lread( file->hand, (char *)ptr, ptr_len ) ;
 | 
						|
#else
 | 
						|
#ifdef S4MACINTOSH
 | 
						|
    rc = (long) ptr_len ;
 | 
						|
    urc = FSRead( file->hand, &rc, ptr ) ;
 | 
						|
    if ( urc == 0 ) urc = ptr_len ;
 | 
						|
    if ( urc == eofErr ) urc = rc ;  /* attempt to read past EOF OK */
 | 
						|
#else
 | 
						|
#ifdef S4WIN32
 | 
						|
    rc = ReadFile( (HANDLE)file->hand, ptr, ptr_len, (unsigned long *)&urc, NULL ) ;
 | 
						|
    if ( !rc )
 | 
						|
      rc = GetLastError() ;
 | 
						|
#else
 | 
						|
#ifdef S4LSEEK
 | 
						|
    /* if reading past EOF */
 | 
						|
    if ( pos+ptr_len > filelength( file->hand ) )
 | 
						|
      urc = (unsigned)read( file->hand, ptr, filelength(file->hand) - pos ) ;
 | 
						|
    else
 | 
						|
      urc = (unsigned)read( file->hand, ptr, ptr_len ) ;
 | 
						|
#else
 | 
						|
    urc = (unsigned)read( file->hand, ptr, ptr_len ) ;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( urc != ptr_len )
 | 
						|
    if ( urc > ptr_len )
 | 
						|
    {
 | 
						|
      file4read_error( file ) ;
 | 
						|
      return 0 ;
 | 
						|
    }
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
#ifdef S4DEBUG_DEV
 | 
						|
  if ( file->has_dup == 1 )
 | 
						|
    if ( file->do_buffer == 1 || file->link.n == 0 )
 | 
						|
      if ( file4cmp_part( file->code_base, ptr, file, pos, urc ) != 0 )
 | 
						|
        e4severe( e4opt, "file4read() - file corruption" ) ;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
  return urc ;
 | 
						|
}
 | 
						|
 | 
						|
int  S4FUNCTION file4read_all( FILE4 *file, long pos, void *ptr, unsigned ptr_len )
 | 
						|
{
 | 
						|
  long rc ;
 | 
						|
  unsigned urc ;
 | 
						|
 | 
						|
#ifdef S4DEBUG
 | 
						|
  if ( file == 0 || pos < 0 || ptr == 0  )
 | 
						|
    e4severe( e4parm, E4_F4READ_ALL ) ;
 | 
						|
  if ( file->hand < 0 && file->file_created != 0 )
 | 
						|
    e4severe( e4parm, E4_F4READ_ALL ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( file->code_base->error_code < 0 )
 | 
						|
    return -1 ;
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
  if ( file->do_buffer )
 | 
						|
    urc = (unsigned) opt4file_read( file, pos, ptr, ptr_len )  ;
 | 
						|
  else
 | 
						|
  {
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4WINDOWS
 | 
						|
    rc = _llseek( file->hand, pos, 0 ) ;
 | 
						|
#else
 | 
						|
#ifdef S4MACINTOSH
 | 
						|
    rc = MAClseek( file->hand, pos, 0, 0 ) ;
 | 
						|
#else
 | 
						|
#ifdef S4WIN32
 | 
						|
    if ( SetFilePointer( (HANDLE)file->hand, pos, NULL, FILE_BEGIN ) != (DWORD)-1 )
 | 
						|
      rc = pos ;
 | 
						|
#else
 | 
						|
#ifdef S4LSEEK
 | 
						|
    rc = f4lseek( file, pos, 0, 0 ) ;
 | 
						|
#else
 | 
						|
    rc = lseek( file->hand, pos, 0 ) ;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
    if ( rc != pos )
 | 
						|
      return file4read_error( file ) ;
 | 
						|
 | 
						|
#ifdef S4WINDOWS
 | 
						|
    urc = (unsigned)_lread( file->hand, (char *)ptr, ptr_len ) ;
 | 
						|
#else
 | 
						|
#ifdef S4MACINTOSH
 | 
						|
    rc = (long) ptr_len ;
 | 
						|
    urc = FSRead( file->hand, &rc, ptr ) ;
 | 
						|
    if ( urc == 0 )
 | 
						|
      urc = ptr_len ;
 | 
						|
#else
 | 
						|
#ifdef S4WIN32
 | 
						|
    rc = ReadFile( (HANDLE)file->hand, ptr, ptr_len, (unsigned long *)&urc, NULL ) ;
 | 
						|
    if ( !rc )
 | 
						|
      rc = GetLastError() ;
 | 
						|
#else
 | 
						|
    urc = (unsigned)read( file->hand, ptr, ptr_len ) ;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
  if ( urc != ptr_len )
 | 
						|
    return file4read_error( file ) ;
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
#ifdef S4DEBUG_DEV
 | 
						|
  if ( file->has_dup == 1 )
 | 
						|
    if ( file->do_buffer == 1 || file->link.n == 0 )
 | 
						|
      if ( file4cmp_part( file->code_base, ptr, file, pos, urc ) != 0 )
 | 
						|
        e4severe( e4opt, "file4read_all() - file corruption" ) ;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
  return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION file4read_error( FILE4 *file )
 | 
						|
{
 | 
						|
  return e4describe( file->code_base, e4read, E4_CREATE_FIL, file->name, (char *) 0 ) ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION file4replace( FILE4 *keep, FILE4 *from )
 | 
						|
{
 | 
						|
#ifdef S4NO_RENAME
 | 
						|
  return e4( from->code_base, e4not_rename, E4_F4REPLACE ) ;
 | 
						|
#else
 | 
						|
  FILE4 tmp ;
 | 
						|
  int from_do_alloc_free, rc ;
 | 
						|
  char *from_name ;
 | 
						|
#ifndef S4SINGLE
 | 
						|
  char *buf ;
 | 
						|
  unsigned buf_size ;
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
  int has_opt ;
 | 
						|
#endif
 | 
						|
  long pos, f_len ;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4DEBUG
 | 
						|
  if ( keep == 0 || from == 0  )
 | 
						|
    e4severe( e4parm, E4_F4REPLACE ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
  rc = 0 ;
 | 
						|
  if ( from->is_read_only || keep->is_read_only )
 | 
						|
    return e4( from->code_base, e4parm, E4_PARM_REP ) ;
 | 
						|
 | 
						|
#ifndef S4SINGLE
 | 
						|
  if ( keep->is_exclusive )
 | 
						|
  {
 | 
						|
#endif
 | 
						|
    memcpy( (void *)&tmp, (void *)keep, sizeof ( FILE4 ) ) ;  /* remember settings */
 | 
						|
 | 
						|
    keep->hand = from->hand ;
 | 
						|
    from->hand = tmp.hand ;
 | 
						|
    from_do_alloc_free = from->do_alloc_free ;
 | 
						|
    keep->do_alloc_free = 0 ;
 | 
						|
    from->do_alloc_free = 0 ;
 | 
						|
    from_name = from->name ;
 | 
						|
    from->name = keep->name ;
 | 
						|
    from->is_temp = 1 ;
 | 
						|
    if ( file4close ( from ) )
 | 
						|
      return -1 ;
 | 
						|
    if ( file4close ( keep ) )
 | 
						|
      return -1 ;
 | 
						|
 | 
						|
    if ( rename( from_name, tmp.name ) < 0 )
 | 
						|
      return - 1 ;
 | 
						|
 | 
						|
    if ( from_do_alloc_free )
 | 
						|
      u4free( from_name ) ;
 | 
						|
    if ( file4open ( keep, tmp.code_base, tmp.name, 0 ) )
 | 
						|
      return -1 ;
 | 
						|
    keep->is_temp = tmp.is_temp ;
 | 
						|
    keep->do_alloc_free = tmp.do_alloc_free ;
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
    if ( tmp.link.n != 0 )   /* file was optimized... */
 | 
						|
      file4optimize( keep, tmp.code_base->optimize ,tmp.type ) ;
 | 
						|
#endif
 | 
						|
#ifndef S4SINGLE
 | 
						|
  }
 | 
						|
  else  /* can't lose the file handle if other user's have the file open, so just do a copy */
 | 
						|
  {
 | 
						|
    file4len_set( keep, 0 ) ;
 | 
						|
 | 
						|
    buf_size = from->code_base->mem_size_buffer ;
 | 
						|
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
    has_opt = from->code_base->has_opt && from->code_base->opt.num_buffers ;
 | 
						|
    d4opt_suspend( from->code_base ) ;
 | 
						|
#endif
 | 
						|
 | 
						|
    for ( ;; buf_size -= 0x800 )
 | 
						|
    {
 | 
						|
      if ( buf_size < 0x800 )  /* make one last try */
 | 
						|
      {
 | 
						|
        buf_size = 100 ;
 | 
						|
        buf = (char *)u4alloc_er( from->code_base, buf_size ) ;
 | 
						|
        if ( buf == 0 )
 | 
						|
          return -1 ;
 | 
						|
      }
 | 
						|
      buf = (char *)u4alloc( buf_size ) ;
 | 
						|
      if ( buf )
 | 
						|
        break ;
 | 
						|
    }
 | 
						|
 | 
						|
    pos = 0 ;
 | 
						|
    for( f_len = file4len( from ) ; f_len > 0 ; f_len -= buf_size )
 | 
						|
    {
 | 
						|
      buf_size = ((long)buf_size > f_len) ?  (unsigned)f_len : buf_size ;
 | 
						|
      if ( file4read_all( from, pos, buf, (unsigned)buf_size ) < 0 )
 | 
						|
      {
 | 
						|
        rc = -1 ;
 | 
						|
        break ;
 | 
						|
      }
 | 
						|
      if ( file4write( keep, pos, buf, (unsigned)buf_size ) < 0 )
 | 
						|
      {
 | 
						|
        rc = -1 ;
 | 
						|
        break ;
 | 
						|
      }
 | 
						|
      pos += buf_size ;
 | 
						|
    }
 | 
						|
    from->is_temp = 1 ;
 | 
						|
    file4close( from ) ;
 | 
						|
    u4free( buf ) ;
 | 
						|
#ifndef S4OPTIMIZE_OFF
 | 
						|
    if ( has_opt )
 | 
						|
      d4opt_restart( keep->code_base ) ;
 | 
						|
#endif
 | 
						|
  }
 | 
						|
#endif
 | 
						|
  return rc ;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
#ifdef S4NO_ECVT
 | 
						|
#define S4NO_FCVT
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef S4NO_FCVT
 | 
						|
 | 
						|
#define MAXIMUM 30
 | 
						|
#define PRECISION 17
 | 
						|
 | 
						|
static char value_str[32] ;
 | 
						|
 | 
						|
static double minus[] =
 | 
						|
{1e-256,1e-128,1e-64,
 | 
						|
 1e-32,1e-16,1e-8,
 | 
						|
 1e-4,1e-2,1e-1,1.0} ;
 | 
						|
 | 
						|
 static double plus[] =
 | 
						|
{1e+256,1e+128,1e+64,
 | 
						|
 1e+32,1e+16,1e+8,
 | 
						|
 1e+4,1e+2,1e+1} ;
 | 
						|
 | 
						|
#ifdef S4NO_ECVT
 | 
						|
 char *f4ecvt( double value, int numdigits, int *dec_ptr, int *sign_ptr )
 | 
						|
{
 | 
						|
  int dptr, count, j, k ;
 | 
						|
  char *v_ptr ;
 | 
						|
 | 
						|
  if ( numdigits < 0 )
 | 
						|
    numdigits = 0 ;
 | 
						|
  else
 | 
						|
    if ( numdigits > MAXIMUM ) numdigits = MAXIMUM ;
 | 
						|
 | 
						|
  if ( value < 0.0 )
 | 
						|
  {
 | 
						|
    value = -value ;
 | 
						|
    *sign_ptr = 1 ;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    *sign_ptr = 0 ;
 | 
						|
 | 
						|
  if ( value == 0.0 )
 | 
						|
  {
 | 
						|
    memset( value_str, '0', numdigits ) ;
 | 
						|
    dptr = 0 ;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    dptr = 1 ;
 | 
						|
    k = 256 ;
 | 
						|
    count = 0 ;
 | 
						|
    while ( value < 1.0 )
 | 
						|
    {
 | 
						|
      while ( value < minus[count+1] )
 | 
						|
      {
 | 
						|
        value *= plus[count] ;
 | 
						|
        dptr -= k ;
 | 
						|
      }
 | 
						|
      k /= 2 ;
 | 
						|
      count++ ;
 | 
						|
    }
 | 
						|
    k = 256 ;
 | 
						|
    count = 0 ;
 | 
						|
    while ( value >= 10.0 )
 | 
						|
    {
 | 
						|
      while ( value >= plus[count] )
 | 
						|
      {
 | 
						|
        value *= minus[count] ;
 | 
						|
        dptr += k ;
 | 
						|
      }
 | 
						|
      k /= 2 ;
 | 
						|
      count++ ;
 | 
						|
    }
 | 
						|
 | 
						|
    for ( v_ptr = &value_str[0]; v_ptr <= &value_str[numdigits]; v_ptr++ )
 | 
						|
    {
 | 
						|
      if ( v_ptr >= &value_str[PRECISION] )  *v_ptr = '0' ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
        j = value ;
 | 
						|
        *v_ptr = j + '0' ;
 | 
						|
        value = ( value - j + 1.0e-15 ) * 10.0 ;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    --v_ptr ;
 | 
						|
    if ( *v_ptr >= '5' )
 | 
						|
    {
 | 
						|
      while (1)
 | 
						|
      {
 | 
						|
        if ( v_ptr == &value_str[0] )
 | 
						|
        {
 | 
						|
          dptr++ ;
 | 
						|
          value_str[0] = '1' ;
 | 
						|
          break ;
 | 
						|
        }
 | 
						|
        *v_ptr = 0 ;
 | 
						|
        --v_ptr ;
 | 
						|
        if ( *v_ptr != '9' )
 | 
						|
        {
 | 
						|
          (*v_ptr)++ ;
 | 
						|
          break ;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  *dec_ptr = dptr ;
 | 
						|
  value_str[numdigits] = 0 ;
 | 
						|
  return value_str ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
char *f4fcvt( double value, int numdigits, int *dec_ptr, int *sign_ptr )
 | 
						|
{
 | 
						|
  int dptr, count, j, k ;
 | 
						|
  char *v_ptr ;
 | 
						|
 | 
						|
  if ( numdigits < 0 )
 | 
						|
    numdigits = 0 ;
 | 
						|
  else
 | 
						|
    if ( numdigits > MAXIMUM ) numdigits = MAXIMUM ;
 | 
						|
 | 
						|
  if ( value < 0.0 )
 | 
						|
  {
 | 
						|
    value = -value ;
 | 
						|
    *sign_ptr = 1 ;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    *sign_ptr = 0 ;
 | 
						|
 | 
						|
  if ( value == 0.0 )
 | 
						|
  {
 | 
						|
    memset( value_str, '0', numdigits ) ;
 | 
						|
    dptr = 0 ;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    dptr = 1 ;
 | 
						|
    k = 256 ;
 | 
						|
    count = 0 ;
 | 
						|
    while ( value < 1.0 )
 | 
						|
    {
 | 
						|
      while ( value < minus[count+1] )
 | 
						|
      {
 | 
						|
        value *= plus[count] ;
 | 
						|
        dptr -= k ;
 | 
						|
      }
 | 
						|
      k /= 2 ;
 | 
						|
      count++ ;
 | 
						|
    }
 | 
						|
    k = 256 ;
 | 
						|
    count = 0 ;
 | 
						|
    while ( value >= 10.0 )
 | 
						|
    {
 | 
						|
      while ( value >= plus[count] )
 | 
						|
      {
 | 
						|
        value *= minus[count] ;
 | 
						|
        dptr += k ;
 | 
						|
      }
 | 
						|
      k /= 2 ;
 | 
						|
      count++ ;
 | 
						|
    }
 | 
						|
 | 
						|
    if ( ( numdigits += dptr ) < 0 )
 | 
						|
      numdigits = 0 ;
 | 
						|
    else
 | 
						|
      if ( numdigits > MAXIMUM )  numdigits = MAXIMUM ;
 | 
						|
 | 
						|
    for ( v_ptr = &value_str[0]; v_ptr <= &value_str[numdigits]; v_ptr++ )
 | 
						|
    {
 | 
						|
      if ( v_ptr >= &value_str[PRECISION] )  *v_ptr = '0' ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
        j = value ;
 | 
						|
        *v_ptr = j + '0' ;
 | 
						|
        value = ( value - j + 1.0e-15 ) * 10.0 ;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    --v_ptr ;
 | 
						|
    if ( *v_ptr >= '5' )
 | 
						|
    {
 | 
						|
      while (1)
 | 
						|
      {
 | 
						|
        if ( v_ptr == &value_str[0] )
 | 
						|
        {
 | 
						|
          numdigits++ ;
 | 
						|
          dptr++ ;
 | 
						|
          value_str[0] = '1' ;
 | 
						|
          break ;
 | 
						|
        }
 | 
						|
        *v_ptr = 0 ;
 | 
						|
        --v_ptr ;
 | 
						|
        if ( *v_ptr != '9' )
 | 
						|
        {
 | 
						|
          (*v_ptr)++ ;
 | 
						|
          break ;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  *dec_ptr = dptr ;
 | 
						|
  value_str[numdigits] = 0 ;
 | 
						|
  return value_str ;
 | 
						|
}
 | 
						|
#endif
 |