Skip to content

Commit 9ca0927

Browse files
authored
od: support more output formats with -t (briandfoy#928)
* od: support more output formats with -t * Add other integer format options (u1,u2,u4,d1,d2,d4,o1,o2,o4) as well as the aliases for options -a and -c * 8-byte integer formats could be added in future (these are supported by GNU version) * Make more of an effort to align output for -a and -c modes * sign fix in decimal1() * Use the correct unpack format "c" for signed char * Add a comment to clarify why some ascii character names have an embedded space
1 parent f9614ab commit 9ca0927

File tree

1 file changed

+81
-22
lines changed

1 file changed

+81
-22
lines changed

bin/od

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ my %charescs = (
4444
92 => ' \\\\',
4545
);
4646

47+
# embedded space allows formatting without sprintf
4748
my %charname = (
4849
0 => 'nul',
4950
1 => 'soh',
@@ -53,14 +54,14 @@ my %charname = (
5354
5 => 'enq',
5455
6 => 'ack',
5556
7 => 'bel',
56-
8 => 'bs',
57-
9 => 'ht',
58-
10 => 'nl',
59-
11 => 'vt',
60-
12 => 'ff',
61-
13 => 'cr',
62-
14 => 'so',
63-
15 => 'si',
57+
8 => ' bs',
58+
9 => ' ht',
59+
10 => ' nl',
60+
11 => ' vt',
61+
12 => ' ff',
62+
13 => ' cr',
63+
14 => ' so',
64+
15 => ' si',
6465
16 => 'dle',
6566
17 => 'dc1',
6667
18 => 'dc2',
@@ -70,14 +71,14 @@ my %charname = (
7071
22 => 'syn',
7172
23 => 'etb',
7273
24 => 'can',
73-
25 => 'em',
74+
25 => ' em',
7475
26 => 'sub',
7576
27 => 'esc',
76-
28 => 'fs',
77-
29 => 'gs',
78-
30 => 'rs',
79-
31 => 'us',
80-
32 => 'sp',
77+
28 => ' fs',
78+
29 => ' gs',
79+
30 => ' rs',
80+
31 => ' us',
81+
32 => ' sp',
8182
127 => 'del',
8283
);
8384

@@ -125,7 +126,7 @@ elsif ($opt_c) {
125126
$fmt = \&char1;
126127
}
127128
elsif ($opt_d) {
128-
$fmt = \&udecimal;
129+
$fmt = \&udecimal2;
129130
}
130131
elsif ($opt_e || $opt_F) {
131132
$fmt = \&float8;
@@ -137,7 +138,7 @@ elsif ($opt_H || $opt_X) {
137138
$fmt = \&hex4;
138139
}
139140
elsif ($opt_i || $opt_s) {
140-
$fmt = \&decimal;
141+
$fmt = \&decimal2;
141142
}
142143
elsif ($opt_l) {
143144
$fmt = \&long;
@@ -162,6 +163,28 @@ if (defined $opt_t) {
162163
$fmt = \&hex2;
163164
} elsif ($opt_t eq 'x4') {
164165
$fmt = \&hex4;
166+
} elsif ($opt_t eq 'o1') {
167+
$fmt = \&octal1;
168+
} elsif ($opt_t eq 'o2') {
169+
$fmt = \&octal2;
170+
} elsif ($opt_t eq 'o4') {
171+
$fmt = \&octal4;
172+
} elsif ($opt_t eq 'd1') {
173+
$fmt = \&decimal1;
174+
} elsif ($opt_t eq 'd2') {
175+
$fmt = \&decimal2;
176+
} elsif ($opt_t eq 'd4') {
177+
$fmt = \&decimal4;
178+
} elsif ($opt_t eq 'u1') {
179+
$fmt = \&udecimal1;
180+
} elsif ($opt_t eq 'u2') {
181+
$fmt = \&udecimal2;
182+
} elsif ($opt_t eq 'u4') {
183+
$fmt = \&udecimal4;
184+
} elsif ($opt_t eq 'a') {
185+
$fmt = \&char7bit;
186+
} elsif ($opt_t eq 'c') {
187+
$fmt = \&char1;
165188
} else {
166189
warn "$Program: unexpected output format specifier\n";
167190
exit EX_FAILURE;
@@ -272,6 +295,16 @@ sub octal1 {
272295
$strfmt = '%.3o ' x (scalar @arr);
273296
}
274297

298+
sub decimal1 {
299+
@arr = unpack 'c*', $data;
300+
$strfmt = '%4d ' x (scalar @arr);
301+
}
302+
303+
sub udecimal1 {
304+
@arr = unpack 'C*', $data;
305+
$strfmt = '%3u ' x (scalar @arr);
306+
}
307+
275308
sub hex1 {
276309
@arr = unpack 'C*', $data;
277310
$strfmt = '%.2x ' x (scalar @arr);
@@ -285,7 +318,7 @@ sub char1 {
285318
$arr[0] .= $charescs{$val} . " ";
286319
}
287320
elsif ($val > PRINTMAX || chr($val) !~ m/[[:print:]]/) {
288-
$arr[0] .= sprintf(' %03o', $val);
321+
$arr[0] .= sprintf('%03o ', $val);
289322
}
290323
else {
291324
$arr[0] .= " " . chr($val) . " ";
@@ -300,7 +333,7 @@ sub char7bit {
300333
for my $val (@arr1) {
301334
my $n = $val & 0x7f;
302335
if (exists $charname{$n}) {
303-
$arr[0] .= sprintf '%4s', $charname{$n};
336+
$arr[0] .= $charname{$n} . " ";
304337
}
305338
else {
306339
$arr[0] .= " " . chr($n) . " ";
@@ -309,7 +342,7 @@ sub char7bit {
309342
$strfmt = '%s';
310343
}
311344

312-
sub udecimal {
345+
sub udecimal2 {
313346
@arr = unpack 'S*', $data . zeropad(length($data), 2);
314347
$strfmt = '%5u ' x (scalar @arr);
315348
}
@@ -324,9 +357,9 @@ sub float8 {
324357
$strfmt = '%24.16e ' x (scalar @arr);
325358
}
326359

327-
sub decimal {
360+
sub decimal2 {
328361
@arr = unpack 's*', $data . zeropad(length($data), 2);
329-
$strfmt = '%5d ' x (scalar @arr);
362+
$strfmt = '%6d ' x (scalar @arr);
330363
}
331364

332365
sub long {
@@ -344,6 +377,16 @@ sub octal4 {
344377
$strfmt = '%.11o ' x (scalar @arr);
345378
}
346379

380+
sub decimal4 {
381+
@arr = unpack 'L*', $data . zeropad(length($data), 4);
382+
$strfmt = '%11d ' x (scalar @arr);
383+
}
384+
385+
sub udecimal4 {
386+
@arr = unpack 'L*', $data . zeropad(length($data), 4);
387+
$strfmt = '%11u ' x (scalar @arr);
388+
}
389+
347390
sub hex2 {
348391
@arr = unpack 'S*', $data . zeropad(length($data), 2);
349392
$strfmt = '%.4x ' x (scalar @arr);
@@ -468,7 +511,23 @@ Same as -i
468511
469512
=item -t Type
470513
471-
Select hexadecimal output size as either "x1", "x2" or "x4".
514+
Select output format as one of the following:
515+
516+
a ASCII character names. Same as -a
517+
c Characters with C escapes. Same as -c
518+
o1 1-byte unsigned octal
519+
o2 2-byte unsigned octal
520+
o4 4-byte unsigned octal
521+
d1 1-byte signed decimal
522+
d2 2-byte signed decimal
523+
d4 4-byte signed decimal
524+
u1 1-byte unsigned decimal
525+
u2 2-byte unsigned decimal
526+
u4 4-byte unsigned decimal
527+
x1 1-byte unsigned hexadecimal
528+
x2 2-byte unsigned hexadecimal
529+
x4 4-byte unsigned hexadecimal
530+
472531
This option overrides other formatting options.
473532
474533
=item -X

0 commit comments

Comments
 (0)