📄 trio.c
字号:
}#endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */#if TRIO_FEATURE_QUOTETRIO_PRIVATE BOOLEAN_TTrioFollowedBySeparatorTRIO_ARGS1((position), int position){ int step = 0; char *groupingPointer = internalGrouping; position--; if (position == 0) return FALSE; while (position > 0) { if (*groupingPointer == CHAR_MAX) { /* Disable grouping */ break; /* while */ } else if (*groupingPointer != 0) { step = *groupingPointer++; } if (step == 0) break; position -= step; } return (position == 0);}#endif /* TRIO_FEATURE_QUOTE *//************************************************************************* * TrioGetPosition * * Get the %n$ position. */TRIO_PRIVATE intTrioGetPositionTRIO_ARGS2((format, indexPointer), TRIO_CONST char *format, int *indexPointer){#if TRIO_FEATURE_POSITIONAL char *tmpformat; int number = 0; int index = *indexPointer; number = (int)trio_to_long(&format[index], &tmpformat, BASE_DECIMAL); index = (int)(tmpformat - format); if ((number != 0) && (QUALIFIER_POSITION == format[index++])) { *indexPointer = index; /* * number is decreased by 1, because n$ starts from 1, whereas * the array it is indexing starts from 0. */ return number - 1; }#endif return NO_POSITION;}/************************************************************************* * TrioFindNamespace * * Find registered user-defined specifier. * The prev argument is used for optimization only. */#if TRIO_FEATURE_USER_DEFINEDTRIO_PRIVATE trio_userdef_t *TrioFindNamespaceTRIO_ARGS2((name, prev), TRIO_CONST char *name, trio_userdef_t **prev){ trio_userdef_t *def; if (internalEnterCriticalRegion) (void)internalEnterCriticalRegion(NULL); for (def = internalUserDef; def; def = def->next) { /* Case-sensitive string comparison */ if (trio_equal_case(def->name, name)) break; if (prev) *prev = def; } if (internalLeaveCriticalRegion) (void)internalLeaveCriticalRegion(NULL); return def;}#endif/************************************************************************* * TrioPower * * Description: * Calculate pow(base, exponent), where number and exponent are integers. */#if TRIO_FEATURE_FLOATTRIO_PRIVATE trio_long_double_tTrioPowerTRIO_ARGS2((number, exponent), int number, int exponent){ trio_long_double_t result; if (number == 10) { switch (exponent) { /* Speed up calculation of common cases */ case 0: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1); break; case 1: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0); break; case 2: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1); break; case 3: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2); break; case 4: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3); break; case 5: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4); break; case 6: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5); break; case 7: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6); break; case 8: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7); break; case 9: result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8); break; default: result = trio_powl((trio_long_double_t)number, (trio_long_double_t)exponent); break; } } else { return trio_powl((trio_long_double_t)number, (trio_long_double_t)exponent); } return result;}#endif /* TRIO_FEATURE_FLOAT *//************************************************************************* * TrioLogarithm */#if TRIO_FEATURE_FLOATTRIO_PRIVATE doubleTrioLogarithmTRIO_ARGS2((number, base), double number, int base){ double result; if (number <= 0.0) { /* xlC crashes on log(0) */ result = (number == 0.0) ? trio_ninf() : trio_nan(); } else { if (base == 10) { result = log10(number); } else { result = log10(number) / log10((double)base); } } return result;}#endif /* TRIO_FEATURE_FLOAT *//************************************************************************* * TrioLogarithmBase */#if TRIO_FEATURE_FLOATTRIO_PRIVATE doubleTrioLogarithmBaseTRIO_ARGS1((base), int base){ switch (base) { case BASE_BINARY : return 1.0; case BASE_OCTAL : return 3.0; case BASE_DECIMAL: return 3.321928094887362345; case BASE_HEX : return 4.0; default : return TrioLogarithm((double)base, 2); }}#endif /* TRIO_FEATURE_FLOAT *//************************************************************************* * TrioParse * * Description: * Parse the format string */TRIO_PRIVATE intTrioParseTRIO_ARGS5((type, format, parameters, arglist, argarray), int type, TRIO_CONST char *format, trio_parameter_t *parameters, va_list arglist, trio_pointer_t *argarray){ /* Count the number of times a parameter is referenced */ unsigned short usedEntries[MAX_PARAMETERS]; /* Parameter counters */ int parameterPosition; int currentParam; int maxParam = -1; /* Utility variables */ trio_flags_t flags; int width; int precision; int varsize; int base; int index; /* Index into formatting string */ int dots; /* Count number of dots in modifier part */ BOOLEAN_T positional; /* Does the specifier have a positional? */ BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */ /* * indices specifies the order in which the parameters must be * read from the va_args (this is necessary to handle positionals) */ int indices[MAX_PARAMETERS]; int pos = 0; /* Various variables */ char ch;#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) int charlen;#endif int save_errno; int i = -1; int num; char *tmpformat; /* * The 'parameters' array is not initialized, but we need to * know which entries we have used. */ memset(usedEntries, 0, sizeof(usedEntries)); save_errno = errno; index = 0; parameterPosition = 0;#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) (void)mblen(NULL, 0);#endif while (format[index]) {#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) if (! isascii(format[index])) { /* * Multibyte characters cannot be legal specifiers or * modifiers, so we skip over them. */ charlen = mblen(&format[index], MB_LEN_MAX); index += (charlen > 0) ? charlen : 1; continue; /* while */ }#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ if (CHAR_IDENTIFIER == format[index++]) { if (CHAR_IDENTIFIER == format[index]) { index++; continue; /* while */ } flags = FLAGS_NEW; dots = 0; currentParam = TrioGetPosition(format, &index); positional = (NO_POSITION != currentParam); if (!positional) { /* We have no positional, get the next counter */ currentParam = parameterPosition; } if(currentParam >= MAX_PARAMETERS) { /* Bail out completely to make the error more obvious */ return TRIO_ERROR_RETURN(TRIO_ETOOMANY, index); } if (currentParam > maxParam) maxParam = currentParam; /* Default values */ width = NO_WIDTH; precision = NO_PRECISION; base = NO_BASE; varsize = NO_SIZE; while (TrioIsQualifier(format[index])) { ch = format[index++]; switch (ch) { case QUALIFIER_SPACE: flags |= FLAGS_SPACE; break; case QUALIFIER_PLUS: flags |= FLAGS_SHOWSIGN; break; case QUALIFIER_MINUS: flags |= FLAGS_LEFTADJUST; flags &= ~FLAGS_NILPADDING; break; case QUALIFIER_ALTERNATIVE: flags |= FLAGS_ALTERNATIVE; break; case QUALIFIER_DOT: if (dots == 0) /* Precision */ { dots++; /* Skip if no precision */ if (QUALIFIER_DOT == format[index]) break; /* After the first dot we have the precision */ flags |= FLAGS_PRECISION; if ((QUALIFIER_STAR == format[index])#if defined(QUALIFIER_PARAM) || (QUALIFIER_PARAM == format[index])#endif ) { index++; flags |= FLAGS_PRECISION_PARAMETER; precision = TrioGetPosition(format, &index); if (precision == NO_POSITION) { parameterPosition++; if (positional) precision = parameterPosition; else { precision = currentParam; currentParam = precision + 1; } } else { if (! positional) currentParam = precision + 1; if (width > maxParam) maxParam = precision; } if (currentParam > maxParam) maxParam = currentParam; } else { precision = trio_to_long(&format[index], &tmpformat, BASE_DECIMAL); index = (int)(tmpformat - format); } } else if (dots == 1) /* Base */ { dots++; /* After the second dot we have the base */ flags |= FLAGS_BASE; if ((QUALIFIER_STAR == format[index])#if defined(QUALIFIER_PARAM) || (QUALIFIER_PARAM == format[index])#endif ) { index++; flags |= FLAGS_BASE_PARAMETER; base = TrioGetPosition(format, &index); if (base == NO_POSITION) { parameterPosition++; if (positional) base = parameterPosition; else { base = currentParam; currentParam = base + 1; } } else { if (! positional) currentParam = base + 1; if (base > maxParam) maxParam = base; } if (currentParam > maxParam) maxParam = currentParam; } else { base = trio_to_long(&format[index], &tmpformat, BASE_DECIMAL); if (base > MAX_BASE) return TRIO_ERROR_RETURN(TRIO_EINVAL, index); index = (int)(tmpformat - format); } } else { return TRIO_ERROR_RETURN(TRIO_EINVAL, index); } break; /* QUALIFIER_DOT */#if defined(QUALIFIER_PARAM) case QUALIFIER_PARAM: type = TYPE_PRINT; /* FALLTHROUGH */#endif case QUALIFIER_STAR: /* This has different meanings for print and scan */ if (TYPE_PRINT == type) { /* Read with from parameter */ flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER); width = TrioGetPosition(format, &index); if (width == NO_POSITION) { parameterPosition++; if (positional) width = parameterPosition; else { width = currentParam; currentParam = width + 1; } } else { if (! positional) currentParam = width + 1; if (width > maxParam) maxParam = width; } if (currentParam > maxParam) maxParam = currentParam; }#if TRIO_FEATURE_SCANF else { /* Scan, but do not store result */ flags |= FLAGS_IGNORE; }#endif break; /* QUALIFIER_STAR */ case '0': if (! (flags & FLAGS_LEFTADJUST)) flags |= FLAGS_NILPADDING; /* FALLTHROUGH */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': flags |= FLAGS_WIDTH; /* &format[index - 1] is used to "rewind" the read * character from format */ width = trio_to_long(&format[index - 1], &tmpformat, BASE_DECIMAL); index = (int)(tmpformat - format); break; case QUALIFIER_SHORT: if (flags & FLAGS_SHORTSHORT) return TRIO_ERROR_RETURN(TRIO_EINVAL, index); else if (flags & FLAGS_SHORT) flags |= FLAGS_SHORTSHORT; else flags |= FLAGS_SHORT; break; case QUALIFIER_LONG: if (flags & FLAGS_QUAD) return TRIO_ERROR_RETURN(TRIO_EINVAL, index); else if (flags & FLAGS_LONG) flags |= FLAGS_QUAD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -