doprnt.c

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

C
792
字号
		/* Scan the field width and precision */		case '.':			flagword |= DOTSEEN;			prec = 0;			goto charswitch;		case '*':			if (!(flagword & DOTSEEN)) {				width = va_arg(args, int);				if (width < 0) {					width = -width;					flagword ^= FMINUS;				}			} else {				prec = va_arg(args, int);				if (prec < 0)					prec = 0;			}			goto charswitch;		case '0':	/* obsolescent spec:  leading zero in width */				/* means pad with leading zeros */			if (!(flagword & (DOTSEEN | FMINUS)))				flagword |= PADZERO;		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		case '8':		case '9':		      { register num = fcode - '0';			while (isdigit(fcode = *format)) {				num = num * 10 + fcode - '0';				format++;			}			if (flagword & DOTSEEN)				prec = num;			else				width = num;			goto charswitch;		      }		/* Scan the length modifier */		case 'l':			flagword |= LENGTH;			/* No break */		case 'h':			goto charswitch;		/*		 *	The character addressed by format must be		 *	the format letter -- there is nothing		 *	left for it to be.		 *		 *	The status of the +, -, #, and blank		 *	flags are reflected in the variable		 *	"flagword".  "width" and "prec" contain		 *	numbers corresponding to the digit		 *	strings before and after the decimal		 *	point, respectively. If there was no		 *	decimal point, then flagword & DOTSEEN		 *	is false and the value of prec is meaningless.		 *		 *	The following switch cases set things up		 *	for printing.  What ultimately gets		 *	printed will be padding blanks, a		 *	prefix, left padding zeroes, a value,		 *	right padding zeroes, a suffix, and		 *	more padding blanks.  Padding blanks		 *	will not appear simultaneously on both		 *	the left and the right.  Each case in		 *	this switch will compute the value, and		 *	leave in several variables the informa-		 *	tion necessary to construct what is to		 *	be printed.  		 *		 *	The prefix is a sign, a blank, "0x",		 *	"0X", or null, and is addressed by		 *	"prefix".		 *		 *	The suffix is either null or an		 *	exponent, and is addressed by "suffix".		 *	If there is a suffix, the flagword bit		 *	SUFFIX will be set.		 *		 *	The value to be printed starts at "bp"		 *	and continues up to and not including		 *	"p".		 *		 *	"lzero" and "rzero" will contain the		 *	number of padding zeroes required on		 *	the left and right, respectively.		 *	The flagword bits LZERO and RZERO tell		 *	whether padding zeros are required.		 *		 *	The number of padding blanks, and		 *	whether they go on the left or the		 *	right, will be computed on exit from		 *	the switch.		 */				/*		 *	decimal fixed point representations		 *		 *	HIBITL is 100...000		 *	binary, and is equal to	the maximum		 *	negative number.		 *	We assume a 2's complement machine		 */		case 'd':			/* 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:			{ 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':			/* 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':			mradix = 7;			lradix = 2;			goto fixed;		case 'X':		case 'x':			mradix = 15;			lradix = 3;		fixed:			/* 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':					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 '%':			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;		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))					blankpad(width - k);		}		/* Prefix, if any */		if (prefixlength != 0)			PUT(prefix, prefixlength);		/* Zeroes on the left */		if (flagword & LZERO)			zeropad(lzero);				/* The value itself */		if (n > 0)			PUT(bp, n);		if (flagword & (RZERO | SUFFIX | FMINUS)) {			/* Zeroes on the right */			if (flagword & RZERO)				zeropad(rzero);			/* The suffix */			if (flagword & SUFFIX)				PUT(suffix, suffixlength);			/* Blanks on the right if required */			if (flagword & FMINUS && width > k)				blankpad(width - k);		}	}}/* * Padding was done very naively before. It assumed no more than 20 * characters of padding. csh needs 21 in one place and maybe more. * * The routines below handle all cases. */staticblankpad(n)int n;{	static char *blanks = "                    ";	/* 20 blanks	*/	while (n >= 20) {		PUT(blanks, 20);		n -= 20;	}	if (n > 0) {		PUT(blanks, n);	}}staticzeropad(n)int n;{	static char *zeros = "00000000000000000000";	/* 20 zeros	*/	while (n >= 20) {		PUT(zeros, 20);		n -= 20;	}	if (n > 0) {		PUT(zeros, n);	}}

⌨️ 快捷键说明

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