17aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley/* od.c - Provide octal/hex dumps of data
2d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley *
3d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley * Copyright 2012 Andre Renaud <andre@bluewatersys.com>
44625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley * Copyright 2012 Rob Landley <rob@landley.net>
5d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley *
6f91b7c89bc852868692b9518185421ebb52d67b3Rob Landley * See http://opengroup.org/onlinepubs/9699919799/utilities/od.html
7d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
84625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob LandleyUSE_OD(NEWTOY(od, "j#vN#xsodcbA:t*", TOYFLAG_USR|TOYFLAG_BIN))
9d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
10d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landleyconfig OD
117aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  bool "od"
127aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  default y
137aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  help
14bc382bed736d161b32e22a615489c226173ca030Rob Landley    usage: od [-bcdosxv] [-j #] [-N #] [-A doxn] [-t acdfoux[#]]
154625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley
167aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    -A	Address base (decimal, octal, hexdecimal, none)
17bc382bed736d161b32e22a615489c226173ca030Rob Landley    -j	Skip this many bytes of input
18bc382bed736d161b32e22a615489c226173ca030Rob Landley    -N	Stop dumping after this many bytes
19bc382bed736d161b32e22a615489c226173ca030Rob Landley    -t	output type a(scii) c(har) d(ecimal) f(loat) o(ctal) u(nsigned) (he)x
20bc382bed736d161b32e22a615489c226173ca030Rob Landley    	plus optional size in bytes
21bc382bed736d161b32e22a615489c226173ca030Rob Landley    	aliases: -b=-t o1, -c=-t c, -d=-t u2, -o=-t o2, -s=-t d2, -x=-t x2
22bc382bed736d161b32e22a615489c226173ca030Rob Landley    -v	Don't collapse repeated lines together
23d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley*/
24d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
25c0e56edaf256adb6c60c5a052525a1ffbb927901Rob Landley#define FOR_od
26d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley#include "toys.h"
27d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
28c0e56edaf256adb6c60c5a052525a1ffbb927901Rob LandleyGLOBALS(
297aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  struct arg_list *output_base;
307aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  char *address_base;
317aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  long max_count;
327aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  long jump_bytes;
337aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
340eb0a81c0c8e2ea99320cc42574766081052af86Rob Landley  int address_idx;
350eb0a81c0c8e2ea99320cc42574766081052af86Rob Landley  unsigned types, leftover, star;
367aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  char *buf;
377aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  uint64_t bufs[4]; // force 64-bit alignment
387aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  off_t pos;
39d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley)
40d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
414625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landleystatic char *ascii = "nulsohstxetxeotenqackbel bs ht nl vt ff cr so si"
427aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  "dledc1dc2dc3dc4naksynetbcan emsubesc fs gs rs us sp";
43d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
444625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landleystruct odtype {
457aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  int type;
467aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  int size;
474625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley};
48d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
49b0d4872f532bead29307654bbc511d6083abf2afRob Landleystatic int od_out_t(struct odtype *t, char *buf, int *offset)
50b0d4872f532bead29307654bbc511d6083abf2afRob Landley{
51b0d4872f532bead29307654bbc511d6083abf2afRob Landley  unsigned k;
52b0d4872f532bead29307654bbc511d6083abf2afRob Landley  int throw = 0, pad = 0;
53b0d4872f532bead29307654bbc511d6083abf2afRob Landley
54b0d4872f532bead29307654bbc511d6083abf2afRob Landley  // Handle ascii
55b0d4872f532bead29307654bbc511d6083abf2afRob Landley  if (t->type < 2) {
56b0d4872f532bead29307654bbc511d6083abf2afRob Landley    char c = TT.buf[(*offset)++];
57b0d4872f532bead29307654bbc511d6083abf2afRob Landley    pad += 4;
58b0d4872f532bead29307654bbc511d6083abf2afRob Landley
59b0d4872f532bead29307654bbc511d6083abf2afRob Landley    if (!t->type) {
60b0d4872f532bead29307654bbc511d6083abf2afRob Landley      c &= 127;
61b0d4872f532bead29307654bbc511d6083abf2afRob Landley      if (c<=32) sprintf(buf, "%.3s", ascii+(3*c));
62b0d4872f532bead29307654bbc511d6083abf2afRob Landley      else if (c==127) strcpy(buf, "del");
63b0d4872f532bead29307654bbc511d6083abf2afRob Landley      else sprintf(buf, "%c", c);
64b0d4872f532bead29307654bbc511d6083abf2afRob Landley    } else {
65b0d4872f532bead29307654bbc511d6083abf2afRob Landley      char *bfnrtav = "\b\f\n\r\t\a\v", *s = strchr(bfnrtav, c);
66b0d4872f532bead29307654bbc511d6083abf2afRob Landley      if (s) sprintf(buf, "\\%c", "bfnrtav0"[s-bfnrtav]);
67b0d4872f532bead29307654bbc511d6083abf2afRob Landley      else if (c < 32 || c >= 127) sprintf(buf, "%03o", c);
68b0d4872f532bead29307654bbc511d6083abf2afRob Landley      else {
69b0d4872f532bead29307654bbc511d6083abf2afRob Landley        // TODO: this should be UTF8 aware.
70b0d4872f532bead29307654bbc511d6083abf2afRob Landley        sprintf(buf, "%c", c);
71b0d4872f532bead29307654bbc511d6083abf2afRob Landley      }
72b0d4872f532bead29307654bbc511d6083abf2afRob Landley    }
73b0d4872f532bead29307654bbc511d6083abf2afRob Landley  } else if (CFG_TOYBOX_FLOAT && t->type == 6) {
74b0d4872f532bead29307654bbc511d6083abf2afRob Landley    long double ld;
75b0d4872f532bead29307654bbc511d6083abf2afRob Landley    union {float f; double d; long double ld;} fdl;
76b0d4872f532bead29307654bbc511d6083abf2afRob Landley
77b0d4872f532bead29307654bbc511d6083abf2afRob Landley    memcpy(&fdl, TT.buf+*offset, t->size);
78b0d4872f532bead29307654bbc511d6083abf2afRob Landley    *offset += t->size;
79b0d4872f532bead29307654bbc511d6083abf2afRob Landley    if (sizeof(float) == t->size) {
80b0d4872f532bead29307654bbc511d6083abf2afRob Landley      ld = fdl.f;
81b0d4872f532bead29307654bbc511d6083abf2afRob Landley      pad += (throw = 8)+7;
82b0d4872f532bead29307654bbc511d6083abf2afRob Landley    } else if (sizeof(double) == t->size) {
83b0d4872f532bead29307654bbc511d6083abf2afRob Landley      ld = fdl.d;
84b0d4872f532bead29307654bbc511d6083abf2afRob Landley      pad += (throw = 17)+8;
85b0d4872f532bead29307654bbc511d6083abf2afRob Landley    } else if (sizeof(long double) == t->size) {
86b0d4872f532bead29307654bbc511d6083abf2afRob Landley      ld = fdl.ld;
87b0d4872f532bead29307654bbc511d6083abf2afRob Landley      pad += (throw = 21)+9;
88b0d4872f532bead29307654bbc511d6083abf2afRob Landley    } else error_exit("bad -tf '%d'", t->size);
89b0d4872f532bead29307654bbc511d6083abf2afRob Landley
90b0d4872f532bead29307654bbc511d6083abf2afRob Landley    sprintf(buf, "%.*Le", throw, ld);
91b0d4872f532bead29307654bbc511d6083abf2afRob Landley  // Integer types
92b0d4872f532bead29307654bbc511d6083abf2afRob Landley  } else {
93b0d4872f532bead29307654bbc511d6083abf2afRob Landley    unsigned long long ll = 0, or;
94b0d4872f532bead29307654bbc511d6083abf2afRob Landley    char *c[] = {"%*lld", "%*llu", "%0*llo", "%0*llx"},
95b0d4872f532bead29307654bbc511d6083abf2afRob Landley      *class = c[t->type-2];
96b0d4872f532bead29307654bbc511d6083abf2afRob Landley
97b0d4872f532bead29307654bbc511d6083abf2afRob Landley    // Work out width of field
98b0d4872f532bead29307654bbc511d6083abf2afRob Landley    if (t->size == 8) {
99b0d4872f532bead29307654bbc511d6083abf2afRob Landley      or = -1LL;
100b0d4872f532bead29307654bbc511d6083abf2afRob Landley      if (t->type == 2) or >>= 1;
101b0d4872f532bead29307654bbc511d6083abf2afRob Landley    } else or = (1LL<<(8*t->size))-1;
102b0d4872f532bead29307654bbc511d6083abf2afRob Landley    throw = sprintf(buf, class, 0, or);
103b0d4872f532bead29307654bbc511d6083abf2afRob Landley
104b0d4872f532bead29307654bbc511d6083abf2afRob Landley    // Accumulate integer based on size argument
105b0d4872f532bead29307654bbc511d6083abf2afRob Landley    for (k=0; k < t->size; k++) {
106b0d4872f532bead29307654bbc511d6083abf2afRob Landley      or = TT.buf[(*offset)++];
107b0d4872f532bead29307654bbc511d6083abf2afRob Landley      ll |= or << (8*(IS_BIG_ENDIAN ? t->size-k-1 : k));
108b0d4872f532bead29307654bbc511d6083abf2afRob Landley    }
109b0d4872f532bead29307654bbc511d6083abf2afRob Landley
110b0d4872f532bead29307654bbc511d6083abf2afRob Landley    // Handle negative values
111b0d4872f532bead29307654bbc511d6083abf2afRob Landley    if (t->type == 2) {
112b0d4872f532bead29307654bbc511d6083abf2afRob Landley      or = sizeof(or) - t->size;
113b0d4872f532bead29307654bbc511d6083abf2afRob Landley      throw++;
114b0d4872f532bead29307654bbc511d6083abf2afRob Landley      if (or && (ll & (1l<<((8*t->size)-1))))
115b0d4872f532bead29307654bbc511d6083abf2afRob Landley        ll |= ((or<<(8*or))-1) << (8*t->size);
116b0d4872f532bead29307654bbc511d6083abf2afRob Landley    }
117b0d4872f532bead29307654bbc511d6083abf2afRob Landley
118b0d4872f532bead29307654bbc511d6083abf2afRob Landley    sprintf(buf, class, throw, ll);
119b0d4872f532bead29307654bbc511d6083abf2afRob Landley    pad += throw+1;
120b0d4872f532bead29307654bbc511d6083abf2afRob Landley  }
121b0d4872f532bead29307654bbc511d6083abf2afRob Landley
122b0d4872f532bead29307654bbc511d6083abf2afRob Landley  return pad;
123b0d4872f532bead29307654bbc511d6083abf2afRob Landley}
124b0d4872f532bead29307654bbc511d6083abf2afRob Landley
1254625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landleystatic void od_outline(void)
126d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley{
1277aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  unsigned flags = toys.optflags;
128b0d4872f532bead29307654bbc511d6083abf2afRob Landley  char buf[128], *abases[] = {"", "%07d", "%07o", "%06x"};
129b0d4872f532bead29307654bbc511d6083abf2afRob Landley  struct odtype *types = (struct odtype *)toybuf;
130b0d4872f532bead29307654bbc511d6083abf2afRob Landley  int i, j, len, pad;
1317aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
1327aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (TT.leftover<16) memset(TT.buf+TT.leftover, 0, 16-TT.leftover);
1337aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
1347aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  // Handle duplciate lines as *
1357aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (!(flags&FLAG_v) && TT.jump_bytes != TT.pos && TT.leftover
1367aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    && !memcmp(TT.bufs, TT.bufs + 2, 16))
1377aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  {
1387aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (!TT.star) {
1397aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      xputs("*");
1407aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      TT.star++;
1417aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    }
1427aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
1437aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  // Print line position
1447aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  } else {
1457aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    TT.star = 0;
1467aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
1477aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    xprintf(abases[TT.address_idx], TT.pos);
1487aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (!TT.leftover) {
1497aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if (TT.address_idx) xputc('\n');
1507aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      return;
1517aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    }
1527aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  }
1537aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
1547aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  TT.pos += len = TT.leftover;
1557aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  TT.leftover = 0;
1567aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (TT.star) return;
1577aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
158b0d4872f532bead29307654bbc511d6083abf2afRob Landley  // Find largest "pad" of the output types.
159b0d4872f532bead29307654bbc511d6083abf2afRob Landley  for (i = pad = 0; i<TT.types; i++) {
160b0d4872f532bead29307654bbc511d6083abf2afRob Landley    int bytes = 0;
161b0d4872f532bead29307654bbc511d6083abf2afRob Landley
162b0d4872f532bead29307654bbc511d6083abf2afRob Landley    // If more than one byte of input consumed, average rounding up.
163b0d4872f532bead29307654bbc511d6083abf2afRob Landley    j = od_out_t(types+i, buf, &bytes);
164b0d4872f532bead29307654bbc511d6083abf2afRob Landley    j = (j+bytes-1)/bytes;
165b0d4872f532bead29307654bbc511d6083abf2afRob Landley
166b0d4872f532bead29307654bbc511d6083abf2afRob Landley    if (j > pad) pad = j;
167b0d4872f532bead29307654bbc511d6083abf2afRob Landley  }
168b0d4872f532bead29307654bbc511d6083abf2afRob Landley
1697aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  // For each output type, print one line
1707aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
1717aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  for (i=0; i<TT.types; i++) {
172b0d4872f532bead29307654bbc511d6083abf2afRob Landley    for (j = 0; j<len;) {
173b0d4872f532bead29307654bbc511d6083abf2afRob Landley      int bytes = j;
174b0d4872f532bead29307654bbc511d6083abf2afRob Landley
175b0d4872f532bead29307654bbc511d6083abf2afRob Landley      // pad for as many bytes as were consumed, and indent non-numbered lines
176b0d4872f532bead29307654bbc511d6083abf2afRob Landley      od_out_t(types+i, buf, &bytes);
177b0d4872f532bead29307654bbc511d6083abf2afRob Landley      xprintf("%*s", pad*(bytes-j) + 7*(!!i)*!j, buf);
178b0d4872f532bead29307654bbc511d6083abf2afRob Landley      j = bytes;
1797aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    }
1807aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    xputc('\n');
1817aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  }
1827aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
1837aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  // buffer toggle for "same as last time" check.
1847aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  TT.buf = (char *)((TT.buf == (char *)TT.bufs) ? TT.bufs+2 : TT.bufs);
185d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley}
186d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
187b0d4872f532bead29307654bbc511d6083abf2afRob Landley// Loop through input files
188d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landleystatic void do_od(int fd, char *name)
189d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley{
1907aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  // Skip input, possibly more than one entire file.
191bc382bed736d161b32e22a615489c226173ca030Rob Landley  if (TT.jump_bytes > TT.pos) {
192bc382bed736d161b32e22a615489c226173ca030Rob Landley    off_t pos = TT.jump_bytes-TT.pos, off = lskip(fd, pos);
193bc382bed736d161b32e22a615489c226173ca030Rob Landley
194bc382bed736d161b32e22a615489c226173ca030Rob Landley    if (off >= 0) TT.pos += pos-off;
195bc382bed736d161b32e22a615489c226173ca030Rob Landley    if (TT.jump_bytes > TT.pos) return;
1967aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  }
1977aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
1987aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  for(;;) {
1997aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    char *buf = TT.buf + TT.leftover;
2007aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    int len = 16 - TT.leftover;
2017aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
2027aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (toys.optflags & FLAG_N) {
2037aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if (!TT.max_count) break;
2047aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if (TT.max_count < len) len = TT.max_count;
2057aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    }
2067aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
2077aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    len = readall(fd, buf, len);
2087aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (len < 0) {
2097aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      perror_msg("%s", name);
2107aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      break;
2117aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    }
2127aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (TT.max_count) TT.max_count -= len;
2137aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    TT.leftover += len;
2147aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (TT.leftover < 16) break;
2157aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
2167aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    od_outline();
2177aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  }
218d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley}
219d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
220b0d4872f532bead29307654bbc511d6083abf2afRob Landley// Handle one -t argument (including implicit ones)
221d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landleystatic void append_base(char *base)
222d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley{
2237aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  char *s = base;
2247aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  struct odtype *types = (struct odtype *)toybuf;
2257aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  int type;
2267aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
2277aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  for (;;) {
2287aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    int size = 1;
2297aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
2307aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (!*s) return;
2317aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (TT.types >= sizeof(toybuf)/sizeof(struct odtype)) break;
2327aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (-1 == (type = stridx("acduox"USE_TOYBOX_FLOAT("f"), *(s++)))) break;
2337aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
2347aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (isdigit(*s)) {
2357aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      size = strtol(s, &s, 10);
2367aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if (type < 2 && size != 1) break;
2377aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if (CFG_TOYBOX_FLOAT && type == 6 && size == sizeof(long double));
238bc382bed736d161b32e22a615489c226173ca030Rob Landley      else if (size < 1 || size > 8) break;
2397aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    } else if (CFG_TOYBOX_FLOAT && type == 6) {
2407aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      int sizes[] = {sizeof(float), sizeof(double), sizeof(long double)};
2417aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if (-1 == (size = stridx("FDL", *s))) size = sizeof(double);
2427aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      else {
2437aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley        s++;
2447aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley        size = sizes[size];
2457aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      }
2467aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    } else if (type > 1) {
2477aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if (-1 == (size = stridx("CSIL", *s))) size = 4;
2487aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      else {
2497aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley        s++;
2507aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley        size = 1 << size;
2517aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      }
2527aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    }
2537aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
2547aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    types[TT.types].type = type;
2557aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    types[TT.types].size = size;
2567aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    TT.types++;
2577aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  }
2587aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley
2597aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  error_exit("bad -t %s", base);
260d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley}
261d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley
262d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landleyvoid od_main(void)
263d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley{
2647aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  struct arg_list *arg;
2654625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley
2667aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  TT.buf = (char *)TT.bufs;
2674625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley
2687aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (!TT.address_base) TT.address_idx = 2;
2697aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  else if (0>(TT.address_idx = stridx("ndox", *TT.address_base)))
2707aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    error_exit("bad -A '%c'", *TT.address_base);
2714625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley
2727aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  // Collect -t entries
2734625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley
2747aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  for (arg = TT.output_base; arg; arg = arg->next) append_base(arg->arg);
2757aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (toys.optflags & FLAG_b) append_base("o1");
276bc382bed736d161b32e22a615489c226173ca030Rob Landley  if (toys.optflags & FLAG_c) append_base("c");
2777aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (toys.optflags & FLAG_d) append_base("u2");
2787aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (toys.optflags & FLAG_o) append_base("o2");
2797aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (toys.optflags & FLAG_s) append_base("d2");
2807aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (toys.optflags & FLAG_x) append_base("x2");
2815f6ec72f8eafb1598fe40d388a38137ce52b03a0Rob Landley  if (!TT.types) append_base("o2");
2824625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley
2837aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  loopfiles(toys.optargs, do_od);
2844625d5e9d261d1231ad08cd6d2b7e7e4ba5b87f4Rob Landley
2857aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  if (TT.leftover) od_outline();
2867aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  od_outline();
287d2e47f2d01c4189ecb36772cc1d9d982b57d9b56Rob Landley}
288