/* od.c - Provide octal/hex dumps of data
 *
 * Copyright 2012 Andre Renaud <andre@bluewatersys.com>
 * Copyright 2012 Rob Landley <rob@landley.net>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/od.html

USE_OD(NEWTOY(od, "j#vw#<1=16N#xsodcbA:t*", TOYFLAG_USR|TOYFLAG_BIN))

config OD
  bool "od"
  default y
  help
    usage: od [-bcdosxv] [-j #] [-N #] [-w #] [-A doxn] [-t acdfoux[#]]

    -A	Address base (decimal, octal, hexdecimal, none)
    -j	Skip this many bytes of input
    -N	Stop dumping after this many bytes
    -t	Output type a(scii) c(har) d(ecimal) f(loat) o(ctal) u(nsigned) (he)x
    	plus optional size in bytes
    	aliases: -b=-t o1, -c=-t c, -d=-t u2, -o=-t o2, -s=-t d2, -x=-t x2
    -v	Don't collapse repeated lines together
    -w	Total line width in bytes (default 16)
*/

#define FOR_od
#include "toys.h"

GLOBALS(
  struct arg_list *output_base;
  char *address_base;
  long max_count;
  long width;
  long jump_bytes;

  int address_idx;
  unsigned types, leftover, star;
  char *buf; // Points to buffers[0] or buffers[1].
  char *bufs[2]; // Used to detect duplicate lines.
  off_t pos;
)

static char *ascii = "nulsohstxetxeotenqackbel bs ht nl vt ff cr so si"
  "dledc1dc2dc3dc4naksynetbcan emsubesc fs gs rs us sp";

struct odtype {
  int type;
  int size;
};

static int od_out_t(struct odtype *t, char *buf, int *offset)
{
  unsigned k;
  int throw = 0, pad = 0;

  // Handle ascii
  if (t->type < 2) {
    char c = TT.buf[(*offset)++];
    pad += 4;

    if (!t->type) {
      c &= 127;
      if (c<=32) sprintf(buf, "%.3s", ascii+(3*c));
      else if (c==127) strcpy(buf, "del");
      else sprintf(buf, "%c", c);
    } else {
      char *bfnrtav = "\b\f\n\r\t\a\v", *s = strchr(bfnrtav, c);
      if (s) sprintf(buf, "\\%c", "bfnrtav0"[s-bfnrtav]);
      else if (c < 32 || c >= 127) sprintf(buf, "%03o", c);
      else {
        // TODO: this should be UTF8 aware.
        sprintf(buf, "%c", c);
      }
    }
  } else if (CFG_TOYBOX_FLOAT && t->type == 6) {
    long double ld;
    union {float f; double d; long double ld;} fdl;

    memcpy(&fdl, TT.buf+*offset, t->size);
    *offset += t->size;
    if (sizeof(float) == t->size) {
      ld = fdl.f;
      pad += (throw = 8)+7;
    } else if (sizeof(double) == t->size) {
      ld = fdl.d;
      pad += (throw = 17)+8;
    } else if (sizeof(long double) == t->size) {
      ld = fdl.ld;
      pad += (throw = 21)+9;
    } else error_exit("bad -tf '%d'", t->size);

    sprintf(buf, "%.*Le", throw, ld);
  // Integer types
  } else {
    unsigned long long ll = 0, or;
    char *c[] = {"%*lld", "%*llu", "%0*llo", "%0*llx"},
      *class = c[t->type-2];

    // Work out width of field
    if (t->size == 8) {
      or = -1LL;
      if (t->type == 2) or >>= 1;
    } else or = (1LL<<(8*t->size))-1;
    throw = sprintf(buf, class, 0, or);

    // Accumulate integer based on size argument
    for (k=0; k < t->size; k++) {
      or = TT.buf[(*offset)++];
      ll |= or << (8*(IS_BIG_ENDIAN ? t->size-k-1 : k));
    }

    // Handle negative values
    if (t->type == 2) {
      or = sizeof(or) - t->size;
      throw++;
      if (or && (ll & (1l<<((8*t->size)-1))))
        ll |= ((or<<(8*or))-1) << (8*t->size);
    }

    sprintf(buf, class, throw, ll);
    pad += throw+1;
  }

  return pad;
}

static void od_outline(void)
{
  unsigned flags = toys.optflags;
  char buf[128], *abases[] = {"", "%07lld", "%07llo", "%06llx"};
  struct odtype *types = (struct odtype *)toybuf;
  int i, j, len, pad;

  if (TT.leftover<TT.width) memset(TT.buf+TT.leftover, 0, TT.width-TT.leftover);

  // Handle duplciate lines as *
  if (!(flags&FLAG_v) && TT.jump_bytes != TT.pos && TT.leftover
    && !memcmp(TT.bufs[0], TT.bufs[1], TT.width))
  {
    if (!TT.star) {
      xputs("*");
      TT.star++;
    }

  // Print line position
  } else {
    TT.star = 0;

    // off_t varies so expand it to largest possible size
    xprintf(abases[TT.address_idx], (long long)TT.pos);
    if (!TT.leftover) {
      if (TT.address_idx) xputc('\n');
      return;
    }
  }

  TT.pos += len = TT.leftover;
  TT.leftover = 0;
  if (TT.star) return;

  // Find largest "pad" of the output types.
  for (i = pad = 0; i<TT.types; i++) {
    int bytes = 0;

    // If more than one byte of input consumed, average rounding up.
    j = od_out_t(types+i, buf, &bytes);
    j = (j+bytes-1)/bytes;
   
    if (j > pad) pad = j;
  }

  // For each output type, print one line
  for (i=0; i<TT.types; i++) {
    for (j = 0; j<len;) {
      int bytes = j;

      // pad for as many bytes as were consumed, and indent non-numbered lines
      od_out_t(types+i, buf, &bytes);
      xprintf("%*s", pad*(bytes-j) + 7*(!!i)*!j, buf);
      j = bytes;
    }
    xputc('\n');
  }

  // Toggle buffer for "same as last time" check.
  TT.buf = (TT.buf == TT.bufs[0]) ? TT.bufs[1] : TT.bufs[0];
}

// Loop through input files
static void do_od(int fd, char *name)
{
  // Skip input, possibly more than one entire file.
  if (TT.jump_bytes > TT.pos) {
    off_t pos = TT.jump_bytes-TT.pos, off = lskip(fd, pos);

    if (off >= 0) TT.pos += pos-off;
    if (TT.jump_bytes > TT.pos) return;
  }

  for(;;) {
    char *buf = TT.buf + TT.leftover;
    int len = TT.width - TT.leftover;

    if (toys.optflags & FLAG_N) {
      if (!TT.max_count) break;
      if (TT.max_count < len) len = TT.max_count;
    }

    len = readall(fd, buf, len);
    if (len < 0) {
      perror_msg_raw(name);
      break;
    }
    if (TT.max_count) TT.max_count -= len;
    TT.leftover += len;
    if (TT.leftover < TT.width) break;

    od_outline();
  }
}

// Handle one -t argument (including implicit ones)
static void append_base(char *base)
{
  char *s = base;
  struct odtype *types = (struct odtype *)toybuf;
  int type;

  for (;;) {
    int size = 1;

    if (!*s) return;
    if (TT.types >= sizeof(toybuf)/sizeof(struct odtype)) break;
    if (-1 == (type = stridx("acduox"USE_TOYBOX_FLOAT("f"), *(s++)))) break;

    if (isdigit(*s)) {
      size = strtol(s, &s, 10);
      if (type < 2 && size != 1) break;
      if (CFG_TOYBOX_FLOAT && type == 6 && size == sizeof(long double));
      else if (size < 1 || size > 8) break;
    } else if (CFG_TOYBOX_FLOAT && type == 6) {
      int sizes[] = {sizeof(float), sizeof(double), sizeof(long double)};
      if (-1 == (size = stridx("FDL", *s))) size = sizeof(double);
      else {
        s++;
        size = sizes[size];
      }
    } else if (type > 1) {
      if (-1 == (size = stridx("CSIL", *s))) size = 4;
      else {
        s++;
        size = 1 << size;
      }
    }

    types[TT.types].type = type;
    types[TT.types].size = size;
    TT.types++;
  }

  error_exit("bad -t %s", base);
}

void od_main(void)
{
  struct arg_list *arg;

  TT.bufs[0] = xzalloc(TT.width);
  TT.bufs[1] = xzalloc(TT.width);
  TT.buf = TT.bufs[0];

  if (!TT.address_base) TT.address_idx = 2;
  else if (0>(TT.address_idx = stridx("ndox", *TT.address_base)))
    error_exit("bad -A '%c'", *TT.address_base);

  // Collect -t entries

  for (arg = TT.output_base; arg; arg = arg->next) append_base(arg->arg);
  if (toys.optflags & FLAG_b) append_base("o1");
  if (toys.optflags & FLAG_c) append_base("c");
  if (toys.optflags & FLAG_d) append_base("u2");
  if (toys.optflags & FLAG_o) append_base("o2");
  if (toys.optflags & FLAG_s) append_base("d2");
  if (toys.optflags & FLAG_x) append_base("x2");
  if (!TT.types) append_base("o2");

  loopfiles(toys.optargs, do_od);

  if (TT.leftover) od_outline();
  od_outline();

  if (CFG_TOYBOX_FREE) {
    free(TT.bufs[0]);
    free(TT.bufs[1]);
  }
}
