Mercurial > hg > toybox
comparison toys/posix/od.c @ 694:786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
The actual code should be the same afterward, this is just cosmetic refactoring.
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 13 Nov 2012 17:14:08 -0600 |
parents | 7e846e281e38 |
children | 16167a7c1b5a |
comparison
equal
deleted
inserted
replaced
693:4a5a250e0633 | 694:786841fdb1e0 |
---|---|
1 /* vi: set sw=4 ts=4: | 1 /* od.c - Provide octal/hex dumps of data |
2 * | |
3 * od.c - Provide octal/hex dumps of data | |
4 * | 2 * |
5 * Copyright 2012 Andre Renaud <andre@bluewatersys.com> | 3 * Copyright 2012 Andre Renaud <andre@bluewatersys.com> |
6 * Copyright 2012 Rob Landley <rob@landley.net> | 4 * Copyright 2012 Rob Landley <rob@landley.net> |
7 * | 5 * |
8 * See http://opengroup.org/onlinepubs/9699919799/utilities/od.html | 6 * See http://opengroup.org/onlinepubs/9699919799/utilities/od.html |
9 | 7 |
10 USE_OD(NEWTOY(od, "j#vN#xsodcbA:t*", TOYFLAG_USR|TOYFLAG_BIN)) | 8 USE_OD(NEWTOY(od, "j#vN#xsodcbA:t*", TOYFLAG_USR|TOYFLAG_BIN)) |
11 | 9 |
12 config OD | 10 config OD |
13 bool "od" | 11 bool "od" |
14 default y | 12 default y |
15 help | 13 help |
16 usage: od [-bdosxv] [-j #] [-N #] [-A doxn] [-t arg] | 14 usage: od [-bdosxv] [-j #] [-N #] [-A doxn] [-t arg] |
17 | 15 |
18 -A Address base (decimal, octal, hexdecimal, none) | 16 -A Address base (decimal, octal, hexdecimal, none) |
19 -t output type(s) a (ascii) c (char) d (decimal) foux | 17 -t output type(s) a (ascii) c (char) d (decimal) foux |
20 */ | 18 */ |
21 | 19 |
22 #define FOR_od | 20 #define FOR_od |
23 #include "toys.h" | 21 #include "toys.h" |
24 | 22 |
25 GLOBALS( | 23 GLOBALS( |
26 struct arg_list *output_base; | 24 struct arg_list *output_base; |
27 char *address_base; | 25 char *address_base; |
28 long max_count; | 26 long max_count; |
29 long jump_bytes; | 27 long jump_bytes; |
30 | 28 |
31 unsigned types, leftover, star, address_idx; | 29 unsigned types, leftover, star, address_idx; |
32 char *buf; | 30 char *buf; |
33 uint64_t bufs[4]; // force 64-bit alignment | 31 uint64_t bufs[4]; // force 64-bit alignment |
34 off_t pos; | 32 off_t pos; |
35 ) | 33 ) |
36 | 34 |
37 static char *ascii = "nulsohstxetxeotenqackbel bs ht nl vt ff cr so si" | 35 static char *ascii = "nulsohstxetxeotenqackbel bs ht nl vt ff cr so si" |
38 "dledc1dc2dc3dc4naksynetbcan emsubesc fs gs rs us sp"; | 36 "dledc1dc2dc3dc4naksynetbcan emsubesc fs gs rs us sp"; |
39 | 37 |
40 struct odtype { | 38 struct odtype { |
41 int type; | 39 int type; |
42 int size; | 40 int size; |
43 }; | 41 }; |
44 | 42 |
45 static void od_outline(void) | 43 static void od_outline(void) |
46 { | 44 { |
47 unsigned flags = toys.optflags; | 45 unsigned flags = toys.optflags; |
48 char *abases[] = {"", "%07d", "%07o", "%06x"}; | 46 char *abases[] = {"", "%07d", "%07o", "%06x"}; |
49 struct odtype *types = (struct odtype *)toybuf, *t; | 47 struct odtype *types = (struct odtype *)toybuf, *t; |
50 int i, len; | 48 int i, len; |
51 | 49 |
52 if (TT.leftover<16) memset(TT.buf+TT.leftover, 0, 16-TT.leftover); | 50 if (TT.leftover<16) memset(TT.buf+TT.leftover, 0, 16-TT.leftover); |
53 | 51 |
54 // Handle duplciate lines as * | 52 // Handle duplciate lines as * |
55 if (!(flags&FLAG_v) && TT.jump_bytes != TT.pos && TT.leftover | 53 if (!(flags&FLAG_v) && TT.jump_bytes != TT.pos && TT.leftover |
56 && !memcmp(TT.bufs, TT.bufs + 2, 16)) | 54 && !memcmp(TT.bufs, TT.bufs + 2, 16)) |
57 { | 55 { |
58 if (!TT.star) { | 56 if (!TT.star) { |
59 xputs("*"); | 57 xputs("*"); |
60 TT.star++; | 58 TT.star++; |
61 } | 59 } |
62 | 60 |
63 // Print line position | 61 // Print line position |
64 } else { | 62 } else { |
65 TT.star = 0; | 63 TT.star = 0; |
66 | 64 |
67 xprintf(abases[TT.address_idx], TT.pos); | 65 xprintf(abases[TT.address_idx], TT.pos); |
68 if (!TT.leftover) { | 66 if (!TT.leftover) { |
69 if (TT.address_idx) xputc('\n'); | 67 if (TT.address_idx) xputc('\n'); |
70 return; | 68 return; |
71 } | 69 } |
72 } | 70 } |
73 | 71 |
74 TT.pos += len = TT.leftover; | 72 TT.pos += len = TT.leftover; |
75 TT.leftover = 0; | 73 TT.leftover = 0; |
76 if (TT.star) return; | 74 if (TT.star) return; |
77 | 75 |
78 // For each output type, print one line | 76 // For each output type, print one line |
79 | 77 |
80 for (i=0; i<TT.types; i++) { | 78 for (i=0; i<TT.types; i++) { |
81 int j = 0, pad = i ? 8 : 0; | 79 int j = 0, pad = i ? 8 : 0; |
82 char buf[128]; | 80 char buf[128]; |
83 | 81 |
84 t = types+i; | 82 t = types+i; |
85 while (j<len) { | 83 while (j<len) { |
86 unsigned k; | 84 unsigned k; |
87 int throw = 0; | 85 int throw = 0; |
88 | 86 |
89 // Handle ascii | 87 // Handle ascii |
90 if (t->type < 2) { | 88 if (t->type < 2) { |
91 char c = TT.buf[j++]; | 89 char c = TT.buf[j++]; |
92 pad += 4; | 90 pad += 4; |
93 | 91 |
94 if (!t->type) { | 92 if (!t->type) { |
95 c &= 127; | 93 c &= 127; |
96 if (c<=32) sprintf(buf, "%.3s", ascii+(3*c)); | 94 if (c<=32) sprintf(buf, "%.3s", ascii+(3*c)); |
97 else if (c==127) strcpy(buf, "del"); | 95 else if (c==127) strcpy(buf, "del"); |
98 else sprintf(buf, "%c", c); | 96 else sprintf(buf, "%c", c); |
99 } else { | 97 } else { |
100 char *bfnrtav = "\b\f\n\r\t\a\v", *s = strchr(bfnrtav, c); | 98 char *bfnrtav = "\b\f\n\r\t\a\v", *s = strchr(bfnrtav, c); |
101 if (s) sprintf(buf, "\\%c", "bfnrtav0"[s-bfnrtav]); | 99 if (s) sprintf(buf, "\\%c", "bfnrtav0"[s-bfnrtav]); |
102 else if (c < 32 || c >= 127) sprintf(buf, "%03o", c); | 100 else if (c < 32 || c >= 127) sprintf(buf, "%03o", c); |
103 else { | 101 else { |
104 // TODO: this should be UTF8 aware. | 102 // TODO: this should be UTF8 aware. |
105 sprintf(buf, "%c", c); | 103 sprintf(buf, "%c", c); |
106 } | 104 } |
107 } | 105 } |
108 } else if (CFG_TOYBOX_FLOAT && t->type == 6) { | 106 } else if (CFG_TOYBOX_FLOAT && t->type == 6) { |
109 long double ld; | 107 long double ld; |
110 union {float f; double d; long double ld;} fdl; | 108 union {float f; double d; long double ld;} fdl; |
111 | 109 |
112 memcpy(&fdl, TT.buf+j, t->size); | 110 memcpy(&fdl, TT.buf+j, t->size); |
113 j += t->size; | 111 j += t->size; |
114 if (sizeof(float) == t->size) { | 112 if (sizeof(float) == t->size) { |
115 ld = fdl.f; | 113 ld = fdl.f; |
116 pad += (throw = 8)+7; | 114 pad += (throw = 8)+7; |
117 } else if (sizeof(double) == t->size) { | 115 } else if (sizeof(double) == t->size) { |
118 ld = fdl.d; | 116 ld = fdl.d; |
119 pad += (throw = 17)+8; | 117 pad += (throw = 17)+8; |
120 } else if (sizeof(long double) == t->size) { | 118 } else if (sizeof(long double) == t->size) { |
121 ld = fdl.ld; | 119 ld = fdl.ld; |
122 pad += (throw = 21)+9; | 120 pad += (throw = 21)+9; |
123 } else error_exit("bad -tf '%d'", t->size); | 121 } else error_exit("bad -tf '%d'", t->size); |
124 | 122 |
125 sprintf(buf, "%.*Le", throw, ld); | 123 sprintf(buf, "%.*Le", throw, ld); |
126 // Integer types | 124 // Integer types |
127 } else { | 125 } else { |
128 unsigned long long ll = 0, or; | 126 unsigned long long ll = 0, or; |
129 char *c[] = {"%*lld", "%*llu", "%0*llo", "%0*llx"}, | 127 char *c[] = {"%*lld", "%*llu", "%0*llo", "%0*llx"}, |
130 *class = c[t->type-2]; | 128 *class = c[t->type-2]; |
131 | 129 |
132 // Work out width of field | 130 // Work out width of field |
133 if (t->size == 8) { | 131 if (t->size == 8) { |
134 or = -1LL; | 132 or = -1LL; |
135 if (t->type == 2) or >>= 1; | 133 if (t->type == 2) or >>= 1; |
136 } else or = (1LL<<(8*t->size))-1; | 134 } else or = (1LL<<(8*t->size))-1; |
137 throw = sprintf(buf, class, 0, or); | 135 throw = sprintf(buf, class, 0, or); |
138 | 136 |
139 // Accumulate integer based on size argument | 137 // Accumulate integer based on size argument |
140 for (k=0; k < t->size; k++) { | 138 for (k=0; k < t->size; k++) { |
141 or = TT.buf[j++]; | 139 or = TT.buf[j++]; |
142 ll |= or << (8*(IS_BIG_ENDIAN ? t->size-k-1 : k)); | 140 ll |= or << (8*(IS_BIG_ENDIAN ? t->size-k-1 : k)); |
143 } | 141 } |
144 | 142 |
145 // Handle negative values | 143 // Handle negative values |
146 if (t->type == 2) { | 144 if (t->type == 2) { |
147 or = sizeof(or) - t->size; | 145 or = sizeof(or) - t->size; |
148 throw++; | 146 throw++; |
149 if (or && (ll & (1l<<((8*t->size)-1)))) | 147 if (or && (ll & (1l<<((8*t->size)-1)))) |
150 ll |= ((or<<(8*or))-1) << (8*t->size); | 148 ll |= ((or<<(8*or))-1) << (8*t->size); |
151 } | 149 } |
152 | 150 |
153 sprintf(buf, class, throw, ll); | 151 sprintf(buf, class, throw, ll); |
154 pad += throw+1; | 152 pad += throw+1; |
155 } | 153 } |
156 xprintf("%*s", pad, buf); | 154 xprintf("%*s", pad, buf); |
157 pad = 0; | 155 pad = 0; |
158 } | 156 } |
159 xputc('\n'); | 157 xputc('\n'); |
160 } | 158 } |
161 | 159 |
162 // buffer toggle for "same as last time" check. | 160 // buffer toggle for "same as last time" check. |
163 TT.buf = (char *)((TT.buf == (char *)TT.bufs) ? TT.bufs+2 : TT.bufs); | 161 TT.buf = (char *)((TT.buf == (char *)TT.bufs) ? TT.bufs+2 : TT.bufs); |
164 } | 162 } |
165 | 163 |
166 static void do_od(int fd, char *name) | 164 static void do_od(int fd, char *name) |
167 { | 165 { |
168 // Skip input, possibly more than one entire file. | 166 // Skip input, possibly more than one entire file. |
169 if (TT.jump_bytes < TT.pos) { | 167 if (TT.jump_bytes < TT.pos) { |
170 off_t off = lskip(fd, TT.jump_bytes); | 168 off_t off = lskip(fd, TT.jump_bytes); |
171 if (off > 0) TT.pos += off; | 169 if (off > 0) TT.pos += off; |
172 if (TT.jump_bytes < TT.pos) return; | 170 if (TT.jump_bytes < TT.pos) return; |
173 } | 171 } |
174 | 172 |
175 for(;;) { | 173 for(;;) { |
176 char *buf = TT.buf + TT.leftover; | 174 char *buf = TT.buf + TT.leftover; |
177 int len = 16 - TT.leftover; | 175 int len = 16 - TT.leftover; |
178 | 176 |
179 if (toys.optflags & FLAG_N) { | 177 if (toys.optflags & FLAG_N) { |
180 if (!TT.max_count) break; | 178 if (!TT.max_count) break; |
181 if (TT.max_count < len) len = TT.max_count; | 179 if (TT.max_count < len) len = TT.max_count; |
182 } | 180 } |
183 | 181 |
184 len = readall(fd, buf, len); | 182 len = readall(fd, buf, len); |
185 if (len < 0) { | 183 if (len < 0) { |
186 perror_msg("%s", name); | 184 perror_msg("%s", name); |
187 break; | 185 break; |
188 } | 186 } |
189 if (TT.max_count) TT.max_count -= len; | 187 if (TT.max_count) TT.max_count -= len; |
190 TT.leftover += len; | 188 TT.leftover += len; |
191 if (TT.leftover < 16) break; | 189 if (TT.leftover < 16) break; |
192 | 190 |
193 od_outline(); | 191 od_outline(); |
194 } | 192 } |
195 } | 193 } |
196 | 194 |
197 static void append_base(char *base) | 195 static void append_base(char *base) |
198 { | 196 { |
199 char *s = base; | 197 char *s = base; |
200 struct odtype *types = (struct odtype *)toybuf; | 198 struct odtype *types = (struct odtype *)toybuf; |
201 int type; | 199 int type; |
202 | 200 |
203 for (;;) { | 201 for (;;) { |
204 int size = 1; | 202 int size = 1; |
205 | 203 |
206 if (!*s) return; | 204 if (!*s) return; |
207 if (TT.types >= sizeof(toybuf)/sizeof(struct odtype)) break; | 205 if (TT.types >= sizeof(toybuf)/sizeof(struct odtype)) break; |
208 if (-1 == (type = stridx("acduox"USE_TOYBOX_FLOAT("f"), *(s++)))) break; | 206 if (-1 == (type = stridx("acduox"USE_TOYBOX_FLOAT("f"), *(s++)))) break; |
209 | 207 |
210 if (isdigit(*s)) { | 208 if (isdigit(*s)) { |
211 size = strtol(s, &s, 10); | 209 size = strtol(s, &s, 10); |
212 if (type < 2 && size != 1) break; | 210 if (type < 2 && size != 1) break; |
213 if (CFG_TOYBOX_FLOAT && type == 6 && size == sizeof(long double)); | 211 if (CFG_TOYBOX_FLOAT && type == 6 && size == sizeof(long double)); |
214 else if (size < 0 || size > 8) break; | 212 else if (size < 0 || size > 8) break; |
215 } else if (CFG_TOYBOX_FLOAT && type == 6) { | 213 } else if (CFG_TOYBOX_FLOAT && type == 6) { |
216 int sizes[] = {sizeof(float), sizeof(double), sizeof(long double)}; | 214 int sizes[] = {sizeof(float), sizeof(double), sizeof(long double)}; |
217 if (-1 == (size = stridx("FDL", *s))) size = sizeof(double); | 215 if (-1 == (size = stridx("FDL", *s))) size = sizeof(double); |
218 else { | 216 else { |
219 s++; | 217 s++; |
220 size = sizes[size]; | 218 size = sizes[size]; |
221 } | 219 } |
222 } else if (type > 1) { | 220 } else if (type > 1) { |
223 if (-1 == (size = stridx("CSIL", *s))) size = 4; | 221 if (-1 == (size = stridx("CSIL", *s))) size = 4; |
224 else { | 222 else { |
225 s++; | 223 s++; |
226 size = 1 << size; | 224 size = 1 << size; |
227 } | 225 } |
228 } | 226 } |
229 | 227 |
230 types[TT.types].type = type; | 228 types[TT.types].type = type; |
231 types[TT.types].size = size; | 229 types[TT.types].size = size; |
232 TT.types++; | 230 TT.types++; |
233 } | 231 } |
234 | 232 |
235 error_exit("bad -t %s", base); | 233 error_exit("bad -t %s", base); |
236 } | 234 } |
237 | 235 |
238 void od_main(void) | 236 void od_main(void) |
239 { | 237 { |
240 struct arg_list *arg; | 238 struct arg_list *arg; |
241 | 239 |
242 TT.buf = (char *)TT.bufs; | 240 TT.buf = (char *)TT.bufs; |
243 | 241 |
244 if (!TT.address_base) TT.address_idx = 2; | 242 if (!TT.address_base) TT.address_idx = 2; |
245 else if (0>(TT.address_idx = stridx("ndox", *TT.address_base))) | 243 else if (0>(TT.address_idx = stridx("ndox", *TT.address_base))) |
246 error_exit("bad -A '%c'", *TT.address_base); | 244 error_exit("bad -A '%c'", *TT.address_base); |
247 | 245 |
248 // Collect -t entries | 246 // Collect -t entries |
249 | 247 |
250 for (arg = TT.output_base; arg; arg = arg->next) append_base(arg->arg); | 248 for (arg = TT.output_base; arg; arg = arg->next) append_base(arg->arg); |
251 if (toys.optflags & FLAG_b) append_base("o1"); | 249 if (toys.optflags & FLAG_b) append_base("o1"); |
252 if (toys.optflags & FLAG_d) append_base("u2"); | 250 if (toys.optflags & FLAG_d) append_base("u2"); |
253 if (toys.optflags & FLAG_o) append_base("o2"); | 251 if (toys.optflags & FLAG_o) append_base("o2"); |
254 if (toys.optflags & FLAG_s) append_base("d2"); | 252 if (toys.optflags & FLAG_s) append_base("d2"); |
255 if (toys.optflags & FLAG_x) append_base("x2"); | 253 if (toys.optflags & FLAG_x) append_base("x2"); |
256 if (!TT.output_base) append_base("o2"); | 254 if (!TT.output_base) append_base("o2"); |
257 | 255 |
258 loopfiles(toys.optargs, do_od); | 256 loopfiles(toys.optargs, do_od); |
259 | 257 |
260 if (TT.leftover) od_outline(); | 258 if (TT.leftover) od_outline(); |
261 od_outline(); | 259 od_outline(); |
262 } | 260 } |