📄 trio.c
字号:
} /* Insert the integer part and thousand separators */ charsPerThousand = (int)internalGrouping[0]; groupingIndex = 1; for (i = 1; i < integerDigits + 1; i++) { *(--numberPointer) = digits[(int)fmod(number, dblBase)]; number = floor(number / dblBase); if (number < DBL_EPSILON) break; if ((i > 0) && ((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == 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); integerDigits += length; if (((int)(numberPointer - numberBuffer) - length) > 0) { work = &internalThousandSeparator[length - 1]; while (length-- > 0) *(--numberPointer) = *work--; } /* Advance to next grouping number */ if (charsPerThousand != NO_GROUPING) { switch (internalGrouping[groupingIndex]) { case CHAR_MAX: /* Disable grouping */ charsPerThousand = NO_GROUPING; break; case 0: /* Repeat last group */ break; default: charsPerThousand = (int)internalGrouping[groupingIndex++]; break; } } } } /* Build the exponent */ exponentDigits = 0; if (flags & FLAGS_FLOAT_E) { exponentPointer = &exponentBuffer[sizeof(exponentBuffer) - 1]; *exponentPointer-- = NIL; do { *exponentPointer-- = digits[uExponent % base]; uExponent /= base; exponentDigits++; } while (uExponent); } /* * Calculate expected width. * sign + integer part + thousands separators + decimal point * + fraction + exponent */ expectedWidth = StrLength(numberPointer); if (isNegative || (flags & FLAGS_SHOWSIGN)) expectedWidth += sizeof("-") - 1; if (exponentDigits > 0) expectedWidth += exponentDigits + sizeof("E+") - 1; if (isExponentNegative) expectedWidth += sizeof('-') - 1; if (isHex) expectedWidth += sizeof("0X") - 1; /* Output prefixing */ if (flags & FLAGS_NILPADDING) { /* Leading zeros must be after sign */ if (isNegative) self->OutStream(self, '-'); else if (flags & FLAGS_SHOWSIGN) self->OutStream(self, '+'); if (isHex) { self->OutStream(self, '0'); self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); } if (!(flags & FLAGS_LEFTADJUST)) { for (i = expectedWidth; i < width; i++) { self->OutStream(self, '0'); } } } else { /* Leading spaces must be before sign */ if (!(flags & FLAGS_LEFTADJUST)) { for (i = expectedWidth; i < width; i++) { self->OutStream(self, CHAR_ADJUST); } } if (isNegative) self->OutStream(self, '-'); else if (flags & FLAGS_SHOWSIGN) self->OutStream(self, '+'); if (isHex) { self->OutStream(self, '0'); self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); } } /* Output number */ for (i = 0; numberPointer[i]; i++) { self->OutStream(self, numberPointer[i]); } /* Output exponent */ if (exponentDigits > 0) { self->OutStream(self, isHex ? ((flags & FLAGS_UPPER) ? 'P' : 'p') : ((flags & FLAGS_UPPER) ? 'E' : 'e')); self->OutStream(self, (isExponentNegative) ? '-' : '+'); for (i = 0; i < exponentDigits; i++) { self->OutStream(self, exponentPointer[i + 1]); } } /* Output trailing spaces */ if (flags & FLAGS_LEFTADJUST) { for (i = expectedWidth; i < width; i++) { self->OutStream(self, CHAR_ADJUST); } }}/************************************************************************* * TrioFormatProcess [private] */static intTrioFormatProcess(trio_T *data, const char *format, parameter_T *parameters){#if defined(USE_MULTIBYTE) int charlen;#endif int i; const char *string; void *pointer; unsigned long flags; int width; int precision; int base; int index; index = 0; i = 0;#if defined(USE_MULTIBYTE) mblen(NULL, 0);#endif while (format[index]) {#if defined(USE_MULTIBYTE) if (! isascii(format[index])) { charlen = mblen(&format[index], MB_LEN_MAX); while (charlen-- > 0) { data->OutStream(data, format[index++]); } continue; /* while */ }#endif /* defined(USE_MULTIBYTE) */ if (CHAR_IDENTIFIER == format[index]) { if (CHAR_IDENTIFIER == format[index + 1]) { data->OutStream(data, CHAR_IDENTIFIER); index += 2; } else { /* Skip the parameter entries */ while (parameters[i].type == FORMAT_PARAMETER) i++; flags = parameters[i].flags; /* Find width */ width = parameters[i].width; if (flags & FLAGS_WIDTH_PARAMETER) { /* Get width from parameter list */ width = (int)parameters[width].data.number.as_signed; } /* Find precision */ if (flags & FLAGS_PRECISION) { precision = parameters[i].precision; if (flags & FLAGS_PRECISION_PARAMETER) { /* Get precision from parameter list */ precision = (int)parameters[precision].data.number.as_signed; } } else { precision = NO_PRECISION; } /* Find base */ base = parameters[i].base; if (flags & FLAGS_BASE_PARAMETER) { /* Get base from parameter list */ base = (int)parameters[base].data.number.as_signed; } switch (parameters[i].type) { case FORMAT_CHAR: if (flags & FLAGS_QUOTE) data->OutStream(data, CHAR_QUOTE); if (! (flags & FLAGS_LEFTADJUST)) { while (--width > 0) data->OutStream(data, CHAR_ADJUST); } data->OutStream(data, (char)parameters[i].data.number.as_signed); if (flags & FLAGS_LEFTADJUST) { while(--width > 0) data->OutStream(data, CHAR_ADJUST); } if (flags & FLAGS_QUOTE) data->OutStream(data, CHAR_QUOTE); break; /* FORMAT_CHAR */ case FORMAT_INT: if (base == NO_BASE) base = BASE_DECIMAL; TrioWriteNumber(data, parameters[i].data.number.as_signed, flags, width, precision, base); break; /* FORMAT_INT */ case FORMAT_DOUBLE: TrioWriteDouble(data, parameters[i].data.longdoubleNumber, flags, width, precision, base); break; /* FORMAT_DOUBLE */ case FORMAT_STRING: TrioWriteString(data, parameters[i].data.string, flags, width, precision); break; /* FORMAT_STRING */ case FORMAT_POINTER: { reference_T reference; reference.data = data; reference.parameter = ¶meters[i]; trio_print_pointer(&reference, parameters[i].data.pointer); } break; /* FORMAT_POINTER */ case FORMAT_COUNT: pointer = parameters[i].data.pointer; if (NULL != pointer) { /* * C99 paragraph 7.19.6.1.8 says "the number of * characters written to the output stream so far by * this call", which is data->committed */#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) if (flags & FLAGS_SIZE_T) *(size_t *)pointer = (size_t)data->committed; else#endif#if defined(QUALIFIER_PTRDIFF_T) if (flags & FLAGS_PTRDIFF_T) *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed; else#endif#if defined(QUALIFIER_INTMAX_T) if (flags & FLAGS_INTMAX_T) *(intmax_t *)pointer = (intmax_t)data->committed; else#endif if (flags & FLAGS_QUAD) { *(ULONGLONG int *)pointer = (ULONGLONG)data->committed; } else if (flags & FLAGS_LONG) { *(long int *)pointer = (long int)data->committed; } else if (flags & FLAGS_SHORT) { *(short int *)pointer = (short int)data->committed; } else { *(int *)pointer = (int)data->committed; } } break; /* FORMAT_COUNT */ case FORMAT_PARAMETER: break; /* FORMAT_PARAMETER */#if defined(FORMAT_ERRNO) case FORMAT_ERRNO: string = StrError(parameters[i].data.errorNumber); if (string) { TrioWriteString(data, string, flags, width, precision); } else { data->OutStream(data, '#'); TrioWriteNumber(data, (SLONGEST)parameters[i].data.errorNumber, flags, width, precision, BASE_DECIMAL); } break; /* FORMAT_ERRNO */#endif /* defined(FORMAT_ERRNO) */#if defined(FORMAT_USER_DEFINED) case FORMAT_USER_DEFINED: { reference_T reference; userdef_T *def = NULL; if (parameters[i].user_name[0] == NIL) { /* Use handle */ if ((i > 0) || (parameters[i - 1].type == FORMAT_PARAMETER)) def = (userdef_T *)parameters[i - 1].data.pointer; } else { /* Look up namespace */ def = TrioFindNamespace(parameters[i].user_name, NULL); } if (def) { reference.data = data; reference.parameter = ¶meters[i]; def->callback(&reference); } } break;#endif /* defined(FORMAT_USER_DEFINED) */ default: break; } /* switch parameter type */ /* Prepare for next */ index = parameters[i].indexAfterSpecifier; i++; } } else /* not identifier */ { data->OutStream(data, format[index++]); } } return data->processed;}/************************************************************************* * TrioFormatRef [private] */static intTrioFormatRef(reference_T *reference, const char *format, va_list arglist, void **argarray){ int status; parameter_T parameters[MAX_PARAMETERS]; status = TrioPreprocess(TYPE_PRINT, format, parameters, arglist, argarray); if (status < 0) return status; return TrioFormatProcess(reference->data, format, parameters);}/************************************************************************* * TrioFormat [private] * * Description: * This is the main engine for formatting output */static intTrioFormat(void *destination, size_t destinationSize, void (*OutStream)(trio_T *, int), const char *format, va_list arglist, void **argarray){ int status; trio_T data; parameter_T parameters[MAX_PARAMETERS]; assert(VALID(OutStream)); assert(VALID(format)); assert(VALID(arglist) || VALID(argarray)); memset(&data, 0, sizeof(data)); data.OutStream = OutStream; data.location = destination; data.max = destinationSize;#if defined(USE_LOCALE) if (NULL == internalLocaleValues) { TrioSetLocale(); }#endif status = TrioPreprocess(TYPE_PRINT, format, parameters, arglist, argarray); if (status < 0) return status; return TrioFormatProcess(&data, format, parameters);}/************************************************************************* * TrioOutStreamFile [private] */static voidTrioOutStreamFile(trio_T *self, int output){ FILE *file = (FILE *)self->location; assert(VALID(self)); assert(VALID(file)); self->processed++; self->committed++; (void)fputc(output, file);}/************************************************************************* * TrioOutStreamFileDescriptor [private] */static voidTrioOutStreamFileDescriptor(trio_T *self, int output){ int fd = *((int *)self->location); char ch; assert(VALID(self)); ch = (char)output; (void)write(fd, &ch, sizeof(char)); self->processed++; self->committed++;}/************************************************************************* * TrioOutStreamString [private] */static voidTrioOutStreamString(trio_T *self, int output){ char **buffer = (char **)self->location; assert(VALID(self)); assert(VALID(buffer)); **buffer = (char)output; (*buffer)++; self->processed++; self->committed++;}/************************************************************************* * TrioOutStreamStringMax [private] */static voidTrioOutStreamStringMax(tr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -