📄 trio.c.svn-base
字号:
flags |= FLAGS_VARSIZE_PARAMETER; parameterPosition++; if (positional) varsize = parameterPosition; else { varsize = currentParam; currentParam = varsize + 1; } if (currentParam > maxParam) maxParam = currentParam; break;#endif#if defined(QUALIFIER_ROUNDING_UPPER) case QUALIFIER_ROUNDING_UPPER: flags |= FLAGS_ROUNDING; break;#endif default: /* Bail out completely to make the error more obvious */ return TRIO_ERROR_RETURN(TRIO_EINVAL, index); } } /* while qualifier */ /* * Parameters only need the type and value. The value is * read later. */ if (flags & FLAGS_WIDTH_PARAMETER) { usedEntries[width] += 1; parameters[pos].type = FORMAT_PARAMETER; parameters[pos].flags = 0; indices[width] = pos; width = pos++; } if (flags & FLAGS_PRECISION_PARAMETER) { usedEntries[precision] += 1; parameters[pos].type = FORMAT_PARAMETER; parameters[pos].flags = 0; indices[precision] = pos; precision = pos++; } if (flags & FLAGS_BASE_PARAMETER) { usedEntries[base] += 1; parameters[pos].type = FORMAT_PARAMETER; parameters[pos].flags = 0; indices[base] = pos; base = pos++; } if (flags & FLAGS_VARSIZE_PARAMETER) { usedEntries[varsize] += 1; parameters[pos].type = FORMAT_PARAMETER; parameters[pos].flags = 0; indices[varsize] = pos; varsize = pos++; } indices[currentParam] = pos; switch (format[index++]) {#if defined(SPECIFIER_CHAR_UPPER) case SPECIFIER_CHAR_UPPER: flags |= FLAGS_WIDECHAR; /* FALLTHROUGH */#endif case SPECIFIER_CHAR: if (flags & FLAGS_LONG) flags |= FLAGS_WIDECHAR; else if (flags & FLAGS_SHORT) flags &= ~FLAGS_WIDECHAR; parameters[pos].type = FORMAT_CHAR; break;#if defined(SPECIFIER_STRING_UPPER) case SPECIFIER_STRING_UPPER: flags |= FLAGS_WIDECHAR; /* FALLTHROUGH */#endif case SPECIFIER_STRING: if (flags & FLAGS_LONG) flags |= FLAGS_WIDECHAR; else if (flags & FLAGS_SHORT) flags &= ~FLAGS_WIDECHAR; parameters[pos].type = FORMAT_STRING; break; case SPECIFIER_GROUP: if (TYPE_SCAN == type) { int depth = 1; parameters[pos].type = FORMAT_GROUP; if (format[index] == QUALIFIER_CIRCUMFLEX) index++; if (format[index] == SPECIFIER_UNGROUP) index++; if (format[index] == QUALIFIER_MINUS) index++; /* Skip nested brackets */ while (format[index] != NIL) { if (format[index] == SPECIFIER_GROUP) { depth++; } else if (format[index] == SPECIFIER_UNGROUP) { if (--depth <= 0) { index++; break; } } index++; } } break; case SPECIFIER_INTEGER: parameters[pos].type = FORMAT_INT; break; case SPECIFIER_UNSIGNED: flags |= FLAGS_UNSIGNED; parameters[pos].type = FORMAT_INT; break; case SPECIFIER_DECIMAL: /* Disable base modifier */ flags &= ~FLAGS_BASE_PARAMETER; base = BASE_DECIMAL; parameters[pos].type = FORMAT_INT; break; case SPECIFIER_OCTAL: flags |= FLAGS_UNSIGNED; flags &= ~FLAGS_BASE_PARAMETER; base = BASE_OCTAL; parameters[pos].type = FORMAT_INT; break;#if defined(SPECIFIER_BINARY) case SPECIFIER_BINARY_UPPER: flags |= FLAGS_UPPER; /* FALLTHROUGH */ case SPECIFIER_BINARY: flags |= FLAGS_NILPADDING; flags &= ~FLAGS_BASE_PARAMETER; base = BASE_BINARY; parameters[pos].type = FORMAT_INT; break;#endif case SPECIFIER_HEX_UPPER: flags |= FLAGS_UPPER; /* FALLTHROUGH */ case SPECIFIER_HEX: flags |= FLAGS_UNSIGNED; flags &= ~FLAGS_BASE_PARAMETER; base = BASE_HEX; parameters[pos].type = FORMAT_INT; break; case SPECIFIER_FLOAT_E_UPPER: flags |= FLAGS_UPPER; /* FALLTHROUGH */ case SPECIFIER_FLOAT_E: flags |= FLAGS_FLOAT_E; parameters[pos].type = FORMAT_DOUBLE; break; case SPECIFIER_FLOAT_G_UPPER: flags |= FLAGS_UPPER; /* FALLTHROUGH */ case SPECIFIER_FLOAT_G: flags |= FLAGS_FLOAT_G; parameters[pos].type = FORMAT_DOUBLE; break; case SPECIFIER_FLOAT_F_UPPER: flags |= FLAGS_UPPER; /* FALLTHROUGH */ case SPECIFIER_FLOAT_F: parameters[pos].type = FORMAT_DOUBLE; break; case SPECIFIER_POINTER: if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t)) flags |= FLAGS_QUAD; else if (sizeof(trio_pointer_t) == sizeof(long)) flags |= FLAGS_LONG; parameters[pos].type = FORMAT_POINTER; break; case SPECIFIER_COUNT: parameters[pos].type = FORMAT_COUNT; break;#if defined(SPECIFIER_HEXFLOAT)# if defined(SPECIFIER_HEXFLOAT_UPPER) case SPECIFIER_HEXFLOAT_UPPER: flags |= FLAGS_UPPER; /* FALLTHROUGH */# endif case SPECIFIER_HEXFLOAT: base = BASE_HEX; parameters[pos].type = FORMAT_DOUBLE; break;#endif#if defined(FORMAT_ERRNO) case SPECIFIER_ERRNO: parameters[pos].type = FORMAT_ERRNO; break;#endif#if defined(SPECIFIER_USER_DEFINED_BEGIN) case SPECIFIER_USER_DEFINED_BEGIN: { unsigned int max; int without_namespace = TRUE; parameters[pos].type = FORMAT_USER_DEFINED; parameters[pos].user_name[0] = NIL; tmpformat = (char *)&format[index]; while ((ch = format[index])) { index++; if (ch == SPECIFIER_USER_DEFINED_END) { if (without_namespace) { /* We must get the handle first */ parameters[pos].type = FORMAT_PARAMETER; parameters[pos].indexAfterSpecifier = index; parameters[pos].flags = FLAGS_USER_DEFINED; /* Adjust parameters for insertion of new one */ pos++; usedEntries[currentParam] += 1; parameters[pos].type = FORMAT_USER_DEFINED; currentParam++; indices[currentParam] = pos; if (currentParam > maxParam) maxParam = currentParam; } /* Copy the user data */ max = (unsigned int)(&format[index] - tmpformat); if (max > MAX_USER_DATA) max = MAX_USER_DATA; trio_copy_max(parameters[pos].user_data, max, tmpformat); break; /* while */ } if (ch == SPECIFIER_USER_DEFINED_SEPARATOR) { without_namespace = FALSE; /* Copy the namespace for later looking-up */ max = (int)(&format[index] - tmpformat); if (max > MAX_USER_NAME) max = MAX_USER_NAME; trio_copy_max(parameters[pos].user_name, max, tmpformat); tmpformat = (char *)&format[index]; } } if (ch != SPECIFIER_USER_DEFINED_END) return TRIO_ERROR_RETURN(TRIO_EINVAL, index); } break;#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */ default: /* Bail out completely to make the error more obvious */ return TRIO_ERROR_RETURN(TRIO_EINVAL, index); } /* Count the number of times this entry has been used */ usedEntries[currentParam] += 1; /* Find last sticky parameters */ if (gotSticky && !(flags & FLAGS_STICKY)) { for (i = pos - 1; i >= 0; i--) { if (parameters[i].type == FORMAT_PARAMETER) continue; if ((parameters[i].flags & FLAGS_STICKY) && (parameters[i].type == parameters[pos].type)) { /* Do not overwrite current qualifiers */ flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY); if (width == NO_WIDTH) width = parameters[i].width; if (precision == NO_PRECISION) precision = parameters[i].precision; if (base == NO_BASE) base = parameters[i].base; break; } } } parameters[pos].indexAfterSpecifier = index; parameters[pos].flags = flags; parameters[pos].width = width; parameters[pos].precision = precision; parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base; parameters[pos].varsize = varsize; pos++; if (! positional) parameterPosition++; } /* if identifier */ } /* while format characters left */ for (num = 0; num <= maxParam; num++) { if (usedEntries[num] != 1) { if (usedEntries[num] == 0) /* gap detected */ return TRIO_ERROR_RETURN(TRIO_EGAP, num); else /* double references detected */ return TRIO_ERROR_RETURN(TRIO_EDBLREF, num); } i = indices[num]; /* * FORMAT_PARAMETERS are only present if they must be read, * so it makes no sense to check the ignore flag (besides, * the flags variable is not set for that particular type) */ if ((parameters[i].type != FORMAT_PARAMETER) && (parameters[i].flags & FLAGS_IGNORE)) continue; /* for all arguments */ /* * The stack arguments are read according to ANSI C89 * default argument promotions: * * char = int * short = int * unsigned char = unsigned int * unsigned short = unsigned int * float = double * * In addition to the ANSI C89 these types are read (the * default argument promotions of C99 has not been * considered yet) * * long long * long double * size_t * ptrdiff_t * intmax_t */ switch (parameters[i].type) { case FORMAT_GROUP: case FORMAT_STRING:#if TRIO_WIDECHAR if (flags & FLAGS_WIDECHAR) { parameters[i].data.wstring = (argarray == NULL) ? va_arg(*arglist, trio_wchar_t *) : (trio_wchar_t *)(argarray[num]); } else#endif { parameters[i].data.string = (argarray == NULL) ? va_arg(*arglist, char *) : (char *)(argarray[num]); } break;#if defined(FORMAT_USER_DEFINED) case FORMAT_USER_DEFINED:#endif case FORMAT_POINTER: case FORMAT_COUNT: case FORMAT_UNKNOWN: parameters[i].data.pointer = (argarray == NULL) ? va_arg(*arglist, trio_pointer_t ) : argarray[num]; break; case FORMAT_CHAR: case FORMAT_INT: if (TYPE_SCAN == type) { if (argarray == NULL) parameters[i].data.pointer = (trio_pointer_t)va_arg(*arglist, trio_pointer_t); else { if (parameters[i].type == FORMAT_CHAR) parameters[i].data.pointer = (trio_pointer_t)((char *)argarray[num]); else if (parameters[i].flags & FLAGS_SHORT) parameters[i].data.pointer = (trio_pointer_t)((short *)argarray[num]); else parameters[i].data.pointer = (trio_pointer_t)((int *)argarray[num]); } } else {#if defined(QUALIFIER_VARSIZE) || defined(QUALIFIER_FIXED_SIZE) if (parameters[i].flags & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE)) { if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER) { /* * Variable sizes are mapped onto the fixed sizes, in * accordance with integer promotion. * * Please note that this may not be portable, as we * only guess the size, not the layout of the numbers. * For example, if int is little-endian, and long is * big-endian, then this will fail. */ varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned; } else { /* Used for the I<bits> modifiers */ varsize = parameters[i].varsize; } parameters[i].flags &= ~FLAGS_ALL_VARSIZES; if (varsize <= (int)sizeof(int)) ; else if (varsize <= (int)sizeof(long)) parameters[i].flags |= FLAGS_LONG;#if defined(QUALIFIER_INTMAX_T) else if (varsize <= (int)sizeof(trio_longlong_t)) parameters[i].flags |= FLAGS_QUAD; else parameters[i].flags |= FLAGS_INTMAX_T;#else else parameters[i].flags |= FLAGS_QUAD;#endif }#endif /* defined(QUALIFIER_VARSIZE) */#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) if (parameters[i].flags & FLAGS_SIZE_T) parameters[i].data.number.as_unsigned = (argarray == NULL) ? (trio_uintmax_t)va_arg(*arglist, size_t) : (trio_uintmax_t)(*((size_t *)argarray[num])); else#endif#if defined(QUALIFIER_PTRDIFF_T) if (parameters[i].flags & FLAGS_PTRDIFF_T) parameters[i].data.number.as_unsigned = (argarray == NULL) ? (trio_uintmax_t)va_arg(*arglist, ptrdiff_t) : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num])); else#endif#if defined(QUALIFIER_INTMAX_T) if (parameters[i].flags & FLAGS_INTMAX_T) parameters[i].data.number.as_unsigned = (argarray == NULL) ? (trio_uintmax_t)va_arg(*arglist, trio_intmax_t) : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num])); else#endif if (parameters[i].flags & FLAGS_QUAD) parameters[i].data.number.as_unsigned = (argarray == NULL) ? (trio_uintmax_t)va_arg(*arglist, trio_ulonglong_t) : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num])); else if (parameters[i].flags & FLAGS_LONG) parameters[i].data.number.as_unsigned = (argarray == NULL) ? (trio_uintmax_t)va_arg(*arglist, long) : (trio_uintmax_t)(*((long *)argarray[num])); else { if (argarray == NULL) parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int); else { if (parameters[i].type == FORMAT_CHAR) parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num])); else if (parameters[i].flags & FLAGS_SHORT) parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num])); else parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num])); } } } break; case FORMAT_PARAMETER: /* * The parameter for the user-defined specifier is a pointer, * whereas the rest (width, precision, base) uses an integer. */ if (parameters[i].flags & FLAGS_USER_DEFINED) parameters[i].data.pointer = (argarray == NULL) ? va_arg(*arglist, trio_pointer_t ) : argarray[num]; else parameters[i].data.number.as_unsigned = (argarray == NULL) ? (trio_uintmax_t)va_arg(*arglist, int) : (trio_uintmax_t)(*((int *)argarray[num])); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -