patch 9.1.0732: xxd: cannot use -b and -i together
Problem: xxd: cannot use -b and -i together
(Irgendwer)
Solution: implement the missing changes
(Andre Chang)
fixes: #15362
closes: #15661
Signed-off-by: Andre Chang <andre@augmentcode.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim
index 99e4998..5706871 100644
--- a/src/testdir/test_xxd.vim
+++ b/src/testdir/test_xxd.vim
@@ -269,6 +269,23 @@
endfor
+ " Test 19: Print C include in binary format
+ let s:test += 1
+ call writefile(['TESTabcd09'], 'XXDfile')
+ %d
+ exe '0r! ' . s:xxd_cmd . ' -i -b XXDfile'
+ $d
+ let expected =<< trim [CODE]
+ unsigned char XXDfile[] = {
+ 0b01010100, 0b01000101, 0b01010011, 0b01010100, 0b01100001, 0b01100010,
+ 0b01100011, 0b01100100, 0b00110000, 0b00111001, 0b00001010
+ };
+ unsigned int XXDfile_len = 11;
+ [CODE]
+
+ call assert_equal(expected, getline(1,'$'), s:Mess(s:test))
+
+
%d
bwipe!
call delete('XXDfile')
diff --git a/src/version.c b/src/version.c
index a2d6bfd..6138f51 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 732,
+/**/
731,
/**/
730,
diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c
index 7a3d36a..63f516c 100644
--- a/src/xxd/xxd.c
+++ b/src/xxd/xxd.c
@@ -63,6 +63,7 @@
* 25.01.2024 revert the previous patch (size_t instead of unsigned int)
* 10.02.2024 fix buffer-overflow when writing color output to buffer, #14003
* 10.05.2024 fix another buffer-overflow when writing colored output to buffer, #14738
+ * 10.09.2024 Support -b and -i together, #15661
*
* (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com)
*
@@ -143,7 +144,7 @@
# endif
#endif
-char version[] = "xxd 2024-05-10 by Juergen Weigert et al.";
+char version[] = "xxd 2024-09-15 by Juergen Weigert et al.";
#ifdef WIN32
char osver[] = " (Win32)";
#else
@@ -220,11 +221,11 @@
char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;
/* the different hextypes known by this program: */
-#define HEX_NORMAL 0
-#define HEX_POSTSCRIPT 1
-#define HEX_CINCLUDE 2
-#define HEX_BITS 3 /* not hex a dump, but bits: 01111001 */
-#define HEX_LITTLEENDIAN 4
+#define HEX_NORMAL 0x00 /* no flags set */
+#define HEX_POSTSCRIPT 0x01
+#define HEX_CINCLUDE 0x02
+#define HEX_BITS 0x04 /* not hex a dump, but bits: 01111001 */
+#define HEX_LITTLEENDIAN 0x08
#define CONDITIONAL_CAPITALIZE(c) (capitalize ? toupper((unsigned char)(c)) : (c))
@@ -255,7 +256,7 @@
fprintf(stderr, " or\n %s -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]\n", pname);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -a toggle autoskip: A single '*' replaces nul-lines. Default off.\n");
- fprintf(stderr, " -b binary digit dump (incompatible with -ps,-i). Default hex.\n");
+ fprintf(stderr, " -b binary digit dump (incompatible with -ps). Default hex.\n");
fprintf(stderr, " -C capitalize variable names in C include file style (-i).\n");
fprintf(stderr, " -c cols format <cols> octets per line. Default 16 (-i: 12, -ps: 30).\n");
fprintf(stderr, " -E show characters in EBCDIC. Default ASCII.\n");
@@ -692,11 +693,11 @@
{
pp = argv[1] + (!STRNCMP(argv[1], "--", 2) && argv[1][2]);
if (!STRNCMP(pp, "-a", 2)) autoskip = 1 - autoskip;
- else if (!STRNCMP(pp, "-b", 2)) hextype = HEX_BITS;
- else if (!STRNCMP(pp, "-e", 2)) hextype = HEX_LITTLEENDIAN;
+ else if (!STRNCMP(pp, "-b", 2)) hextype |= HEX_BITS;
+ else if (!STRNCMP(pp, "-e", 2)) hextype |= HEX_LITTLEENDIAN;
else if (!STRNCMP(pp, "-u", 2)) hexx = hexxa + 16;
- else if (!STRNCMP(pp, "-p", 2)) hextype = HEX_POSTSCRIPT;
- else if (!STRNCMP(pp, "-i", 2)) hextype = HEX_CINCLUDE;
+ else if (!STRNCMP(pp, "-p", 2)) hextype |= HEX_POSTSCRIPT;
+ else if (!STRNCMP(pp, "-i", 2)) hextype |= HEX_CINCLUDE;
else if (!STRNCMP(pp, "-C", 2)) capitalize = 1;
else if (!STRNCMP(pp, "-d", 2)) decimal_offset = 1;
else if (!STRNCMP(pp, "-r", 2)) revert++;
@@ -856,11 +857,19 @@
argc--;
}
+ if (hextype != (HEX_CINCLUDE | HEX_BITS))
+ {
+ /* Allow at most one bit to be set in hextype */
+ if (hextype & (hextype - 1))
+ error_exit(1, "only one of -b, -e, -u, -p, -i can be used");
+ }
+
if (!colsgiven || (!cols && hextype != HEX_POSTSCRIPT))
switch (hextype)
{
case HEX_POSTSCRIPT: cols = 30; break;
case HEX_CINCLUDE: cols = 12; break;
+ case HEX_CINCLUDE | HEX_BITS:
case HEX_BITS: cols = 6; break;
case HEX_NORMAL:
case HEX_LITTLEENDIAN:
@@ -870,6 +879,7 @@
if (octspergrp < 0)
switch (hextype)
{
+ case HEX_CINCLUDE | HEX_BITS:
case HEX_BITS: octspergrp = 1; break;
case HEX_NORMAL: octspergrp = 2; break;
case HEX_LITTLEENDIAN: octspergrp = 4; break;
@@ -966,7 +976,7 @@
}
}
- if (hextype == HEX_CINCLUDE)
+ if (hextype & HEX_CINCLUDE)
{
/* A user-set variable name overrides fp == stdin */
if (varname == NULL && fp != stdin)
@@ -982,11 +992,28 @@
p = 0;
while ((length < 0 || p < length) && (c = getc_or_die(fp)) != EOF)
- {
- FPRINTF_OR_DIE((fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X",
+ {
+ if (hextype & HEX_BITS)
+ {
+ if (p == 0)
+ fputs_or_die(" ", fpo);
+ else if (p % cols == 0)
+ fputs_or_die(",\n ", fpo);
+ else
+ fputs_or_die(", ", fpo);
+
+ FPRINTF_OR_DIE((fpo, "0b"));
+ for (int j = 7; j >= 0; j--)
+ putc_or_die((c & (1 << j)) ? '1' : '0', fpo);
+ p++;
+ }
+ else
+ {
+ FPRINTF_OR_DIE((fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X",
(p % cols) ? ", " : (!p ? " " : ",\n "), c));
- p++;
- }
+ p++;
+ }
+ }
if (p)
fputs_or_die("\n", fpo);