📄 trio.c
字号:
{ if (parameters[i].flags & FLAGS_LONG) parameters[i].data.longdoublePointer = (arglist != NULL) ? va_arg(arglist, long double *) : (long double *)((long double *)argarray[num]); else { if (arglist != NULL) parameters[i].data.doublePointer = va_arg(arglist, double *); else { if (parameters[i].flags & FLAGS_SHORT) parameters[i].data.doublePointer = (double *)((float *)argarray[num]); else parameters[i].data.doublePointer = (double *)((double *)argarray[num]); } } } else { if (parameters[i].flags & FLAGS_LONG) parameters[i].data.longdoubleNumber = (arglist != NULL) ? va_arg(arglist, long double) : (long double)(*((long double *)argarray[num])); else { if (arglist != NULL) parameters[i].data.longdoubleNumber = (long double)va_arg(arglist, double); else { if (parameters[i].flags & FLAGS_SHORT) parameters[i].data.longdoubleNumber = (long double)(*((float *)argarray[num])); else parameters[i].data.longdoubleNumber = (long double)(long double)(*((double *)argarray[num])); } } } break;#if defined(FORMAT_ERRNO) case FORMAT_ERRNO: parameters[i].data.errorNumber = errno; break;#endif default: break; } } /* for all specifiers */ return num;}/************************************************************************* * * @FORMATTING * ************************************************************************//************************************************************************* * TrioWriteNumber [private] * * Description: * Output a number. * The complexity of this function is a result of the complexity * of the dependencies of the flags. */static voidTrioWriteNumber(trio_T *self, SLONGEST number, unsigned long flags, int width, int precision, int base){ BOOLEAN_T isNegative; char buffer[MAX_CHARS_IN(LONGEST) * MAX_LOCALE_SEPARATOR_LENGTH * MAX_LOCALE_GROUPS]; char *bufferend; char *pointer; const char *digits; int i; int length; char *p; int charsPerThousand; int groupingIndex; 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 (flags & FLAGS_UNSIGNED) isNegative = FALSE; else if ((isNegative = (((SLONGEST)number) < 0))) number = -number; if (flags & FLAGS_QUAD) number &= (ULONGLONG)-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; charsPerThousand = (int)internalGrouping[0]; groupingIndex = 1; for (i = 1; i < (int)sizeof(buffer); i++) { *pointer-- = digits[number % base]; number /= base; if (number == 0) break; if ((flags & FLAGS_QUOTE) && (charsPerThousand != NO_GROUPING) && (i % charsPerThousand == 0)) { /* * We are building the number from the least significant * to the most significant digit, so we have to copy the * thousand separator backwards */ length = StrLength(internalThousandSeparator); if (((int)(pointer - buffer) - length) > 0) { p = &internalThousandSeparator[length - 1]; while (length-- > 0) *pointer-- = *p--; } /* Advance to next grouping number */ switch (internalGrouping[groupingIndex]) { case CHAR_MAX: /* Disable grouping */ charsPerThousand = NO_GROUPING; break; case 0: /* Repeat last group */ break; default: charsPerThousand = (int)internalGrouping[groupingIndex++]; break; } } } /* Adjust width */ width -= (bufferend - pointer) - 1; /* Adjust precision */ if (NO_PRECISION != precision) { precision -= (bufferend - pointer) - 1; if (precision < 0) precision = 0; flags |= FLAGS_NILPADDING; } /* Adjust width further */ if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) width--; if (flags & FLAGS_ALTERNATIVE) { switch (base) { case BASE_BINARY: case BASE_HEX: width -= 2; break; case BASE_OCTAL: width--; break; default: break; } } /* Output prefixes spaces if needed */ if (! ((flags & FLAGS_LEFTADJUST) || ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION)))) { count = (precision == NO_PRECISION) ? 0 : 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, ' '); if (flags & FLAGS_ALTERNATIVE) { switch (base) { case BASE_BINARY: self->OutStream(self, '0'); self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b'); break; case BASE_OCTAL: 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--; } } /* 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); }}/************************************************************************* * TrioWriteString [private] * * Description: * Output a string */static voidTrioWriteString(trio_T *self, const char *string, unsigned long flags, int width, int precision){ int length; int ch; assert(VALID(self)); assert(VALID(self->OutStream)); if (string == NULL) { string = null; length = sizeof(null) - 1; /* Disable quoting for the null pointer */ flags &= (~FLAGS_QUOTE); width = 0; } else { length = StrLength(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 = (unsigned char)(*string++); if (flags & FLAGS_ALTERNATIVE) { if (! (isprint(ch) || isspace(ch))) { /* * Non-printable characters are converted to C escapes or * \number, if no C escape exists. */ self->OutStream(self, CHAR_BACKSLASH); switch (ch) { case '\a': 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, (SLONGEST)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); } } if (flags & FLAGS_LEFTADJUST) { while (width-- > 0) self->OutStream(self, CHAR_ADJUST); } if (flags & FLAGS_QUOTE) self->OutStream(self, CHAR_QUOTE);}/************************************************************************* * TrioWriteDouble [private] */static voidTrioWriteDouble(trio_T *self, long double longdoubleNumber, unsigned long flags, int width, int precision, int base){ int charsPerThousand; int length; double number; double precisionPower; double workNumber; int integerDigits; int fractionDigits; int exponentDigits; int expectedWidth; int exponent; unsigned int uExponent = 0; double dblBase; BOOLEAN_T isNegative; BOOLEAN_T isExponentNegative = FALSE; BOOLEAN_T isHex; const char *digits; char numberBuffer[MAX_CHARS_IN(double) * MAX_LOCALE_SEPARATOR_LENGTH * MAX_LOCALE_GROUPS]; char *numberPointer; char exponentBuffer[MAX_CHARS_IN(double)]; char *exponentPointer = NULL; int groupingIndex; char *work; int i; BOOLEAN_T onlyzero; int set_precision = precision; assert(VALID(self)); assert(VALID(self->OutStream)); assert(base == BASE_DECIMAL || base == BASE_HEX); number = (double)longdoubleNumber; #if defined(USE_NON_NUMBERS) /* Look for infinite numbers and non-a-number first */ switch (TrioIsInfinite(number)) { case 1: /* Positive infinity */ TrioWriteString(self, (flags & FLAGS_UPPER) ? INFINITE_UPPER : INFINITE_LOWER, flags, width, precision); return; case -1: /* Negative infinity */ TrioWriteString(self, (flags & FLAGS_UPPER) ? "-" INFINITE_UPPER : "-" INFINITE_LOWER, flags, width, precision); return; default: /* Finitude */ break; } if (TrioIsNan(number)) { TrioWriteString(self, (flags & FLAGS_UPPER) ? NAN_UPPER : NAN_LOWER, flags, width, precision); return; }#endif /* defined(USE_NON_NUMBERS) */ /* Normal numbers */ digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; isHex = (base == BASE_HEX); dblBase = (double)base; if (precision == NO_PRECISION) precision = FLT_DIG; precisionPower = pow(10.0, (double)precision); isNegative = (number < 0.0); if (isNegative) number = -number; if ((flags & FLAGS_FLOAT_G) || isHex) { if ((number < 1.0e-4) || (number > precisionPower)) flags |= FLAGS_FLOAT_E;#if defined(TRIO_UNIX98) if (precision == 0) precision = 1;#endif } if (flags & FLAGS_FLOAT_E) { /* Scale the number */ workNumber = log10(number); if (workNumber == -HUGE_VAL) { exponent = 0; /* Undo setting */ if (flags & FLAGS_FLOAT_G) flags &= ~FLAGS_FLOAT_E; } else { exponent = (int)floor(workNumber); number /= pow(10.0, (double)exponent); isExponentNegative = (exponent < 0); uExponent = (isExponentNegative) ? -exponent : exponent; /* No thousand separators */ flags &= ~FLAGS_QUOTE; } } /* * Truncated number. * * precision is number of significant digits for FLOAT_G * and number of fractional digits for others */ integerDigits = (floor(number) > DBL_EPSILON) ? 1 + (int)log10(floor(number)) : 1; fractionDigits = (flags & FLAGS_FLOAT_G) ? precision - integerDigits : precision; number = floor(0.5 + number * pow(10.0, (double)fractionDigits)); if ((int)log10(number) + 1 > integerDigits + fractionDigits) { /* Adjust if number was rounded up one digit (ie. 99 to 100) */ integerDigits++; } /* Build the fraction part */ numberPointer = &numberBuffer[sizeof(numberBuffer) - 1]; *numberPointer = NIL; onlyzero = TRUE; for (i = 0; i < fractionDigits; i++) { *(--numberPointer) = digits[(int)fmod(number, dblBase)]; number = floor(number / dblBase); if((set_precision == NO_PRECISION) || (flags & FLAGS_ALTERNATIVE)) { /* Prune trailing zeroes */ if (numberPointer[0] != digits[0]) onlyzero = FALSE; else if (onlyzero && (numberPointer[0] == digits[0])) numberPointer++; } else onlyzero = FALSE; } /* Insert decimal point */ if ((flags & FLAGS_ALTERNATIVE) || ((fractionDigits > 0) && !onlyzero)) { i = StrLength(internalDecimalPoint); while (i> 0) { *(--numberPointer) = internalDecimalPoint[--i]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -