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
 |