From 2434c3f7f665e06541aae27695a1c1248e6fb15c Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Thu, 10 Nov 2022 19:38:21 +0000 Subject: [PATCH] Make terminal write's automatic number width less surprising --- src/avrdude.1 | 18 +++++++++++------- src/doc/avrdude.texi | 19 ++++++++++++------- src/term.c | 32 +++++++++++++++++++------------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/avrdude.1 b/src/avrdude.1 index a2225a1a..3b9e0ce5 100644 --- a/src/avrdude.1 +++ b/src/avrdude.1 @@ -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. 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 -smaller range when a suffix specifies a smaller type. Out of range signed -numbers trigger a warning. +smaller range when a suffix specifies a smaller type. .Pp 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 -integer. If an integer suffix specifies a size explicitly the corresponding -number of least significant bytes are written. Otherwise, signed and unsigned -integers alike occupy the smallest of 1, 2, 4, or 8 bytes needed to -accommodate them in their respective representation. +smallest size of one, two, four and eight bytes that can accommodate any +n-digit hex integer. If an integer suffix specifies a size explicitly the +corresponding number of least significant bytes are written, and a warning +shown if the number does not fit into the desired representation. Otherwise, +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 One trailing comma at the end of .Ar data diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index cb8bd103..4bd90b94 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -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} 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 -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 -zeros) use the smallest size of 1, 2, 4 and 8 bytes that can accommodate -any n-digit hex integer. If an integer suffix specifies a size explicitly -the corresponding number of least significant bytes are written. -Otherwise, signed and unsigned integers alike occupy the smallest of 1, 2, -4, or 8 bytes needed to accommodate them in their respective -representation. +zeros) use the smallest size of one, two, four and eight bytes that can +accommodate any n-digit hex integer. If an integer suffix specifies a size +explicitly the corresponding number of least significant bytes are +written, and a warning shown if the number does not fit into the desired +representation. Otherwise, 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, +@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 and paste of lists. diff --git a/src/term.c b/src/term.c index bd4e57b1..943b964f 100644 --- a/src/term.c +++ b/src/term.c @@ -185,7 +185,7 @@ static int chardump_line(char *buffer, unsigned char *p, int n, int pad) { unsigned char b[128]; // 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); 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" "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" - "smaller range when a suffix specifies a smaller type. Out of range signed\n" - "numbers trigger a warning.\n" + "smaller range when a suffix specifies a smaller type.\n" "\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" - "integer. If an integer suffix specifies a size explicitly the corresponding\n" - "number of least significant bytes are written. Otherwise, signed and unsigned\n" - "integers alike occupy the smallest of 1, 2, 4, or 8 bytes needed to\n" - "accommodate them in their respective representation.\n" + "smallest size of one, two, four and eight bytes that can accommodate any\n" + "n-digit hex integer. If an integer suffix specifies a size explicitly the\n" + "corresponding number of least significant bytes are written, and a warning\n" + "shown if the number does not fit into the desired representation. Otherwise,\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; } @@ -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; } else if(is_signed) { - // Smallest size that fits signed representation + // Smallest size that fits signed or unsigned (asymmetric to meet user expectation) data.size = is_outside_int64_t? 8: - data.ll < INT32_MIN || data.ll > INT32_MAX? 8: - data.ll < INT16_MIN || data.ll > INT16_MAX? 4: - data.ll < INT8_MIN || data.ll > INT8_MAX? 2: 1; + data.ll < INT32_MIN || data.ll > (long long) UINT32_MAX? 8: + data.ll < INT16_MIN || data.ll > (long long) UINT16_MAX? 4: + data.ll < INT8_MIN || data.ll > (long long) UINT8_MAX? 2: 1; } else { // 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 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, " "interpreted as %d-byte %lld; consider 'U' suffix\n", argi, data.size*8, data.size, (long long int) data.ll); }