1 /* od -- dump files in octal and other formats
2 Copyright (C) 92, 1995-2004 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Written by Jim Meyering. */
20 /* Busyboxed by Denis Vlasenko
22 Based on od.c from coreutils-5.2.1
25 00000073 t parse_old_offset
27 00000090 r long_options
28 00000092 t print_named_ascii
29 000000bf t print_ascii
30 00000168 t write_block
31 00000366 t decode_format_string
34 Tested for compat with coreutils 6.3
35 using this script. Minor differences fixed.
39 time /path/to/coreutils/od \
48 diff -u -a std bbox >bbox.diff || { echo Different!; sleep 1; }
55 #define assert(a) ((void)0)
57 /* Check for 0x7f is a coreutils 6.3 addition */
58 #define ISPRINT(c) (((c)>=' ') && (c) != 0x7f)
60 typedef long double longdouble_t;
61 typedef unsigned long long ulonglong_t;
62 typedef long long llong;
65 # define xstrtooff_sfx xstrtoull_sfx
67 # define xstrtooff_sfx xstrtoul_sfx
70 /* The default number of input bytes per output line. */
71 #define DEFAULT_BYTES_PER_BLOCK 16
73 /* The number of decimal digits of precision in a float. */
78 /* The number of decimal digits of precision in a double. */
83 /* The number of decimal digits of precision in a long double. */
85 # define LDBL_DIG DBL_DIG
111 /* Each output format specification (from '-t spec' or from
112 old-style options) is represented by one of these structures. */
114 enum output_format fmt;
116 void (*print_function) (size_t, const char *, const char *);
118 int hexl_mode_trailer;
122 /* Convert the number of 8-bit bytes of a binary representation to
123 the number of characters (digits + sign if the type is signed)
124 required to represent the same quantity in the specified base/type.
125 For example, a 32-bit (4-byte) quantity may require a field width
126 as wide as the following for these types:
130 8 unsigned hexadecimal */
132 static const uint8_t bytes_to_oct_digits[] =
133 {0, 3, 6, 8, 11, 14, 16, 19, 22, 25, 27, 30, 32, 35, 38, 41, 43};
135 static const uint8_t bytes_to_signed_dec_digits[] =
136 {1, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 28, 30, 33, 35, 37, 40};
138 static const uint8_t bytes_to_unsigned_dec_digits[] =
139 {0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39};
141 static const uint8_t bytes_to_hex_digits[] =
142 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32};
144 /* Convert enum size_spec to the size of the named type. */
145 static const signed char width_bytes[] = {
157 /* Ensure that for each member of 'enum size_spec' there is an
158 initializer in the width_bytes array. */
160 int assert_width_bytes_matches_size_spec_decl
161 [sizeof width_bytes / sizeof width_bytes[0] == N_SIZE_SPECS ? 1 : -1];
164 static size_t string_min;
165 static int flag_dump_strings;
167 /* Non-zero if an old-style 'pseudo-address' was specified. */
168 static int flag_pseudo_start;
170 /* The difference between the old-style pseudo starting address and
171 the number of bytes to skip. */
172 static off_t pseudo_offset;
174 /* Function that accepts an address and an optional following char,
175 and prints the address and char to stdout. */
176 static void (*format_address) (off_t, char);
178 /* The number of input bytes to skip before formatting and writing. */
179 static off_t n_bytes_to_skip; // = 0;
181 /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
182 input is formatted. */
183 static int limit_bytes_to_format; // = 0;
185 /* The maximum number of bytes that will be formatted. */
186 static off_t max_bytes_to_format;
188 /* The offset of the first byte after the last byte to be formatted. */
189 static off_t end_offset;
191 /* When nonzero and two or more consecutive blocks are equal, format
192 only the first block and output an asterisk alone on the following
193 line to indicate that identical blocks have been elided. */
194 static int abbreviate_duplicate_blocks = 1;
196 /* An array of specs describing how to format each input block. */
197 static size_t n_specs;
198 static struct tspec *spec;
200 /* The number of input bytes formatted per output line. It must be
201 a multiple of the least common multiple of the sizes associated with
202 the specified output types. It should be as large as possible, but
203 no larger than 16 -- unless specified with the -w option. */
204 static size_t bytes_per_block;
206 /* Human-readable representation of *file_list (for error messages).
207 It differs from *file_list only when *file_list is "-". */
208 static char const *input_filename;
210 /* A NULL-terminated list of the file-arguments from the command line. */
211 static char const *const *file_list;
213 /* Initializer for file_list if no file-arguments
214 were specified on the command line. */
215 static char const *const default_file_list[] = { "-", NULL };
217 /* The input stream associated with the current file. */
218 static FILE *in_stream;
222 #define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
223 static unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] = {
224 [sizeof(char)] = CHAR,
225 #if USHRT_MAX != UCHAR_MAX
226 [sizeof(short)] = SHORT,
228 #if UINT_MAX != USHRT_MAX
231 #if ULONG_MAX != UINT_MAX
232 [sizeof(long)] = LONG,
234 #if ULLONG_MAX != ULONG_MAX
235 [sizeof(ulonglong_t)] = LONG_LONG,
239 #define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
240 static unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] = {
241 /* gcc seems to allow repeated indexes. Last one stays */
242 [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
243 [sizeof(double)] = FLOAT_DOUBLE,
244 [sizeof(float)] = FLOAT_SINGLE,
249 gcd(unsigned u, unsigned v)
260 /* Compute the least common multiple of U and V. */
262 lcm(unsigned u, unsigned v) {
263 unsigned t = gcd(u, v);
270 print_s_char(size_t n_bytes, const char *block, const char *fmt_string)
273 int tmp = *(signed char *) block;
274 printf(fmt_string, tmp);
275 block += sizeof(unsigned char);
280 print_char(size_t n_bytes, const char *block, const char *fmt_string)
283 unsigned tmp = *(unsigned char *) block;
284 printf(fmt_string, tmp);
285 block += sizeof(unsigned char);
290 print_s_short(size_t n_bytes, const char *block, const char *fmt_string)
292 n_bytes /= sizeof(signed short);
294 int tmp = *(signed short *) block;
295 printf(fmt_string, tmp);
296 block += sizeof(unsigned short);
301 print_short(size_t n_bytes, const char *block, const char *fmt_string)
303 n_bytes /= sizeof(unsigned short);
305 unsigned tmp = *(unsigned short *) block;
306 printf(fmt_string, tmp);
307 block += sizeof(unsigned short);
312 print_int(size_t n_bytes, const char *block, const char *fmt_string)
314 n_bytes /= sizeof(unsigned);
316 unsigned tmp = *(unsigned *) block;
317 printf(fmt_string, tmp);
318 block += sizeof(unsigned);
322 #if UINT_MAX == ULONG_MAX
323 # define print_long print_int
326 print_long(size_t n_bytes, const char *block, const char *fmt_string)
328 n_bytes /= sizeof(unsigned long);
330 unsigned long tmp = *(unsigned long *) block;
331 printf(fmt_string, tmp);
332 block += sizeof(unsigned long);
337 #if ULONG_MAX == ULLONG_MAX
338 # define print_long_long print_long
341 print_long_long(size_t n_bytes, const char *block, const char *fmt_string)
343 n_bytes /= sizeof(ulonglong_t);
345 ulonglong_t tmp = *(ulonglong_t *) block;
346 printf(fmt_string, tmp);
347 block += sizeof(ulonglong_t);
353 print_float(size_t n_bytes, const char *block, const char *fmt_string)
355 n_bytes /= sizeof(float);
357 float tmp = *(float *) block;
358 printf(fmt_string, tmp);
359 block += sizeof(float);
364 print_double(size_t n_bytes, const char *block, const char *fmt_string)
366 n_bytes /= sizeof(double);
368 double tmp = *(double *) block;
369 printf(fmt_string, tmp);
370 block += sizeof(double);
375 print_long_double(size_t n_bytes, const char *block, const char *fmt_string)
377 n_bytes /= sizeof(longdouble_t);
379 longdouble_t tmp = *(longdouble_t *) block;
380 printf(fmt_string, tmp);
381 block += sizeof(longdouble_t);
385 /* print_[named]_ascii are optimized for speed.
386 * Remember, someday you may want to pump gigabytes thru this thing.
387 * Saving a dozen of .text bytes here is counter-productive */
390 print_named_ascii(size_t n_bytes, const char *block,
391 const char *unused_fmt_string ATTRIBUTE_UNUSED)
393 /* Names for some non-printing characters. */
394 static const char charname[33][3] = {
395 "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
396 " bs", " ht", " nl", " vt", " ff", " cr", " so", " si",
397 "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
398 "can", " em", "sub", "esc", " fs", " gs", " rs", " us",
401 // buf[N] pos: 01234 56789
402 char buf[12] = " x\0 0xx\0";
403 // actually " x\0 xxx\0", but I want to share the string with below.
404 // [12] because we take three 32bit stack slots anyway, and
405 // gcc is too dumb to initialize with constant stores,
406 // it copies initializer from rodata. Oh well.
409 unsigned masked_c = *(unsigned char *) block++;
412 if (masked_c == 0x7f) {
413 fputs(" del", stdout);
416 if (masked_c > ' ') {
421 /* Why? Because printf(" %3.3s") is much slower... */
422 buf[6] = charname[masked_c][0];
423 buf[7] = charname[masked_c][1];
424 buf[8] = charname[masked_c][2];
425 fputs(buf+5, stdout);
430 print_ascii(size_t n_bytes, const char *block,
431 const char *unused_fmt_string ATTRIBUTE_UNUSED)
433 // buf[N] pos: 01234 56789
434 char buf[12] = " x\0 0xx\0";
438 unsigned c = *(unsigned char *) block++;
473 default: /* c is never larger than 040 */
474 buf[7] = (c >> 3) + '0';
475 buf[8] = (c & 7) + '0';
482 /* Given a list of one or more input filenames FILE_LIST, set the global
483 file pointer IN_STREAM and the global string INPUT_FILENAME to the
484 first one that can be successfully opened. Modify FILE_LIST to
485 reference the next filename in the list. A file name of "-" is
486 interpreted as standard input. If any file open fails, give an error
487 message and return nonzero. */
493 input_filename = *file_list;
497 in_stream = fopen_or_warn_stdin(input_filename);
499 if (in_stream == stdin)
500 input_filename = bb_msg_standard_input;
506 if (limit_bytes_to_format && !flag_dump_strings)
507 setbuf(in_stream, NULL);
510 /* Test whether there have been errors on in_stream, and close it if
511 it is not standard input. Return nonzero if there has been an error
512 on in_stream or stdout; return zero otherwise. This function will
513 report more than one error only if both a read and a write error
514 have occurred. IN_ERRNO, if nonzero, is the error number
515 corresponding to the most recent action for IN_STREAM. */
518 check_and_close(void)
521 if (ferror(in_stream)) {
522 bb_error_msg("%s: read error", input_filename);
525 fclose_if_not_stdin(in_stream);
529 if (ferror(stdout)) {
530 bb_error_msg("write error");
535 /* If S points to a single valid modern od format string, put
536 a description of that format in *TSPEC, make *NEXT point at the
537 character following the just-decoded format (if *NEXT is non-NULL),
538 and return zero. For example, if S were "d4afL"
539 *NEXT would be set to "afL" and *TSPEC would be
541 fmt = SIGNED_DECIMAL;
542 size = INT or LONG; (whichever integral_type_size[4] resolves to)
543 print_function = print_int; (assuming size == INT)
544 fmt_string = "%011d%c";
546 S_ORIG is solely for reporting errors. It should be the full format
550 decode_one_format(const char *s_orig, const char *s, const char **next,
553 enum size_spec size_spec;
555 enum output_format fmt;
558 char *fmt_string = NULL;
559 void (*print_function) (size_t, const char *, const char *);
561 unsigned field_width = 0;
564 assert(tspec != NULL);
571 static const char CSIL[] = "CSIL";
574 p = strchr(CSIL, *s);
578 size = bb_strtou(s, &end, 0);
580 || MAX_INTEGRAL_TYPE_SIZE < size
581 || integral_type_size[size] == NO_SIZE
583 bb_error_msg_and_die("invalid type string '%s'; "
584 "%u-byte %s type is not supported",
585 s_orig, size, "integral");
590 static const uint8_t CSIL_sizeof[] = {
596 size = CSIL_sizeof[p - CSIL];
599 #define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format) \
600 ((Spec) == LONG_LONG ? (Max_format) \
601 : ((Spec) == LONG ? (Long_format) : (Min_format)))
603 #define FMT_BYTES_ALLOCATED 9
604 size_spec = integral_type_size[size];
607 static const char doux[] = "doux";
608 static const char doux_fmt_letter[][4] = {
609 "lld", "llo", "llu", "llx"
611 static const enum output_format doux_fmt[] = {
617 static const uint8_t *const doux_bytes_to_XXX[] = {
618 bytes_to_signed_dec_digits,
620 bytes_to_unsigned_dec_digits,
623 static const char doux_fmtstring[][sizeof(" %%0%u%s")] = {
630 pos = strchr(doux, c) - doux;
632 field_width = doux_bytes_to_XXX[pos][size];
633 p = doux_fmt_letter[pos] + 2;
634 if (size_spec == LONG) p--;
635 if (size_spec == LONG_LONG) p -= 2;
636 fmt_string = xasprintf(doux_fmtstring[pos], field_width, p);
641 print_function = (fmt == SIGNED_DECIMAL
646 print_function = (fmt == SIGNED_DECIMAL
651 print_function = print_int;
654 print_function = print_long;
656 default: /* case LONG_LONG: */
657 print_function = print_long_long;
664 static const char FDL[] = "FDL";
666 fmt = FLOATING_POINT;
670 size = sizeof(double);
672 size = bb_strtou(s, &end, 0);
673 if (errno == ERANGE || size > MAX_FP_TYPE_SIZE
674 || fp_type_size[size] == NO_SIZE
676 bb_error_msg_and_die("invalid type string '%s'; "
677 "%u-byte %s type is not supported",
678 s_orig, size, "floating point");
683 static const uint8_t FDL_sizeof[] = {
686 sizeof(longdouble_t),
689 size = FDL_sizeof[p - FDL];
692 size_spec = fp_type_size[size];
696 print_function = print_float;
697 field_width = FLT_DIG + 8;
698 /* Don't use %#e; not all systems support it. */
699 fmt_string = xasprintf(" %%%d.%de", field_width, FLT_DIG);
702 print_function = print_double;
703 field_width = DBL_DIG + 8;
704 fmt_string = xasprintf(" %%%d.%de", field_width, DBL_DIG);
706 default: /* case FLOAT_LONG_DOUBLE: */
707 print_function = print_long_double;
708 field_width = LDBL_DIG + 8;
709 fmt_string = xasprintf(" %%%d.%dLe", field_width, LDBL_DIG);
717 fmt = NAMED_CHARACTER;
719 print_function = print_named_ascii;
726 print_function = print_ascii;
730 bb_error_msg_and_die("invalid character '%c' "
731 "in type string '%s'", *s, s_orig);
734 tspec->size = size_spec;
736 tspec->print_function = print_function;
737 tspec->fmt_string = fmt_string;
739 tspec->field_width = field_width;
740 tspec->hexl_mode_trailer = (*s == 'z');
741 if (tspec->hexl_mode_trailer)
748 /* Decode the modern od format string S. Append the decoded
749 representation to the global array SPEC, reallocating SPEC if
750 necessary. Return zero if S is valid, nonzero otherwise. */
753 decode_format_string(const char *s)
755 const char *s_orig = s;
761 decode_one_format(s_orig, s, &next, &tspec);
766 spec = xrealloc(spec, n_specs * sizeof(*spec));
767 memcpy(&spec[n_specs-1], &tspec, sizeof *spec);
771 /* Given a list of one or more input filenames FILE_LIST, set the global
772 file pointer IN_STREAM to position N_SKIP in the concatenation of
773 those files. If any file operation fails or if there are fewer than
774 N_SKIP bytes in the combined input, give an error message and return
775 nonzero. When possible, use seek rather than read operations to
776 advance IN_STREAM. */
784 while (in_stream) { /* !EOF */
785 struct stat file_stats;
787 /* First try seeking. For large offsets, this extra work is
788 worthwhile. If the offset is below some threshold it may be
789 more efficient to move the pointer by reading. There are two
790 issues when trying to seek:
791 - the file must be seekable.
792 - before seeking to the specified position, make sure
793 that the new position is in the current file.
794 Try to do that by getting file's size using fstat.
795 But that will work only for regular files. */
797 /* The st_size field is valid only for regular files
798 (and for symbolic links, which cannot occur here).
799 If the number of bytes left to skip is at least
800 as large as the size of the current file, we can
801 decrement n_skip and go on to the next file. */
802 if (fstat(fileno(in_stream), &file_stats) == 0
803 && S_ISREG(file_stats.st_mode) && file_stats.st_size >= 0
805 if (file_stats.st_size < n_skip) {
806 n_skip -= file_stats.st_size;
807 /* take check&close / open_next route */
809 if (fseeko(in_stream, n_skip, SEEK_CUR) != 0)
814 /* If it's not a regular file with nonnegative size,
815 position the file pointer by reading. */
817 size_t n_bytes_read, n_bytes_to_read = BUFSIZ;
820 if (n_skip < n_bytes_to_read)
821 n_bytes_to_read = n_skip;
822 n_bytes_read = fread(buf, 1, n_bytes_to_read, in_stream);
823 n_skip -= n_bytes_read;
824 if (n_bytes_read != n_bytes_to_read)
825 break; /* EOF on this file or error */
836 bb_error_msg_and_die("cannot skip past end of combined input");
840 typedef void FN_format_address(off_t address, char c);
843 format_address_none(off_t address ATTRIBUTE_UNUSED, char c ATTRIBUTE_UNUSED)
847 static char address_fmt[] = "%0n"OFF_FMT"xc";
848 /* Corresponds to 'x' above */
849 #define address_base_char address_fmt[sizeof(address_fmt)-3]
850 /* Corresponds to 'n' above */
851 #define address_pad_len_char address_fmt[2]
854 format_address_std(off_t address, char c)
856 /* Corresponds to 'c' */
857 address_fmt[sizeof(address_fmt)-2] = c;
858 printf(address_fmt, address);
861 #if ENABLE_GETOPT_LONG
862 /* only used with --traditional */
864 format_address_paren(off_t address, char c)
867 format_address_std(address, ')');
872 format_address_label(off_t address, char c)
874 format_address_std(address, ' ');
875 format_address_paren(address + pseudo_offset, c);
880 dump_hexl_mode_trailer(size_t n_bytes, const char *block)
884 unsigned c = *(unsigned char *) block++;
885 c = (ISPRINT(c) ? c : '.');
891 /* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
892 of the N_SPEC format specs. CURRENT_OFFSET is the byte address of
893 CURR_BLOCK in the concatenation of input files, and it is printed
894 (optionally) only before the output line associated with the first
895 format spec. When duplicate blocks are being abbreviated, the output
896 for a sequence of identical input blocks is the output for the first
897 block followed by an asterisk alone on a line. It is valid to compare
898 the blocks PREV_BLOCK and CURR_BLOCK only when N_BYTES == BYTES_PER_BLOCK.
899 That condition may be false only for the last input block -- and then
900 only when it has not been padded to length BYTES_PER_BLOCK. */
903 write_block(off_t current_offset, size_t n_bytes,
904 const char *prev_block, const char *curr_block)
906 static char first = 1;
907 static char prev_pair_equal = 0;
910 if (abbreviate_duplicate_blocks
912 && n_bytes == bytes_per_block
913 && memcmp(prev_block, curr_block, bytes_per_block) == 0
915 if (prev_pair_equal) {
916 /* The two preceding blocks were equal, and the current
917 block is the same as the last one, so print nothing. */
925 for (i = 0; i < n_specs; i++) {
927 format_address(current_offset, '\0');
929 printf("%*s", address_pad_len_char - '0', "");
930 (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
931 if (spec[i].hexl_mode_trailer) {
932 /* space-pad out to full line width, then dump the trailer */
933 int datum_width = width_bytes[spec[i].size];
934 int blank_fields = (bytes_per_block - n_bytes) / datum_width;
935 int field_width = spec[i].field_width + 1;
936 printf("%*s", blank_fields * field_width, "");
937 dump_hexl_mode_trailer(n_bytes, curr_block);
945 read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
947 assert(0 < n && n <= bytes_per_block);
949 *n_bytes_in_buffer = 0;
954 while (in_stream != NULL) { /* EOF. */
958 n_needed = n - *n_bytes_in_buffer;
959 n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, in_stream);
960 *n_bytes_in_buffer += n_read;
961 if (n_read == n_needed)
963 /* error check is done in check_and_close */
969 /* Return the least common multiple of the sizes associated
970 with the format specs. */
978 for (i = 0; i < n_specs; i++)
979 l_c_m = lcm(l_c_m, width_bytes[(int) spec[i].size]);
983 #if ENABLE_GETOPT_LONG
984 /* If S is a valid traditional offset specification with an optional
985 leading '+' return nonzero and set *OFFSET to the offset it denotes. */
988 parse_old_offset(const char *s, off_t *offset)
990 static const struct suffix_mult Bb[] = {
998 /* Skip over any leading '+'. */
999 if (s[0] == '+') ++s;
1001 /* Determine the radix we'll use to interpret S. If there is a '.',
1002 * it's decimal, otherwise, if the string begins with '0X'or '0x',
1003 * it's hexadecimal, else octal. */
1007 p[0] = '\0'; /* cheating */
1009 } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
1012 *offset = xstrtooff_sfx(s, radix, Bb);
1015 return (*offset >= 0);
1019 /* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
1020 formatted block to standard output, and repeat until the specified
1021 maximum number of bytes has been read or until all input has been
1022 processed. If the last block read is smaller than BYTES_PER_BLOCK
1023 and its size is not a multiple of the size associated with a format
1024 spec, extend the input block with zero bytes until its length is a
1025 multiple of all format spec sizes. Write the final block. Finally,
1026 write on a line by itself the offset of the byte after the last byte
1027 read. Accumulate return values from calls to read_block and
1028 check_and_close, and if any was nonzero, return nonzero.
1029 Otherwise, return zero. */
1035 off_t current_offset;
1037 size_t n_bytes_read;
1039 block[0] = xmalloc(2*bytes_per_block);
1040 block[1] = block[0] + bytes_per_block;
1042 current_offset = n_bytes_to_skip;
1045 if (limit_bytes_to_format) {
1048 if (current_offset >= end_offset) {
1052 n_needed = MIN(end_offset - current_offset,
1053 (off_t) bytes_per_block);
1054 read_block(n_needed, block[idx], &n_bytes_read);
1055 if (n_bytes_read < bytes_per_block)
1057 assert(n_bytes_read == bytes_per_block);
1058 write_block(current_offset, n_bytes_read,
1059 block[!idx], block[idx]);
1060 current_offset += n_bytes_read;
1065 read_block(bytes_per_block, block[idx], &n_bytes_read);
1066 if (n_bytes_read < bytes_per_block)
1068 assert(n_bytes_read == bytes_per_block);
1069 write_block(current_offset, n_bytes_read,
1070 block[!idx], block[idx]);
1071 current_offset += n_bytes_read;
1076 if (n_bytes_read > 0) {
1078 size_t bytes_to_write;
1082 /* Make bytes_to_write the smallest multiple of l_c_m that
1083 is at least as large as n_bytes_read. */
1084 bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
1086 memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
1087 write_block(current_offset, bytes_to_write,
1088 block[!idx], block[idx]);
1089 current_offset += n_bytes_read;
1092 format_address(current_offset, '\n');
1094 if (limit_bytes_to_format && current_offset >= end_offset)
1100 /* Read a single byte into *C from the concatenation of the input files
1101 named in the global array FILE_LIST. On the first call to this
1102 function, the global variable IN_STREAM is expected to be an open
1103 stream associated with the input file INPUT_FILENAME. If IN_STREAM
1104 is at end-of-file, close it and update the global variables IN_STREAM
1105 and INPUT_FILENAME so they correspond to the next file in the list.
1106 Then try to read a byte from the newly opened file. Repeat if
1107 necessary until EOF is reached for the last file in FILE_LIST, then
1108 set *C to EOF and return. Subsequent calls do likewise. The return
1109 value is nonzero if any errors occured, zero otherwise. */
1114 while (in_stream) { /* !EOF */
1115 *c = fgetc(in_stream);
1124 /* Read N bytes into BLOCK from the concatenation of the input files
1125 named in the global array FILE_LIST. On the first call to this
1126 function, the global variable IN_STREAM is expected to be an open
1127 stream associated with the input file INPUT_FILENAME. If all N
1128 bytes cannot be read from IN_STREAM, close IN_STREAM and update
1129 the global variables IN_STREAM and INPUT_FILENAME. Then try to
1130 read the remaining bytes from the newly opened file. Repeat if
1131 necessary until EOF is reached for the last file in FILE_LIST.
1132 On subsequent calls, don't modify BLOCK and return zero. Set
1133 *N_BYTES_IN_BUFFER to the number of bytes read. If an error occurs,
1134 it will be detected through ferror when the stream is about to be
1135 closed. If there is an error, give a message but continue reading
1136 as usual and return nonzero. Otherwise return zero. */
1138 /* STRINGS mode. Find each "string constant" in the input.
1139 A string constant is a run of at least 'string_min' ASCII
1140 graphic (or formatting) characters terminated by a null.
1141 Based on a function written by Richard Stallman for a
1142 traditional version of od. Return nonzero if an error
1143 occurs. Otherwise, return zero. */
1148 size_t bufsize = MAX(100, string_min);
1149 char *buf = xmalloc(bufsize);
1150 off_t address = n_bytes_to_skip;
1156 /* See if the next 'string_min' chars are all printing chars. */
1158 if (limit_bytes_to_format && (end_offset - string_min <= address))
1161 while (!limit_bytes_to_format || address < end_offset) {
1163 bufsize += bufsize/8;
1164 buf = xrealloc(buf, bufsize);
1167 if (c < 0) { /* EOF */
1175 goto tryline; /* It isn't; give up on this string. */
1176 buf[i++] = c; /* String continues; store it all. */
1179 if (i < string_min) /* Too short! */
1182 /* If we get here, the string is all printable and null-terminated,
1183 * so print it. It is all in 'buf' and 'i' is its length. */
1185 format_address(address - i - 1, ' ');
1187 for (i = 0; (c = buf[i]); i++) {
1189 case '\007': fputs("\\a", stdout); break;
1190 case '\b': fputs("\\b", stdout); break;
1191 case '\f': fputs("\\f", stdout); break;
1192 case '\n': fputs("\\n", stdout); break;
1193 case '\r': fputs("\\r", stdout); break;
1194 case '\t': fputs("\\t", stdout); break;
1195 case '\v': fputs("\\v", stdout); break;
1196 default: putc(c, stdout);
1202 /* We reach this point only if we search through
1203 (max_bytes_to_format - string_min) bytes before reaching EOF. */
1209 int od_main(int argc, char **argv);
1210 int od_main(int argc, char **argv)
1212 static const struct suffix_mult bkm[] = {
1220 /* The old-style 'pseudo starting address' to be printed in parentheses
1221 after any true address. */
1222 off_t pseudo_start = 0; // only for gcc
1242 OPT_traditional = (1 << 18) * ENABLE_GETOPT_LONG,
1244 #if ENABLE_GETOPT_LONG
1245 static const struct option long_options[] = {
1246 { "skip-bytes", required_argument, NULL, 'j' },
1247 { "address-radix", required_argument, NULL, 'A' },
1248 { "read-bytes", required_argument, NULL, 'N' },
1249 { "format", required_argument, NULL, 't' },
1250 { "output-duplicates", no_argument, NULL, 'v' },
1251 { "strings", optional_argument, NULL, 'S' },
1252 { "width", optional_argument, NULL, 'w' },
1253 { "traditional", no_argument, NULL, 0xff },
1254 { NULL, 0, NULL, 0 }
1257 char *str_A, *str_N, *str_j, *str_S;
1259 llist_t *lst_t = NULL;
1262 format_address = format_address_std;
1263 address_base_char = 'o';
1264 address_pad_len_char = '7';
1265 flag_dump_strings = 0;
1267 /* Parse command line */
1268 opt_complementary = "t::"; // list
1269 #if ENABLE_GETOPT_LONG
1270 applet_long_options = long_options;
1272 opt = getopt32(argc, argv, "A:N:abcdfhij:lot:vxsS:"
1273 "w::", // -w with optional param
1274 // -S was -s and also had optional parameter
1275 // but in coreutils 6.3 it was renamed and now has
1276 // _mandatory_ parameter
1277 &str_A, &str_N, &str_j, &lst_t, &str_S, &str_w);
1281 static const char doxn[] = "doxn";
1282 static const char doxn_address_base_char[] = {
1283 'u', 'o', 'x', /* '?' fourth one is not important */
1285 static const uint8_t doxn_address_pad_len_char[] = {
1286 '7', '7', '6', /* '?' */
1290 p = strchr(doxn, str_A[0]);
1292 bb_error_msg_and_die("bad output address radix "
1293 "'%c' (must be [doxn])", str_A[0]);
1295 if (pos == 3) format_address = format_address_none;
1296 address_base_char = doxn_address_base_char[pos];
1297 address_pad_len_char = doxn_address_pad_len_char[pos];
1300 limit_bytes_to_format = 1;
1301 max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm);
1303 if (opt & OPT_a) decode_format_string("a");
1304 if (opt & OPT_b) decode_format_string("oC");
1305 if (opt & OPT_c) decode_format_string("c");
1306 if (opt & OPT_d) decode_format_string("u2");
1307 if (opt & OPT_f) decode_format_string("fF");
1308 if (opt & OPT_h) decode_format_string("x2");
1309 if (opt & OPT_i) decode_format_string("d2");
1310 if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm);
1311 if (opt & OPT_l) decode_format_string("d4");
1312 if (opt & OPT_o) decode_format_string("o2");
1313 //if (opt & OPT_t)...
1315 decode_format_string(lst_t->data);
1316 lst_t = lst_t->link;
1318 if (opt & OPT_v) abbreviate_duplicate_blocks = 0;
1319 if (opt & OPT_x) decode_format_string("x2");
1320 if (opt & OPT_s) decode_format_string("d2");
1323 string_min = xstrtou_sfx(str_S, 0, bkm);
1324 flag_dump_strings = 1;
1326 //if (opt & OPT_w)...
1327 //if (opt & OPT_traditional)...
1329 if (flag_dump_strings && n_specs > 0)
1330 bb_error_msg_and_die("no type may be specified when dumping strings");
1332 /* If the --traditional option is used, there may be from
1333 * 0 to 3 remaining command line arguments; handle each case
1335 * od [file] [[+]offset[.][b] [[+]label[.][b]]]
1336 * The offset and pseudo_start have the same syntax.
1338 * FIXME: POSIX 1003.1-2001 with XSI requires support for the
1339 * traditional syntax even if --traditional is not given. */
1341 #if ENABLE_GETOPT_LONG
1342 if (opt & OPT_traditional) {
1346 if (parse_old_offset(argv[0], &o1)) {
1347 n_bytes_to_skip = o1;
1351 } else if (argc == 2) {
1352 if (parse_old_offset(argv[0], &o1)
1353 && parse_old_offset(argv[1], &o2)
1355 n_bytes_to_skip = o1;
1356 flag_pseudo_start = 1;
1360 } else if (parse_old_offset(argv[1], &o2)) {
1361 n_bytes_to_skip = o2;
1366 bb_error_msg_and_die("invalid second operand "
1367 "in compatibility mode '%s'", argv[1]);
1369 } else if (argc == 3) {
1370 if (parse_old_offset(argv[1], &o1)
1371 && parse_old_offset(argv[2], &o2)
1373 n_bytes_to_skip = o1;
1374 flag_pseudo_start = 1;
1380 bb_error_msg_and_die("in compatibility mode "
1381 "the last two arguments must be offsets");
1383 } else if (argc > 3) {
1384 bb_error_msg_and_die("compatibility mode supports "
1385 "at most three arguments");
1388 if (flag_pseudo_start) {
1389 if (format_address == format_address_none) {
1390 address_base_char = 'o';
1391 address_pad_len_char = '7';
1392 format_address = format_address_paren;
1394 format_address = format_address_label;
1399 if (limit_bytes_to_format) {
1400 end_offset = n_bytes_to_skip + max_bytes_to_format;
1401 if (end_offset < n_bytes_to_skip)
1402 bb_error_msg_and_die("skip-bytes + read-bytes is too large");
1406 decode_format_string("o2");
1410 /* If no files were listed on the command line,
1411 set the global pointer FILE_LIST so that it
1412 references the null-terminated list of one name: "-". */
1413 file_list = default_file_list;
1415 /* Set the global pointer FILE_LIST so that it
1416 references the first file-argument on the command-line. */
1417 file_list = (char const *const *) argv;
1420 /* open the first input file */
1422 /* skip over any unwanted header bytes */
1423 skip(n_bytes_to_skip);
1427 pseudo_offset = (flag_pseudo_start ? pseudo_start - n_bytes_to_skip : 0);
1429 /* Compute output block length. */
1432 if (opt & OPT_w) { /* -w: width */
1433 bytes_per_block = 32;
1435 bytes_per_block = xatou(str_w);
1436 if (!bytes_per_block || bytes_per_block % l_c_m != 0) {
1437 bb_error_msg("warning: invalid width %zu; using %d instead",
1438 bytes_per_block, l_c_m);
1439 bytes_per_block = l_c_m;
1442 bytes_per_block = l_c_m;
1443 if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
1444 bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
1448 for (i = 0; i < n_specs; i++) {
1449 printf("%d: fmt=\"%s\" width=%d\n",
1450 i, spec[i].fmt_string, width_bytes[spec[i].size]);
1454 if (flag_dump_strings)
1459 if (fclose(stdin) == EOF)
1460 bb_perror_msg_and_die(bb_msg_standard_input);
1462 return (ioerror != 0); /* err != 0 - return 1 (failure) */