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

📄 snprintf.c

📁 minicom的源码,linux下常用的串口程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This version of snprintf() and vsnprintf() is based on Sprint from * SIO by Panagiotis Tsirigotis, as included with xidentd-2.2.1. * * The modifications were made by The XFree86 Project, Inc and are * Copyright 1999 by The XFree86 Project, Inc.  These modifications * consist of removing the support for writing to file streams, * renaming some functions, ansification, and making some adjustments * to achieve the semantics for snprintf and vsnprintf() as described * in the relevant man page for FreeBSD 2.2.8. * * * The original version carries the following notice: * * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis * * The author (Panagiotis Tsirigotis) grants permission to use, copy, * and distribute this software and its documentation for any purpose * and without fee, provided that a) the above copyright notice extant in * files in this distribution is not removed from files included in any * redistribution, and b) this file is also included in any redistribution. * * Modifications to this software may be distributed, either by distributing * the modified software or by distributing patches to the original software, * under the following additional terms: * * 1. The version number will be modified as follows: *      a. The first 3 components of the version number *         (i.e. <number>.<number>.<number>) will remain unchanged. *      b. A new component will be appended to the version number to indicate *         the modification level. The form of this component is up to the *         author of the modifications. * * 2. The author of the modifications will include his/her name by appending *    it along with the new version number to this file and will be *    responsible for any wrong behavior of the modified software. * * The author makes no representations about the suitability of this * software for any purpose.  It is provided "as is" without any express * or implied warranty. * * Changes and modifications for:  * * xinetd Version 2.1.4-bsdi * xinetd Version 2.1.4-freebsd * xinetd Version 2.1.4-linux * * are       * * (c) Copyright 1995 by Charles Murcko * All Rights Reserved *//* $XFree86: xc/lib/misc/snprintf.c,v 3.1 1999/04/28 15:04:51 dawes Exp $ *//* * Assumption: systems that don't have snprintf and vsnprintf do have * ecvt, fcvt and gcvt. *//* From: Id: sprint.c,v 1.5 1995/09/10 18:35:09 chuck Exp */#ifdef HAVE_CONFIG_H# include <config.h>#endif#ifndef HAVE_STDARG_H#error Need stdarg here!#endif#include <ctype.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <sys/types.h>#ifndef SCOPE#define SCOPE					/**/#endif#ifndef WIDE_INT#define WIDE_INT				long#endiftypedef WIDE_INT wide_int;typedef unsigned WIDE_INT u_wide_int;typedef int bool_int;#ifndef FALSE#define FALSE					0#define TRUE					1#endif#define NUL					'\0'#define S_NULL					"(null)"#define S_NULL_LEN				6#define FLOAT_DIGITS				6#define EXPONENT_LENGTH				10typedef enum { NO = 0, YES = 1 } boolean_e ;/* * 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. * 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 * While using this macro, note that the nextb pointer is NOT updated. * * 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, cc )					\	{								\	    if ( sp < bep )						\		*sp++ = c ;						\	    cc++ ;							\	}#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, cc ) ;				\		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 = YESstatic char *conv_10(wide_int num, bool_int is_unsigned,			bool_int * is_negative, char *buf_end, int *len);SCOPE int vsnprintf(char *str, size_t size, const char *fmt, va_list ap);/* * snprintf is based on SIO's Sprint. * * Sprint is the equivalent of printf for SIO. * It returns the # of chars written * Assumptions: *     - all floating point arguments are passed as doubles */SCOPE int snprintf(char *str, size_t size, const char *fmt, ...){    int cc;    va_list ap;    va_start(ap, fmt);    cc = vsnprintf(str, size, fmt, ap);    va_end(ap);    return cc;}/* * 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).  Always add decimal point if add_dp is YES. */static char *conv_fp(char format, double num, boolean_e add_dp, int precision,	bool_int *is_negative, char buf[], int *len){    char *s = buf;    char *p;    int decimal_point;    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);    /*     * 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 ]) */static char *conv_p2(u_wide_int num, int nbits, char format, char *buf_end, int *len){    int mask = (1 << nbits) - 1;    char *p = buf_end;    static char low_digits[] = "0123456789abcdef";    static char upper_digits[] = "0123456789ABCDEF";    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 ]) */static char *conv_10(wide_int num, bool_int is_unsigned, bool_int *is_negative,	char *buf_end, int *len){    char *p = buf_end;    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);

⌨️ 快捷键说明

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