coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

coreutils/src/od.c (366 lines, 12 KiB) -rw-r--r-- file download

4540c2a Jamozed 2020-07-06 23:15:03
0
// od.c, version 0.8.1
c1461fb Jamozed 2020-06-27 14:35:08
1
// OMKOV coreutils implementation of POSIX od
c1461fb Jamozed 2020-06-27 14:35:08
2
// Copyright (C) 2020, Jakob Wakeling
e2140ec Jamozed 2022-03-06 15:27:45
3
// MIT Licence
c1461fb Jamozed 2020-06-27 14:35:08
4
c1461fb Jamozed 2020-06-27 14:35:08
5
/*
4540c2a Jamozed 2020-07-06 23:15:03
6
	TODO Improve error handling
c1461fb Jamozed 2020-06-27 14:35:08
7
	TODO Implement [[+]offset[.][b]] operand as required by POSIX.
c1461fb Jamozed 2020-06-27 14:35:08
8
	TODO Fix segfault when using standard input.
c1461fb Jamozed 2020-06-27 14:35:08
9
*/
c1461fb Jamozed 2020-06-27 14:35:08
10
b181413 Jamozed 2022-02-05 22:32:00
11
#include "util/error.h"
b181413 Jamozed 2022-02-05 22:32:00
12
#include "util/optget.h"
4540c2a Jamozed 2020-07-06 23:15:03
13
c1461fb Jamozed 2020-06-27 14:35:08
14
#include <errno.h>
c1461fb Jamozed 2020-06-27 14:35:08
15
#include <limits.h>
c1461fb Jamozed 2020-06-27 14:35:08
16
#include <stdbool.h>
c1461fb Jamozed 2020-06-27 14:35:08
17
#include <stdint.h>
c1461fb Jamozed 2020-06-27 14:35:08
18
#include <stdio.h>
c1461fb Jamozed 2020-06-27 14:35:08
19
#include <stdlib.h>
30cf081 Jamozed 2020-08-28 23:01:02
20
#include <string.h>
4540c2a Jamozed 2020-07-06 23:15:03
21
4540c2a Jamozed 2020-07-06 23:15:03
22
#define VERSION "0.8.1"
30cf081 Jamozed 2020-08-28 23:01:02
23
30cf081 Jamozed 2020-08-28 23:01:02
24
static struct lop lops[] = {
30cf081 Jamozed 2020-08-28 23:01:02
25
	{ "help",    ARG_NUL, 256 },
30cf081 Jamozed 2020-08-28 23:01:02
26
	{ "version", ARG_NUL, 257 },
30cf081 Jamozed 2020-08-28 23:01:02
27
	{ NULL, 0, 0 }
30cf081 Jamozed 2020-08-28 23:01:02
28
};
c1461fb Jamozed 2020-06-27 14:35:08
29
c1461fb Jamozed 2020-06-27 14:35:08
30
typedef struct {
c1461fb Jamozed 2020-06-27 14:35:08
31
	union {
c1461fb Jamozed 2020-06-27 14:35:08
32
		uint8_t  i8[16]; uint16_t i16[8];
c1461fb Jamozed 2020-06-27 14:35:08
33
		uint32_t i32[4]; uint64_t i64[2];
c1461fb Jamozed 2020-06-27 14:35:08
34
		float    f32[4]; double   f64[2];
c1461fb Jamozed 2020-06-27 14:35:08
35
	};
c1461fb Jamozed 2020-06-27 14:35:08
36
	long count;
c1461fb Jamozed 2020-06-27 14:35:08
37
} block_t;
c1461fb Jamozed 2020-06-27 14:35:08
38
c1461fb Jamozed 2020-06-27 14:35:08
39
typedef struct { int type, bytes, pads, padm; char *form; } type_t;
c1461fb Jamozed 2020-06-27 14:35:08
40
typedef struct { int *data; size_t cap, len; } list_t;
c1461fb Jamozed 2020-06-27 14:35:08
41
c1461fb Jamozed 2020-06-27 14:35:08
42
enum { ta = 19, tb = 4, tc = 20, td = 9, tl = 21, to = 5, ts = 1, tx = 13  };
c1461fb Jamozed 2020-06-27 14:35:08
43
static type_t types[] = {
c1461fb Jamozed 2020-06-27 14:35:08
44
	{ 'd', 1,  4, 80, "%4d"     }, { 'd', 2,  6, 56, "%6d"     },
c1461fb Jamozed 2020-06-27 14:35:08
45
	{ 'd', 4, 11, 48, "%11d"    }, { 'd', 8, 21, 44, "%21ld"   },
c1461fb Jamozed 2020-06-27 14:35:08
46
	{ 'o', 1,  3, 64, "%03hho"  }, { 'o', 2,  6, 56, "%06ho"   },
c1461fb Jamozed 2020-06-27 14:35:08
47
	{ 'o', 4, 11, 48, "%011o"   }, { 'o', 8, 22, 46, "%022lo"  },
c1461fb Jamozed 2020-06-27 14:35:08
48
	{ 'u', 1,  3, 64, "%3hhu"   }, { 'u', 2,  5, 48, "%5hu"    },
c1461fb Jamozed 2020-06-27 14:35:08
49
	{ 'u', 4, 10, 44, "%10u"    }, { 'u', 8, 20, 42, "%20lu"   },
c1461fb Jamozed 2020-06-27 14:35:08
50
	{ 'x', 1,  2, 48, "%2hhx"   }, { 'x', 2,  4, 40, "%4hx"    },
c1461fb Jamozed 2020-06-27 14:35:08
51
	{ 'x', 4,  8, 36, "%8x"     }, { 'x', 8, 16, 34, "%16lx"   },
c1461fb Jamozed 2020-06-27 14:35:08
52
	{ 'f', 4, 15, 64, "%15.7e"  }, { 'f', 8, 22, 46, "%22.14e" },
c1461fb Jamozed 2020-06-27 14:35:08
53
	{  0 , 0,  0,  0, NULL      }, { 'a', 1,  3, 64, ""        },
c1461fb Jamozed 2020-06-27 14:35:08
54
	{ 'c', 1,  3, 64, ""        }, { 'l', 1,  3, 64, ""        }
c1461fb Jamozed 2020-06-27 14:35:08
55
};
c1461fb Jamozed 2020-06-27 14:35:08
56
c1461fb Jamozed 2020-06-27 14:35:08
57
static const char *const aTABL[] = {
c1461fb Jamozed 2020-06-27 14:35:08
58
	"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
c1461fb Jamozed 2020-06-27 14:35:08
59
	" bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
c1461fb Jamozed 2020-06-27 14:35:08
60
	"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
c1461fb Jamozed 2020-06-27 14:35:08
61
	"can", " em", "sub", "esc", " fs", " gs", " rs", " us",
c1461fb Jamozed 2020-06-27 14:35:08
62
	" sp"
c1461fb Jamozed 2020-06-27 14:35:08
63
};
c1461fb Jamozed 2020-06-27 14:35:08
64
static const char *const cTABL[] = {
c1461fb Jamozed 2020-06-27 14:35:08
65
	" \\0", "001",  "002",  "003",  "004",  "005",  "006",  " \\a",
c1461fb Jamozed 2020-06-27 14:35:08
66
	" \\b", " \\t", " \\n", " \\v", " \\f", " \\r", "016",  "017",
c1461fb Jamozed 2020-06-27 14:35:08
67
	"020",  "021",  "022",  "023",  "024",  "025",  "026",  "027",
c1461fb Jamozed 2020-06-27 14:35:08
68
	"030",  "031",  "032",  "033",  "034",  "035",  "036",  "037"
c1461fb Jamozed 2020-06-27 14:35:08
69
};
c1461fb Jamozed 2020-06-27 14:35:08
70
static const char *const lTABL[] = {
c1461fb Jamozed 2020-06-27 14:35:08
71
	" \\0", "001",  "002",  "003",  "004",  "005",  "006",  "007",
c1461fb Jamozed 2020-06-27 14:35:08
72
	" \\b", " \\t", " \\n", "013",  " \\f", " \\r", "016",  "017",
c1461fb Jamozed 2020-06-27 14:35:08
73
	"020",  "021",  "022",  "023",  "024",  "025",  "026",  "027",
c1461fb Jamozed 2020-06-27 14:35:08
74
	"030",  "031",  "032",  "033",  "034",  "035",  "036",  "037",
c1461fb Jamozed 2020-06-27 14:35:08
75
};
c1461fb Jamozed 2020-06-27 14:35:08
76
c1461fb Jamozed 2020-06-27 14:35:08
77
static char Aform[] = "%08jo";
c1461fb Jamozed 2020-06-27 14:35:08
78
static bool vflag;
c1461fb Jamozed 2020-06-27 14:35:08
79
static bool Nflag;
c1461fb Jamozed 2020-06-27 14:35:08
80
c1461fb Jamozed 2020-06-27 14:35:08
81
static uintmax_t start, limit, offset, total;
c1461fb Jamozed 2020-06-27 14:35:08
82
static list_t tlist; static int mpad = 0;
c1461fb Jamozed 2020-06-27 14:35:08
83
c1461fb Jamozed 2020-06-27 14:35:08
84
static char **files; static FILE *file;
c1461fb Jamozed 2020-06-27 14:35:08
85
c1461fb Jamozed 2020-06-27 14:35:08
86
static inline uintmax_t bparse(char *str);
c1461fb Jamozed 2020-06-27 14:35:08
87
static inline int tparse(char *str);
c1461fb Jamozed 2020-06-27 14:35:08
88
static inline int skip(uintmax_t offset);
c1461fb Jamozed 2020-06-27 14:35:08
89
c1461fb Jamozed 2020-06-27 14:35:08
90
static inline void aprint_generic(uintmax_t addr, char c);
c1461fb Jamozed 2020-06-27 14:35:08
91
static inline void aprint_none(uintmax_t addr, char c);
c1461fb Jamozed 2020-06-27 14:35:08
92
static void (*aprint)(uintmax_t, char) = aprint_generic;
c1461fb Jamozed 2020-06-27 14:35:08
93
c1461fb Jamozed 2020-06-27 14:35:08
94
static inline int bread(block_t *blk);
c1461fb Jamozed 2020-06-27 14:35:08
95
static inline void bprint(block_t *blk, int ti);
c1461fb Jamozed 2020-06-27 14:35:08
96
c1461fb Jamozed 2020-06-27 14:35:08
97
static inline FILE *fnext(void);
c1461fb Jamozed 2020-06-27 14:35:08
98
c1461fb Jamozed 2020-06-27 14:35:08
99
static inline list_t linit(void);
c1461fb Jamozed 2020-06-27 14:35:08
100
static inline void lpush(list_t *list, int i);
c1461fb Jamozed 2020-06-27 14:35:08
101
be8a914 Jamozed 2020-10-26 12:22:47
102
static void hlp(void);
be8a914 Jamozed 2020-10-26 12:22:47
103
static void ver(void);
c1461fb Jamozed 2020-06-27 14:35:08
104
4540c2a Jamozed 2020-07-06 23:15:03
105
int main(int ac, char *av[]) { A0 = av[0];
30cf081 Jamozed 2020-08-28 23:01:02
106
	struct opt opt = OPTGET_INIT; opt.lops = lops; int ret = 0;
c1461fb Jamozed 2020-06-27 14:35:08
107
	opt.str = "A:bcdj:N:ost:vx"; tlist = linit();
30cf081 Jamozed 2020-08-28 23:01:02
108
	for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) {
c1461fb Jamozed 2020-06-27 14:35:08
109
	case 'A': switch(opt.arg[0]) {
c1461fb Jamozed 2020-06-27 14:35:08
110
		case 'd': { aprint = aprint_generic; Aform[4] = 'u'; continue; }
c1461fb Jamozed 2020-06-27 14:35:08
111
		case 'o': { aprint = aprint_generic; Aform[4] = 'o'; continue; }
c1461fb Jamozed 2020-06-27 14:35:08
112
		case 'x': { aprint = aprint_generic; Aform[4] = 'x'; continue; }
c1461fb Jamozed 2020-06-27 14:35:08
113
		case 'n': { aprint = aprint_none; continue; }
4540c2a Jamozed 2020-07-06 23:15:03
114
		default: { warn("%c: invalid address base", opt.arg[0]); ret = 1;
4540c2a Jamozed 2020-07-06 23:15:03
115
			goto end; }}
c1461fb Jamozed 2020-06-27 14:35:08
116
	case 'b': { lpush(&tlist, tb); break; }
c1461fb Jamozed 2020-06-27 14:35:08
117
	case 'c': { lpush(&tlist, tl); break; }
c1461fb Jamozed 2020-06-27 14:35:08
118
	case 'd': { lpush(&tlist, td); break; }
be8a914 Jamozed 2020-10-26 12:22:47
119
	case 'j': {
be8a914 Jamozed 2020-10-26 12:22:47
120
		errno = 0; start = bparse(opt.arg); if (errno) {
be8a914 Jamozed 2020-10-26 12:22:47
121
		warn("%s: invalid skip value", opt.arg); ret = 1; goto end; }
be8a914 Jamozed 2020-10-26 12:22:47
122
		break;
be8a914 Jamozed 2020-10-26 12:22:47
123
	}
be8a914 Jamozed 2020-10-26 12:22:47
124
	case 'N': {
be8a914 Jamozed 2020-10-26 12:22:47
125
		errno = 0; limit = bparse(opt.arg); if (errno) {
4540c2a Jamozed 2020-07-06 23:15:03
126
		warn("%s: invalid limit value", opt.arg); ret = 1; goto end; }
be8a914 Jamozed 2020-10-26 12:22:47
127
		Nflag = true; break;
be8a914 Jamozed 2020-10-26 12:22:47
128
	}
c1461fb Jamozed 2020-06-27 14:35:08
129
	case 'o': { lpush(&tlist, to); break; }
c1461fb Jamozed 2020-06-27 14:35:08
130
	case 's': { lpush(&tlist, ts); break; }
c1461fb Jamozed 2020-06-27 14:35:08
131
	case 't': { if (tparse(opt.arg)) { goto end; } break; }
c1461fb Jamozed 2020-06-27 14:35:08
132
	case 'v': { vflag = true; break; }
c1461fb Jamozed 2020-06-27 14:35:08
133
	case 'x': { lpush(&tlist, tx); break; }
be8a914 Jamozed 2020-10-26 12:22:47
134
	case 256: { hlp(); return 0; }
be8a914 Jamozed 2020-10-26 12:22:47
135
	case 257: { ver(); return 0; }
c1461fb Jamozed 2020-06-27 14:35:08
136
	default: { ret = 1; goto end; }
c1461fb Jamozed 2020-06-27 14:35:08
137
	}
c1461fb Jamozed 2020-06-27 14:35:08
138
	
c1461fb Jamozed 2020-06-27 14:35:08
139
	if (!tlist.len) { lpush(&tlist, to); }
4540c2a Jamozed 2020-07-06 23:15:03
140
	if (opt.ind == ac) { file = stdin; }
4540c2a Jamozed 2020-07-06 23:15:03
141
	else { files = av + opt.ind; file = fnext(); }
c1461fb Jamozed 2020-06-27 14:35:08
142
	
c1461fb Jamozed 2020-06-27 14:35:08
143
	for (size_t i = 0; i < tlist.len; ++i) { int t = tlist.data[i];
c1461fb Jamozed 2020-06-27 14:35:08
144
		if (types[t].padm > mpad) { mpad = types[t].padm; }
c1461fb Jamozed 2020-06-27 14:35:08
145
	}
c1461fb Jamozed 2020-06-27 14:35:08
146
	for (size_t i = 0; i < tlist.len; ++i) { int t = tlist.data[i];
c1461fb Jamozed 2020-06-27 14:35:08
147
		if (types[t].padm < mpad) {
c1461fb Jamozed 2020-06-27 14:35:08
148
			int d = mpad - types[t].padm;
c1461fb Jamozed 2020-06-27 14:35:08
149
			int e = d / (16 / types[t].bytes);
c1461fb Jamozed 2020-06-27 14:35:08
150
			types[t].pads = e; types[t].padm = mpad;
c1461fb Jamozed 2020-06-27 14:35:08
151
		} else { types[t].pads = 0; }
c1461fb Jamozed 2020-06-27 14:35:08
152
	}
c1461fb Jamozed 2020-06-27 14:35:08
153
	
c1461fb Jamozed 2020-06-27 14:35:08
154
	block_t b0, b1; int c; bool btok = false, bskp = false;
c1461fb Jamozed 2020-06-27 14:35:08
155
	if (skip(start) == EOF) {
4540c2a Jamozed 2020-07-06 23:15:03
156
		warn("cannot skip past end of input"); ret = 1; goto end;
c1461fb Jamozed 2020-06-27 14:35:08
157
	}
c1461fb Jamozed 2020-06-27 14:35:08
158
	
c1461fb Jamozed 2020-06-27 14:35:08
159
	while ((c = bread(btok ? &b0 : &b1)) > 0) {
c1461fb Jamozed 2020-06-27 14:35:08
160
		if (!vflag && b0.i64[0] == b1.i64[0] && b0.i64[1] == b1.i64[1]) {
c1461fb Jamozed 2020-06-27 14:35:08
161
			if (!bskp) { fputs("*\n", stdout); bskp = true; }
c1461fb Jamozed 2020-06-27 14:35:08
162
		}
c1461fb Jamozed 2020-06-27 14:35:08
163
		else {
c1461fb Jamozed 2020-06-27 14:35:08
164
			(*aprint)(offset - (uintmax_t)c, ' ');
c1461fb Jamozed 2020-06-27 14:35:08
165
			bprint(btok ? &b0 : &b1, tlist.data[0]);
c1461fb Jamozed 2020-06-27 14:35:08
166
			for (size_t i = 1; i < tlist.len; ++i) {
c1461fb Jamozed 2020-06-27 14:35:08
167
				fputs("         ", stdout);
c1461fb Jamozed 2020-06-27 14:35:08
168
				bprint(btok ? &b0 : &b1, tlist.data[i]);
c1461fb Jamozed 2020-06-27 14:35:08
169
			} bskp = false;
c1461fb Jamozed 2020-06-27 14:35:08
170
		}
c1461fb Jamozed 2020-06-27 14:35:08
171
		if (c < 16) { break; } btok = !btok;
c1461fb Jamozed 2020-06-27 14:35:08
172
	} (*aprint)(offset, '\n');
c1461fb Jamozed 2020-06-27 14:35:08
173
	
c1461fb Jamozed 2020-06-27 14:35:08
174
end:
c1461fb Jamozed 2020-06-27 14:35:08
175
	free(tlist.data); return ret;
c1461fb Jamozed 2020-06-27 14:35:08
176
}
c1461fb Jamozed 2020-06-27 14:35:08
177
c1461fb Jamozed 2020-06-27 14:35:08
178
static inline uintmax_t bparse(char *str) {
c1461fb Jamozed 2020-06-27 14:35:08
179
	register uintmax_t n = 0, d; register int b = 10;
c1461fb Jamozed 2020-06-27 14:35:08
180
	if (*str == '0') {
c1461fb Jamozed 2020-06-27 14:35:08
181
		if (*++str == 'x' || *str == 'X') { b = 16; ++str; }
c1461fb Jamozed 2020-06-27 14:35:08
182
		else { b = 8; }
c1461fb Jamozed 2020-06-27 14:35:08
183
	}
c1461fb Jamozed 2020-06-27 14:35:08
184
	
c1461fb Jamozed 2020-06-27 14:35:08
185
	if (b == 16) for (;; ++str) {
c1461fb Jamozed 2020-06-27 14:35:08
186
		if (*str >= '0' && *str <= '9') { d = (uintmax_t)*str - '0'; }
c1461fb Jamozed 2020-06-27 14:35:08
187
		else if (*str >= 'A' && *str <= 'F') { d = (uintmax_t)*str - 'K'; }
c1461fb Jamozed 2020-06-27 14:35:08
188
		else if (*str >= 'a' && *str <= 'f') { d = (uintmax_t)*str - 'k'; }
c1461fb Jamozed 2020-06-27 14:35:08
189
		else { break; }
c1461fb Jamozed 2020-06-27 14:35:08
190
		if (n > (UINTMAX_MAX - d) / 16) { errno = ERANGE; return 0; }
c1461fb Jamozed 2020-06-27 14:35:08
191
		n = n * 16 + d;
c1461fb Jamozed 2020-06-27 14:35:08
192
	}
c1461fb Jamozed 2020-06-27 14:35:08
193
	else for (; *str >= '0' && *str < b + '0'; ++str) {
c1461fb Jamozed 2020-06-27 14:35:08
194
		d = (uintmax_t)*str - '0';
c1461fb Jamozed 2020-06-27 14:35:08
195
		if (n > (UINTMAX_MAX - d) / (uintmax_t)b) { errno = ERANGE; return 0; }
c1461fb Jamozed 2020-06-27 14:35:08
196
		n = n * (uintmax_t)b + d;
c1461fb Jamozed 2020-06-27 14:35:08
197
	}
c1461fb Jamozed 2020-06-27 14:35:08
198
	
c1461fb Jamozed 2020-06-27 14:35:08
199
	switch (*str) {
c1461fb Jamozed 2020-06-27 14:35:08
200
	case 'b': { d = 512; goto mul; }
c1461fb Jamozed 2020-06-27 14:35:08
201
	case 'k': { d = 1024; goto mul; }
c1461fb Jamozed 2020-06-27 14:35:08
202
	case 'm': { d = 1048576; }
c1461fb Jamozed 2020-06-27 14:35:08
203
mul:	if (n > UINTMAX_MAX / d) { errno = ERANGE; return 0; }
c1461fb Jamozed 2020-06-27 14:35:08
204
		n *= d; ++str;
c1461fb Jamozed 2020-06-27 14:35:08
205
	}
c1461fb Jamozed 2020-06-27 14:35:08
206
	
c1461fb Jamozed 2020-06-27 14:35:08
207
	if (*str) { errno = EINVAL; return 0; }
c1461fb Jamozed 2020-06-27 14:35:08
208
	return n;
c1461fb Jamozed 2020-06-27 14:35:08
209
}
c1461fb Jamozed 2020-06-27 14:35:08
210
c1461fb Jamozed 2020-06-27 14:35:08
211
static inline int atow(char **str) {
c1461fb Jamozed 2020-06-27 14:35:08
212
	register int n = 0, d;
c1461fb Jamozed 2020-06-27 14:35:08
213
	for (; **str >= '0' && **str <= '9'; ++*str) {
c1461fb Jamozed 2020-06-27 14:35:08
214
		d = (int)**str - '0';
c1461fb Jamozed 2020-06-27 14:35:08
215
		if (n > (INT_MAX - d) / 10) { return -1; }
c1461fb Jamozed 2020-06-27 14:35:08
216
		n = n * 10 + d;
c1461fb Jamozed 2020-06-27 14:35:08
217
	} return n;
c1461fb Jamozed 2020-06-27 14:35:08
218
}
c1461fb Jamozed 2020-06-27 14:35:08
219
c1461fb Jamozed 2020-06-27 14:35:08
220
static inline int tparse(char *str) { register int c;
c1461fb Jamozed 2020-06-27 14:35:08
221
	for (char *s = str; *s; ++s) { register int b = 0;
c1461fb Jamozed 2020-06-27 14:35:08
222
		if (*s == 'a') { lpush(&tlist, ta); continue; }
c1461fb Jamozed 2020-06-27 14:35:08
223
		else if (*s == 'c') { lpush(&tlist, tc); continue; }
c1461fb Jamozed 2020-06-27 14:35:08
224
		else if (*s == 'd' || *s == 'o' || *s == 'u' || *s == 'x') {
c1461fb Jamozed 2020-06-27 14:35:08
225
			char *p = s + 1;
c1461fb Jamozed 2020-06-27 14:35:08
226
			if (*p == 'C') { b = sizeof(char); ++p; }
c1461fb Jamozed 2020-06-27 14:35:08
227
			else if (*p == 'S') { b = sizeof(short); ++p; }
c1461fb Jamozed 2020-06-27 14:35:08
228
			else if (*p == 'I') { b = sizeof(int); ++p; }
c1461fb Jamozed 2020-06-27 14:35:08
229
			else if (*p == 'L') { b = sizeof(long); ++p; }
c1461fb Jamozed 2020-06-27 14:35:08
230
			else if ((b = atow(&p)) == -1) { goto fail; }
c1461fb Jamozed 2020-06-27 14:35:08
231
			ssize_t m = p - (s + 1); if (!m) { b = sizeof(int); }
c1461fb Jamozed 2020-06-27 14:35:08
232
			if (!(b == 1 || b == 2 || b == 4 || b == 8)) {
4540c2a Jamozed 2020-07-06 23:15:03
233
				error(1, "no %d-byte integer type", b);
c1461fb Jamozed 2020-06-27 14:35:08
234
			} else { c = *s; s += m; }
c1461fb Jamozed 2020-06-27 14:35:08
235
		}
c1461fb Jamozed 2020-06-27 14:35:08
236
		else if (*s == 'f') { char *p = s + 1;
c1461fb Jamozed 2020-06-27 14:35:08
237
			if (*p == 'F') { b = sizeof(float); ++p; }
c1461fb Jamozed 2020-06-27 14:35:08
238
			else if (*p == 'D') { b = sizeof(double); ++p; }
c1461fb Jamozed 2020-06-27 14:35:08
239
			else if (*p == 'L') { b = sizeof(/*long*/ double); ++p; }
c1461fb Jamozed 2020-06-27 14:35:08
240
			else if ((b = atow(&p)) == -1) { goto fail; }
c1461fb Jamozed 2020-06-27 14:35:08
241
			ssize_t m = p - (s + 1); if (!m) { b = sizeof(double); }
c1461fb Jamozed 2020-06-27 14:35:08
242
			if (!(b == 4 || b == 8 /*|| b == 16*/)) {
4540c2a Jamozed 2020-07-06 23:15:03
243
				error(1, "no %d-byte float type", b);
c1461fb Jamozed 2020-06-27 14:35:08
244
			}
c1461fb Jamozed 2020-06-27 14:35:08
245
			else { c = 'f'; s += m; }
c1461fb Jamozed 2020-06-27 14:35:08
246
		}
c1461fb Jamozed 2020-06-27 14:35:08
247
		else {
4540c2a Jamozed 2020-07-06 23:15:03
248
fail:		error(1, "%s: invalid type string", str);
c1461fb Jamozed 2020-06-27 14:35:08
249
		}
c1461fb Jamozed 2020-06-27 14:35:08
250
		
c1461fb Jamozed 2020-06-27 14:35:08
251
		for (int i = 0; types[i].type; ++i) {
c1461fb Jamozed 2020-06-27 14:35:08
252
			if (types[i].type == c && types[i].bytes == b) {
c1461fb Jamozed 2020-06-27 14:35:08
253
				lpush(&tlist, i);
c1461fb Jamozed 2020-06-27 14:35:08
254
			}
c1461fb Jamozed 2020-06-27 14:35:08
255
		}
c1461fb Jamozed 2020-06-27 14:35:08
256
	} return 0;
c1461fb Jamozed 2020-06-27 14:35:08
257
}
c1461fb Jamozed 2020-06-27 14:35:08
258
c1461fb Jamozed 2020-06-27 14:35:08
259
static inline int skip(uintmax_t n) {
c1461fb Jamozed 2020-06-27 14:35:08
260
	for (; n; --n) if (fgetc(file) == EOF && fnext() == NULL) { return EOF; }
c1461fb Jamozed 2020-06-27 14:35:08
261
	offset = start; return 0;
c1461fb Jamozed 2020-06-27 14:35:08
262
}
c1461fb Jamozed 2020-06-27 14:35:08
263
c1461fb Jamozed 2020-06-27 14:35:08
264
static inline void aprint_generic(uintmax_t addr, char c) {
c1461fb Jamozed 2020-06-27 14:35:08
265
	printf(Aform, addr); fputc(c, stdout); return;
c1461fb Jamozed 2020-06-27 14:35:08
266
}
c1461fb Jamozed 2020-06-27 14:35:08
267
static inline void aprint_none(uintmax_t addr, char c) {
c1461fb Jamozed 2020-06-27 14:35:08
268
	(void)(addr); (void)(c); return;
c1461fb Jamozed 2020-06-27 14:35:08
269
}
c1461fb Jamozed 2020-06-27 14:35:08
270
c1461fb Jamozed 2020-06-27 14:35:08
271
static inline int bread(block_t *blk) {
c1461fb Jamozed 2020-06-27 14:35:08
272
	int i = 0; int c;
c1461fb Jamozed 2020-06-27 14:35:08
273
	while (i < 16 && (!Nflag || total < limit)) {
c1461fb Jamozed 2020-06-27 14:35:08
274
		if (file == NULL || (c = fgetc(file)) == EOF) {
c1461fb Jamozed 2020-06-27 14:35:08
275
			if ((file = fnext()) == NULL) { break; }
c1461fb Jamozed 2020-06-27 14:35:08
276
			else { continue; }
c1461fb Jamozed 2020-06-27 14:35:08
277
		} blk->i8[i++] = (uint8_t)c; ++total;
c1461fb Jamozed 2020-06-27 14:35:08
278
	}
c1461fb Jamozed 2020-06-27 14:35:08
279
	offset += (uintmax_t)i;
c1461fb Jamozed 2020-06-27 14:35:08
280
	blk->count = i; return i;
c1461fb Jamozed 2020-06-27 14:35:08
281
}
c1461fb Jamozed 2020-06-27 14:35:08
282
c1461fb Jamozed 2020-06-27 14:35:08
283
static inline void bprint(block_t *blk, int ti) {
c1461fb Jamozed 2020-06-27 14:35:08
284
	type_t t = types[ti]; bool spc = false; long count = blk->count / t.bytes;
c1461fb Jamozed 2020-06-27 14:35:08
285
	
c1461fb Jamozed 2020-06-27 14:35:08
286
	for (int i = 0; i < count; ++i) {
c1461fb Jamozed 2020-06-27 14:35:08
287
		if (spc) { fputc(' ', stdout); } else { spc = true; }
c1461fb Jamozed 2020-06-27 14:35:08
288
		for (int j = 0; j < t.pads; ++j) { fputc(' ', stdout); }
c1461fb Jamozed 2020-06-27 14:35:08
289
		
c1461fb Jamozed 2020-06-27 14:35:08
290
		switch (t.type) {
c1461fb Jamozed 2020-06-27 14:35:08
291
		case 'a': { register uint8_t c = blk->i8[i] & 127;
c1461fb Jamozed 2020-06-27 14:35:08
292
			if (c <= 32) { fputs(aTABL[c], stdout); }
c1461fb Jamozed 2020-06-27 14:35:08
293
			else if (c == 127) { fputs("del", stdout); }
c1461fb Jamozed 2020-06-27 14:35:08
294
			else { printf("%3c", c); } break;
c1461fb Jamozed 2020-06-27 14:35:08
295
		}
c1461fb Jamozed 2020-06-27 14:35:08
296
		case 'c': case 'l': { register uint8_t c = blk->i8[i];
c1461fb Jamozed 2020-06-27 14:35:08
297
			if (c < 32) { fputs(t.type == 'c' ? cTABL[c] : lTABL[c], stdout); }
c1461fb Jamozed 2020-06-27 14:35:08
298
			else if (c >= 127) { printf("%3o", c); }
c1461fb Jamozed 2020-06-27 14:35:08
299
			else { printf("%3c", c); } break;
c1461fb Jamozed 2020-06-27 14:35:08
300
		}
c1461fb Jamozed 2020-06-27 14:35:08
301
		default: { char *form = types[ti].form;
c1461fb Jamozed 2020-06-27 14:35:08
302
			if (t.type == 'f') {
c1461fb Jamozed 2020-06-27 14:35:08
303
				if (t.bytes == 4) { printf(form, (double)blk->f32[i]); }
c1461fb Jamozed 2020-06-27 14:35:08
304
				else if (t.bytes == 8) { printf(form, blk->f64[i]); }
c1461fb Jamozed 2020-06-27 14:35:08
305
			}
c1461fb Jamozed 2020-06-27 14:35:08
306
			else {
c1461fb Jamozed 2020-06-27 14:35:08
307
				if (t.bytes == 1) { printf(form, blk->i8[i]); }
c1461fb Jamozed 2020-06-27 14:35:08
308
				else if (t.bytes == 2) { printf(form, blk->i16[i]); }
c1461fb Jamozed 2020-06-27 14:35:08
309
				else if (t.bytes == 4) { printf(form, blk->i32[i]); }
c1461fb Jamozed 2020-06-27 14:35:08
310
				else if (t.bytes == 8) { printf(form, blk->i64[i]); }
c1461fb Jamozed 2020-06-27 14:35:08
311
			}
c1461fb Jamozed 2020-06-27 14:35:08
312
		}
c1461fb Jamozed 2020-06-27 14:35:08
313
		}
c1461fb Jamozed 2020-06-27 14:35:08
314
	} fputc('\n', stdout);
c1461fb Jamozed 2020-06-27 14:35:08
315
	return;
c1461fb Jamozed 2020-06-27 14:35:08
316
}
c1461fb Jamozed 2020-06-27 14:35:08
317
c1461fb Jamozed 2020-06-27 14:35:08
318
static inline FILE *fnext(void) {
c1461fb Jamozed 2020-06-27 14:35:08
319
	if (file && file != stdin) { fclose(file); }
c1461fb Jamozed 2020-06-27 14:35:08
320
	if (*files) { FILE *f;
c1461fb Jamozed 2020-06-27 14:35:08
321
		if (files[0][0] == '-' && files[0][1] == '\0') { f = stdin; }
c1461fb Jamozed 2020-06-27 14:35:08
322
		else if (!(f = fopen(*files, "r"))) {
4540c2a Jamozed 2020-07-06 23:15:03
323
			warn("%s: %s\n", *files, strerror(errno)); return NULL;
c1461fb Jamozed 2020-06-27 14:35:08
324
		} ++files; return f;
c1461fb Jamozed 2020-06-27 14:35:08
325
	} else { return NULL; }
c1461fb Jamozed 2020-06-27 14:35:08
326
}
c1461fb Jamozed 2020-06-27 14:35:08
327
c1461fb Jamozed 2020-06-27 14:35:08
328
static inline list_t linit(void) {
c1461fb Jamozed 2020-06-27 14:35:08
329
	list_t list; list.cap = 32; list.len = 0;
c1461fb Jamozed 2020-06-27 14:35:08
330
	list.data = (int *)malloc(sizeof(int) * list.cap);
c1461fb Jamozed 2020-06-27 14:35:08
331
	return list;
c1461fb Jamozed 2020-06-27 14:35:08
332
}
c1461fb Jamozed 2020-06-27 14:35:08
333
c1461fb Jamozed 2020-06-27 14:35:08
334
static inline void lpush(list_t *list, int i) {
c1461fb Jamozed 2020-06-27 14:35:08
335
	if (list->len >= list->cap) {
c1461fb Jamozed 2020-06-27 14:35:08
336
		list->data = (int *)realloc(list->data, list->cap *= 2);
c1461fb Jamozed 2020-06-27 14:35:08
337
	} list->data[list->len++] = i; return;
c1461fb Jamozed 2020-06-27 14:35:08
338
}
c1461fb Jamozed 2020-06-27 14:35:08
339
be8a914 Jamozed 2020-10-26 12:22:47
340
static void hlp(void) {
c1461fb Jamozed 2020-06-27 14:35:08
341
	puts("od - dump files in various formats\n");
c1461fb Jamozed 2020-06-27 14:35:08
342
	puts("usage: od [-bcdosvx] [-A base] [-j skip] [-N count] [-t type] \
c1461fb Jamozed 2020-06-27 14:35:08
343
[file...]\n");
c1461fb Jamozed 2020-06-27 14:35:08
344
	puts("options:");
c1461fb Jamozed 2020-06-27 14:35:08
345
	puts("  -A base    Offset address base ('d', 'o', 'x', or 'n')");
c1461fb Jamozed 2020-06-27 14:35:08
346
	puts("  -b         Interpret bytes in octal (-t01)");
c1461fb Jamozed 2020-06-27 14:35:08
347
	puts("  -c         Interpret bytes as characters");
c1461fb Jamozed 2020-06-27 14:35:08
348
	puts("  -d         Interpret words in unsigned decimal (-tu2)");
c1461fb Jamozed 2020-06-27 14:35:08
349
	puts("  -j skip    Number of bytes to skip from the beginning of input");
c1461fb Jamozed 2020-06-27 14:35:08
350
	puts("  -N count   Number of bytes to process in total");
c1461fb Jamozed 2020-06-27 14:35:08
351
	puts("  -o         Interpret words in octal (-to2)");
c1461fb Jamozed 2020-06-27 14:35:08
352
	puts("  -s         Interpret words in signed decimal (-td2)");
c1461fb Jamozed 2020-06-27 14:35:08
353
	puts("  -t type    Interpret data according to specified types");
c1461fb Jamozed 2020-06-27 14:35:08
354
	puts("  -v         Write all input data");
c1461fb Jamozed 2020-06-27 14:35:08
355
	puts("  -x         Interpret words in hexadecimal (-tx2)");
c1461fb Jamozed 2020-06-27 14:35:08
356
	puts("  --help     Display help information");
c1461fb Jamozed 2020-06-27 14:35:08
357
	puts("  --version  Display version information");
c1461fb Jamozed 2020-06-27 14:35:08
358
}
c1461fb Jamozed 2020-06-27 14:35:08
359
be8a914 Jamozed 2020-10-26 12:22:47
360
static void ver(void) {
4540c2a Jamozed 2020-07-06 23:15:03
361
	puts("OMKOV coreutils od, version " VERSION);
c1461fb Jamozed 2020-06-27 14:35:08
362
	puts("Copyright (C) 2020, Jakob Wakeling");
e2140ec Jamozed 2022-03-06 15:27:45
363
	puts("MIT Licence (https://opensource.org/licenses/MIT)");
c1461fb Jamozed 2020-06-27 14:35:08
364
}
365