diff options
Diffstat (limited to 'toys/posix/od.c')
-rw-r--r-- | toys/posix/od.c | 434 |
1 files changed, 216 insertions, 218 deletions
diff --git a/toys/posix/od.c b/toys/posix/od.c index ef420b87..948a99e1 100644 --- a/toys/posix/od.c +++ b/toys/posix/od.c @@ -1,6 +1,4 @@ -/* vi: set sw=4 ts=4: - * - * od.c - Provide octal/hex dumps of data +/* od.c - Provide octal/hex dumps of data * * Copyright 2012 Andre Renaud <andre@bluewatersys.com> * Copyright 2012 Rob Landley <rob@landley.net> @@ -10,253 +8,253 @@ USE_OD(NEWTOY(od, "j#vN#xsodcbA:t*", TOYFLAG_USR|TOYFLAG_BIN)) config OD - bool "od" - default y - help - usage: od [-bdosxv] [-j #] [-N #] [-A doxn] [-t arg] + bool "od" + default y + help + usage: od [-bdosxv] [-j #] [-N #] [-A doxn] [-t arg] - -A Address base (decimal, octal, hexdecimal, none) - -t output type(s) a (ascii) c (char) d (decimal) foux + -A Address base (decimal, octal, hexdecimal, none) + -t output type(s) a (ascii) c (char) d (decimal) foux */ #define FOR_od #include "toys.h" GLOBALS( - struct arg_list *output_base; - char *address_base; - long max_count; - long jump_bytes; - - unsigned types, leftover, star, address_idx; - char *buf; - uint64_t bufs[4]; // force 64-bit alignment - off_t pos; + struct arg_list *output_base; + char *address_base; + long max_count; + long jump_bytes; + + unsigned types, leftover, star, address_idx; + char *buf; + uint64_t bufs[4]; // force 64-bit alignment + off_t pos; ) static char *ascii = "nulsohstxetxeotenqackbel bs ht nl vt ff cr so si" - "dledc1dc2dc3dc4naksynetbcan emsubesc fs gs rs us sp"; + "dledc1dc2dc3dc4naksynetbcan emsubesc fs gs rs us sp"; struct odtype { - int type; - int size; + int type; + int size; }; static void od_outline(void) { - unsigned flags = toys.optflags; - char *abases[] = {"", "%07d", "%07o", "%06x"}; - struct odtype *types = (struct odtype *)toybuf, *t; - int i, len; - - if (TT.leftover<16) memset(TT.buf+TT.leftover, 0, 16-TT.leftover); - - // Handle duplciate lines as * - if (!(flags&FLAG_v) && TT.jump_bytes != TT.pos && TT.leftover - && !memcmp(TT.bufs, TT.bufs + 2, 16)) - { - if (!TT.star) { - xputs("*"); - TT.star++; - } - - // Print line position - } else { - TT.star = 0; - - xprintf(abases[TT.address_idx], TT.pos); - if (!TT.leftover) { - if (TT.address_idx) xputc('\n'); - return; - } - } - - TT.pos += len = TT.leftover; - TT.leftover = 0; - if (TT.star) return; - - // For each output type, print one line - - for (i=0; i<TT.types; i++) { - int j = 0, pad = i ? 8 : 0; - char buf[128]; - - t = types+i; - while (j<len) { - unsigned k; - int throw = 0; - - // Handle ascii - if (t->type < 2) { - char c = TT.buf[j++]; - 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+j, t->size); - j += 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[j++]; - 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; - } - xprintf("%*s", pad, buf); - pad = 0; - } - xputc('\n'); - } - - // buffer toggle for "same as last time" check. - TT.buf = (char *)((TT.buf == (char *)TT.bufs) ? TT.bufs+2 : TT.bufs); + unsigned flags = toys.optflags; + char *abases[] = {"", "%07d", "%07o", "%06x"}; + struct odtype *types = (struct odtype *)toybuf, *t; + int i, len; + + if (TT.leftover<16) memset(TT.buf+TT.leftover, 0, 16-TT.leftover); + + // Handle duplciate lines as * + if (!(flags&FLAG_v) && TT.jump_bytes != TT.pos && TT.leftover + && !memcmp(TT.bufs, TT.bufs + 2, 16)) + { + if (!TT.star) { + xputs("*"); + TT.star++; + } + + // Print line position + } else { + TT.star = 0; + + xprintf(abases[TT.address_idx], TT.pos); + if (!TT.leftover) { + if (TT.address_idx) xputc('\n'); + return; + } + } + + TT.pos += len = TT.leftover; + TT.leftover = 0; + if (TT.star) return; + + // For each output type, print one line + + for (i=0; i<TT.types; i++) { + int j = 0, pad = i ? 8 : 0; + char buf[128]; + + t = types+i; + while (j<len) { + unsigned k; + int throw = 0; + + // Handle ascii + if (t->type < 2) { + char c = TT.buf[j++]; + 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+j, t->size); + j += 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[j++]; + 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; + } + xprintf("%*s", pad, buf); + pad = 0; + } + xputc('\n'); + } + + // buffer toggle for "same as last time" check. + TT.buf = (char *)((TT.buf == (char *)TT.bufs) ? TT.bufs+2 : TT.bufs); } static void do_od(int fd, char *name) { - // Skip input, possibly more than one entire file. - if (TT.jump_bytes < TT.pos) { - off_t off = lskip(fd, TT.jump_bytes); - if (off > 0) TT.pos += off; - if (TT.jump_bytes < TT.pos) return; - } - - for(;;) { - char *buf = TT.buf + TT.leftover; - int len = 16 - 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("%s", name); - break; - } - if (TT.max_count) TT.max_count -= len; - TT.leftover += len; - if (TT.leftover < 16) break; - - od_outline(); - } + // Skip input, possibly more than one entire file. + if (TT.jump_bytes < TT.pos) { + off_t off = lskip(fd, TT.jump_bytes); + if (off > 0) TT.pos += off; + if (TT.jump_bytes < TT.pos) return; + } + + for(;;) { + char *buf = TT.buf + TT.leftover; + int len = 16 - 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("%s", name); + break; + } + if (TT.max_count) TT.max_count -= len; + TT.leftover += len; + if (TT.leftover < 16) break; + + od_outline(); + } } 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 < 0 || 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); + 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 < 0 || 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; + struct arg_list *arg; - TT.buf = (char *)TT.bufs; + TT.buf = (char *)TT.bufs; - 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); + 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 + // 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_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.output_base) append_base("o2"); + 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_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.output_base) append_base("o2"); - loopfiles(toys.optargs, do_od); + loopfiles(toys.optargs, do_od); - if (TT.leftover) od_outline(); - od_outline(); + if (TT.leftover) od_outline(); + od_outline(); } |