Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/ntp/libntp/snprintf.c
Show First 20 Lines • Show All 883 Lines • ▼ Show 20 Lines | case PRINT_S_CONV: | ||||
(UINTPTR_T)strvalue, 16, width, | (UINTPTR_T)strvalue, 16, width, | ||||
precision, flags); | precision, flags); | ||||
} | } | ||||
break; | break; | ||||
case 'n': | case 'n': | ||||
switch (cflags) { | switch (cflags) { | ||||
case PRINT_C_CHAR: | case PRINT_C_CHAR: | ||||
charptr = va_arg(args, signed char *); | charptr = va_arg(args, signed char *); | ||||
*charptr = len; | *charptr = (signed char)len; | ||||
break; | break; | ||||
case PRINT_C_SHORT: | case PRINT_C_SHORT: | ||||
shortptr = va_arg(args, short int *); | shortptr = va_arg(args, short int *); | ||||
*shortptr = len; | *shortptr = (short int)len; | ||||
break; | break; | ||||
case PRINT_C_LONG: | case PRINT_C_LONG: | ||||
longptr = va_arg(args, long int *); | longptr = va_arg(args, long int *); | ||||
*longptr = len; | *longptr = (long int)len; | ||||
break; | break; | ||||
case PRINT_C_LLONG: | case PRINT_C_LLONG: | ||||
llongptr = va_arg(args, LLONG *); | llongptr = va_arg(args, LLONG *); | ||||
*llongptr = len; | *llongptr = (LLONG)len; | ||||
break; | break; | ||||
case PRINT_C_SIZE: | case PRINT_C_SIZE: | ||||
/* | /* | ||||
* C99 says that with the "z" length | * C99 says that with the "z" length | ||||
* modifier, "a following `n' conversion | * modifier, "a following `n' conversion | ||||
* specifier applies to a pointer to a | * specifier applies to a pointer to a | ||||
* signed integer type corresponding to | * signed integer type corresponding to | ||||
* size_t argument." (7.19.6.1, 7) | * size_t argument." (7.19.6.1, 7) | ||||
*/ | */ | ||||
sizeptr = va_arg(args, SSIZE_T *); | sizeptr = va_arg(args, SSIZE_T *); | ||||
*sizeptr = len; | *sizeptr = (SSIZE_T)len; | ||||
break; | break; | ||||
case PRINT_C_INTMAX: | case PRINT_C_INTMAX: | ||||
intmaxptr = va_arg(args, INTMAX_T *); | intmaxptr = va_arg(args, INTMAX_T *); | ||||
*intmaxptr = len; | *intmaxptr = (INTMAX_T)len; | ||||
break; | break; | ||||
case PRINT_C_PTRDIFF: | case PRINT_C_PTRDIFF: | ||||
ptrdiffptr = va_arg(args, PTRDIFF_T *); | ptrdiffptr = va_arg(args, PTRDIFF_T *); | ||||
*ptrdiffptr = len; | *ptrdiffptr = (PTRDIFF_T)len; | ||||
break; | break; | ||||
default: | default: | ||||
intptr = va_arg(args, int *); | intptr = va_arg(args, int *); | ||||
*intptr = len; | *intptr = (int)len; | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
case '%': /* Print a "%" character verbatim. */ | case '%': /* Print a "%" character verbatim. */ | ||||
OUTCHAR(str, len, size, ch); | OUTCHAR(str, len, size, ch); | ||||
break; | break; | ||||
default: /* Skip other characters. */ | default: /* Skip other characters. */ | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 268 Lines • ▼ Show 20 Lines | if ((intpart = cast(ufvalue)) == UINTMAX_MAX) { | ||||
*overflow = 1; | *overflow = 1; | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Factor of ten with the number of digits needed for the fractional | * Factor of ten with the number of digits needed for the fractional | ||||
* part. For example, if the precision is 3, the mask will be 1000. | * part. For example, if the precision is 3, the mask will be 1000. | ||||
*/ | */ | ||||
mask = mypow10(precision); | mask = (UINTMAX_T)mypow10(precision); | ||||
/* | /* | ||||
* We "cheat" by converting the fractional part to integer by | * We "cheat" by converting the fractional part to integer by | ||||
* multiplying by a factor of ten. | * multiplying by a factor of ten. | ||||
*/ | */ | ||||
if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { | if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { | ||||
/* | /* | ||||
* For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 | * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 | ||||
* (because precision = 3). Now, myround(1000 * 0.99962) will | * (because precision = 3). Now, myround(1000 * 0.99962) will | ||||
▲ Show 20 Lines • Show All 235 Lines • ▼ Show 20 Lines | cast(LDOUBLE value) | ||||
* represented exactly as an LDOUBLE value (but is less than LDBL_MAX), | * represented exactly as an LDOUBLE value (but is less than LDBL_MAX), | ||||
* it may be increased to the nearest higher representable value for the | * it may be increased to the nearest higher representable value for the | ||||
* comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE | * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE | ||||
* value although converting the latter to UINTMAX_T would overflow. | * value although converting the latter to UINTMAX_T would overflow. | ||||
*/ | */ | ||||
if (value >= UINTMAX_MAX) | if (value >= UINTMAX_MAX) | ||||
return UINTMAX_MAX; | return UINTMAX_MAX; | ||||
result = value; | result = (UINTMAX_T)value; | ||||
/* | /* | ||||
* At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to | * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to | ||||
* an integer type converts e.g. 1.9 to 2 instead of 1 (which violates | * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates | ||||
* the standard). Sigh. | * the standard). Sigh. | ||||
*/ | */ | ||||
return (result <= value) ? result : result - 1; | return (result <= value) ? result : result - 1; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 660 Lines • Show Last 20 Lines |