[PATCH] od: added -t option

From: Greg Reagle <greg.reagle_AT_umbc.edu>
Date: Mon, 28 Sep 2015 23:05:25 -0400

---
 od.1 |    6 ++-
 od.c |  152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 152 insertions(+), 6 deletions(-)
diff --git a/od.1 b/od.1
index 783799b..cd00f98 100644
--- a/od.1
+++ b/od.1
_AT_@ -7,6 +7,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl A Ar d|o|x|n
+.Op Fl t Ar a|c|d|f|o|u|x
 .Op Ar file...
 .Sh DESCRIPTION
 .Nm
_AT_@ -20,6 +21,9 @@ is a filter, i.e. reads from standard input.
 .Sh OPTIONS
 .Bl -tag -width Ds
 .It Fl A Ar d|o|x|n
-
 Display the address in base \fId\fRecimal | \fIo\fRctal | he\fIx\fRadecimal |
 \fIn\fRone.  If unspecified, the default is octal.
+.It Fl t Ar a|c|d|f|o|u|x
+Display the content as n\fIa\fRmed character, \fIc\fRharacter, signed
+\fId\fRecimal, \fIf\fRloating point, \fIo\fRctal, \fIu\fRnsigned decimal, or
+he\fIx\fRadecimal.  If unspecified, the default is octal.
diff --git a/od.c b/od.c
index a766d59..f09e4ec 100644
--- a/od.c
+++ b/od.c
_AT_@ -5,11 +5,12 @@
 #include "util.h"
 
 static char *address_radix = "o";
+static char *type = "o";
 
 static void
 usage(void)
 {
-	eprintf("usage: %s [-A d|o|x|n] [file ...]\n", argv0);
+	eprintf("usage: %s [-A d|o|x|n] [-t a|c|d|f|o|u|x] [file ...]\n", argv0);
 }
 
 void
_AT_@ -17,13 +18,13 @@ print_address(FILE *f, char radix, size_t addr)
 {
 	switch (radix) {
 	case 'x':
-		fprintf(f, "%.7zx ", addr);
+		fprintf(f, "%06zx ", addr);
 		break;
 	case 'd':
-		fprintf(f, "%.7zd ", addr);
+		fprintf(f, "%06zd ", addr);
 		break;
 	case 'o':
-		fprintf(f, "%.7zo ", addr);
+		fprintf(f, "%06zo ", addr);
 		break;
 	case 'n':
 		fprintf(f, "%s", " ");
_AT_@ -33,6 +34,142 @@ print_address(FILE *f, char radix, size_t addr)
 	}
 }
 
+static char char_string[2];
+
+char *
+escaped_char(unsigned char c)
+{
+	switch (c) {
+	case '\0':
+		return("\\0");
+	case '\a':
+		return("\\a");
+	case '\b':
+		return("\\b");
+	case '\t':
+		return("\\t");
+	case '\n':
+		return("\\n");
+	case '\v':
+		return("\\v");
+	case '\f':
+		return("\\f");
+	case '\r':
+		return("\\r");
+	default:
+		char_string[0] = c;
+		char_string[1] = '\0';
+		return char_string;
+	}
+}
+
+char *
+named_char(unsigned char c)
+{
+	switch (c) {
+	case 000:
+		return("nul");
+	case 001:
+		return("soh");
+	case 002:
+		return("stx");
+	case 003:
+		return("etx");
+	case 004:
+		return("eot");
+	case 005:
+		return("enq");
+	case 006:
+		return("ack");
+	case 007:
+		return("bel");
+	case 010:
+		return("bs");
+	case 011:
+		return("ht");
+	case 012:
+		return("nl");
+	case 013:
+		return("vt");
+	case 014:
+		return("ff");
+	case 015:
+		return("cr");
+	case 016:
+		return("so");
+	case 017:
+		return("si");
+	case 020:
+		return("dle");
+	case 021:
+		return("dc1");
+	case 022:
+		return("dc2");
+	case 023:
+		return("dc3");
+	case 024:
+		return("dc4");
+	case 025:
+		return("nak");
+	case 026:
+		return("syn");
+	case 027:
+		return("etb");
+	case 030:
+		return("can");
+	case 031:
+		return("em");
+	case 032:
+		return("sub");
+	case 033:
+		return("esc");
+	case 034:
+		return("fs");
+	case 035:
+		return("gs");
+	case 036:
+		return("rs");
+	case 037:
+		return("us");
+	case 040:
+		return("sp");
+	case 0177:
+		return("del");
+	default:
+		char_string[0] = c;
+		char_string[1] = '\0';
+		return char_string;
+	}
+}
+
+void
+print_content(FILE *f, char type, unsigned char cont)
+{
+	switch (type) {
+	case 'a':
+		fprintf(f, "%3s ", named_char(cont));
+		break;
+	case 'c':
+		fprintf(f, "%3s ", escaped_char(cont));
+		break;
+	case 'd':
+		fprintf(f, "%4hhd ", cont);
+		break;
+	case 'f':
+		usage();
+		break;
+	case 'o':
+		fprintf(f, "%03hho ", cont);
+		break;
+	case 'u':
+		fprintf(f, "%3hhu ", cont);
+		break;
+	case 'x':
+		fprintf(f, "%02hhx ", cont);
+		break;
+	}
+}
+
 void
 od(FILE *fp_in, const char *s_in, FILE *fp_out, const char *s_out)
 {
_AT_@ -49,7 +186,7 @@ od(FILE *fp_in, const char *s_in, FILE *fp_out, const char *s_out)
 				if (addr != 0) fprintf(fp_out, "%s", "\n");
 				print_address(fp_out, address_radix[0], addr);
 			}
-			fprintf(fp_out, "%.2hhx ", buf[i]);
+			print_content(fp_out, type[0], buf[i]);
 		}
 		if (feof(fp_in) || ferror(fp_in) || ferror(fp_out))
 			break;
_AT_@ -69,6 +206,11 @@ main(int argc, char *argv[])
 		if ((strlen(address_radix) > 1) || (!strchr("doxn", address_radix[0])))
 			usage();
 		break;
+	case 't':
+		type = EARGF(usage());
+		if ((strlen(type) > 1) || (!strchr("acdfoux", type[0])))
+			usage();
+		break;
 	default:
 		usage();
 	} ARGEND;
-- 
1.7.10.4
--------------030903090506000903070208--
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Tue Sep 29 2015 - 10:48:10 CEST