doprnt.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,011 行 · 第 1/2 页

C
1,011
字号
		 *	binary, and is equal to	the maximum		 *	negative number.		 *	We assume a 2's complement machine		 */		case 'd':		case 'D':		case 'i':		case 'I':			/* Fetch the argument to be printed */			if (flagword & LENGTH)				val = va_arg(args, long);			else				val = va_arg(args, int);			/* Set buffer pointer to last digit */			p = bp = buf + MAXDIGS;			/* If signed conversion, make sign */			if (val < 0) {				prefix = "-";				prefixlength = 1;				/*				 * Negate, checking in				 * advance for possible				 * overflow.				 */				if (val != HIBITL)					val = -val;				else     /* number is -HIBITL; convert last */					 /* digit now and get positive number */					*--bp = _lowdigit(&val);			} else if (flagword & FPLUS) {				prefix = "+";				prefixlength = 1;			} else if (flagword & FBLANK) {				prefix = " ";				prefixlength = 1;			}		decimal:			/*			 * If both the zero pad specifier and precision are			 * specified, the zero pad specifier is ignored.			 */			if((flagword & (DOTSEEN|PADZERO)) == (DOTSEEN|PADZERO))			    flagword &= ~PADZERO;			{ register long qval = val;				if (qval <= 9) {					if (qval != 0 || !(flagword & DOTSEEN))						*--bp = qval + '0';				} else {					do {						n = qval;						qval /= 10;						*--bp = n - qval * 10 + '0';					} while (qval > 9);					*--bp = qval + '0';				}			}			/* Calculate minimum padding zero requirement */			if (flagword & DOTSEEN) {				register leadzeroes = prec - (p - bp);				if (leadzeroes > 0) {					otherlength = lzero = leadzeroes;					flagword |= LZERO;				}			}			break;		case 'U':		case 'u':			/* Fetch the argument to be printed */			if (flagword & LENGTH)				val = va_arg(args, long);			else				val = va_arg(args, unsigned);			p = bp = buf + MAXDIGS;			if (val & HIBITL)				*--bp = _lowdigit(&val);			goto decimal;		/*		 *	non-decimal fixed point representations		 *	for radix equal to a power of two		 *		 *	"mradix" is one less than the radix for the conversion.		 *	"lradix" is one less than the base 2 log		 *	of the radix for the conversion. Conversion is unsigned.		 *	HIBITL is 100...000		 *	binary, and is equal to	the maximum		 *	negative number.		 *	We assume a 2's complement machine		 */		case 'O':		case 'o':			mradix = 7;			lradix = 2;			goto fixed;		case 'p':			/* pointer: treat as %08x */			width = 8;			prec = 0;			flagword = PADZERO;			/* FALLTHRU */		case 'X':		case 'x':			mradix = 15;			lradix = 3;		fixed:			/*			 * If both the zero pad specifier and precision are			 * specified, the zero pad specifier is ignored.			 */			if((flagword & (DOTSEEN|PADZERO)) == (DOTSEEN|PADZERO))			    flagword &= ~PADZERO;			/* Fetch the argument to be printed */			if (flagword & LENGTH)				val = va_arg(args, long);			else				val = va_arg(args, unsigned);			/* Set translate table for digits */			tab = (fcode == 'X') ?			    "0123456789ABCDEF" : "0123456789abcdef";			/* Develop the digits of the value */			p = bp = buf + MAXDIGS;			{ register long qval = val;				if (qval == 0) {					if (!(flagword & DOTSEEN)) {						otherlength = lzero = 1;						flagword |= LZERO;					}				} else					do {						*--bp = tab[qval & mradix];						qval = ((qval >> 1) & ~HIBITL)								 >> lradix;					} while (qval != 0);			}			/* Calculate minimum padding zero requirement */			if (flagword & DOTSEEN) {				register leadzeroes = prec - (p - bp);				if (leadzeroes > 0) {					otherlength = lzero = leadzeroes;					flagword |= LZERO;				}			}			/* Handle the # flag */			if (flagword & FSHARP && val != 0)				switch (fcode) {				case 'O':				case 'o':					if (!(flagword & LZERO)) {						otherlength = lzero = 1;						flagword |= LZERO;					}					break;				case 'x':					prefix = "0x";					prefixlength = 2;					break;				case 'X':					prefix = "0X";					prefixlength = 2;					break;				}			break;		case 'E':		case 'e':			/*			 * E-format.  The general strategy			 * here is fairly easy: we take			 * what ecvt gives us and re-format it.			 */			/* Establish default precision */			if (!(flagword & DOTSEEN))				prec = 6;			/* Develop the mantissa */			bp = cvt(&args, min(prec + 1, MAXECVT), &decpt, &sign,			    0, &fp_class, &is_zero);			/* Determine the prefix */		e_merge:#if defined(mips) && !defined(MOXIE)			if (fp_class == FP_QNAN || fp_class == FP_SNAN) {				bp = "NaN";				p = bp + strlen(bp);				break;			}			if (fp_class == FP_POS_INF) {				if(flagword & FPLUS) 					bp = "+Infinity";				else					bp = "Infinity";				p = bp + strlen(bp);				break;			}			if (fp_class == FP_NEG_INF) {				bp = "-Infinity";				p = bp + strlen(bp);				break;			}#endif			if (sign) {				prefix = "-";				prefixlength = 1;			} else if (flagword & FPLUS) {				prefix = "+";				prefixlength = 1;			} else if (flagword & FBLANK) {				prefix = " ";				prefixlength = 1;			}			/* Place the first digit in the buffer*/			p = &buf[0];			*p++ = (*bp != '\0') ? *bp++ : '0';			/* Put in a decimal point if needed */			if (prec != 0 || (flagword & FSHARP))				*p++ = _lc_radix;			/* Create the rest of the mantissa */			{ register rz = prec;				for ( ; rz > 0 && *bp != '\0'; --rz)					*p++ = *bp++;				if (rz > 0) {					otherlength = rzero = rz;					flagword |= RZERO;				}			}			bp = &buf[0];			/* Create the exponent */			*(suffix = &expbuf[MAXESIZ]) = '\0';			if (!is_zero) {				register int nn = decpt - 1;				if (nn < 0)				    nn = -nn;				for ( ; nn > 9; nn /= 10)					*--suffix = todigit(nn % 10);				*--suffix = todigit(nn);			}			/* Prepend leading zeroes to the exponent */			while (suffix > &expbuf[MAXESIZ - 2])				*--suffix = '0';			/* Put in the exponent sign */			*--suffix = (decpt > 0 || is_zero) ? '+' : '-';			/* Put in the e */			*--suffix = isupper(fcode) ? 'E'  : 'e';			/* compute size of suffix */			otherlength += (suffixlength = &expbuf[MAXESIZ]								 - suffix);			flagword |= SUFFIX;			break;		case 'f':			/*			 * F-format floating point.  This is a			 * good deal less simple than E-format.			 * The overall strategy will be to call			 * fcvt, reformat its result into buf,			 * and calculate how many trailing			 * zeroes will be required.  There will			 * never be any leading zeroes needed.			 */			/* Establish default precision */			if (!(flagword & DOTSEEN))				prec = 6;			/* Do the conversion */			bp = cvt(&args, min(prec, MAXFCVT), &decpt, &sign, 1,			    &fp_class, &is_zero);			/* Determine the prefix */		f_merge:#if defined(mips) && !defined(MOXIE)			if (fp_class == FP_QNAN || fp_class == FP_SNAN) {				bp = "NaN";				p = bp + strlen(bp);				break;			}			if (fp_class == FP_POS_INF) {				if(flagword & FPLUS) 					bp = "+Infinity";				else					bp = "Infinity";				p = bp + strlen(bp);				break;			}			if (fp_class == FP_NEG_INF) {				bp = "-Infinity";				p = bp + strlen(bp);				break;			}#endif			if (sign && decpt > -prec && *bp != '0') {				prefix = "-";				prefixlength = 1;			} else if (flagword & FPLUS) {				prefix = "+";				prefixlength = 1;			} else if (flagword & FBLANK) {				prefix = " ";				prefixlength = 1;			}			/* Initialize buffer pointer */			p = &buf[0];			{ register int nn = decpt;				/* Emit the digits before the decimal point */				k = 0;				do {					*p++ = (nn <= 0 || *bp == '\0' 						|| k >= MAXFSIG) ?				    		'0' : (k++, *bp++);				} while (--nn > 0);				/* Decide whether we need a decimal point */				if ((flagword & FSHARP) || prec > 0)					*p++ = _lc_radix;				/* Digits (if any) after the decimal point */				nn = min(prec, MAXFCVT);				if (prec > nn) {					flagword |= RZERO;					otherlength = rzero = prec - nn;				}				while (--nn >= 0)					*p++ = (++decpt <= 0 || *bp == '\0' ||				   	    k >= MAXFSIG) ? '0' : (k++, *bp++);			}			bp = &buf[0];			break;		case 'G':		case 'g':			/*			 * g-format.  We play around a bit			 * and then jump into e or f, as needed.			 */					/* Establish default precision */			if (!(flagword & DOTSEEN))				prec = 6;			else if (prec == 0)				prec = 1;			/* Do the conversion */			bp = cvt(&args, min(prec, MAXECVT), &decpt, &sign, 0,			    &fp_class, &is_zero);			if (is_zero)				decpt = 1;			{ register int kk = prec;				if (!(flagword & FSHARP)) {					n = strlen(bp);					if (n < kk)						kk = n;					while (kk >= 1 && bp[kk-1] == '0')						--kk;				}								if (decpt < -3 || decpt > prec) {					prec = kk - 1;					goto e_merge;				}				prec = kk - decpt;				goto f_merge;			}		case '%':			buf[0] = fcode;			goto c_merge;		case 'c':			buf[0] = va_arg(args, int);		c_merge:			p = (bp = &buf[0]) + 1;			break;		case 's':			bp = va_arg(args, char *);			if (bp == NULL) {	/* DAG -- robustness addition */				bp = "(null)";				flagword &= ~DOTSEEN;			}			if (!(flagword & DOTSEEN))				p = bp + strlen(bp);			else { /* a strnlen function would  be useful here! */				register char *qp = bp;				while (*qp++ != '\0' && --prec >= 0)					;				p = qp - 1;			}			break;		case 'n':			if(flagword & LENGTH){			    lnp = va_arg(args, long *);			    if (lnp != NULL)				*lnp = count;			} else if(flagword & SHORT){			    snp = va_arg(args, short *);			    if (snp != NULL)				*snp = count;			} else {			    np = va_arg(args, int *);			    if (np != NULL)				*np = count;			}			p = bp = &buf[0];			width = prefixlength = otherlength = flagword = 0;			break;		default: /* this is technically an error; what we do is to */			/* back up the format pointer to the offending char */			/* and continue with the format scan */			format--;			continue;		}		/* Calculate number of padding blanks */		k = (n = p - bp) + prefixlength + otherlength;		if (width <= k)			count += k;		else {			count += width;			/* Set up for padding zeroes if requested */			/* Otherwise emit padding blanks unless output is */			/* to be left-justified.  */			if (flagword & PADZERO) {				if (!(flagword & LZERO)) {					flagword |= LZERO;					lzero = width - k;				}				else					lzero += width - k;				k = width; /* cancel padding blanks */			} else				/* Blanks on left if required */				if (!(flagword & FMINUS))					PAD(_blanks, width - k);		}		/* Prefix, if any */		if (prefixlength != 0)			PUT(prefix, prefixlength);		/* Zeroes on the left */		if (flagword & LZERO)			PAD(_zeroes, lzero);				/* The value itself */		if (n > 0)			PUT(bp, n);		if (flagword & (RZERO | SUFFIX | FMINUS)) {			/* Zeroes on the right */			if (flagword & RZERO)				PAD(_zeroes, rzero);			/* The suffix */			if (flagword & SUFFIX)				PUT(suffix, suffixlength);			/* Blanks on the right if required */			if (flagword & FMINUS && width > k)				PAD(_blanks, width - k);		}	}}

⌨️ 快捷键说明

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