xxd: implement -p
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 25 Jan 2017 15:50:30 +0000 (16:50 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 25 Jan 2017 15:50:30 +0000 (16:50 +0100)
While at it, tweaked hexdump --help

function                                             old     new   delta
xxd_main                                             364     414     +50
packed_usage                                       31097   31114     +17

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
util-linux/hexdump.c
util-linux/hexdump_xxd.c

index a4483a114c6745212d6af2115c6d59e101d0ec86..25f771201a8942faafb4ea3e48666dc4df4874be 100644 (file)
 //usage:       "[-bcCdefnosvx" IF_FEATURE_HEXDUMP_REVERSE("R") "] [FILE]..."
 //usage:#define hexdump_full_usage "\n\n"
 //usage:       "Display FILEs (or stdin) in a user specified format\n"
-//usage:     "\n       -b              One-byte octal display"
-//usage:     "\n       -c              One-byte character display"
-//usage:     "\n       -C              Canonical hex+ASCII, 16 bytes per line"
-//usage:     "\n       -d              Two-byte decimal display"
-//usage:     "\n       -e FORMAT_STRING"
+//usage:     "\n       -b              1-byte octal display"
+//usage:     "\n       -c              1-byte character display"
+//usage:     "\n       -d              2-byte decimal display"
+//usage:     "\n       -o              2-byte octal display"
+//usage:     "\n       -x              2-byte hex display"
+//usage:     "\n       -C              hex+ASCII 16 bytes per line"
+//usage:     "\n       -v              Show all (no dup folding)"
+//usage:     "\n       -e FORMAT_STR   Example: '16/1 \"%02x|\"\"\\n\"'"
 //usage:     "\n       -f FORMAT_FILE"
 // exactly the same help text lines in hexdump and xxd:
-//usage:     "\n       -n LENGTH       Interpret only LENGTH bytes of input"
-//usage:     "\n       -o              Two-byte octal display"
+//usage:     "\n       -n LENGTH       Show only first LENGTH bytes"
 //usage:     "\n       -s OFFSET       Skip OFFSET bytes"
-//usage:     "\n       -v              Display all input data"
-//usage:     "\n       -x              Two-byte hexadecimal display"
 //usage:       IF_FEATURE_HEXDUMP_REVERSE(
 //usage:     "\n       -R              Reverse of 'hexdump -Cv'")
+// TODO: NONCOMPAT!!! move -R to xxd -r
 //usage:
 //usage:#define hd_trivial_usage
 //usage:       "FILE..."
index 813e7fe57793ad6f429bf1f6d1d03511b141cb82..cc34ea64971ac1f09862832d2b64791677bd369e 100644 (file)
 //usage:       "Hex dump FILE (or stdin)\n"
 //usage:     "\n       -g N            Bytes per group"
 //usage:     "\n       -c N            Bytes per line"
+//usage:     "\n       -p              Show only hex bytes, assumes -c30"
 // exactly the same help text lines in hexdump and xxd:
-//usage:     "\n       -l LENGTH       Interpret only LENGTH bytes of input"
+//usage:     "\n       -l LENGTH       Show only first LENGTH bytes"
 //usage:     "\n       -s OFFSET       Skip OFFSET bytes"
+// TODO: implement -r (see hexdump -R)
 
 #include "libbb.h"
 #include "dump.h"
@@ -70,11 +72,12 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 #define OPT_l (1 << 0)
 #define OPT_s (1 << 1)
 #define OPT_a (1 << 2)
+#define OPT_p (1 << 3)
        opt_complementary = "?1"; /* 1 argument max */
-       opt = getopt32(argv, "l:s:ag:+c:+", &opt_l, &opt_s, &bytes, &cols);
+       opt = getopt32(argv, "l:s:apg:+c:+", &opt_l, &opt_s, &bytes, &cols);
        argv += optind;
 
-//     dumper->dump_vflag = ALL; // default
+       dumper->dump_vflag = ALL;
 //     if (opt & OPT_a)
 //             dumper->dump_vflag = SKIPNUL; ..does not exist
        if (opt & OPT_l) {
@@ -93,9 +96,16 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
                //BUGGY for /proc/version (unseekable?)
        }
 
-       bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: "
-       if (cols == 0)
-               cols = 16;
+       if (opt & OPT_p) {
+               if (cols == 0)
+                       cols = 30;
+               bytes = cols; /* -p ignores -gN */
+       } else {
+               if (cols == 0)
+                       cols = 16;
+               bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: "
+       }
+
        if (bytes < 1 || bytes >= cols) {
                sprintf(buf, "%u/1 \"%%02x\"", cols); // cols * "xx"
                bb_dump_add(dumper, buf);
@@ -109,7 +119,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
 #define BS "/1 \"%02x \""
 #define B  "/1 \"%02x\""
                unsigned i;
-               char *bigbuf = xmalloc(1 + cols * (sizeof(BS)-1));
+               char *bigbuf = xmalloc(cols * (sizeof(BS)-1));
                char *p = bigbuf;
                for (i = 1; i <= cols; i++) {
                        if (i == cols || i % bytes)
@@ -125,8 +135,10 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
                free(bigbuf);
        }
 
-       sprintf(buf, "\"  \"%u/1 \"%%_p\"\"\n\"", cols); // "  ASCII\n"
-       bb_dump_add(dumper, buf);
+       if (!(opt & OPT_p)) {
+               sprintf(buf, "\"  \"%u/1 \"%%_p\"\"\n\"", cols); // "  ASCII\n"
+               bb_dump_add(dumper, buf);
+       }
 
        return bb_dump_dump(dumper, argv);
 }