Browse Source

od: -l,I,L indeed depend on sizeof(long), fix this

function                                             old     new   delta
.rodata                                           105255  105252      -3
od_main                                             1917    1901     -16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-19)             Total: -19 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Denys Vlasenko 10 months ago
parent
commit
6d9427420b
3 changed files with 39 additions and 29 deletions
  1. 13 8
      coreutils/od.c
  2. 7 3
      coreutils/od_bloaty.c
  3. 19 18
      testsuite/od.tests

+ 13 - 8
coreutils/od.c

@@ -170,12 +170,17 @@ static const char *const add_strings[] ALIGN_PTR = {
 	"4/4 \" %15.7e\""  "\"\n\"",            /* 7: f */
 	"4/4 \" %08x\""    "\"\n\"",            /* 8: H, X */
 	"8/2 \" %04x\""    "\"\n\"",            /* 9: h, x */
-	/* This probably also depends on word width of the arch (what is "long"?) */
-	/* should be "2/8" or "4/4" depending on sizeof(long)? */
-	"2/8 \" %20lld\""  "\"\n\"",            /* 10: I, L, l */
-	"4/4 \" %11d\""    "\"\n\"",            /* 11: i */
-	"4/4 \" %011o\""   "\"\n\"",            /* 12: O */
-	"8/2 \" %6d\""     "\"\n\"",            /* 13: s */
+	"4/4 \" %11d\""    "\"\n\"",            /* 10: i */
+	"4/4 \" %011o\""   "\"\n\"",            /* 11: O */
+	"8/2 \" %6d\""     "\"\n\"",            /* 12: s */
+	/* -I,L,l: depend on word width of the arch (what is "long"?) */
+#if ULONG_MAX > 0xffffffff
+	"2/8 \" %20lld\""  "\"\n\"",            /* 13: I, L, l */
+#define L_ 13
+#else
+	/* 32-bit arch: -I,L,l are the same as -i */
+#define L_ 10
+#endif
 };
 
 static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxsv";
@@ -183,8 +188,8 @@ static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxsv";
 static const char od_o2si[] ALIGN1 = {
 	0, 1, 2, 3, 5,     /* aBbcD */
 	4, 6, 6, 7, 8,     /* deFfH */
-	9, 10, 11, 10, 10, /* hIiLl */
-	12, 1, 8, 9, 13    /* OoXxs */
+	9, L_, 10, L_, L_, /* hIiLl */
+	11, 1, 8, 9, 12    /* OoXxs */
 };
 
 int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;

+ 7 - 3
coreutils/od_bloaty.c

@@ -1257,11 +1257,15 @@ int od_main(int argc UNUSED_PARAM, char **argv)
 	if (opt & OPT_f) decode_format_string("fF");
 	if (opt & (OPT_h|OPT_x)) decode_format_string("x2");
 	if (opt & (OPT_H|OPT_X)) decode_format_string("xI");
+	/* -I,L,l: depend on word width of the arch (what is "long"?) */
+#if ULONG_MAX > 0xffffffff
 	if (opt & OPT_i) decode_format_string("dI");
+	if (opt & (OPT_I|OPT_l|OPT_L)) decode_format_string("dL");
+#else
+	/* 32-bit arch: -I,L,l are the same as -i */
+	if (opt & (OPT_i|OPT_I|OPT_l|OPT_L)) decode_format_string("dI");
+#endif
 	if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm_suffixes);
-	/* This probably also depends on word width of the arch (what is "long"?) */
-	/* should be "d4" or "d8" depending on sizeof(long)? */
-	if (opt & (OPT_I|OPT_l|OPT_L)) decode_format_string("d8");
 	if (opt & (OPT_o|OPT_B)) decode_format_string("o2");
 	if (opt & OPT_O) decode_format_string("oI");
 	while (lst_t) {

+ 19 - 18
testsuite/od.tests

@@ -8,11 +8,11 @@
 
 input="$(printf '\001\002\003\nABC\xfe')"
 
-le=false
-{ printf '\0\1' | od -s | grep -q 256; } && le=true
-readonly le
+little_endian=false
+{ printf '\0\1' | od -s | grep -q 256; } && little_endian=true
+readonly little_endian
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od (little-endian)" \
         "od" \
 "\
@@ -70,7 +70,7 @@ testing "od -B" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -o (little-endian)" \
         "od -o" \
 "\
@@ -98,7 +98,7 @@ testing "od -c" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -d (little-endian)" \
         "od -d" \
 "\
@@ -108,7 +108,7 @@ testing "od -d (little-endian)" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -D (little-endian)" \
         "od -D" \
 "\
@@ -119,7 +119,7 @@ testing "od -D (little-endian)" \
 SKIP=
 
 optional !DESKTOP  #DESKTOP: unrecognized option: e
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -e (!DESKTOP little-endian)" \
         "od -e" \
 "\
@@ -130,7 +130,7 @@ testing "od -e (!DESKTOP little-endian)" \
 SKIP=
 
 optional !DESKTOP  #DESKTOP: unrecognized option: F
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -F (!DESKTOP little-endian)" \
         "od -F" \
 "\
@@ -140,7 +140,7 @@ testing "od -F (!DESKTOP little-endian)" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -f (little-endian)" \
         "od -f" \
 "\
@@ -150,7 +150,7 @@ testing "od -f (little-endian)" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -H (little-endian)" \
         "od -H" \
 "\
@@ -160,7 +160,7 @@ testing "od -H (little-endian)" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -X (little-endian)" \
         "od -X" \
 "\
@@ -170,7 +170,7 @@ testing "od -X (little-endian)" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -h (little-endian)" \
         "od -h" \
 "\
@@ -180,7 +180,7 @@ testing "od -h (little-endian)" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -x (little-endian)" \
         "od -x" \
 "\
@@ -190,7 +190,7 @@ testing "od -x (little-endian)" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -i (little-endian)" \
         "od -i" \
 "\
@@ -200,7 +200,7 @@ testing "od -i (little-endian)" \
 	"" "$input"
 SKIP=
 
-$le || SKIP=1
+$little_endian || SKIP=1
 testing "od -O (little-endian)" \
         "od -O" \
 "\
@@ -210,8 +210,9 @@ testing "od -O (little-endian)" \
 	"" "$input"
 SKIP=
 
-# This probably also depends on word width of the arch (what is "long"?)
-$le || SKIP=1
+# 32-bit?
+printf '00000000' | od -l | grep -q '808464432 *808464432' && SKIP=1 #yes, skip
+$little_endian || SKIP=1
 testing "od -I (little-endian)" \
         "od -I" \
 "\