From: Paul Eggert Date: Fri, 27 Jun 2025 15:45:53 +0000 (-0700) Subject: od: support uintmax_t too X-Git-Tag: v9.8~274 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=274226dbff6866b130bc69b84a7b7c8c00c3264d;p=thirdparty%2Fcoreutils.git od: support uintmax_t too This has practical effect only on hypothetical platforms where uintmax_t is wider than unsigned long long int. * src/od.c (enum size_spec): New constant INTMAX. (MAX_INTEGRAL_TYPE_WIDTH): Now equals UINTMAX_WIDTH. (FMT_BYTES_ALLOCATED): Allow for the extra "l" in "%lld". Also, fix off-by-two error in size calculation. (width_bytes, integral_type_size): Add entries for uintmax_t. (print_intmax): New function. (decode_one_function): Use it. (ISPEC_TO_FORMAT): New arg Max_fmt. All uses changed. --- diff --git a/src/od.c b/src/od.c index 54869a32c5..27eb1ad417 100644 --- a/src/od.c +++ b/src/od.c @@ -71,7 +71,7 @@ enum size_spec INT, LONG, LONG_LONG, - /* FIXME: add INTMAX support, too */ + INTMAX, FLOAT_HALF, FLOAT_SINGLE, FLOAT_DOUBLE, @@ -92,7 +92,7 @@ enum output_format CHARACTER }; -enum { MAX_INTEGRAL_TYPE_WIDTH = ULLONG_WIDTH }; +enum { MAX_INTEGRAL_TYPE_WIDTH = UINTMAX_WIDTH }; /* The maximum number of bytes needed for a format string, including the trailing nul. Each format string expects a variable amount of @@ -101,8 +101,8 @@ enum { MAX_INTEGRAL_TYPE_WIDTH = ULLONG_WIDTH }; enum { FMT_BYTES_ALLOCATED = - (sizeof "%*.99" + 1 - + MAX (sizeof "ld", + (sizeof "%*.99" - 1 + + MAX (sizeof "lld", MAX (sizeof "jd", MAX (sizeof "jo", MAX (sizeof "ju", @@ -167,6 +167,7 @@ static const int width_bytes[] = sizeof (int), sizeof (long int), sizeof (unsigned long long int), + sizeof (uintmax_t), #if BF16_SUPPORTED sizeof (bfloat16), #else @@ -292,8 +293,11 @@ static enum size_spec const integral_type_size[] = #if UINT_MAX < ULONG_MAX [sizeof (unsigned long int)] = LONG, #endif -#if ULONG_MAX < ULLONG_MAX +#if ULONG_MAX < ULLONG_MAX && ULLONG_MAX < UINTMAX_MAX [sizeof (unsigned long long int)] = LONG_LONG, +#endif +#if ULONG_MAX < UINTMAX_MAX + [sizeof (uintmax_t)] = INTMAX, #endif }; @@ -561,6 +565,7 @@ PRINT_TYPE (print_short, unsigned short int) PRINT_TYPE (print_int, unsigned int) PRINT_TYPE (print_long, unsigned long int) PRINT_TYPE (print_long_long, unsigned long long int) +PRINT_TYPE (print_intmax, uintmax_t) PRINT_FLOATTYPE (print_bfloat, bfloat16, ftoastr, FLT_BUFSIZE_BOUND) PRINT_FLOATTYPE (print_halffloat, float16, ftoastr, FLT_BUFSIZE_BOUND) @@ -783,10 +788,11 @@ decode_one_format (char const *s_orig, char const *s, char const **next, break; } -#define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format) \ - ((Spec) == LONG_LONG ? (Max_format) \ - : ((Spec) == LONG ? (Long_format) \ - : (Min_format))) \ +#define ISPEC_TO_FORMAT(Spec, Min_fmt, Long_fmt, Long_long_fmt, Max_fmt) \ + ((Spec) == INTMAX ? (Max_fmt) \ + : (Spec) == LONG_LONG ? (Long_long_fmt) \ + : (Spec) == LONG ? (Long_fmt) \ + : (Min_fmt)) size_spec = integral_type_size[size]; @@ -796,28 +802,28 @@ decode_one_format (char const *s_orig, char const *s, char const **next, fmt = SIGNED_DECIMAL; field_width = bytes_to_signed_dec_digits[size]; sprintf (tspec->fmt_string, "%%*%s", - ISPEC_TO_FORMAT (size_spec, "d", "ld", "jd")); + ISPEC_TO_FORMAT (size_spec, "d", "ld", "lld", "jd")); break; case 'o': fmt = OCTAL; sprintf (tspec->fmt_string, "%%*.%d%s", (field_width = bytes_to_oct_digits[size]), - ISPEC_TO_FORMAT (size_spec, "o", "lo", "jo")); + ISPEC_TO_FORMAT (size_spec, "o", "lo", "llo", "jo")); break; case 'u': fmt = UNSIGNED_DECIMAL; field_width = bytes_to_unsigned_dec_digits[size]; sprintf (tspec->fmt_string, "%%*%s", - ISPEC_TO_FORMAT (size_spec, "u", "lu", "ju")); + ISPEC_TO_FORMAT (size_spec, "u", "lu", "llu", "ju")); break; case 'x': fmt = HEXADECIMAL; sprintf (tspec->fmt_string, "%%*.%d%s", (field_width = bytes_to_hex_digits[size]), - ISPEC_TO_FORMAT (size_spec, "x", "lx", "jx")); + ISPEC_TO_FORMAT (size_spec, "x", "lx", "llx", "jx")); break; default: @@ -850,6 +856,10 @@ decode_one_format (char const *s_orig, char const *s, char const **next, print_function = print_long_long; break; + case INTMAX: + print_function = print_intmax; + break; + default: affirm (false); }