Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (7 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/coreutils/od_bloaty.c

    r2725 r3232  
    1414   You should have received a copy of the GNU General Public License
    1515   along with this program; if not, write to the Free Software Foundation,
    16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    17 
     16   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     17 */
    1818/* Written by Jim Meyering.  */
    19 
    20 /* Busyboxed by Denys Vlasenko
    21 
    22 Based on od.c from coreutils-5.2.1
    23 Top bloat sources:
    24 
    25 00000073 t parse_old_offset
    26 0000007b t get_lcm
    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
    32 00000a71 T od_main
    33 
    34 Tested for compat with coreutils 6.3
    35 using this script. Minor differences fixed.
    36 
    37 #!/bin/sh
    38 echo STD
    39 time /path/to/coreutils/od \
    40 ...params... \
    41 >std
    42 echo Exit code $?
    43 echo BBOX
    44 time ./busybox od \
    45 ...params... \
    46 >bbox
    47 echo Exit code $?
    48 diff -u -a std bbox >bbox.diff || { echo Different!; sleep 1; }
    49 
    50 */
    51 
    52 #include "libbb.h"
    53 
     19/* Busyboxed by Denys Vlasenko, based on od.c from coreutils-5.2.1 */
     20
     21
     22/* #include "libbb.h" - done in od.c */
    5423#define assert(a) ((void)0)
    5524
     25
     26//usage:#if ENABLE_DESKTOP
     27//usage:#define od_trivial_usage
     28//usage:       "[-abcdfhilovxs] [-t TYPE] [-A RADIX] [-N SIZE] [-j SKIP] [-S MINSTR] [-w WIDTH] [FILE]..."
     29// We don't support:
     30// ... [FILE] [[+]OFFSET[.][b]]
     31// Support is buggy for:
     32// od --traditional [OPTION]... [FILE] [[+]OFFSET[.][b] [+][LABEL][.][b]]
     33
     34//usage:#define od_full_usage "\n\n"
     35//usage:       "Print FILEs (or stdin) unambiguously, as octal bytes by default"
     36//usage:#endif
     37
     38enum {
     39    OPT_A = 1 << 0,
     40    OPT_N = 1 << 1,
     41    OPT_a = 1 << 2,
     42    OPT_b = 1 << 3,
     43    OPT_c = 1 << 4,
     44    OPT_d = 1 << 5,
     45    OPT_f = 1 << 6,
     46    OPT_h = 1 << 7,
     47    OPT_i = 1 << 8,
     48    OPT_j = 1 << 9,
     49    OPT_l = 1 << 10,
     50    OPT_o = 1 << 11,
     51    OPT_t = 1 << 12,
     52    /* When zero and two or more consecutive blocks are equal, format
     53       only the first block and output an asterisk alone on the following
     54       line to indicate that identical blocks have been elided: */
     55    OPT_v = 1 << 13,
     56    OPT_x = 1 << 14,
     57    OPT_s = 1 << 15,
     58    OPT_S = 1 << 16,
     59    OPT_w = 1 << 17,
     60    OPT_traditional = (1 << 18) * ENABLE_LONG_OPTS,
     61};
     62
     63#define OD_GETOPT32() getopt32(argv, \
     64    "A:N:abcdfhij:lot:vxsS:w::", \
     65    /* -w with optional param */ \
     66    /* -S was -s and also had optional parameter */ \
     67    /* but in coreutils 6.3 it was renamed and now has */ \
     68    /* _mandatory_ parameter */ \
     69    &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block)
     70
     71
    5672/* Check for 0x7f is a coreutils 6.3 addition */
    57 #define ISPRINT(c) (((c)>=' ') && (c) != 0x7f)
     73#define ISPRINT(c) (((c) >= ' ') && (c) < 0x7f)
    5874
    5975typedef long double longdouble_t;
     
    159175};
    160176
    161 static smallint flag_dump_strings;
    162 /* Non-zero if an old-style 'pseudo-address' was specified.  */
    163 static smallint flag_pseudo_start;
    164 static smallint limit_bytes_to_format;
    165 /* When zero and two or more consecutive blocks are equal, format
    166    only the first block and output an asterisk alone on the following
    167    line to indicate that identical blocks have been elided.  */
    168 static smallint verbose;
    169 static smallint ioerror;
    170 
    171 static size_t string_min;
     177static smallint exit_code;
     178
     179static unsigned string_min;
    172180
    173181/* An array of specs describing how to format each input block.  */
     
    180188/* The difference between the old-style pseudo starting address and
    181189   the number of bytes to skip.  */
     190#if ENABLE_LONG_OPTS
    182191static off_t pseudo_offset;
     192#else
     193enum { pseudo_offset = 0 };
     194#endif
    183195/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
    184196   input is formatted.  */
     
    215227#define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
    216228static const unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = {
    217     /* gcc seems to allow repeated indexes. Last one stays */
     229    /* gcc seems to allow repeated indexes. Last one wins */
    218230    [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
    219231    [sizeof(double)] = FLOAT_DOUBLE,
     
    377389    // buf[N] pos:  01234 56789
    378390    char buf[12] = "   x\0 0xx\0";
    379     // actually "   x\0 xxx\0", but I want to share the string with below.
     391    // actually "   x\0 xxx\0", but want to share string with print_ascii.
    380392    // [12] because we take three 32bit stack slots anyway, and
    381393    // gcc is too dumb to initialize with constant stores,
     
    473485            break;
    474486        }
    475         ioerror = 1;
    476     }
    477 
    478     if (limit_bytes_to_format && !flag_dump_strings)
     487        exit_code = 1;
     488    }
     489
     490    if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N)
    479491        setbuf(in_stream, NULL);
    480492}
     
    496508                    : file_list[-1]
    497509            );
    498             ioerror = 1;
     510            exit_code = 1;
    499511        }
    500512        fclose_if_not_stdin(in_stream);
     
    503515
    504516    if (ferror(stdout)) {
    505         bb_error_msg(bb_msg_write_error);
    506         ioerror = 1;
     517        bb_error_msg_and_die(bb_msg_write_error);
    507518    }
    508519}
     
    535546    unsigned field_width = 0;
    536547    int pos;
    537 
    538548
    539549    switch (*s) {
     
    782792            } else {
    783793                if (fseeko(in_stream, n_skip, SEEK_CUR) != 0)
    784                     ioerror = 1;
     794                    exit_code = 1;
    785795                return;
    786796            }
     
    883893    size_t i;
    884894
    885     if (!verbose && !first
     895    if (!(option_mask32 & OPT_v)
     896     && !first
    886897     && n_bytes == bytes_per_block
    887898     && memcmp(prev_block, curr_block, bytes_per_block) == 0
     
    905916            if (spec[i].hexl_mode_trailer) {
    906917                /* space-pad out to full line width, then dump the trailer */
    907                 int datum_width = width_bytes[spec[i].size];
    908                 int blank_fields = (bytes_per_block - n_bytes) / datum_width;
    909                 int field_width = spec[i].field_width + 1;
     918                unsigned datum_width = width_bytes[spec[i].size];
     919                unsigned blank_fields = (bytes_per_block - n_bytes) / datum_width;
     920                unsigned field_width = spec[i].field_width + 1;
    910921                printf("%*s", blank_fields * field_width, "");
    911922                dump_hexl_mode_trailer(n_bytes, curr_block);
     
    954965    return l_c_m;
    955966}
    956 
    957 #if ENABLE_LONG_OPTS
    958 /* If S is a valid traditional offset specification with an optional
    959    leading '+' return nonzero and set *OFFSET to the offset it denotes.  */
    960 
    961 static int
    962 parse_old_offset(const char *s, off_t *offset)
    963 {
    964     static const struct suffix_mult Bb[] = {
    965         { "B", 1024 },
    966         { "b", 512 },
    967         { "", 0 }
    968     };
    969     char *p;
    970     int radix;
    971 
    972     /* Skip over any leading '+'. */
    973     if (s[0] == '+') ++s;
    974 
    975     /* Determine the radix we'll use to interpret S.  If there is a '.',
    976      * it's decimal, otherwise, if the string begins with '0X'or '0x',
    977      * it's hexadecimal, else octal.  */
    978     p = strchr(s, '.');
    979     radix = 8;
    980     if (p) {
    981         p[0] = '\0'; /* cheating */
    982         radix = 10;
    983     } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
    984         radix = 16;
    985 
    986     *offset = xstrtooff_sfx(s, radix, Bb);
    987     if (p) p[0] = '.';
    988 
    989     return (*offset >= 0);
    990 }
    991 #endif
    992967
    993968/* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
     
    1008983    size_t n_bytes_read;
    1009984
    1010     block[0] = xmalloc(2*bytes_per_block);
     985    block[0] = xmalloc(2 * bytes_per_block);
    1011986    block[1] = block[0] + bytes_per_block;
    1012987
    1013988    idx = 0;
    1014     if (limit_bytes_to_format) {
     989    if (option_mask32 & OPT_N) {
    1015990        while (1) {
    1016991            size_t n_needed;
     
    1019994                break;
    1020995            }
    1021             n_needed = MIN(end_offset - current_offset,
    1022                 (off_t) bytes_per_block);
     996            n_needed = MIN(end_offset - current_offset, (off_t) bytes_per_block);
    1023997            read_block(n_needed, block[idx], &n_bytes_read);
    1024998            if (n_bytes_read < bytes_per_block)
    1025999                break;
    10261000            assert(n_bytes_read == bytes_per_block);
    1027             write_block(current_offset, n_bytes_read,
    1028                    block[!idx], block[idx]);
     1001            write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
    10291002            current_offset += n_bytes_read;
    1030             idx = !idx;
     1003            idx ^= 1;
    10311004        }
    10321005    } else {
     
    10361009                break;
    10371010            assert(n_bytes_read == bytes_per_block);
    1038             write_block(current_offset, n_bytes_read,
    1039                    block[!idx], block[idx]);
     1011            write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
    10401012            current_offset += n_bytes_read;
    1041             idx = !idx;
     1013            idx ^= 1;
    10421014        }
    10431015    }
     
    10501022
    10511023        /* Make bytes_to_write the smallest multiple of l_c_m that
    1052             is at least as large as n_bytes_read.  */
     1024          is at least as large as n_bytes_read.  */
    10531025        bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
    10541026
    10551027        memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
    10561028        write_block(current_offset, bytes_to_write,
    1057                    block[!idx], block[idx]);
     1029                block[idx ^ 1], block[idx]);
    10581030        current_offset += n_bytes_read;
    10591031    }
     
    10611033    format_address(current_offset, '\n');
    10621034
    1063     if (limit_bytes_to_format && current_offset >= end_offset)
     1035    if ((option_mask32 & OPT_N) && current_offset >= end_offset)
    10641036        check_and_close();
    10651037
    10661038    free(block[0]);
    1067 }
    1068 
    1069 /* Read a single byte into *C from the concatenation of the input files
    1070    named in the global array FILE_LIST.  On the first call to this
    1071    function, the global variable IN_STREAM is expected to be an open
    1072    stream associated with the input file INPUT_FILENAME.  If IN_STREAM
    1073    is at end-of-file, close it and update the global variables IN_STREAM
    1074    and INPUT_FILENAME so they correspond to the next file in the list.
    1075    Then try to read a byte from the newly opened file.  Repeat if
    1076    necessary until EOF is reached for the last file in FILE_LIST, then
    1077    set *C to EOF and return.  Subsequent calls do likewise.  */
    1078 
    1079 static void
    1080 read_char(int *c)
    1081 {
    1082     while (in_stream) { /* !EOF */
    1083         *c = fgetc(in_stream);
    1084         if (*c != EOF)
    1085             return;
    1086         check_and_close();
    1087         open_next_file();
    1088     }
    1089     *c = EOF;
    10901039}
    10911040
     
    11131062dump_strings(off_t address, off_t end_offset)
    11141063{
    1115     size_t bufsize = MAX(100, string_min);
    1116     char *buf = xmalloc(bufsize);
     1064    unsigned bufsize = MAX(100, string_min);
     1065    unsigned char *buf = xmalloc(bufsize);
    11171066
    11181067    while (1) {
     
    11221071        /* See if the next 'string_min' chars are all printing chars.  */
    11231072 tryline:
    1124         if (limit_bytes_to_format && (end_offset - string_min <= address))
     1073        if ((option_mask32 & OPT_N) && (end_offset - string_min <= address))
    11251074            break;
    11261075        i = 0;
    1127         while (!limit_bytes_to_format || address < end_offset) {
     1076        while (!(option_mask32 & OPT_N) || address < end_offset) {
    11281077            if (i == bufsize) {
    11291078                bufsize += bufsize/8;
    11301079                buf = xrealloc(buf, bufsize);
    11311080            }
    1132             read_char(&c);
    1133             if (c < 0) { /* EOF */
    1134                 free(buf);
    1135                 return;
     1081
     1082            while (in_stream) { /* !EOF */
     1083                c = fgetc(in_stream);
     1084                if (c != EOF)
     1085                    goto got_char;
     1086                check_and_close();
     1087                open_next_file();
    11361088            }
     1089            /* EOF */
     1090            goto ret;
     1091 got_char:
    11371092            address++;
    11381093            if (!c)
     
    11461101            goto tryline;
    11471102
    1148         /* If we get here, the string is all printable and NUL-terminated,
    1149          * so print it.  It is all in 'buf' and 'i' is its length.  */
     1103        /* If we get here, the string is all printable and NUL-terminated */
    11501104        buf[i] = 0;
    11511105        format_address(address - i - 1, ' ');
     
    11681122    /* We reach this point only if we search through
    11691123       (max_bytes_to_format - string_min) bytes before reaching EOF.  */
     1124    check_and_close();
     1125 ret:
    11701126    free(buf);
    1171 
    1172     check_and_close();
    1173 }
     1127}
     1128
     1129#if ENABLE_LONG_OPTS
     1130/* If S is a valid traditional offset specification with an optional
     1131   leading '+' return nonzero and set *OFFSET to the offset it denotes.  */
     1132
     1133static int
     1134parse_old_offset(const char *s, off_t *offset)
     1135{
     1136    static const struct suffix_mult Bb[] = {
     1137        { "B", 1024 },
     1138        { "b", 512 },
     1139        { "", 0 }
     1140    };
     1141    char *p;
     1142    int radix;
     1143
     1144    /* Skip over any leading '+'. */
     1145    if (s[0] == '+') ++s;
     1146    if (!isdigit(s[0])) return 0; /* not a number */
     1147
     1148    /* Determine the radix we'll use to interpret S.  If there is a '.',
     1149     * it's decimal, otherwise, if the string begins with '0X'or '0x',
     1150     * it's hexadecimal, else octal.  */
     1151    p = strchr(s, '.');
     1152    radix = 8;
     1153    if (p) {
     1154        p[0] = '\0'; /* cheating */
     1155        radix = 10;
     1156    } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
     1157        radix = 16;
     1158
     1159    *offset = xstrtooff_sfx(s, radix, Bb);
     1160    if (p) p[0] = '.';
     1161
     1162    return (*offset >= 0);
     1163}
     1164#endif
    11741165
    11751166int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    1176 int od_main(int argc, char **argv)
     1167int od_main(int argc UNUSED_PARAM, char **argv)
    11771168{
    11781169    static const struct suffix_mult bkm[] = {
     
    11811172        { "m", 1024*1024 },
    11821173        { "", 0 }
    1183     };
    1184     enum {
    1185         OPT_A = 1 << 0,
    1186         OPT_N = 1 << 1,
    1187         OPT_a = 1 << 2,
    1188         OPT_b = 1 << 3,
    1189         OPT_c = 1 << 4,
    1190         OPT_d = 1 << 5,
    1191         OPT_f = 1 << 6,
    1192         OPT_h = 1 << 7,
    1193         OPT_i = 1 << 8,
    1194         OPT_j = 1 << 9,
    1195         OPT_l = 1 << 10,
    1196         OPT_o = 1 << 11,
    1197         OPT_t = 1 << 12,
    1198         OPT_v = 1 << 13,
    1199         OPT_x = 1 << 14,
    1200         OPT_s = 1 << 15,
    1201         OPT_S = 1 << 16,
    1202         OPT_w = 1 << 17,
    1203         OPT_traditional = (1 << 18) * ENABLE_LONG_OPTS,
    12041174    };
    12051175#if ENABLE_LONG_OPTS
     
    12101180        "format\0"            Required_argument "t"
    12111181        "output-duplicates\0" No_argument       "v"
     1182        /* Yes, it's true: -S NUM, but --strings[=NUM]!
     1183         * that is, NUM is mandatory for -S but optional for --strings!
     1184         */
    12121185        "strings\0"           Optional_argument "S"
    12131186        "width\0"             Optional_argument "w"
     
    12151188        ;
    12161189#endif
    1217     char *str_A, *str_N, *str_j, *str_S;
     1190    const char *str_A, *str_N, *str_j, *str_S = "3";
    12181191    llist_t *lst_t = NULL;
    12191192    unsigned opt;
    12201193    int l_c_m;
    1221     /* The old-style 'pseudo starting address' to be printed in parentheses
    1222        after any true address.  */
    1223     off_t pseudo_start = pseudo_start; // for gcc
    12241194    /* The number of input bytes to skip before formatting and writing.  */
    12251195    off_t n_bytes_to_skip = 0;
     
    12331203    address_base_char = 'o';
    12341204    address_pad_len_char = '7';
    1235     /* flag_dump_strings = 0; - already is */
    12361205
    12371206    /* Parse command line */
     
    12401209    applet_long_options = od_longopts;
    12411210#endif
    1242     opt = getopt32(argv, "A:N:abcdfhij:lot:vxsS:"
    1243         "w::", // -w with optional param
    1244         // -S was -s and also had optional parameter
    1245         // but in coreutils 6.3 it was renamed and now has
    1246         // _mandatory_ parameter
    1247         &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block);
    1248     argc -= optind;
     1211    opt = OD_GETOPT32();
    12491212    argv += optind;
    12501213    if (opt & OPT_A) {
     
    12681231    }
    12691232    if (opt & OPT_N) {
    1270         limit_bytes_to_format = 1;
    12711233        max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm);
    12721234    }
     
    12811243    if (opt & OPT_l) decode_format_string("d4");
    12821244    if (opt & OPT_o) decode_format_string("o2");
    1283     //if (opt & OPT_t)...
    12841245    while (lst_t) {
    12851246        decode_format_string(llist_pop(&lst_t));
    12861247    }
    1287     if (opt & OPT_v) verbose = 1;
    12881248    if (opt & OPT_x) decode_format_string("x2");
    12891249    if (opt & OPT_s) decode_format_string("d2");
    12901250    if (opt & OPT_S) {
    1291         string_min = 3;
    12921251        string_min = xstrtou_sfx(str_S, 0, bkm);
    1293         flag_dump_strings = 1;
    1294     }
    1295     //if (opt & OPT_w)...
    1296     //if (opt & OPT_traditional)...
    1297 
    1298     if (flag_dump_strings && n_specs > 0)
    1299         bb_error_msg_and_die("no type may be specified when dumping strings");
     1252    }
     1253
     1254    // Bloat:
     1255    //if ((option_mask32 & OPT_S) && n_specs > 0)
     1256    //  bb_error_msg_and_die("no type may be specified when dumping strings");
    13001257
    13011258    /* If the --traditional option is used, there may be from
    13021259     * 0 to 3 remaining command line arguments;  handle each case
    13031260     * separately.
    1304      * od [file] [[+]offset[.][b] [[+]label[.][b]]]
     1261     * od [FILE] [[+]OFFSET[.][b] [[+]LABEL[.][b]]]
    13051262     * The offset and pseudo_start have the same syntax.
    13061263     *
     
    13101267#if ENABLE_LONG_OPTS
    13111268    if (opt & OPT_traditional) {
    1312         off_t o1, o2;
    1313 
    1314         if (argc == 1) {
    1315             if (parse_old_offset(argv[0], &o1)) {
    1316                 n_bytes_to_skip = o1;
    1317                 --argc;
    1318                 ++argv;
     1269        if (argv[0]) {
     1270            off_t pseudo_start = -1;
     1271            off_t o1, o2;
     1272
     1273            if (!argv[1]) { /* one arg */
     1274                if (parse_old_offset(argv[0], &o1)) {
     1275                    /* od --traditional OFFSET */
     1276                    n_bytes_to_skip = o1;
     1277                    argv++;
     1278                }
     1279                /* od --traditional FILE */
     1280            } else if (!argv[2]) { /* two args */
     1281                if (parse_old_offset(argv[0], &o1)
     1282                 && parse_old_offset(argv[1], &o2)
     1283                ) {
     1284                    /* od --traditional OFFSET LABEL */
     1285                    n_bytes_to_skip = o1;
     1286                    pseudo_start = o2;
     1287                    argv += 2;
     1288                } else if (parse_old_offset(argv[1], &o2)) {
     1289                    /* od --traditional FILE OFFSET */
     1290                    n_bytes_to_skip = o2;
     1291                    argv[1] = NULL;
     1292                } else {
     1293                    bb_error_msg_and_die("invalid second argument '%s'", argv[1]);
     1294                }
     1295            } else if (!argv[3]) { /* three args */
     1296                if (parse_old_offset(argv[1], &o1)
     1297                 && parse_old_offset(argv[2], &o2)
     1298                ) {
     1299                    /* od --traditional FILE OFFSET LABEL */
     1300                    n_bytes_to_skip = o1;
     1301                    pseudo_start = o2;
     1302                    argv[1] = NULL;
     1303                } else {
     1304                    bb_error_msg_and_die("the last two arguments must be offsets");
     1305                }
     1306            } else { /* >3 args */
     1307                bb_error_msg_and_die("too many arguments");
    13191308            }
    1320         } else if (argc == 2) {
    1321             if (parse_old_offset(argv[0], &o1)
    1322              && parse_old_offset(argv[1], &o2)
    1323             ) {
    1324                 n_bytes_to_skip = o1;
    1325                 flag_pseudo_start = 1;
    1326                 pseudo_start = o2;
    1327                 argv += 2;
    1328                 argc -= 2;
    1329             } else if (parse_old_offset(argv[1], &o2)) {
    1330                 n_bytes_to_skip = o2;
    1331                 --argc;
    1332                 argv[1] = argv[0];
    1333                 ++argv;
    1334             } else {
    1335                 bb_error_msg_and_die("invalid second operand "
    1336                     "in compatibility mode '%s'", argv[1]);
     1309
     1310            if (pseudo_start >= 0) {
     1311                if (format_address == format_address_none) {
     1312                    address_base_char = 'o';
     1313                    address_pad_len_char = '7';
     1314                    format_address = format_address_paren;
     1315                } else {
     1316                    format_address = format_address_label;
     1317                }
     1318                pseudo_offset = pseudo_start - n_bytes_to_skip;
    13371319            }
    1338         } else if (argc == 3) {
    1339             if (parse_old_offset(argv[1], &o1)
    1340              && parse_old_offset(argv[2], &o2)
    1341             ) {
    1342                 n_bytes_to_skip = o1;
    1343                 flag_pseudo_start = 1;
    1344                 pseudo_start = o2;
    1345                 argv[2] = argv[0];
    1346                 argv += 2;
    1347                 argc -= 2;
    1348             } else {
    1349                 bb_error_msg_and_die("in compatibility mode "
    1350                     "the last two arguments must be offsets");
    1351             }
    1352         } else if (argc > 3)    {
    1353             bb_error_msg_and_die("compatibility mode supports "
    1354                 "at most three arguments");
    1355         }
    1356 
    1357         if (flag_pseudo_start) {
    1358             if (format_address == format_address_none) {
    1359                 address_base_char = 'o';
    1360                 address_pad_len_char = '7';
    1361                 format_address = format_address_paren;
    1362             } else
    1363                 format_address = format_address_label;
    1364         }
    1365     }
    1366 #endif
    1367 
    1368     if (limit_bytes_to_format) {
     1320        }
     1321        /* else: od --traditional (without args) */
     1322    }
     1323#endif
     1324
     1325    if (option_mask32 & OPT_N) {
    13691326        end_offset = n_bytes_to_skip + max_bytes_to_format;
    13701327        if (end_offset < n_bytes_to_skip)
    1371             bb_error_msg_and_die("skip-bytes + read-bytes is too large");
     1328            bb_error_msg_and_die("SKIP + SIZE is too large");
    13721329    }
    13731330
    13741331    if (n_specs == 0) {
    13751332        decode_format_string("o2");
    1376         n_specs = 1;
     1333        /*n_specs = 1; - done by decode_format_string */
    13771334    }
    13781335
     
    13811338       references the null-terminated list of one name: "-".  */
    13821339    file_list = bb_argv_dash;
    1383     if (argc > 0) {
     1340    if (argv[0]) {
    13841341        /* Set the global pointer FILE_LIST so that it
    13851342           references the first file-argument on the command-line.  */
     
    13871344    }
    13881345
    1389     /* open the first input file */
     1346    /* Open the first input file */
    13901347    open_next_file();
    1391     /* skip over any unwanted header bytes */
     1348    /* Skip over any unwanted header bytes */
    13921349    skip(n_bytes_to_skip);
    13931350    if (!in_stream)
    13941351        return EXIT_FAILURE;
    13951352
    1396     pseudo_offset = (flag_pseudo_start ? pseudo_start - n_bytes_to_skip : 0);
    1397 
    1398     /* Compute output block length.  */
     1353    /* Compute output block length */
    13991354    l_c_m = get_lcm();
    14001355
     
    14181373#endif
    14191374
    1420     if (flag_dump_strings)
     1375    if (option_mask32 & OPT_S)
    14211376        dump_strings(n_bytes_to_skip, end_offset);
    14221377    else
    14231378        dump(n_bytes_to_skip, end_offset);
    14241379
    1425     if (fclose(stdin) == EOF)
     1380    if (fclose(stdin))
    14261381        bb_perror_msg_and_die(bb_msg_standard_input);
    14271382
    1428     return ioerror;
    1429 }
     1383    return exit_code;
     1384}
Note: See TracChangeset for help on using the changeset viewer.