summary refs log tree commit diff
path: root/.bin/xx.c
diff options
context:
space:
mode:
authorJune McEnroe <programble@gmail.com>2017-03-18 23:50:22 -0400
committerJune McEnroe <programble@gmail.com>2017-03-18 23:50:22 -0400
commitfa22c1e9a9ff6aa1e5b40fc75033d3f5611b3ba0 (patch)
treec0adb9d05060901cd9e93c288f0d1fd93b292c67 /.bin/xx.c
parentFix non-string-literal-format-string in bri (diff)
downloadsrc-fa22c1e9a9ff6aa1e5b40fc75033d3f5611b3ba0.tar.gz
src-fa22c1e9a9ff6aa1e5b40fc75033d3f5611b3ba0.zip
Add -u option to xx
Diffstat (limited to '')
-rwxr-xr-x.bin/xx.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/.bin/xx.c b/.bin/xx.c
index 6af0d6a7..e92d12d3 100755
--- a/.bin/xx.c
+++ b/.bin/xx.c
@@ -23,34 +23,10 @@ enum {
     FLAG_ASCII = 1,
     FLAG_OFFSET = 2,
     FLAG_SKIP = 4,
+    FLAG_UNDUMP = 8,
 };
 
-int main(int argc, char *argv[]) {
-    size_t cols = 16;
-    size_t group = 8;
-    uint8_t flags = FLAG_ASCII | FLAG_OFFSET;
-    char *path = NULL;
-
-    int opt;
-    while ((opt = getopt(argc, argv, "ac:fg:hk")) > 0) {
-        switch (opt) {
-            case 'a': flags ^= FLAG_ASCII; break;
-            case 'f': flags ^= FLAG_OFFSET; break;
-            case 'k': flags ^= FLAG_SKIP; break;
-            case 'c': cols = strtoul(optarg, NULL, 10); break;
-            case 'g': group = strtoul(optarg, NULL, 10); break;
-            default:
-                fprintf(stderr, "usage: xx [-afk] [-c cols] [-g group] [file]\n");
-                return (opt == 'h') ? EX_OK : EX_USAGE;
-        }
-    }
-    if (!cols) return EX_USAGE;
-    if (argc > optind)
-        path = argv[optind];
-
-    FILE *file = path ? fopen(path, "r") : stdin;
-    if (!file) err(EX_NOINPUT, "%s", path);
-
+void dump(size_t cols, size_t group, uint8_t flags, FILE *file) {
     uint8_t buf[cols];
     size_t offset = 0, len = 0;
     for (;;) {
@@ -87,6 +63,49 @@ int main(int argc, char *argv[]) {
         printf("\n");
         if (len < sizeof(buf)) break;
     }
+}
+
+void undump(FILE *file) {
+    uint8_t byte;
+    int match;
+    while (1 == (match = fscanf(file, " %hhx", &byte))) {
+        printf("%c", byte);
+    }
+    if (match == 0) errx(EX_DATAERR, "invalid input");
+}
+
+int main(int argc, char *argv[]) {
+    size_t cols = 16;
+    size_t group = 8;
+    uint8_t flags = FLAG_ASCII | FLAG_OFFSET;
+    char *path = NULL;
+
+    int opt;
+    while ((opt = getopt(argc, argv, "ac:fg:hku")) > 0) {
+        switch (opt) {
+            case 'a': flags ^= FLAG_ASCII; break;
+            case 'f': flags ^= FLAG_OFFSET; break;
+            case 'k': flags ^= FLAG_SKIP; break;
+            case 'u': flags ^= FLAG_UNDUMP; break;
+            case 'c': cols = strtoul(optarg, NULL, 10); break;
+            case 'g': group = strtoul(optarg, NULL, 10); break;
+            default:
+                fprintf(stderr, "usage: xx [-afku] [-c cols] [-g group] [file]\n");
+                return (opt == 'h') ? EX_OK : EX_USAGE;
+        }
+    }
+    if (!cols) return EX_USAGE;
+    if (argc > optind)
+        path = argv[optind];
+
+    FILE *file = path ? fopen(path, "r") : stdin;
+    if (!file) err(EX_NOINPUT, "%s", path);
+
+    if (flags & FLAG_UNDUMP) {
+        undump(file);
+    } else {
+        dump(cols, group, flags, file);
+    }
 
     if (ferror(file)) err(EX_IOERR, "%s", path);
     return EX_OK;