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

📄 snprintf.c

📁 samba服务器!
💻 C
📖 第 1 页 / 共 3 页
字号:
				cnk->type = CNK_PRCNT;				break;			default:				/* Unknown, bail out*/				goto done;			}			ch = *format++;			state = DP_S_DEFAULT;			break;		case DP_S_DONE:			break;		default:			/* hmm? */			break; /* some picky compilers need this */		}	}	/* retieve the format arguments */	for (pnum = 0; pnum < max_pos; pnum++) {		int i;		if (clist[pnum].num == 0) {			/* ignoring a parameter should not be permitted			 * all parameters must be matched at least once			 * BUT seem some system ignore this rule ...			 * at least my glibc based system does --SSS			 */#ifdef DEBUG_SNPRINTF			printf("parameter at position %d not used\n", pnum+1);#endif			/* eat the parameter */			va_arg (args, int);			continue;		}		for (i = 1; i < clist[pnum].num; i++) {			if (clist[pnum].chunks[0]->type != clist[pnum].chunks[i]->type) {				/* nooo noo no!				 * all the references to a parameter				 * must be of the same type				 */				goto done;			}		}		cnk = clist[pnum].chunks[0];		switch (cnk->type) {		case CNK_INT:			if (cnk->cflags == DP_C_SHORT) 				cnk->value = va_arg (args, int);			else if (cnk->cflags == DP_C_LONG)				cnk->value = va_arg (args, long int);			else if (cnk->cflags == DP_C_LLONG)				cnk->value = va_arg (args, LLONG);			else if (cnk->cflags == DP_C_SIZET)				cnk->value = va_arg (args, ssize_t);			else				cnk->value = va_arg (args, int);			for (i = 1; i < clist[pnum].num; i++) {				clist[pnum].chunks[i]->value = cnk->value;			}			break;		case CNK_OCTAL:		case CNK_UINT:		case CNK_HEX:			if (cnk->cflags == DP_C_SHORT)				cnk->value = va_arg (args, unsigned int);			else if (cnk->cflags == DP_C_LONG)				cnk->value = (unsigned long int)va_arg (args, unsigned long int);			else if (cnk->cflags == DP_C_LLONG)				cnk->value = (LLONG)va_arg (args, unsigned LLONG);			else if (cnk->cflags == DP_C_SIZET)				cnk->value = (size_t)va_arg (args, size_t);			else				cnk->value = (unsigned int)va_arg (args, unsigned int);			for (i = 1; i < clist[pnum].num; i++) {				clist[pnum].chunks[i]->value = cnk->value;			}			break;		case CNK_FLOAT:			if (cnk->cflags == DP_C_LDOUBLE)				cnk->fvalue = va_arg (args, LDOUBLE);			else				cnk->fvalue = va_arg (args, double);			for (i = 1; i < clist[pnum].num; i++) {				clist[pnum].chunks[i]->fvalue = cnk->fvalue;			}			break;		case CNK_CHAR:			cnk->value = va_arg (args, int);			for (i = 1; i < clist[pnum].num; i++) {				clist[pnum].chunks[i]->value = cnk->value;			}			break;		case CNK_STRING:			cnk->strvalue = va_arg (args, char *);			if (!cnk->strvalue) cnk->strvalue = "(NULL)";			for (i = 1; i < clist[pnum].num; i++) {				clist[pnum].chunks[i]->strvalue = cnk->strvalue;			}			break;		case CNK_PTR:			cnk->strvalue = va_arg (args, void *);			for (i = 1; i < clist[pnum].num; i++) {				clist[pnum].chunks[i]->strvalue = cnk->strvalue;			}			break;		case CNK_NUM:			if (cnk->cflags == DP_C_CHAR)				cnk->pnum = va_arg (args, char *);			else if (cnk->cflags == DP_C_SHORT)				cnk->pnum = va_arg (args, short int *);			else if (cnk->cflags == DP_C_LONG)				cnk->pnum = va_arg (args, long int *);			else if (cnk->cflags == DP_C_LLONG)				cnk->pnum = va_arg (args, LLONG *);			else if (cnk->cflags == DP_C_SIZET)				cnk->pnum = va_arg (args, ssize_t *);			else				cnk->pnum = va_arg (args, int *);			for (i = 1; i < clist[pnum].num; i++) {				clist[pnum].chunks[i]->pnum = cnk->pnum;			}			break;		case CNK_PRCNT:			break;		default:			/* what ?? */			goto done;		}	}	/* print out the actual string from chunks */	currlen = 0;	cnk = chunks;	while (cnk) {		int len, min, max;		if (cnk->min_star) min = cnk->min_star->value;		else min = cnk->min;		if (cnk->max_star) max = cnk->max_star->value;		else max = cnk->max;		switch (cnk->type) {		case CNK_FMT_STR:			if (maxlen != 0 && maxlen > currlen) {				if (maxlen > (currlen + cnk->len)) len = cnk->len;				else len = maxlen - currlen;				memcpy(&(buffer[currlen]), &(base[cnk->start]), len);			}			currlen += cnk->len;							break;		case CNK_INT:		case CNK_UINT:			fmtint (buffer, &currlen, maxlen, cnk->value, 10, min, max, cnk->flags);			break;		case CNK_OCTAL:			fmtint (buffer, &currlen, maxlen, cnk->value, 8, min, max, cnk->flags);			break;		case CNK_HEX:			fmtint (buffer, &currlen, maxlen, cnk->value, 16, min, max, cnk->flags);			break;		case CNK_FLOAT:			fmtfp (buffer, &currlen, maxlen, cnk->fvalue, min, max, cnk->flags);			break;		case CNK_CHAR:			dopr_outch (buffer, &currlen, maxlen, cnk->value);			break;		case CNK_STRING:			if (max == -1) {				max = strlen(cnk->strvalue);			}			fmtstr (buffer, &currlen, maxlen, cnk->strvalue, cnk->flags, min, max);			break;		case CNK_PTR:			fmtint (buffer, &currlen, maxlen, (long)(cnk->strvalue), 16, min, max, cnk->flags);			break;		case CNK_NUM:			if (cnk->cflags == DP_C_CHAR)				*((char *)(cnk->pnum)) = (char)currlen;			else if (cnk->cflags == DP_C_SHORT)				*((short int *)(cnk->pnum)) = (short int)currlen;			else if (cnk->cflags == DP_C_LONG)				*((long int *)(cnk->pnum)) = (long int)currlen;			else if (cnk->cflags == DP_C_LLONG)				*((LLONG *)(cnk->pnum)) = (LLONG)currlen;			else if (cnk->cflags == DP_C_SIZET)				*((ssize_t *)(cnk->pnum)) = (ssize_t)currlen;			else				*((int *)(cnk->pnum)) = (int)currlen;			break;		case CNK_PRCNT:			dopr_outch (buffer, &currlen, maxlen, '%');			break;		default:			/* what ?? */			goto done;		}		cnk = cnk->next;	}	if (maxlen != 0) {		if (currlen < maxlen - 1) 			buffer[currlen] = '\0';		else if (maxlen > 0) 			buffer[maxlen - 1] = '\0';	}	ret = currlen;done:	va_end(args);	while (chunks) {		cnk = chunks->next;		free(chunks);		chunks = cnk;	}	if (clist) {		for (pnum = 0; pnum < max_pos; pnum++) {			if (clist[pnum].chunks) free(clist[pnum].chunks);		}		free(clist);	}	return ret;}static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,		    char *value, int flags, int min, int max){	int padlen, strln;     /* amount to pad */	int cnt = 0;#ifdef DEBUG_SNPRINTF	printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);#endif	if (value == 0) {		value = "<NULL>";	}	for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */	padlen = min - strln;	if (padlen < 0) 		padlen = 0;	if (flags & DP_F_MINUS) 		padlen = -padlen; /* Left Justify */		while (padlen > 0) {		dopr_outch (buffer, currlen, maxlen, ' ');		--padlen;	}	while (*value && (cnt < max)) {		dopr_outch (buffer, currlen, maxlen, *value++);		++cnt;	}	while (padlen < 0) {		dopr_outch (buffer, currlen, maxlen, ' ');		++padlen;	}}/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */static void fmtint(char *buffer, size_t *currlen, size_t maxlen,		    LLONG value, int base, int min, int max, int flags){	int signvalue = 0;	unsigned LLONG uvalue;	char convert[20];	int place = 0;	int spadlen = 0; /* amount to space pad */	int zpadlen = 0; /* amount to zero pad */	int caps = 0;		if (max < 0)		max = 0;		uvalue = value;		if(!(flags & DP_F_UNSIGNED)) {		if( value < 0 ) {			signvalue = '-';			uvalue = -value;		} else {			if (flags & DP_F_PLUS)  /* Do a sign (+/i) */				signvalue = '+';			else if (flags & DP_F_SPACE)				signvalue = ' ';		}	}  	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */	do {		convert[place++] =			(caps? "0123456789ABCDEF":"0123456789abcdef")			[uvalue % (unsigned)base  ];		uvalue = (uvalue / (unsigned)base );	} while(uvalue && (place < 20));	if (place == 20) place--;	convert[place] = 0;	zpadlen = max - place;	spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);	if (zpadlen < 0) zpadlen = 0;	if (spadlen < 0) spadlen = 0;	if (flags & DP_F_ZERO) {		zpadlen = MAX(zpadlen, spadlen);		spadlen = 0;	}	if (flags & DP_F_MINUS) 		spadlen = -spadlen; /* Left Justifty */#ifdef DEBUG_SNPRINTF	printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",	       zpadlen, spadlen, min, max, place);#endif	/* Spaces */	while (spadlen > 0) {		dopr_outch (buffer, currlen, maxlen, ' ');		--spadlen;	}	/* Sign */	if (signvalue) 		dopr_outch (buffer, currlen, maxlen, signvalue);	/* Zeros */	if (zpadlen > 0) {		while (zpadlen > 0) {			dopr_outch (buffer, currlen, maxlen, '0');			--zpadlen;		}	}	/* Digits */	while (place > 0) 		dopr_outch (buffer, currlen, maxlen, convert[--place]);  	/* Left Justified spaces */	while (spadlen < 0) {		dopr_outch (buffer, currlen, maxlen, ' ');		++spadlen;	}}static LDOUBLE abs_val(LDOUBLE value){	LDOUBLE result = value;	if (value < 0)		result = -value;		return result;}static LDOUBLE POW10(int exp){	LDOUBLE result = 1;		while (exp) {		result *= 10;		exp--;	}  	return result;}static LLONG ROUND(LDOUBLE value){	LLONG intpart;	intpart = (LLONG)value;	value = value - intpart;	if (value >= 0.5) intpart++;		return intpart;}/* a replacement for modf that doesn't need the math library. Should   be portable, but slow */static double my_modf(double x0, double *iptr){	int i;	LLONG l=0;	double x = x0;	double f = 1.0;	for (i=0;i<100;i++) {		l = (long)x;		if (l <= (x+1) && l >= (x-1)) break;		x *= 0.1;		f *= 10.0;	}	if (i == 100) {		/* yikes! the number is beyond what we can handle. What do we do? */		(*iptr) = 0;		return 0;	}	if (i != 0) {		double i2;		double ret;		ret = my_modf(x0-l*f, &i2);		(*iptr) = l*f + i2;		return ret;	} 	(*iptr) = l;	return x - (*iptr);}static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,		   LDOUBLE fvalue, int min, int max, int flags){	int signvalue = 0;	double ufvalue;	char iconvert[311];	char fconvert[311];	int iplace = 0;	int fplace = 0;	int padlen = 0; /* amount to pad */	int zpadlen = 0; 	int caps = 0;	int idx;	double intpart;	double fracpart;	double temp;  	/* 	 * AIX manpage says the default is 0, but Solaris says the default	 * is 6, and sprintf on AIX defaults to 6	 */	if (max < 0)		max = 6;	ufvalue = abs_val (fvalue);	if (fvalue < 0) {		signvalue = '-';	} else {		if (flags & DP_F_PLUS) { /* Do a sign (+/i) */			signvalue = '+';		} else {			if (flags & DP_F_SPACE)				signvalue = ' ';		}	}#if 0	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */#endif#if 0	 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */#endif	/* 	 * Sorry, we only support 9 digits past the decimal because of our 	 * conversion method	 */	if (max > 9)		max = 9;	/* We "cheat" by converting the fractional part to integer by	 * multiplying by a factor of 10	 */	temp = ufvalue;	my_modf(temp, &intpart);	fracpart = ROUND((POW10(max)) * (ufvalue - intpart));		if (fracpart >= POW10(max)) {		intpart++;		fracpart -= POW10(max);	}	/* Convert integer part */	do {		temp = intpart*0.1;		my_modf(temp, &intpart);		idx = (int) ((temp -intpart +0.05)* 10.0);		/* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */

⌨️ 快捷键说明

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