📄 trio.c.svn-base
字号:
case FORMAT_DOUBLE: if (TYPE_SCAN == type) { if (parameters[i].flags & FLAGS_LONGDOUBLE) parameters[i].data.longdoublePointer = (argarray == NULL) ? va_arg(*arglist, trio_long_double_t *) : (trio_long_double_t *)argarray[num]; else { if (parameters[i].flags & FLAGS_LONG) parameters[i].data.doublePointer = (argarray == NULL) ? va_arg(*arglist, double *) : (double *)argarray[num]; else parameters[i].data.doublePointer = (argarray == NULL) ? (double *)va_arg(*arglist, float *) : (double *)((float *)argarray[num]); } } else { if (parameters[i].flags & FLAGS_LONGDOUBLE) parameters[i].data.longdoubleNumber = (argarray == NULL) ? va_arg(*arglist, trio_long_double_t) : (trio_long_double_t)(*((trio_long_double_t *)argarray[num])); else { if (argarray == NULL) parameters[i].data.longdoubleNumber = (trio_long_double_t)va_arg(*arglist, double); else { if (parameters[i].flags & FLAGS_SHORT) parameters[i].data.longdoubleNumber = (trio_long_double_t)(*((float *)argarray[num])); else parameters[i].data.longdoubleNumber = (trio_long_double_t)(*((double *)argarray[num])); } } } break;#if defined(FORMAT_ERRNO) case FORMAT_ERRNO: parameters[i].data.errorNumber = save_errno; break;#endif default: break; } } /* for all specifiers */ return num;}/************************************************************************* * * FORMATTING * ************************************************************************//************************************************************************* * TrioWriteNumber * * Description: * Output a number. * The complexity of this function is a result of the complexity * of the dependencies of the flags. */TRIO_PRIVATE voidTrioWriteNumberTRIO_ARGS6((self, number, flags, width, precision, base), trio_class_t *self, trio_uintmax_t number, trio_flags_t flags, int width, int precision, int base){ BOOLEAN_T isNegative; BOOLEAN_T isNumberZero; BOOLEAN_T isPrecisionZero; BOOLEAN_T ignoreNumber; char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; char *bufferend; char *pointer; TRIO_CONST char *digits; int i; int length; char *p; int count; assert(VALID(self)); assert(VALID(self->OutStream)); assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; if (base == NO_BASE) base = BASE_DECIMAL; isNumberZero = (number == 0); isPrecisionZero = (precision == 0); ignoreNumber = (isNumberZero && isPrecisionZero && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL))); if (flags & FLAGS_UNSIGNED) { isNegative = FALSE; flags &= ~FLAGS_SHOWSIGN; } else { isNegative = ((trio_intmax_t)number < 0); if (isNegative) number = -((trio_intmax_t)number); } if (flags & FLAGS_QUAD) number &= (trio_ulonglong_t)-1; else if (flags & FLAGS_LONG) number &= (unsigned long)-1; else number &= (unsigned int)-1; /* Build number */ pointer = bufferend = &buffer[sizeof(buffer) - 1]; *pointer-- = NIL; for (i = 1; i < (int)sizeof(buffer); i++) { *pointer-- = digits[number % base]; number /= base; if (number == 0) break; if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1)) { /* * We are building the number from the least significant * to the most significant digit, so we have to copy the * thousand separator backwards */ length = internalThousandSeparatorLength; if (((int)(pointer - buffer) - length) > 0) { p = &internalThousandSeparator[length - 1]; while (length-- > 0) *pointer-- = *p--; } } } if (! ignoreNumber) { /* Adjust width */ width -= (bufferend - pointer) - 1; } /* Adjust precision */ if (NO_PRECISION != precision) { precision -= (bufferend - pointer) - 1; if (precision < 0) precision = 0; flags |= FLAGS_NILPADDING; } /* Calculate padding */ count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION))) ? precision : 0; /* Adjust width further */ if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) width--; if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero) { switch (base) { case BASE_BINARY: case BASE_HEX: width -= 2; break; case BASE_OCTAL: if (!(flags & FLAGS_NILPADDING) || (count == 0)) width--; break; default: break; } } /* Output prefixes spaces if needed */ if (! ((flags & FLAGS_LEFTADJUST) || ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION)))) { while (width-- > count) self->OutStream(self, CHAR_ADJUST); } /* width has been adjusted for signs and alternatives */ if (isNegative) self->OutStream(self, '-'); else if (flags & FLAGS_SHOWSIGN) self->OutStream(self, '+'); else if (flags & FLAGS_SPACE) self->OutStream(self, ' '); /* Prefix is not written when the value is zero */ if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero) { switch (base) { case BASE_BINARY: self->OutStream(self, '0'); self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b'); break; case BASE_OCTAL: if (!(flags & FLAGS_NILPADDING) || (count == 0)) self->OutStream(self, '0'); break; case BASE_HEX: self->OutStream(self, '0'); self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); break; default: break; } /* switch base */ } /* Output prefixed zero padding if needed */ if (flags & FLAGS_NILPADDING) { if (precision == NO_PRECISION) precision = width; while (precision-- > 0) { self->OutStream(self, '0'); width--; } } if (! ignoreNumber) { /* Output the number itself */ while (*(++pointer)) { self->OutStream(self, *pointer); } } /* Output trailing spaces if needed */ if (flags & FLAGS_LEFTADJUST) { while (width-- > 0) self->OutStream(self, CHAR_ADJUST); }}/************************************************************************* * TrioWriteStringCharacter * * Description: * Output a single character of a string */TRIO_PRIVATE voidTrioWriteStringCharacterTRIO_ARGS3((self, ch, flags), trio_class_t *self, int ch, trio_flags_t flags){ if (flags & FLAGS_ALTERNATIVE) { if (! isprint(ch)) { /* * Non-printable characters are converted to C escapes or * \number, if no C escape exists. */ self->OutStream(self, CHAR_BACKSLASH); switch (ch) { case '\007': self->OutStream(self, 'a'); break; case '\b': self->OutStream(self, 'b'); break; case '\f': self->OutStream(self, 'f'); break; case '\n': self->OutStream(self, 'n'); break; case '\r': self->OutStream(self, 'r'); break; case '\t': self->OutStream(self, 't'); break; case '\v': self->OutStream(self, 'v'); break; case '\\': self->OutStream(self, '\\'); break; default: self->OutStream(self, 'x'); TrioWriteNumber(self, (trio_uintmax_t)ch, FLAGS_UNSIGNED | FLAGS_NILPADDING, 2, 2, BASE_HEX); break; } } else if (ch == CHAR_BACKSLASH) { self->OutStream(self, CHAR_BACKSLASH); self->OutStream(self, CHAR_BACKSLASH); } else { self->OutStream(self, ch); } } else { self->OutStream(self, ch); }}/************************************************************************* * TrioWriteString * * Description: * Output a string */TRIO_PRIVATE voidTrioWriteStringTRIO_ARGS5((self, string, flags, width, precision), trio_class_t *self, TRIO_CONST char *string, trio_flags_t flags, int width, int precision){ int length; int ch; assert(VALID(self)); assert(VALID(self->OutStream)); if (string == NULL) { string = internalNullString; length = sizeof(internalNullString) - 1; /* Disable quoting for the null pointer */ flags &= (~FLAGS_QUOTE); width = 0; } else { length = trio_length(string); } if ((NO_PRECISION != precision) && (precision < length)) { length = precision; } width -= length; if (flags & FLAGS_QUOTE) self->OutStream(self, CHAR_QUOTE); if (! (flags & FLAGS_LEFTADJUST)) { while (width-- > 0) self->OutStream(self, CHAR_ADJUST); } while (length-- > 0) { /* The ctype parameters must be an unsigned char (or EOF) */ ch = (int)((unsigned char)(*string++)); TrioWriteStringCharacter(self, ch, flags); } if (flags & FLAGS_LEFTADJUST) { while (width-- > 0) self->OutStream(self, CHAR_ADJUST); } if (flags & FLAGS_QUOTE) self->OutStream(self, CHAR_QUOTE);}/************************************************************************* * TrioWriteWideStringCharacter * * Description: * Output a wide string as a multi-byte sequence */#if TRIO_WIDECHARTRIO_PRIVATE intTrioWriteWideStringCharacterTRIO_ARGS4((self, wch, flags, width), trio_class_t *self, trio_wchar_t wch, trio_flags_t flags, int width){ int size; int i; int ch; char *string; char buffer[MB_LEN_MAX + 1]; if (width == NO_WIDTH) width = sizeof(buffer); size = wctomb(buffer, wch); if ((size <= 0) || (size > width) || (buffer[0] == NIL)) return 0; string = buffer; i = size; while ((width >= i) && (width-- > 0) && (i-- > 0)) { /* The ctype parameters must be an unsigned char (or EOF) */ ch = (int)((unsigned char)(*string++)); TrioWriteStringCharacter(self, ch, flags); } return size;}#endif /* TRIO_WIDECHAR *//************************************************************************* * TrioWriteWideString * * Description: * Output a wide character string as a multi-byte string */#if TRIO_WIDECHARTRIO_PRIVATE voidTrioWriteWideStringTRIO_ARGS5((self, wstring, flags, width, precision), trio_class_t *self, TRIO_CONST trio_wchar_t *wstring, trio_flags_t flags, int width, int precision){ int length; int size; assert(VALID(self)); assert(VALID(self->OutStream));#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) (void)mblen(NULL, 0);#endif if (wstring == NULL) { TrioWriteString(self, NULL, flags, width, precision); return; } if (NO_PRECISION == precision) { length = INT_MAX; } else { length = precision; width -= length; } if (flags & FLAGS_QUOTE) self->OutStream(self, CHAR_QUOTE); if (! (flags & FLAGS_LEFTADJUST)) { while (width-- > 0) self->OutStream(self, CHAR_ADJUST); } while (length > 0) { size = TrioWriteWideStringCharacter(self, *wstring++, flags, length); if (size == 0) break; /* while */ length -= size; } if (flags & FLAGS_LEFTADJUST) { while (width-- > 0) self->OutStream(self, CHAR_ADJUST); } if (flags & FLAGS_QUOTE) self->OutStream(self, CHAR_QUOTE);}#endif /* TRIO_WIDECHAR *//************************************************************************* * TrioWriteDouble * * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm * * "5.2.4.2.2 paragraph #4 * * The accuracy [...] is implementation defined, as is the accuracy * of the conversion between floating-point internal representations * and string representations performed by the libray routine in * <stdio.h>" *//* FIXME: handle all instances of constant long-double number (L) * and *l() math functions. */TRIO_PRIVATE voidTrioWriteDoubleTRIO_ARGS6((self, number, flags, width, precision, base), trio_class_t *se
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -