Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

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

    r3232 r3621  
    2121
    2222/* #include "libbb.h" - done in od.c */
     23#include "common_bufsiz.h"
    2324#define assert(a) ((void)0)
    2425
     
    6768    /* but in coreutils 6.3 it was renamed and now has */ \
    6869    /* _mandatory_ parameter */ \
    69     &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block)
     70    &str_A, &str_N, &str_j, &lst_t, &str_S, &G.bytes_per_block)
    7071
    7172
     
    175176};
    176177
    177 static smallint exit_code;
    178 
    179 static unsigned string_min;
    180 
    181 /* An array of specs describing how to format each input block.  */
    182 static size_t n_specs;
    183 static struct tspec *spec;
    184 
    185 /* Function that accepts an address and an optional following char,
    186    and prints the address and char to stdout.  */
    187 static void (*format_address)(off_t, char);
    188 /* The difference between the old-style pseudo starting address and
    189    the number of bytes to skip.  */
     178struct globals {
     179    smallint exit_code;
     180
     181    unsigned string_min;
     182
     183    /* An array of specs describing how to format each input block.  */
     184    unsigned n_specs;
     185    struct tspec *spec;
     186
     187    /* Function that accepts an address and an optional following char,
     188       and prints the address and char to stdout.  */
     189    void (*format_address)(off_t, char);
     190
     191    /* The difference between the old-style pseudo starting address and
     192       the number of bytes to skip.  */
    190193#if ENABLE_LONG_OPTS
    191 static off_t pseudo_offset;
    192 #else
    193 enum { pseudo_offset = 0 };
    194 #endif
    195 /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
    196    input is formatted.  */
    197 
    198 /* The number of input bytes formatted per output line.  It must be
    199    a multiple of the least common multiple of the sizes associated with
    200    the specified output types.  It should be as large as possible, but
    201    no larger than 16 -- unless specified with the -w option.  */
    202 static unsigned bytes_per_block = 32; /* have to use unsigned, not size_t */
    203 
    204 /* A NULL-terminated list of the file-arguments from the command line.  */
    205 static const char *const *file_list;
    206 
    207 /* The input stream associated with the current file.  */
    208 static FILE *in_stream;
     194    off_t pseudo_offset;
     195# define G_pseudo_offset G.pseudo_offset
     196#endif
     197    /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
     198       input is formatted.  */
     199
     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    unsigned bytes_per_block; /* have to use unsigned, not size_t */
     205
     206    /* A NULL-terminated list of the file-arguments from the command line.  */
     207    const char *const *file_list;
     208
     209    /* The input stream associated with the current file.  */
     210    FILE *in_stream;
     211
     212    bool not_first;
     213    bool prev_pair_equal;
     214} FIX_ALIASING;
     215#if !ENABLE_LONG_OPTS
     216enum { G_pseudo_offset = 0 };
     217#endif
     218#define G (*(struct globals*)bb_common_bufsiz1)
     219#define INIT_G() do { \
     220    setup_common_bufsiz(); \
     221    BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
     222    G.bytes_per_block = 32; \
     223} while (0)
     224
    209225
    210226#define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
     
    388404    };
    389405    // buf[N] pos:  01234 56789
    390     char buf[12] = "   x\0 0xx\0";
    391     // actually "   x\0 xxx\0", but want to share string with print_ascii.
     406    char buf[12] = "   x\0 xxx\0";
    392407    // [12] because we take three 32bit stack slots anyway, and
    393408    // gcc is too dumb to initialize with constant stores,
    394409    // it copies initializer from rodata. Oh well.
     410    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65410
    395411
    396412    while (n_bytes--) {
     
    420436{
    421437    // buf[N] pos:  01234 56789
    422     char buf[12] = "   x\0 0xx\0";
     438    char buf[12] = "   x\0 xxx\0";
    423439
    424440    while (n_bytes--) {
     
    456472            s = "  \\v";
    457473            break;
    458         case '\x7f':
    459             s = " 177";
    460             break;
    461         default: /* c is never larger than 040 */
    462             buf[7] = (c >> 3) + '0';
     474        default:
     475            buf[6] = (c >> 6 & 3) + '0';
     476            buf[7] = (c >> 3 & 7) + '0';
    463477            buf[8] = (c & 7) + '0';
    464478            s = buf + 5;
     
    479493{
    480494    while (1) {
    481         if (!*file_list)
     495        if (!*G.file_list)
    482496            return;
    483         in_stream = fopen_or_warn_stdin(*file_list++);
    484         if (in_stream) {
    485             break;
    486         }
    487         exit_code = 1;
     497        G.in_stream = fopen_or_warn_stdin(*G.file_list++);
     498        if (G.in_stream) {
     499            break;
     500        }
     501        G.exit_code = 1;
    488502    }
    489503
    490504    if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N)
    491         setbuf(in_stream, NULL);
     505        setbuf(G.in_stream, NULL);
    492506}
    493507
     
    502516check_and_close(void)
    503517{
    504     if (in_stream) {
    505         if (ferror(in_stream))  {
    506             bb_error_msg("%s: read error", (in_stream == stdin)
     518    if (G.in_stream) {
     519        if (ferror(G.in_stream))    {
     520            bb_error_msg("%s: read error", (G.in_stream == stdin)
    507521                    ? bb_msg_standard_input
    508                     : file_list[-1]
     522                    : G.file_list[-1]
    509523            );
    510             exit_code = 1;
    511         }
    512         fclose_if_not_stdin(in_stream);
    513         in_stream = NULL;
     524            G.exit_code = 1;
     525        }
     526        fclose_if_not_stdin(G.in_stream);
     527        G.in_stream = NULL;
    514528    }
    515529
     
    747761        assert(s != next);
    748762        s = next;
    749         spec = xrealloc_vector(spec, 4, n_specs);
    750         memcpy(&spec[n_specs], &tspec, sizeof(spec[0]));
    751         n_specs++;
     763        G.spec = xrealloc_vector(G.spec, 4, G.n_specs);
     764        memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0]));
     765        G.n_specs++;
    752766    }
    753767}
     
    766780        return;
    767781
    768     while (in_stream) { /* !EOF */
     782    while (G.in_stream) { /* !EOF */
    769783        struct stat file_stats;
    770784
     
    784798               as large as the size of the current file, we can
    785799               decrement n_skip and go on to the next file.  */
    786         if (fstat(fileno(in_stream), &file_stats) == 0
     800        if (fstat(fileno(G.in_stream), &file_stats) == 0
    787801         && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0
    788802        ) {
     
    791805                /* take "check & close / open_next" route */
    792806            } else {
    793                 if (fseeko(in_stream, n_skip, SEEK_CUR) != 0)
    794                     exit_code = 1;
     807                if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0)
     808                    G.exit_code = 1;
    795809                return;
    796810            }
     
    805819                if (n_skip < n_bytes_to_read)
    806820                    n_bytes_to_read = n_skip;
    807                 n_bytes_read = fread(buf, 1, n_bytes_to_read, in_stream);
     821                n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream);
    808822                n_skip -= n_bytes_read;
    809823                if (n_bytes_read != n_bytes_to_read)
     
    858872{
    859873    format_address_std(address, ' ');
    860     format_address_paren(address + pseudo_offset, c);
     874    format_address_paren(address + G_pseudo_offset, c);
    861875}
    862876#endif
     
    889903        const char *prev_block, const char *curr_block)
    890904{
    891     static char first = 1;
    892     static char prev_pair_equal = 0;
    893     size_t i;
     905    unsigned i;
    894906
    895907    if (!(option_mask32 & OPT_v)
    896      && !first
    897      && n_bytes == bytes_per_block
    898      && memcmp(prev_block, curr_block, bytes_per_block) == 0
     908     && G.not_first
     909     && n_bytes == G.bytes_per_block
     910     && memcmp(prev_block, curr_block, G.bytes_per_block) == 0
    899911    ) {
    900         if (prev_pair_equal) {
     912        if (G.prev_pair_equal) {
    901913            /* The two preceding blocks were equal, and the current
    902914               block is the same as the last one, so print nothing.  */
    903915        } else {
    904916            puts("*");
    905             prev_pair_equal = 1;
     917            G.prev_pair_equal = 1;
    906918        }
    907919    } else {
    908         first = 0;
    909         prev_pair_equal = 0;
    910         for (i = 0; i < n_specs; i++) {
     920        G.not_first = 1;
     921        G.prev_pair_equal = 0;
     922        for (i = 0; i < G.n_specs; i++) {
    911923            if (i == 0)
    912                 format_address(current_offset, '\0');
     924                G.format_address(current_offset, '\0');
    913925            else
    914926                printf("%*s", address_pad_len_char - '0', "");
    915             (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
    916             if (spec[i].hexl_mode_trailer) {
     927            (*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string);
     928            if (G.spec[i].hexl_mode_trailer) {
    917929                /* space-pad out to full line width, then dump the trailer */
    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;
     930                unsigned datum_width = width_bytes[G.spec[i].size];
     931                unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width;
     932                unsigned field_width = G.spec[i].field_width + 1;
    921933                printf("%*s", blank_fields * field_width, "");
    922934                dump_hexl_mode_trailer(n_bytes, curr_block);
     
    930942read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
    931943{
    932     assert(0 < n && n <= bytes_per_block);
     944    assert(0 < n && n <= G.bytes_per_block);
    933945
    934946    *n_bytes_in_buffer = 0;
     
    937949        return;
    938950
    939     while (in_stream != NULL) { /* EOF.  */
     951    while (G.in_stream != NULL) { /* EOF.  */
    940952        size_t n_needed;
    941953        size_t n_read;
    942954
    943955        n_needed = n - *n_bytes_in_buffer;
    944         n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, in_stream);
     956        n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream);
    945957        *n_bytes_in_buffer += n_read;
    946958        if (n_read == n_needed)
     
    961973    int l_c_m = 1;
    962974
    963     for (i = 0; i < n_specs; i++)
    964         l_c_m = lcm(l_c_m, width_bytes[(int) spec[i].size]);
     975    for (i = 0; i < G.n_specs; i++)
     976        l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]);
    965977    return l_c_m;
    966978}
     
    983995    size_t n_bytes_read;
    984996
    985     block[0] = xmalloc(2 * bytes_per_block);
    986     block[1] = block[0] + bytes_per_block;
     997    block[0] = xmalloc(2 * G.bytes_per_block);
     998    block[1] = block[0] + G.bytes_per_block;
    987999
    9881000    idx = 0;
     
    9941006                break;
    9951007            }
    996             n_needed = MIN(end_offset - current_offset, (off_t) bytes_per_block);
     1008            n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block);
    9971009            read_block(n_needed, block[idx], &n_bytes_read);
    998             if (n_bytes_read < bytes_per_block)
     1010            if (n_bytes_read < G.bytes_per_block)
    9991011                break;
    1000             assert(n_bytes_read == bytes_per_block);
     1012            assert(n_bytes_read == G.bytes_per_block);
    10011013            write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
    10021014            current_offset += n_bytes_read;
     
    10051017    } else {
    10061018        while (1) {
    1007             read_block(bytes_per_block, block[idx], &n_bytes_read);
    1008             if (n_bytes_read < bytes_per_block)
     1019            read_block(G.bytes_per_block, block[idx], &n_bytes_read);
     1020            if (n_bytes_read < G.bytes_per_block)
    10091021                break;
    1010             assert(n_bytes_read == bytes_per_block);
     1022            assert(n_bytes_read == G.bytes_per_block);
    10111023            write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
    10121024            current_offset += n_bytes_read;
     
    10311043    }
    10321044
    1033     format_address(current_offset, '\n');
     1045    G.format_address(current_offset, '\n');
    10341046
    10351047    if ((option_mask32 & OPT_N) && current_offset >= end_offset)
     
    10621074dump_strings(off_t address, off_t end_offset)
    10631075{
    1064     unsigned bufsize = MAX(100, string_min);
     1076    unsigned bufsize = MAX(100, G.string_min);
    10651077    unsigned char *buf = xmalloc(bufsize);
    10661078
     
    10691081        int c;
    10701082
    1071         /* See if the next 'string_min' chars are all printing chars.  */
     1083        /* See if the next 'G.string_min' chars are all printing chars.  */
    10721084 tryline:
    1073         if ((option_mask32 & OPT_N) && (end_offset - string_min <= address))
     1085        if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address))
    10741086            break;
    10751087        i = 0;
     
    10801092            }
    10811093
    1082             while (in_stream) { /* !EOF */
    1083                 c = fgetc(in_stream);
     1094            while (G.in_stream) { /* !EOF */
     1095                c = fgetc(G.in_stream);
    10841096                if (c != EOF)
    10851097                    goto got_char;
     
    10981110        }
    10991111
    1100         if (i < string_min)     /* Too short! */
     1112        if (i < G.string_min)       /* Too short! */
    11011113            goto tryline;
    11021114
    11031115        /* If we get here, the string is all printable and NUL-terminated */
    11041116        buf[i] = 0;
    1105         format_address(address - i - 1, ' ');
     1117        G.format_address(address - i - 1, ' ');
    11061118
    11071119        for (i = 0; (c = buf[i]); i++) {
     
    11211133
    11221134    /* We reach this point only if we search through
    1123        (max_bytes_to_format - string_min) bytes before reaching EOF.  */
     1135       (max_bytes_to_format - G.string_min) bytes before reaching EOF.  */
    11241136    check_and_close();
    11251137 ret:
     
    11671179int od_main(int argc UNUSED_PARAM, char **argv)
    11681180{
    1169     static const struct suffix_mult bkm[] = {
    1170         { "b", 512 },
    1171         { "k", 1024 },
    1172         { "m", 1024*1024 },
    1173         { "", 0 }
    1174     };
    11751181#if ENABLE_LONG_OPTS
    11761182    static const char od_longopts[] ALIGN1 =
     
    11991205    off_t max_bytes_to_format = 0;
    12001206
    1201     spec = NULL;
    1202     format_address = format_address_std;
     1207    INIT_G();
     1208
     1209    /*G.spec = NULL; - already is */
     1210    G.format_address = format_address_std;
    12031211    address_base_char = 'o';
    12041212    address_pad_len_char = '7';
     
    12261234                "'%c' (must be [doxn])", str_A[0]);
    12271235        pos = p - doxn;
    1228         if (pos == 3) format_address = format_address_none;
     1236        if (pos == 3) G.format_address = format_address_none;
    12291237        address_base_char = doxn_address_base_char[pos];
    12301238        address_pad_len_char = doxn_address_pad_len_char[pos];
    12311239    }
    12321240    if (opt & OPT_N) {
    1233         max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm);
     1241        max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm_suffixes);
    12341242    }
    12351243    if (opt & OPT_a) decode_format_string("a");
     
    12401248    if (opt & OPT_h) decode_format_string("x2");
    12411249    if (opt & OPT_i) decode_format_string("d2");
    1242     if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm);
     1250    if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm_suffixes);
    12431251    if (opt & OPT_l) decode_format_string("d4");
    12441252    if (opt & OPT_o) decode_format_string("o2");
     
    12491257    if (opt & OPT_s) decode_format_string("d2");
    12501258    if (opt & OPT_S) {
    1251         string_min = xstrtou_sfx(str_S, 0, bkm);
     1259        G.string_min = xstrtou_sfx(str_S, 0, bkm_suffixes);
    12521260    }
    12531261
    12541262    // Bloat:
    1255     //if ((option_mask32 & OPT_S) && n_specs > 0)
     1263    //if ((option_mask32 & OPT_S) && G.n_specs > 0)
    12561264    //  bb_error_msg_and_die("no type may be specified when dumping strings");
    12571265
     
    13091317
    13101318            if (pseudo_start >= 0) {
    1311                 if (format_address == format_address_none) {
     1319                if (G.format_address == format_address_none) {
    13121320                    address_base_char = 'o';
    13131321                    address_pad_len_char = '7';
    1314                     format_address = format_address_paren;
     1322                    G.format_address = format_address_paren;
    13151323                } else {
    1316                     format_address = format_address_label;
     1324                    G.format_address = format_address_label;
    13171325                }
    1318                 pseudo_offset = pseudo_start - n_bytes_to_skip;
     1326                G_pseudo_offset = pseudo_start - n_bytes_to_skip;
    13191327            }
    13201328        }
     
    13291337    }
    13301338
    1331     if (n_specs == 0) {
     1339    if (G.n_specs == 0) {
    13321340        decode_format_string("o2");
    1333         /*n_specs = 1; - done by decode_format_string */
     1341        /*G.n_specs = 1; - done by decode_format_string */
    13341342    }
    13351343
     
    13371345       set the global pointer FILE_LIST so that it
    13381346       references the null-terminated list of one name: "-".  */
    1339     file_list = bb_argv_dash;
     1347    G.file_list = bb_argv_dash;
    13401348    if (argv[0]) {
    13411349        /* Set the global pointer FILE_LIST so that it
    13421350           references the first file-argument on the command-line.  */
    1343         file_list = (char const *const *) argv;
     1351        G.file_list = (char const *const *) argv;
    13441352    }
    13451353
     
    13481356    /* Skip over any unwanted header bytes */
    13491357    skip(n_bytes_to_skip);
    1350     if (!in_stream)
     1358    if (!G.in_stream)
    13511359        return EXIT_FAILURE;
    13521360
     
    13551363
    13561364    if (opt & OPT_w) { /* -w: width */
    1357         if (!bytes_per_block || bytes_per_block % l_c_m != 0) {
     1365        if (!G.bytes_per_block || G.bytes_per_block % l_c_m != 0) {
    13581366            bb_error_msg("warning: invalid width %u; using %d instead",
    1359                     (unsigned)bytes_per_block, l_c_m);
    1360             bytes_per_block = l_c_m;
     1367                    (unsigned)G.bytes_per_block, l_c_m);
     1368            G.bytes_per_block = l_c_m;
    13611369        }
    13621370    } else {
    1363         bytes_per_block = l_c_m;
     1371        G.bytes_per_block = l_c_m;
    13641372        if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
    1365             bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
     1373            G.bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
    13661374    }
    13671375
    13681376#ifdef DEBUG
    1369     for (i = 0; i < n_specs; i++) {
     1377    for (i = 0; i < G.n_specs; i++) {
    13701378        printf("%d: fmt=\"%s\" width=%d\n",
    13711379            i, spec[i].fmt_string, width_bytes[spec[i].size]);
     
    13811389        bb_perror_msg_and_die(bb_msg_standard_input);
    13821390
    1383     return exit_code;
    1384 }
     1391    return G.exit_code;
     1392}
Note: See TracChangeset for help on using the changeset viewer.