---
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 : Thu Oct 01 2015 - 22:48:09 CEST