--- od.1 | 3 ++ od.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/od.1 b/od.1 index 6fe99c8..b47d752 100644 --- a/od.1 +++ b/od.1 _AT_@ -30,6 +30,9 @@ he\fIx\fRadecimal | \fIn\fRone. If unspecified, the default is octal. Display the content as n\fIa\fRmed character, \fIc\fRharacter, signed \fId\fRecimal, \fIo\fRctal, \fIu\fRnsigned decimal, or he\fIx\fRadecimal. If unspecified, the default is octal. +Another character is optional indicating size of \fIC\fRhar, \fII\fRnt, +\fIS\fRhort, or \fIL\fRong. If unspecified the default is short, or +char for types a or c. .It Fl v Always set. Write all input data, including duplicate lines. .It Fl j Ar skip diff --git a/od.c b/od.c index eab7f9e..1ab1ea3 100644 --- a/od.c +++ b/od.c _AT_@ -11,6 +11,7 @@ static off_t maxbytes = -1; static off_t skip = 0; static unsigned char addrbase = 'o'; static unsigned char type = 'o'; +static unsigned char size = 'S'; static void printaddress(FILE *f, off_t addr) _AT_@ -26,7 +27,7 @@ printaddress(FILE *f, off_t addr) } static void -printchar(FILE *f, unsigned char c) +printvalue(FILE *f, unsigned char *c) { const char *namedict[] = { "nul", "soh", "stx", "etx", "eot", "enq", "ack", _AT_@ -41,55 +42,95 @@ printchar(FILE *f, unsigned char c) ['\n'] = "\\n", ['\v'] = "\\v", ['\f'] = "\\f", ['\r'] = "\\r", }; - const char *fmtdict[] = { - ['d'] = "%4hhd ", ['o'] = "%03hho ", - ['u'] = "%3hhu ", ['x'] = "%02hhx ", + const char *fmtdict[][130] = { + ['d']['C'] = "%4hhd ", ['o']['C'] = "%03hho ", + ['u']['C'] = "%3hhu ", ['x']['C'] = "%02hhx ", + ['d']['S'] = "%6hd ", ['o']['S'] = "%06ho ", + ['u']['S'] = "%5hu ", ['x']['S'] = "%04hx ", + ['d']['I'] = "%11d ", ['o']['I'] = "%011o ", + ['u']['I'] = "%10u ", ['x']['I'] = "%08x ", + ['d']['L'] = "%20ld ", ['o']['L'] = "%022lo ", + ['u']['L'] = "%20lu ", ['x']['L'] = "%016lx ", }; switch (type) { case 'a': - c &= ~128; /* clear high bit as required by standard */ - if (c < LEN(namedict) || c == 127) { - fprintf(f, "%3s ", (c == 127) ? "del" : namedict[c]); + *c &= ~128; /* clear high bit as required by standard */ + if (*c < LEN(namedict) || *c == 127) { + fprintf(f, "%3s ", (*c == 127) ? "del" : namedict[*c]); } else { - fprintf(f, "%3c ", c); + fprintf(f, "%3c ", *c); } break; case 'c': - if (strchr("\a\b\t\n\b\f\r\0", c)) { - fprintf(f, "%3s ", escdict[c]); + if (strchr("\a\b\t\n\v\b\f\r\0", *c)) { + fprintf(f, "%3s ", escdict[*c]); } else { - fprintf(f, "%3c ", c); + fprintf(f, "%3c ", *c); } break; default: - fprintf(f, fmtdict[type], c); + switch (size) { + case 'C': + fprintf(f, fmtdict[type][size], *c); + break; + case 'I': + fprintf(f, fmtdict[type][size], * (int *) c); + break; + case 'L': + fprintf(f, fmtdict[type][size], * (long *) c); + break; + case 'S': + default: + fprintf(f, fmtdict[type][size], * (short *) c); + break; + } } } static void +clear(unsigned char * buffer, int size) +{ + for (int i = 0; i < size; ++i) + buffer[i] = 0; +} + +static void od(FILE *in, char *in_name, FILE *out, char *out_name) { - off_t addr; - size_t i, chunklen; - unsigned char buf[BUFSIZ]; + off_t addr, counter; + size_t chunklen, incr; + unsigned char buf[1], value[sizeof(long)]; + const int sizedict[] = { + ['C'] = sizeof(char), ['I'] = sizeof(int), ['L'] = sizeof(long), + ['S'] = sizeof(short), + }; - for (addr = 0; (chunklen = fread(buf, 1, BUFSIZ, in)); ) { - for (i = 0; i < chunklen && (maxbytes == -1 || - (addr - skip) < maxbytes); ++i, ++addr) { - if (addr - skip < 0) - continue; - if (((addr - skip) % bytes_per_line) == 0) { - if (addr - skip) - fputc('\n', out); - printaddress(out, addr); - } - printchar(out, buf[i]); + incr = sizedict[size]; + for (addr = 0; (addr < skip) && (chunklen = fread(buf, 1, 1, in)); ++addr) + if (feof(in) || ferror(in)) + break; + clear(value, incr); + counter = addr - skip; + for ( ; ((maxbytes == -1 || (counter < maxbytes)) && + (chunklen = fread(buf, 1, 1, in))); ++addr, ++counter) { + if ((counter % bytes_per_line) == 0) { + if (counter) + fputc('\n', out); + printaddress(out, addr); + } + value[counter % incr] = buf[0]; + if ( ((counter % incr) == (incr - 1)) && counter) { + printvalue(out, value); + clear(value, incr); } - if (feof(in) || ferror(in) || ferror(out)) + if (ferror(in) || ferror(out)) break; } - if (addr - skip > 0) + if ((counter > 0) && (counter % incr) > 0) { + printvalue(out, value); + } + if (counter > 0) fputc('\n', out); if (addrbase != 'n') { printaddress(out, MAX(addr, skip)); _AT_@ -127,10 +168,18 @@ main(int argc, char *argv[]) break; case 't': s = EARGF(usage()); - if (strlen(s) != 1 || !strchr("acdoux", s[0])) + if (strlen(s) < 1 || strlen(s) > 2 || !strchr("acdoux", s[0])) usage(); type = s[0]; - break; + if (strlen(s) == 2) { + if (!strchr("doux", s[0]) || !strchr("CISL", s[1])) { + usage(); + } else { + size = s[1]; + } + } + if (type == 'a' || type == 'c') + size = 'C'; case 'v': /* Always set. Use "uniq -f 1 -c" to handle duplicate lines. */ break; -- 1.9.1 --------------090204040209020607000307--Received on Mon Sep 17 2001 - 00:00:00 CEST
This archive was generated by hypermail 2.3.0 : Fri Oct 02 2015 - 07:00:12 CEST