📄 vasnprintf.c
字号:
+ 1 /* turn floor into ceil */ + precision + 10; /* sign, decimal point etc. */ break; case 'e': case 'E': case 'g': case 'G': case 'a': case 'A': tmp_length = precision + 12; /* sign, decimal point, exponent etc. */ break; case 'c':# ifdef HAVE_WINT_T if (type == TYPE_WIDE_CHAR) tmp_length = MB_CUR_MAX; else# endif tmp_length = 1; break; case 's':# ifdef HAVE_WCHAR_T if (type == TYPE_WIDE_STRING) tmp_length = wcslen (a.arg[dp->arg_index].a.a_wide_string) * MB_CUR_MAX; else# endif tmp_length = strlen (a.arg[dp->arg_index].a.a_string); break; case 'p': tmp_length = (unsigned int) (sizeof (void *) * CHAR_BIT * 0.25 /* binary -> hexadecimal */ ) + 1 /* turn floor into ceil */ + 2; /* account for leading 0x */ break; default: abort (); } if (tmp_length < width) tmp_length = width; tmp_length++; /* account for trailing NUL */ } if (tmp_length <= sizeof (tmpbuf)) tmp = tmpbuf; else { tmp = (char *) malloc (tmp_length); if (tmp == NULL) { /* Out of memory. */ if (!(result == resultbuf || result == NULL)) free (result); freea (buf); CLEANUP (); errno = ENOMEM; return NULL; } }#endif /* Construct the format string for calling snprintf or sprintf. */ p = buf; *p++ = '%'; if (dp->flags & FLAG_GROUP) *p++ = '\''; if (dp->flags & FLAG_LEFT) *p++ = '-'; if (dp->flags & FLAG_SHOWSIGN) *p++ = '+'; if (dp->flags & FLAG_SPACE) *p++ = ' '; if (dp->flags & FLAG_ALT) *p++ = '#'; if (dp->flags & FLAG_ZERO) *p++ = '0'; if (dp->width_start != dp->width_end) { size_t n = dp->width_end - dp->width_start; memcpy (p, dp->width_start, n); p += n; } if (dp->precision_start != dp->precision_end) { size_t n = dp->precision_end - dp->precision_start; memcpy (p, dp->precision_start, n); p += n; } switch (type) {#ifdef HAVE_INT64_AND_I64 case TYPE_INT64: case TYPE_UINT64: *p++ = 'I'; *p++ = '6'; *p++ = '4'; break;#endif#ifdef HAVE_LONG_LONG case TYPE_LONGLONGINT: case TYPE_ULONGLONGINT:#ifdef HAVE_INT64_AND_I64 /* The system (sn)printf uses %I64. Also assume * that long long == __int64. */ *p++ = 'I'; *p++ = '6'; *p++ = '4'; break;#else *p++ = 'l'; /*FALLTHROUGH*/#endif#endif case TYPE_LONGINT: case TYPE_ULONGINT:#ifdef HAVE_WINT_T case TYPE_WIDE_CHAR:#endif#ifdef HAVE_WCHAR_T case TYPE_WIDE_STRING:#endif *p++ = 'l'; break;#ifdef HAVE_LONG_DOUBLE case TYPE_LONGDOUBLE: *p++ = 'L'; break;#endif default: break; } *p = dp->conversion;#if HAVE_SNPRINTF p[1] = '%'; p[2] = 'n'; p[3] = '\0';#else p[1] = '\0';#endif /* Construct the arguments for calling snprintf or sprintf. */ prefix_count = 0; if (dp->width_arg_index >= 0) { if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; } if (dp->precision_arg_index >= 0) { if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) abort (); prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int; }#if HAVE_SNPRINTF /* Prepare checking whether snprintf returns the count via %n. */ ENSURE_ALLOCATION (length + 1); result[length] = '\0';#endif for (;;) { size_t maxlen; int count; int retcount; maxlen = allocated - length; count = -1; retcount = 0;#if HAVE_SNPRINTF#define SNPRINTF_BUF(arg) \ switch (prefix_count) \ { \ case 0: \ retcount = snprintf (result + length, maxlen, buf, \ arg, &count); \ break; \ case 1: \ retcount = snprintf (result + length, maxlen, buf, \ prefixes[0], arg, &count); \ break; \ case 2: \ retcount = snprintf (result + length, maxlen, buf, \ prefixes[0], prefixes[1], arg, \ &count); \ break; \ default: \ abort (); \ }#else#define SNPRINTF_BUF(arg) \ switch (prefix_count) \ { \ case 0: \ count = sprintf (tmp, buf, arg); \ break; \ case 1: \ count = sprintf (tmp, buf, prefixes[0], arg); \ break; \ case 2: \ count = sprintf (tmp, buf, prefixes[0], prefixes[1],\ arg); \ break; \ default: \ abort (); \ }#endif switch (type) { case TYPE_SCHAR: { int arg = a.arg[dp->arg_index].a.a_schar; SNPRINTF_BUF (arg); } break; case TYPE_UCHAR: { unsigned int arg = a.arg[dp->arg_index].a.a_uchar; SNPRINTF_BUF (arg); } break; case TYPE_SHORT: { int arg = a.arg[dp->arg_index].a.a_short; SNPRINTF_BUF (arg); } break; case TYPE_USHORT: { unsigned int arg = a.arg[dp->arg_index].a.a_ushort; SNPRINTF_BUF (arg); } break; case TYPE_INT: { int arg = a.arg[dp->arg_index].a.a_int; SNPRINTF_BUF (arg); } break; case TYPE_UINT: { unsigned int arg = a.arg[dp->arg_index].a.a_uint; SNPRINTF_BUF (arg); } break; case TYPE_LONGINT: { long int arg = a.arg[dp->arg_index].a.a_longint; SNPRINTF_BUF (arg); } break; case TYPE_ULONGINT: { unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint; SNPRINTF_BUF (arg); } break;#ifdef HAVE_INT64_AND_I64 case TYPE_INT64: { __int64 arg = a.arg[dp->arg_index].a.a_int64; SNPRINTF_BUF (arg); } break; case TYPE_UINT64: { unsigned __int64 arg = a.arg[dp->arg_index].a.a_uint64; SNPRINTF_BUF (arg); } break; #endif#ifdef HAVE_LONG_LONG#ifndef HAVE_LONG_LONG_FORMAT case TYPE_LONGLONGINT: case TYPE_ULONGLONGINT: { unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint; int width; int precision; width = 0; if (dp->width_start != dp->width_end) { if (dp->width_arg_index >= 0) { int arg; if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; width = (arg < 0 ? -arg : arg); } else { const char *digitp = dp->width_start; do width = width * 10 + (*digitp++ - '0'); while (digitp != dp->width_end); } } precision = -1; if (dp->precision_start != dp->precision_end) { if (dp->precision_arg_index >= 0) { int arg; if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->precision_arg_index].a.a_int; precision = (arg < 0 ? 0 : arg); } else { const char *digitp = dp->precision_start + 1; precision = 0; do precision = precision * 10 + (*digitp++ - '0'); while (digitp != dp->precision_end); } } count = print_long_long (result + length, maxlen, width, precision, dp->flags, dp->conversion, arg); } break;#else case TYPE_LONGLONGINT: { long long int arg = a.arg[dp->arg_index].a.a_longlongint; SNPRINTF_BUF (arg); } break; case TYPE_ULONGLONGINT: { unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint; SNPRINTF_BUF (arg); } break;#endif#endif case TYPE_DOUBLE: { double arg = a.arg[dp->arg_index].a.a_double; SNPRINTF_BUF (arg); } break;#ifdef HAVE_LONG_DOUBLE case TYPE_LONGDOUBLE: { long double arg = a.arg[dp->arg_index].a.a_longdouble; SNPRINTF_BUF (arg); } break;#endif case TYPE_CHAR: { int arg = a.arg[dp->arg_index].a.a_char; SNPRINTF_BUF (arg); } break;#ifdef HAVE_WINT_T case TYPE_WIDE_CHAR: { wint_t arg = a.arg[dp->arg_index].a.a_wide_char; SNPRINTF_BUF (arg); } break;#endif case TYPE_STRING: { const char *arg = a.arg[dp->arg_index].a.a_string; SNPRINTF_BUF (arg); } break;#ifdef HAVE_WCHAR_T case TYPE_WIDE_STRING: { const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; SNPRINTF_BUF (arg); } break;#endif case TYPE_POINTER: { void *arg = a.arg[dp->arg_index].a.a_pointer; SNPRINTF_BUF (arg); } break; default: abort (); }#if HAVE_SNPRINTF /* Portability: Not all implementations of snprintf() are ISO C 99 compliant. Determine the number of bytes that snprintf() has produced or would have produced. */ if (count >= 0) { /* Verify that snprintf() has NUL-terminated its result. */ if (count < maxlen && result[length + count] != '\0') abort (); /* Portability hack. */ if (retcount > count) count = retcount; } else { /* snprintf() doesn't understand the '%n' directive. */ if (p[1] != '\0') { /* Don't use the '%n' directive; instead, look at the snprintf() return value. */ p[1] = '\0'; continue; } count = retcount; }#endif /* Attempt to handle failure. */ if (count < 0) { if (!(result == resultbuf || result == NULL)) free (result); freea (buf); CLEANUP (); errno = EINVAL; return NULL; }#if !HAVE_SNPRINTF if (count >= tmp_length) /* tmp_length was incorrectly calculated - fix the code above! */ abort ();#endif /* Make room for the result. */ if (count >= maxlen) { /* Need at least count bytes. But allocate proportionally, to avoid looping eternally if snprintf() reports a too small count. */ size_t n = length + count; if (n < 2 * allocated) n = 2 * allocated; ENSURE_ALLOCATION (n);#if HAVE_SNPRINTF continue;#endif }#if HAVE_SNPRINTF /* The snprintf() result did fit. */#else /* Append the sprintf() result. */ memcpy (result + length, tmp, count); if (tmp != tmpbuf) free (tmp);#endif length += count; break; } } } } /* Add the final NUL. */ ENSURE_ALLOCATION (length + 1); result[length] = '\0'; if (result != resultbuf && length + 1 < allocated) { /* Shrink the allocated memory if possible. */ char *memory; memory = (char *) realloc (result, length + 1); if (memory != NULL) result = memory; } freea (buf); CLEANUP (); *lengthp = length; return result; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -