Make terminal write's automatic number width less surprising

This commit is contained in:
Stefan Rueger 2022-11-10 19:38:21 +00:00
parent 4c92030e3a
commit 2434c3f7f6
No known key found for this signature in database
GPG Key ID: B0B4F1FD86B1EC55
3 changed files with 42 additions and 27 deletions

View File

@ -866,15 +866,19 @@ always treated as unsigned. +0x or -0x hex numbers are treated as signed
unless they have a U suffix. Unsigned integers cannot be larger than 2^64-1. unless they have a U suffix. Unsigned integers cannot be larger than 2^64-1.
If n is an unsigned integer then -n is also a valid unsigned integer as in C. If n is an unsigned integer then -n is also a valid unsigned integer as in C.
Signed integers must fall into the [-2^63, 2^63-1] range or a correspondingly Signed integers must fall into the [-2^63, 2^63-1] range or a correspondingly
smaller range when a suffix specifies a smaller type. Out of range signed smaller range when a suffix specifies a smaller type.
numbers trigger a warning.
.Pp .Pp
Ordinary 0x hex integers with n hex digits (counting leading zeros) use the Ordinary 0x hex integers with n hex digits (counting leading zeros) use the
smallest size of 1, 2, 4 and 8 bytes that can accommodate any n-digit hex smallest size of one, two, four and eight bytes that can accommodate any
integer. If an integer suffix specifies a size explicitly the corresponding n-digit hex integer. If an integer suffix specifies a size explicitly the
number of least significant bytes are written. Otherwise, signed and unsigned corresponding number of least significant bytes are written, and a warning
integers alike occupy the smallest of 1, 2, 4, or 8 bytes needed to shown if the number does not fit into the desired representation. Otherwise,
accommodate them in their respective representation. unsigned integers occupy the smallest of one, two, four or eight bytes
needed. Signed numbers are allowed to fit into the smallest signed or
smallest unsigned representation: For example, 255 is stored as one byte as
255U would fit in one byte, though as a signed number it would not fit into a
one-byte interval [-128, 127]. The number -1 is stored in one byte whilst -1U
needs eight bytes as it is the same as 0xFFFFffffFFFFffffU.
.Pp .Pp
One trailing comma at the end of One trailing comma at the end of
.Ar data .Ar data

View File

@ -1429,15 +1429,20 @@ numbers are treated as signed unless they have a @code{U} suffix. Unsigned
integers cannot be larger than 2^64-1. If @var{n} is an unsigned integer then @var{-n} integers cannot be larger than 2^64-1. If @var{n} is an unsigned integer then @var{-n}
is also a valid unsigned integer as in C. Signed integers must fall into is also a valid unsigned integer as in C. Signed integers must fall into
the [-2^63, 2^63-1] range or a correspondingly smaller range when a suffix the [-2^63, 2^63-1] range or a correspondingly smaller range when a suffix
specifies a smaller type. Out of range signed numbers trigger a warning. specifies a smaller type.
Ordinary @code{0x} hex integers with @var{n} hex digits (counting leading Ordinary @code{0x} hex integers with @var{n} hex digits (counting leading
zeros) use the smallest size of 1, 2, 4 and 8 bytes that can accommodate zeros) use the smallest size of one, two, four and eight bytes that can
any n-digit hex integer. If an integer suffix specifies a size explicitly accommodate any n-digit hex integer. If an integer suffix specifies a size
the corresponding number of least significant bytes are written. explicitly the corresponding number of least significant bytes are
Otherwise, signed and unsigned integers alike occupy the smallest of 1, 2, written, and a warning shown if the number does not fit into the desired
4, or 8 bytes needed to accommodate them in their respective representation. Otherwise, unsigned integers occupy the smallest of one,
representation. two, four or eight bytes needed. Signed numbers are allowed to fit into
the smallest signed or smallest unsigned representation: For example,
@code{255} is stored as one byte as @code{255U} would fit in one byte,
though as a signed number it would not fit into a one-byte interval [-128,
127]. The number @code{-1} is stored in one byte whilst @code{-1U} needs
eight bytes as it is the same as @code{0xFFFFffffFFFFffffU}.
One trailing comma at the end of data items is ignored to facilitate copy One trailing comma at the end of data items is ignored to facilitate copy
and paste of lists. and paste of lists.

View File

@ -185,7 +185,7 @@ static int chardump_line(char *buffer, unsigned char *p, int n, int pad) {
unsigned char b[128]; unsigned char b[128];
// Sanity check // Sanity check
n = n < 1? 1: n > sizeof b? sizeof b: n; n = n < 1? 1: n > (int) sizeof b? (int) sizeof b: n;
memcpy(b, p, n); memcpy(b, p, n);
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
@ -390,15 +390,19 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
"unless they have a U suffix. Unsigned integers cannot be larger than 2^64-1.\n" "unless they have a U suffix. Unsigned integers cannot be larger than 2^64-1.\n"
"If n is an unsigned integer then -n is also a valid unsigned integer as in C.\n" "If n is an unsigned integer then -n is also a valid unsigned integer as in C.\n"
"Signed integers must fall into the [-2^63, 2^63-1] range or a correspondingly\n" "Signed integers must fall into the [-2^63, 2^63-1] range or a correspondingly\n"
"smaller range when a suffix specifies a smaller type. Out of range signed\n" "smaller range when a suffix specifies a smaller type.\n"
"numbers trigger a warning.\n"
"\n" "\n"
"Ordinary 0x hex integers with n hex digits (counting leading zeros) use the\n" "Ordinary 0x hex integers with n hex digits (counting leading zeros) use the\n"
"smallest size of 1, 2, 4 and 8 bytes that can accommodate any n-digit hex\n" "smallest size of one, two, four and eight bytes that can accommodate any\n"
"integer. If an integer suffix specifies a size explicitly the corresponding\n" "n-digit hex integer. If an integer suffix specifies a size explicitly the\n"
"number of least significant bytes are written. Otherwise, signed and unsigned\n" "corresponding number of least significant bytes are written, and a warning\n"
"integers alike occupy the smallest of 1, 2, 4, or 8 bytes needed to\n" "shown if the number does not fit into the desired representation. Otherwise,\n"
"accommodate them in their respective representation.\n" "unsigned integers occupy the smallest of one, two, four or eight bytes\n"
"needed. Signed numbers are allowed to fit into the smallest signed or\n"
"smallest unsigned representation: For example, 255 is stored as one byte as\n"
"255U would fit in one byte, though as a signed number it would not fit into a\n"
"one-byte interval [-128, 127]. The number -1 is stored in one byte whilst -1U\n"
"needs eight bytes as it is the same as 0xFFFFffffFFFFffffU.\n"
); );
return -1; return -1;
} }
@ -530,12 +534,12 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
data.size = nhexdigs > 8? 8: nhexdigs > 4? 4: nhexdigs > 2? 2: 1; data.size = nhexdigs > 8? 8: nhexdigs > 4? 4: nhexdigs > 2? 2: 1;
} else if(is_signed) { } else if(is_signed) {
// Smallest size that fits signed representation // Smallest size that fits signed or unsigned (asymmetric to meet user expectation)
data.size = data.size =
is_outside_int64_t? 8: is_outside_int64_t? 8:
data.ll < INT32_MIN || data.ll > INT32_MAX? 8: data.ll < INT32_MIN || data.ll > (long long) UINT32_MAX? 8:
data.ll < INT16_MIN || data.ll > INT16_MAX? 4: data.ll < INT16_MIN || data.ll > (long long) UINT16_MAX? 4:
data.ll < INT8_MIN || data.ll > INT8_MAX? 2: 1; data.ll < INT8_MIN || data.ll > (long long) UINT8_MAX? 2: 1;
} else { } else {
// Smallest size that fits unsigned representation // Smallest size that fits unsigned representation
@ -564,9 +568,11 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
} }
} else if(nl==2 && nh==0 && ns==0) { // LL } else if(nl==2 && nh==0 && ns==0) { // LL
data.size = 8; data.size = 8;
if(is_outside_int64_t || is_signed)
is_out_of_range = 1;
} }
if(is_outside_int64_t || is_out_of_range) if(is_out_of_range)
pmsg_error("(write) %s out of int%d_t range, " pmsg_error("(write) %s out of int%d_t range, "
"interpreted as %d-byte %lld; consider 'U' suffix\n", argi, data.size*8, data.size, (long long int) data.ll); "interpreted as %d-byte %lld; consider 'U' suffix\n", argi, data.size*8, data.size, (long long int) data.ll);
} }