Created od, with improvements suggested by FRIGN
This commit is contained in:
parent
521c3734af
commit
fd0d1e4567
2
LICENSE
2
LICENSE
@ -54,7 +54,7 @@ Authors/contributors include:
|
|||||||
© 2014 Ari Malinen <ari.malinen@gmail.com>
|
© 2014 Ari Malinen <ari.malinen@gmail.com>
|
||||||
© 2014 Brandon Mulcahy <brandon@jangler.info>
|
© 2014 Brandon Mulcahy <brandon@jangler.info>
|
||||||
© 2014 Adria Garriga <rhaps0dy@installgentoo.com>
|
© 2014 Adria Garriga <rhaps0dy@installgentoo.com>
|
||||||
© 2014 Greg Reagle <greg.reagle@umbc.edu>
|
© 2014-2015 Greg Reagle <greg.reagle@umbc.edu>
|
||||||
© 2015 Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com>
|
© 2015 Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com>
|
||||||
© 2015 Quentin Rameau <quinq@quinq.eu.org>
|
© 2015 Quentin Rameau <quinq@quinq.eu.org>
|
||||||
© 2015 Dionysis Grigoropoulos <info@erethon.com>
|
© 2015 Dionysis Grigoropoulos <info@erethon.com>
|
||||||
|
1
Makefile
1
Makefile
@ -115,6 +115,7 @@ BIN =\
|
|||||||
nice\
|
nice\
|
||||||
nl\
|
nl\
|
||||||
nohup\
|
nohup\
|
||||||
|
od\
|
||||||
paste\
|
paste\
|
||||||
printenv\
|
printenv\
|
||||||
printf\
|
printf\
|
||||||
|
1
README
1
README
@ -54,6 +54,7 @@ The following tools are implemented:
|
|||||||
=*|o nice .
|
=*|o nice .
|
||||||
#*|o nl .
|
#*|o nl .
|
||||||
=*|o nohup .
|
=*|o nohup .
|
||||||
|
od a lot
|
||||||
#*|o paste .
|
#*|o paste .
|
||||||
=*|x printenv .
|
=*|x printenv .
|
||||||
#*|o printf .
|
#*|o printf .
|
||||||
|
1
TODO
1
TODO
@ -10,7 +10,6 @@ diff
|
|||||||
ed
|
ed
|
||||||
getconf
|
getconf
|
||||||
install
|
install
|
||||||
od
|
|
||||||
patch
|
patch
|
||||||
pathchk
|
pathchk
|
||||||
stty
|
stty
|
||||||
|
30
od.1
Normal file
30
od.1
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
.Dd September 28, 2015
|
||||||
|
.Dt OD 1
|
||||||
|
.Os sbase
|
||||||
|
.Sh NAME
|
||||||
|
.Nm od
|
||||||
|
.Nd octal dump
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl A Ar d|o|x|n
|
||||||
|
.Op Fl t Ar a|c|d|o|u|x
|
||||||
|
.Op Ar file...
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
writes an octal dump of each
|
||||||
|
.Ar file
|
||||||
|
to stdout. If no
|
||||||
|
.Ar file
|
||||||
|
is given, then
|
||||||
|
.Nm
|
||||||
|
reads from stdin.
|
||||||
|
.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|o|u|x
|
||||||
|
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.
|
||||||
|
.El
|
177
od.c
Normal file
177
od.c
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
static char addr_radix = 'o';
|
||||||
|
static char *type = "o";
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
eprintf("usage: %s [-A d|o|x|n] [-t a|c|d|o|u|x] [file ...]\n", argv0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_address(FILE *f, size_t addr)
|
||||||
|
{
|
||||||
|
switch (addr_radix) {
|
||||||
|
case 'x':
|
||||||
|
fprintf(f, "%06zx ", addr);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
fprintf(f, "%06zd ", addr);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
fprintf(f, "%s", " ");
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
default:
|
||||||
|
fprintf(f, "%06zo ", addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char char_string[2];
|
||||||
|
|
||||||
|
static const 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
named_char(unsigned char c)
|
||||||
|
{
|
||||||
|
static const int table_size = 33;
|
||||||
|
static const char * named_chars[] = {"nul", "soh", "stx", "etx", "eot",
|
||||||
|
"enq", "ack", "bel", "bs", "ht", "nl", "vt", "ff", "cr", "so", "si",
|
||||||
|
"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", "can", "em",
|
||||||
|
"sub", "esc", "fs", "gs", "rs", "us", "sp"};
|
||||||
|
|
||||||
|
c &= ~128; /* clear high bit of byte, as required by standard */
|
||||||
|
if (c < table_size) {
|
||||||
|
return named_chars[c];
|
||||||
|
} else if (c == 127) {
|
||||||
|
return "del";
|
||||||
|
} else {
|
||||||
|
char_string[0] = c;
|
||||||
|
char_string[1] = '\0';
|
||||||
|
return char_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static 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 'o':
|
||||||
|
fprintf(f, "%03hho ", cont);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
fprintf(f, "%3hhu ", cont);
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
fprintf(f, "%02hhx ", cont);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
od(FILE *fp_in, const char *name_in, FILE *fp_out, const char *name_out)
|
||||||
|
{
|
||||||
|
unsigned char buf[BUFSIZ];
|
||||||
|
size_t addr, buf_size, i;
|
||||||
|
const size_t bytes_per_line = 16;
|
||||||
|
|
||||||
|
addr = 0;
|
||||||
|
for (; (buf_size = fread(buf, 1, BUFSIZ, fp_in)); ) {
|
||||||
|
for (i = 0; i < buf_size; ++i, ++addr) {
|
||||||
|
if ((addr % bytes_per_line) == 0) {
|
||||||
|
if (addr != 0) fprintf(fp_out, "%s", "\n");
|
||||||
|
print_address(fp_out, addr);
|
||||||
|
}
|
||||||
|
print_content(fp_out, type[0], buf[i]);
|
||||||
|
}
|
||||||
|
if (feof(fp_in) || ferror(fp_in) || ferror(fp_out))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(fp_out, "\n%.7zx \n", addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int ret = 0;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
ARGBEGIN {
|
||||||
|
case 'A':
|
||||||
|
s = EARGF(usage());
|
||||||
|
if (strlen(s) > 1 || !strchr("doxn", s[0]))
|
||||||
|
usage();
|
||||||
|
addr_radix = s[0];
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
type = EARGF(usage());
|
||||||
|
if (strlen(type) > 1 || !strchr("acdoux", type[0]))
|
||||||
|
usage();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
} ARGEND;
|
||||||
|
|
||||||
|
if (!argc) {
|
||||||
|
od(stdin, "<stdin>", stdout, "<stdout>");
|
||||||
|
} else {
|
||||||
|
for (; *argv; argc--, argv++) {
|
||||||
|
if (!strcmp(*argv, "-")) {
|
||||||
|
*argv = "<stdin>";
|
||||||
|
fp = stdin;
|
||||||
|
} else if (!(fp = fopen(*argv, "r"))) {
|
||||||
|
weprintf("fopen %s:", *argv);
|
||||||
|
ret = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
od(fp, *argv, stdout, "<stdout>");
|
||||||
|
if (fp != stdin && fshut(fp, *argv))
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user