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

📄 sprint.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis * All rights reserved.  The file named COPYRIGHT specifies the terms * and conditions for redistribution. */static char RCSid[] = "sprint.c,v 1.3 1995/09/03 00:36:21 duane Exp" ;#include <string.h>#include <ctype.h>#include "sio.h"#include "impl.h"#ifndef WIDE_INT#define WIDE_INT							long#endiftypedef WIDE_INT 							wide_int ;typedef unsigned WIDE_INT 				u_wide_int ;typedef int 								bool_int ;#define S_NULL								"(null)"#define S_NULL_LEN						6#define FLOAT_DIGITS						6#define EXPONENT_LENGTH					10/* * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions * * XXX: this is a magic number; do not decrease it */#define NUM_BUF_SIZE						512/* * The INS_CHAR macro inserts a character in the buffer and writes * the buffer back to disk if necessary * It uses the char pointers sp and bep: * 	sp points to the next available character in the buffer * 	bep points to the end-of-buffer+1 * While using this macro, note that the nextb pointer is NOT updated. * * No I/O is performed if fd is not positive. Negative fd values imply * conversion with the output directed to a string. Excess characters * are discarded if the string overflows. * * NOTE: Evaluation of the c argument should not have any side-effects */#define INS_CHAR( c, sp, bep, odp, cc, fd )											\			{																						\				if ( sp < bep )																\				{																					\					*sp++ = c ;																	\					cc++ ;																		\				}																					\				else																				\				{																					\					if ( fd >= 0 )																\					{																				\						odp->nextb = sp ;														\						if ( __sio_writef( odp, fd ) != bep - odp->start )			\							return( ( cc != 0 ) ? cc : SIO_ERR ) ;						\						sp = odp->nextb ;														\						*sp++ = c ;																\						cc++ ;																	\					}																				\				}																					\				if ( __SIO_MUST_FLUSH( *odp, c ) && fd >= 0 ) 						\				{																					\					int b_in_buffer = sp - odp->start ;									\																									\					odp->nextb = sp ;															\					if ( __sio_writef( odp, fd ) != b_in_buffer )					\						return( cc ) ;															\					sp = odp->nextb ;															\				}																					\			}#define NUM( c )			( c - '0' )#define STR_TO_DEC( str, num )									\									num = NUM( *str++ ) ;			\									while ( isdigit( *str ) )		\									{										\										num *= 10 ;						\										num += NUM( *str++ ) ;		\									}/* * This macro does zero padding so that the precision * requirement is satisfied. The padding is done by * adding '0's to the left of the string that is going * to be printed. */#define FIX_PRECISION( adjust, precision, s, s_len )				\					if ( adjust )												\						while ( s_len < precision )						\						{															\							*--s = '0' ;										\							s_len++ ;											\						}/* * Macro that does padding. The padding is done by printing * the character ch. */#define PAD( width, len, ch )			do														\												{														\													INS_CHAR( ch, sp, bep, odp, cc, fd ) ;	\													width-- ;										\												}														\												while ( width > len )/* * Prefix the character ch to the string str * Increase length * Set the has_prefix flag */#define PREFIX( str, length, ch )	*--str = ch ; length++ ; has_prefix = YESPRIVATE char *conv_10(), *conv_p2(), *conv_fp() ;/* * Sprint is the equivalent of printf for SIO. * It returns the # of chars written * Assumptions: *     - all floating point arguments are passed as doubles *//* VARARGS2 */#ifdef __STRICT_ANSI__int Sprint( int fd, char *fmt, ... ){	__sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;	register __sio_od_t *odp = ODP( dp ) ;	register int cc ;	va_list ap ;	IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;	va_start( ap, fmt ) ;#elseint Sprint( fd, fmt, va_alist )	int fd ;	register char *fmt ;	va_dcl{	__sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;	register __sio_od_t *odp = ODP( dp ) ;	register int cc ;	va_list ap ;	IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;	va_start( ap ) ;#endif	cc = __sio_converter( odp, fd, fmt, ap ) ;	va_end( ap ) ;	return( cc ) ;}/* * This is the equivalent of vfprintf for SIO */int Sprintv( fd, fmt, ap )	int fd ;	char *fmt ;	va_list ap ;{	__sio_descriptor_t *dp = &__sio_descriptors[ fd ] ;	register __sio_od_t *odp = ODP( dp ) ;	IO_SETUP( fd, dp, __SIO_OUTPUT_STREAM, SIO_ERR ) ;	return( __sio_converter( odp, fd, fmt, ap ) ) ;}/* * Convert a floating point number to a string formats 'f', 'e' or 'E'. * The result is placed in buf, and len denotes the length of the string * The sign is returned in the is_negative argument (and is not placed * in buf). */PRIVATE char *conv_fp( format, num, add_dp, precision, is_negative, buf, len )	register char format ;	register double num ;	boolean_e add_dp ;			/* always add decimal point if YES */	int precision ;	bool_int *is_negative ;	char buf[] ;	int *len ;{	register char *s = buf ;	register char *p ;	int decimal_point ;# if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__bsdi__)	char *ecvt(), *fcvt() ;# endif	char *conv_10() ;# if 0	char *strcpy() ;# endif# if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__bsdi__)	if ( format == 'f' )		p = fcvt( num, precision, &decimal_point, is_negative ) ;	else /* either e or E format */		p = ecvt( num, precision+1, &decimal_point, is_negative ) ;# endif	/*	 * Check for Infinity and NaN	 */	if ( isalpha( *p ) )	{		*len = strlen( strcpy( buf, p ) ) ;		*is_negative = FALSE ;		return( buf ) ;	}	if ( format == 'f' )		if ( decimal_point <= 0 )		{			*s++ = '0' ;			if ( precision > 0 )			{				*s++ = '.' ;				while ( decimal_point++ < 0 )					*s++ = '0' ;			}			else if ( add_dp )				*s++ = '.' ;		}		else		{			while ( decimal_point-- > 0 )				*s++ = *p++ ;			if ( precision > 0 || add_dp ) *s++ = '.' ;		}	else	{		*s++ = *p++ ;		if ( precision > 0 || add_dp ) *s++ = '.' ;	}	/*	 * copy the rest of p, the NUL is NOT copied	 */	while ( *p ) *s++ = *p++ ;	if ( format != 'f' )	{		char temp[ EXPONENT_LENGTH ] ;				/* for exponent conversion */		int t_len ;		bool_int exponent_is_negative ;		*s++ = format ;		/* either e or E */		decimal_point-- ;		if ( decimal_point != 0 )		{			p = conv_10( (wide_int)decimal_point, FALSE, &exponent_is_negative,												&temp[ EXPONENT_LENGTH ], &t_len ) ;			*s++ = exponent_is_negative ? '-' : '+' ;			/*			 * Make sure the exponent has at least 2 digits			 */			if ( t_len == 1 )				*s++ = '0' ;			while ( t_len-- ) *s++ = *p++ ;		}		else		{			*s++ = '+' ;			*s++ = '0' ;			*s++ = '0' ;		}	}	*len = s - buf ;	return( buf ) ;}/* * Convert num to a base X number where X is a power of 2. nbits determines X. * For example, if nbits is 3, we do base 8 conversion * Return value: *			a pointer to a string containing the number * * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) */PRIVATE char *conv_p2( num, nbits, format, buf_end, len )	register u_wide_int num ;	register int nbits ;	char format ;	char *buf_end ;	register int *len ;{	register int mask = ( 1 << nbits ) - 1 ;	register char *p = buf_end ;	static char low_digits[] = "0123456789abcdef" ;	static char upper_digits[] = "0123456789ABCDEF" ;	register char *digits = ( format == 'X' ) ? upper_digits : low_digits ;	do	{		*--p = digits[ num & mask ] ;		num >>= nbits ;	}	while( num ) ;	*len = buf_end - p ;	return( p ) ;}/* * Convert num to its decimal format. * Return value: *       - a pointer to a string containing the number (no sign) *			- len contains the length of the string *			- is_negative is set to TRUE or FALSE depending on the sign *			  of the number (always set to FALSE if is_unsigned is TRUE) * * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) */PRIVATE char *conv_10( num, is_unsigned, is_negative, buf_end, len )	register wide_int num ;	register bool_int is_unsigned ;	register bool_int *is_negative ;	char *buf_end ;	register int *len ;{	register char *p = buf_end ;	register u_wide_int magnitude ;	if ( is_unsigned )	{		magnitude = (u_wide_int) num ;		*is_negative = FALSE ;	}	else	{		*is_negative = ( num < 0 ) ;		/*		 * On a 2's complement machine, negating the most negative integer		 * results in a number that cannot be represented as a signed integer.		 * Here is what we do to obtain the number's magnitude:		 *		a. add 1 to the number		 *		b. negate it (becomes positive)		 *		c. convert it to unsigned		 *		d. add 1		 */		if ( *is_negative )		{			wide_int t = num + 1 ;			magnitude = ( (u_wide_int) -t ) + 1 ;		}		else			magnitude = (u_wide_int) num ;	}	/*	 * We use a do-while loop so that we write at least 1 digit	 */	do	{		register u_wide_int new_magnitude = magnitude / 10 ;		*--p = magnitude - new_magnitude*10 + '0' ;		magnitude = new_magnitude ;	}	while ( magnitude ) ;	*len = buf_end - p ;	return( p ) ;}/* * Do format conversion placing the output in odp */

⌨️ 快捷键说明

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