aboutsummaryrefslogtreecommitdiff
path: root/toys/other/xxd.c
blob: e9ad839318a70a169e5e566daf7ee1c2a925db9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/* xxd.c - hexdump.
 *
 * Copyright 2015 The Android Open Source Project
 *
 * No obvious standard, output looks like:
 * 0000000: 4c69 6e75 7820 7665 7273 696f 6e20 332e  Linux version 3.
 *
 * TODO: support for reversing a hexdump back into the original data.
 * TODO: -s seek

USE_XXD(NEWTOY(xxd, ">1c#<1>4096=16l#g#<1=2", TOYFLAG_USR|TOYFLAG_BIN))

config XXD
  bool "xxd"
  default y
  help
    usage: xxd [-c n] [-g n] [-l n] [file]

    Hexdump a file to stdout.  If no file is listed, copy from stdin.
    Filename "-" is a synonym for stdin.

    -c n	Show n bytes per line (default 16).
    -g n	Group bytes by adding a ' ' every n bytes (default 2).
    -l n	Limit of n bytes before stopping (default is no limit).
*/

#define FOR_xxd
#include "toys.h"

GLOBALS(
  long g;
  long l;
  long c;
)

static void do_xxd(int fd, char *name)
{
  long long pos = 0;
  int i, len, space;

  while (0<(len = readall(fd, toybuf, (TT.l && TT.l-pos<TT.c)?TT.l-pos:TT.c))) {
    printf("%08llx: ", pos);
    pos += len;
    space = 2*TT.c+TT.c/TT.g+1;

    for (i=0; i<len;) {
      space -= printf("%02x", toybuf[i]);
      if (!(++i%TT.g)) {
        putchar(' ');
        space--;
      }
    }

    printf("%*s", space, "");
    for (i=0; i<len; i++)
      putchar((toybuf[i]>=' ' && toybuf[i]<='~') ? toybuf[i] : '.');
    putchar('\n');
  }
  if (len<0) perror_exit("read");
}

void xxd_main(void)
{
  loopfiles(toys.optargs, do_xxd);
}