⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sio.c

📁 牛顿插值方法求解多项式的系数
💻 C
字号:
/* * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis * (c) Portions Copyright 1998-2001 by Rob Braun * All rights reserved.  The file named COPYRIGHT specifies the terms  * and conditions for redistribution. */#include "config.h"#ifndef linux#include <sys/types.h>#endif#ifdef _APPLE_#undef HAVE_MMAP#endif#include <limits.h>#include <stdlib.h>#include <unistd.h>#include "sio.h"#include "impl.h"/* * SIO WRITE FUNCTIONS: Swrite, Sputc *//* * Stream write call: arguments same as those of write(2) */int Swrite( int fd, const char *addr, unsigned int nbytes ){	__sio_descriptor_t *dp ;	__sio_od_t *odp ;	unsigned int b_transferred ;	unsigned int b_avail ;	int total_b_transferred ;	int b_written ;	int b_in_buffer ;	if ( nbytes > INT_MAX )		return( SIO_ERR );	if( sio_setup( fd, &dp, __SIO_OUTPUT_STREAM ) == SIO_ERR )		return( SIO_ERR );	odp = ODP( dp ) ;	ASSERT( odp->start <= odp->nextb && odp->nextb <= odp->buf_end ) ;	b_avail = odp->buf_end - odp->nextb ;	b_transferred = MIN( nbytes, b_avail ) ;	sio_memcopy( addr, odp->nextb, b_transferred ) ;	odp->nextb += b_transferred ;	/*	 * check if we are done	 */	if ( b_transferred == nbytes )		return( b_transferred ) ;	/*	 * at this point we know that the buffer is full	 */	b_in_buffer = odp->buf_end - odp->start ;	b_written = __sio_writef( odp, fd ) ;	if ( b_written != b_in_buffer )		return( (b_written >= (int)nbytes) ? (int)nbytes : b_written ) ;		total_b_transferred = b_transferred ;	addr += b_transferred ;	nbytes -= b_transferred ;	for ( ;; )	{		b_transferred = MIN( nbytes, odp->buffer_size ) ;		sio_memcopy( addr, odp->nextb, b_transferred ) ;		odp->nextb += b_transferred ;		nbytes -= b_transferred ;		if ( nbytes == 0 )		{			total_b_transferred += b_transferred ;			break ;		}		/*		 * the buffer is full		 */		b_written = __sio_writef( odp, fd ) ;		if ( b_written != (int)odp->buffer_size )		{			if ( b_written != SIO_ERR )			{				total_b_transferred += b_written ;				odp->nextb += b_written ;			}			break ;		}		/*		 * everything is ok		 */		total_b_transferred += b_transferred ;		addr += b_transferred ;	}	return( total_b_transferred ) ;}/* * Add a character to a file */static int Sputc( int fd, char c ){	__sio_descriptor_t *dp ;	__sio_od_t *odp ;	if( sio_setup( fd, &dp, __SIO_OUTPUT_STREAM) == SIO_ERR )		return( SIO_ERR );	odp = ODP( dp ) ;	ASSERT( odp->start <= odp->nextb && odp->nextb <= odp->buf_end ) ;	/*	 * The following is a weak check since we should really be	 * checking that nextb == buf_end (it would be an error for	 * nextb to exceed buf_end; btw, the assertion above, when	 * enabled makes sure this does not occur).	 *	 * NOTE: __sio_writef NEVER uses data beyond the end of buffer.	 */	if ( odp->nextb >= odp->buf_end )	{		int b_in_buffer = odp->buf_end - odp->start ;		/*		 * There is nothing we can do if __sio_writef does not manage		 * to write the whole buffer		 */		if ( __sio_writef( odp, fd ) != b_in_buffer )			return( SIO_ERR ) ;	}	*odp->nextb++ = c ;	if ( __SIO_MUST_FLUSH( *odp, c ) && __sio_writef( odp, fd ) == SIO_ERR )		return( SIO_ERR ) ;	return ( c ) ;}/* * SIO READ FUNCTIONS *//* * Read a line from a file * Returns a pointer to the beginning of the line or NULL */char *Srdline( int fd ){	__sio_descriptor_t *dp ;	__sio_id_t *idp ;	char *cp ;	char *line_start ;	int b_left ;	int extension ;	if( sio_setup( fd, &dp, __SIO_INPUT_STREAM ) == SIO_ERR )		return( NULL );	idp = IDP( dp ) ;	ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;#ifdef HAVE_MMAP	if ( idp->memory_mapped && __sio_switch( idp, fd ) == FAILURE )		return( NULL ) ;#endif	b_left = idp->end - idp->nextb ;	/*	 * Look for a '\n'. If the search fails, extend the buffer	 * and search again (the extension is performed by copying the	 * bytes that were searched to the auxiliary buffer and reading 	 * new input in the main buffer).	 * If the new input still does not contain a '\n' and there is	 * more space in the main buffer (this can happen with network	 * connections), read more input until either the buffer is full	 * or a '\n' is found.	 * Finally, set cp to point to the '\n', and line_start to	 * the beginning of the line	 */	if ( b_left && ( cp = sio_memscan( idp->nextb, b_left, '\n' ) ) != NULL )	{		line_start = idp->nextb ;		idp->nextb = cp + 1 ;	}	else	{		extension = __sio_extend_buffer( idp, fd, b_left ) ;		if ( extension > 0 )		{			ASSERT( idp->start <= idp->nextb && idp->nextb <= idp->end ) ;			line_start = idp->start ;			cp = sio_memscan( idp->nextb, extension, '\n' ) ;			if ( cp != NULL )				idp->nextb = cp + 1 ;			else				for ( ;; )				{					idp->nextb = idp->end ;					extension = __sio_more( idp, fd ) ;					if ( extension > 0 )					{						cp = sio_memscan( idp->nextb, extension, '\n' ) ;						if ( cp == NULL )							continue ;						idp->nextb = cp + 1 ;						break ;					}					else					{						/*						 * If there is spare room in the buffer avoid trashing						 * the last character						 */						if ( idp->end < &idp->buf[ idp->buffer_size ] )							cp = idp->end ;						else							cp = &idp->buf[ idp->buffer_size - 1 ] ;						break ;					}				}		}		else					/* buffer could not be extended */			if ( b_left == 0 )			{				/*				 * Set errno to 0 if EOF has been reached				 */				if ( extension == 0 )					errno = 0 ;				return( NULL ) ;			}			else			{				line_start = idp->start ;				cp = idp->end ;				/*				 * By setting idp->nextb to be equal to idp->end,				 * subsequent calls to Srdline will return NULL because				 * __sio_extend_buffer will be invoked and it will return 0.				 */				idp->nextb = idp->end ;			}	}	*cp = NUL ;	idp->line_length = cp - line_start ;	return( line_start ) ;}/* * SIO CONTROL FUNCTIONS *//* * Flush the buffer associated with the given file descriptor * The special value, SIO_FLUSH_ALL flushes all buffers * * Return value: *			0 :  if fd is SIO_FLUSH_ALL or if the flush is successful *		SIO_ERR: if fd is not SIO_FLUSH_ALL and *								the flush is unsuccessful *							or the descriptor is not initialized or it is not  *								an output descriptor */int Sflush( int fd ){   __sio_descriptor_t *dp ;   int b_in_buffer ;   if ( fd == SIO_FLUSH_ALL )   {      for ( fd = 0, dp = __sio_descriptors ;				fd < __sio_n_descriptors ;				dp++, fd++ )         if ( DESCRIPTOR_INITIALIZED( dp ) &&							dp->stream_type == __SIO_OUTPUT_STREAM )            (void) __sio_writef( ODP( dp ), fd ) ;      return( 0 ) ;   }   else   {      if ( fd >= __sio_n_descriptors ) {         errno = EBADF ;         return( SIO_ERR ) ;      }      dp = &__sio_descriptors[ fd ] ;      if( (! DESCRIPTOR_INITIALIZED( dp )) ||             (dp->stream_type != __SIO_OUTPUT_STREAM) )         return( SIO_ERR );      b_in_buffer = ODP( dp )->nextb - ODP( dp )->start ;      if ( __sio_writef( ODP( dp ), fd ) != b_in_buffer )         return( SIO_ERR ) ;      else         return( 0 ) ;   }}/* * Close the file descriptor. This call is provided because * a file descriptor may be closed and then reopened. There is * no easy way for SIO to identify such a situation, so Sclose * must be used. * * Sclose invokes Sdone which finalizes the buffer. * There is no SIO_CLOSE_ALL value for fd because such a thing * would imply that the program will exit very soon, therefore * the closing of all file descriptors will be done in the kernel * (and the finalization will be done by the finalization function * NOTE: not true if the OS does not support a finalization function) * * There is no need to invoke SETUP; Sdone will do it. */int Sclose( int fd ){	if ( __SIO_FD_INITIALIZED( fd ) ) {		if ( Sdone( fd ) == SIO_ERR ) {			close( fd ); 			return( SIO_ERR ) ;		}	}	return( close( fd ) ) ;}/* * Changes the type of buffering on the specified descriptor. * As a side-effect, it initializes the descriptor as an output stream. */int Sbuftype( int fd, int type ){	__sio_descriptor_t *dp ;	/*	 * Check for a valid type	 */	if ( type != SIO_LINEBUF && type != SIO_FULLBUF && type != SIO_NOBUF )	{		errno = EINVAL ;		return( SIO_ERR ) ;	}	if( sio_setup( fd, &dp, __SIO_OUTPUT_STREAM ) == SIO_ERR )		return( SIO_ERR );	ODP( dp )->buftype = type ;	return( 0 ) ;}#ifndef sio_memscanstatic char *sio_memscan( const char *from, int how_many, char ch ){   char *p ;   char *last = from + how_many ;   for ( p = from ; p < last ; p++ )      if ( *p == ch )         return( p ) ;      return( 0 ) ;}#endif	/* sio_memscan */#ifdef NEED_MEMCOPYvoid __sio_memcopy( const char *from, char *to, int nbytes ){   while ( nbytes-- )      *to++ = *from++ ;}#endif /* NEED_MEMCOPY */int sio_setup(int fd, __sio_descriptor_t **dp, unsigned int type){   if ( fd >= __sio_n_descriptors ) {      if( Smorefds(fd) != 0 ) {         errno = EBADF;         return(SIO_ERR);      }   }   *dp = &__sio_descriptors[ fd ];   if( DESCRIPTOR_INITIALIZED( *dp ) ) {      if( (*dp)->stream_type != type ) {         errno = EBADF;         return( SIO_ERR );      }   } else if( __sio_init(*dp, fd, type) == SIO_ERR )      return( SIO_ERR );   return( 0 );}/* * The Sputchar function depends on the fact that the fields *                              nextb, buf_end, end * are 0 if a stream descriptor is not being used or has not yet been * initialized. * This is true initially because of the static allocation of the * descriptor array, and Sdone must make sure that it is true * after I/O on a descriptor is over. */int Sputchar( int fd, char c ){   int ret = 0;   if( __SIO_OD( fd ).nextb < __SIO_OD( fd ).buf_end ) {      if( __SIO_OD(fd).buftype == SIO_FULLBUF ) {         ret = *(__SIO_OD(fd).nextb)++ = (unsigned char) (c);      } else if ( __SIO_OD(fd).buftype == SIO_LINEBUF ) {         if( (*(__SIO_OD(fd).nextb) = (unsigned char)(c)) != '\n' ) {            ret = *(__SIO_OD(fd).nextb)++;         } else {            ret = Sputc( fd, *(__SIO_OD(fd).nextb) );         }      } else {         ret = Sputc( fd, c );      }   } else {      ret = Sputc( fd, c );   }   return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -