?? snprintf.c
字號:
if (numbersigned) { if (number < 0) { /* Deal with negativity */ sign = '-'; number = -number; } else if (flags & FLAG_SIGNED) { sign = '+'; } else if (flags & FLAG_SIGN_PAD) { sign = ' '; } } /* Create number */ if (numbersigned) { if (number == 0) iszero = 1; do { PUSH(number % base); number /= base; len++; } while (number != 0); } else { if (unumber == 0) iszero = 1; do { PUSH(unumber % base); unumber /= base; len++; } while (unumber != 0); } /* Octal hash character (alternate form) */ if (fmt == 'o' && (flags & FLAG_HASH) && precision <= len && precision != 0 && !iszero ) { precision = len + 1; } /* Determine width of sign, if any. */ if ( (fmt == 'x' || fmt == 'X') && (flags & FLAG_HASH) && !iszero ) addprefix = 2; else if (sign != 0) addprefix = 1; /* Make up precision (zero pad on left) */ while (len < precision) { PUSH(0); len++; } if (len + addprefix < width) { totallen = width; widthpad = width - (len + addprefix); } else totallen = len + addprefix; if (*nmax <= 1) return totallen; /* Write sign or "0x" */ if (flags & FLAG_ZERO_PAD) { if (addprefix == 2) /* 0x */ { if (*nmax > 1) { **pinsertion = '0'; *pinsertion += 1; *nmax -= 1; } if (*nmax > 1) { **pinsertion = fmt; *pinsertion += 1; *nmax -= 1; } } else if (addprefix == 1) /* sign */ { if (*nmax > 1) { **pinsertion = sign; *pinsertion += 1; *nmax -= 1; } } } /* Width pad */ if ( !(flags & FLAG_LEFT_ALIGN) ) { if (*nmax <= 1) widthpad = 0; else if ((int) *nmax + 1 < widthpad) widthpad = *nmax - 1; if (flags & FLAG_ZERO_PAD) memset(*pinsertion, '0', widthpad); else memset(*pinsertion, ' ', widthpad); *pinsertion += widthpad; *nmax -= widthpad; } /* Write sign or "0x" */ if ( !(flags & FLAG_ZERO_PAD) ) { if (addprefix == 2) /* 0x */ { if (*nmax > 1) { **pinsertion = '0'; *pinsertion += 1; *nmax -= 1; } if (*nmax > 1) { **pinsertion = fmt; *pinsertion += 1; *nmax -= 1; } } else if (addprefix == 1) /* sign */ { if (*nmax > 1) { **pinsertion = sign; *pinsertion += 1; *nmax -= 1; } } } /* Write number */ if (*nmax <= 1) len = 0; else if ((int) *nmax + 1 < len) len = *nmax - 1; for (; len > 0; len--) { char n = POP(); if (n <= 9) { **pinsertion = n + '0'; *pinsertion += 1; } else { **pinsertion = n - 10 + char10; *pinsertion += 1; } } *nmax -= len; if (flags & FLAG_LEFT_ALIGN) { if (*nmax <= 1) widthpad = 0; else if ((int) *nmax + 1 < widthpad) widthpad = *nmax - 1; memset(*pinsertion, ' ', widthpad); *pinsertion += widthpad; *nmax -= widthpad; } return totallen;}/* * WARNING: Assumes 32 bit longs and 64 bit doubles */typedef union { double D; struct { unsigned long W0; unsigned long W1; };} DBLBITS;#define EXP_MASK 0x7FF00000#define SIGN_MASK 0x80000000#define MANTISSA_MASK ~(SIGN_MASK | EXP_MASK)#define QNAN_MASK 0x00080000 /* first bit of mantissa */#ifdef SNPRINTF_FLOAT/* These functions not defined on all platforms, so * do the checks manually * WARNING: Assumes 64-bit IEEE representation * (so it won't run on your Cray :) */#define ISNAN(x) \ ( (((DBLBITS *) &x)->W1 & EXP_MASK) == EXP_MASK \ && ((((DBLBITS *) &x)->W1 & MANTISSA_MASK) != 0 || ((DBLBITS *) &x)->W0 != 0) )#define ISQNAN(x) \ ( ISNAN(x) && (((DBLBITS *) &x)->W1 & QNAN_MASK) )#define ISSNAN(x) \ ( ISNAN(x) && !ISQNAN(x) )#define ISINF(x) \ ( (((DBLBITS *) &x)->W1 & EXP_MASK) == EXP_MASK \ && ((((DBLBITS *) &x)->W1 & MANTISSA_MASK) == 0 && ((DBLBITS *) &x)->W0 == 0) )/* Format a double-precision float into the buffer. Parameters: * *&pinsertion Reference to pointer to buffer (can be reference to NULL) * &nmax Reference to size of buffer. This is may be modified * fmt Format character (one of "eEfgG") * flags 0 or combination of flags (see .h file for #defines) * width Width of double, as defined in printf * precision Precision of double, as defined in printf * ap Argument list */static int pvsnfmt_double(char **pinsertion, long *nmax, const char fmt, int flags, int width, int precision, char prefix, va_list *ap){ char *digits; int sign = 0; int dec; double value = va_arg(*ap, double); int len; int pad = 0; int signwidth = 0; int totallen; char signchar = 0; int leadingzeros = 0; int printdigits; /* temporary var used in different contexts */ /* Check for special values first */ char *special = 0; if (ISSNAN(value)) special = "NaN"; else if (ISQNAN(value)) special = "NaN"; else if ( ISINF(value) ) { if (value < 0) sign = 1; special = "Inf"; } if (special) { totallen = len = co_strlen(special); /* Sign (this is silly for NaN but conforming to printf */ if (flags & (FLAG_SIGNED | FLAG_SIGN_PAD) || sign) { if (sign) signchar = '-'; else if (flags & FLAG_SIGN_PAD) signchar = ' '; else signchar = '+'; totallen++; } /* Padding */ if (totallen < width) pad = width - totallen; else pad = 0; totallen += pad ; /* Sign now if zeropad */ if (flags & FLAG_ZERO_PAD && signchar) { if (*nmax > 1) { **pinsertion = signchar; *pinsertion += 1; *nmax -= 1; } } /* Right align */ if ( !(flags & FLAG_LEFT_ALIGN) ) { if (*nmax <= 1) pad = 0; else if ((int) *nmax - 1 < pad ) pad = *nmax - 1; if (flags & FLAG_ZERO_PAD) memset(*pinsertion, '0', pad ); else memset(*pinsertion, ' ', pad ); *pinsertion += pad ; *nmax -= pad ; } /* Sign now if not zeropad */ if (!(flags & FLAG_ZERO_PAD) && signchar) { if (*nmax > 1) { **pinsertion = signchar; *pinsertion += 1; *nmax -= 1; } } if (*nmax <= 0) len = 0; else if ((int) *nmax - 1 < len) len = *nmax - 1; memcpy(*pinsertion, special, len); *pinsertion += len; *nmax -= len; /* Left align */ if (flags & FLAG_LEFT_ALIGN) { if (*nmax <= 1) pad = 0; else if ((int) *nmax - 1 < pad ) pad = *nmax - 1; memset(*pinsertion, ' ', pad ); *pinsertion += pad ; *nmax -= pad ; } return totallen; } if (fmt == 'f') { if (precision == UNKNOWN_PRECISION) precision = 6; digits = FCVT(value, precision, &dec, &sign); len = co_strlen(digits); if (dec > 0) totallen = dec; else totallen = 0; /* plus 1 for decimal place */
if (dec <= 0) totallen += 2; /* and trailing ".0" */ else if (precision > 0 || flags & FLAG_HASH) totallen += 1;
/* Determine sign width (0 or 1) */ if (flags & (FLAG_SIGNED | FLAG_SIGN_PAD) || sign) { if (sign) signchar = '-'; else if (flags & FLAG_SIGN_PAD) signchar = ' '; else signchar = '+'; totallen++; } /* Determine if leading zeros required */ if (dec <= 0) { leadingzeros = 1 - dec; /* add one for zero before decimal point (0.) */ } if (leadingzeros - 1 > precision) totallen += precision; else if (len - dec > 0) totallen += precision; else totallen += leadingzeros; /* Determine padding width */ if (totallen < width) pad = width - totallen; totallen += pad; if (*nmax <= 1) return totallen; /* Now that the length has been calculated, print as much of it * as possible into the buffer */ /* Print sign now if padding with zeros */ if (flags & FLAG_ZERO_PAD && signchar != 0) { if (*nmax > 1) { **pinsertion = signchar; *pinsertion += 1; *nmax -= 1; } } /* Print width padding if right-aligned */ if ( !(flags & FLAG_LEFT_ALIGN) ) { if (*nmax <= 1) pad = 0; else if ((int) *nmax - 1 < pad) pad = *nmax - 1; if (flags & FLAG_ZERO_PAD) memset(*pinsertion, '0', pad); else memset(*pinsertion, ' ', pad); *pinsertion += pad; *nmax -= pad; } /* Print sign now if padding was spaces */ if ( !(flags & FLAG_ZERO_PAD) && signchar != 0 ) { **pinsertion = signchar; *pinsertion += 1; *nmax -= 1; } /* Print leading zeros */ if (leadingzeros) { /* Print "0.", then leadingzeros - 1 */ if (*nmax > 1) { **pinsertion = '0'; *pinsertion += 1; *nmax -= 1; } if (precision > 0 || flags & FLAG_HASH) { if (*nmax > 1) { **pinsertion = '.'; *pinsertion += 1; *nmax -= 1; } } /* WARNING not rounding here! * i.e. printf(".3f", 0.0007) gives "0.000" not "0.001" * * This whole function could do with a rewrite... */ if (leadingzeros - 1 > precision) { leadingzeros = precision + 1; len = 0; } /* END WARNING */ precision -= leadingzeros - 1; if (*nmax <= 1) leadingzeros = 0; else if ((int) *nmax /* - 1 */ < leadingzeros /* -1 */) leadingzeros = *nmax; /* -1 */ leadingzeros--; memset(*pinsertion, '0', leadingzeros); *pinsertion += leadingzeros; *nmax -= leadingzeros; } /* Print digits before decimal place */ if (dec > 0) { if (*nmax <= 1) printdigits = 0; else if ((int) *nmax - 1 < dec) printdigits = *nmax - 1; else printdigits = dec; memcpy(*pinsertion, digits, printdigits); *pinsertion += printdigits; *nmax -= printdigits; if (precision > 0 || flags & FLAG_HASH) { /* Print decimal place */ if (*nmax > 1) { **pinsertion = '.'; *pinsertion += 1; *nmax -= 1; } /* Print trailing zero if no precision but hash given */ if (precision == 0 && *nmax > 1) { **pinsertion = '0'; *pinsertion += 1; *nmax -= 1; } } /* Bypass the digits we've already printed */ len -= dec; digits += dec; } /* Print digits after decimal place */ if (len > precision) len = precision; if (*nmax <= 1) printdigits = 0; else if ((int) *nmax - 1 < len) printdigits = *nmax - 1; else printdigits = len; memcpy(*pinsertion, digits, printdigits); *pinsertion += printdigits; *nmax -= printdigits; /* Print left-aligned pad */ if (flags & FLAG_LEFT_ALIGN) { if (*nmax <= 1) pad = 0; else if ((int) *nmax - 1 < pad) pad = *nmax - 1; memset(*pinsertion, ' ', pad); *pinsertion += pad; *nmax -= pad; } return totallen; } return 0;}#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -