Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/coreutils/fold.c

    r1765 r2725  
    66
    77   Modified for busybox based on coreutils v 5.0
    8    Copyright (C) 2003 Glenn McGrath <bug1@iinet.net.au>
     8   Copyright (C) 2003 Glenn McGrath
    99
    10    Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     10   Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1111*/
     12#include "libbb.h"
     13#include "unicode.h"
    1214
    13 #include "libbb.h"
     15/* This is a NOEXEC applet. Be very careful! */
    1416
    15 static unsigned long flags;
    16 #define FLAG_COUNT_BYTES    1
    17 #define FLAG_BREAK_SPACES   2
    18 #define FLAG_WIDTH          4
     17/* Must match getopt32 call */
     18#define FLAG_COUNT_BYTES        1
     19#define FLAG_BREAK_SPACES       2
     20#define FLAG_WIDTH              4
    1921
    2022/* Assuming the current column is COLUMN, return the column that
    2123   printing C will move the cursor to.
    2224   The first column is 0. */
     25static int adjust_column(unsigned column, char c)
     26{
     27    if (option_mask32 & FLAG_COUNT_BYTES)
     28        return ++column;
    2329
    24 static int adjust_column(int column, char c)
    25 {
    26     if (!(flags & FLAG_COUNT_BYTES)) {
    27         if (c == '\b') {
    28             if (column > 0)
    29                 column--;
    30         } else if (c == '\r')
     30    if (c == '\t')
     31        return column + 8 - column % 8;
     32
     33    if (c == '\b') {
     34        if ((int)--column < 0)
    3135            column = 0;
    32         else if (c == '\t')
    33             column = column + 8 - column % 8;
    34         else            /* if (isprint (c)) */
     36    }
     37    else if (c == '\r')
     38        column = 0;
     39    else { /* just a printable char */
     40        if (unicode_status != UNICODE_ON /* every byte is a new char */
     41         || (c & 0xc0) != 0x80 /* it isn't a 2nd+ byte of a Unicode char */
     42        ) {
    3543            column++;
    36     } else
    37         column++;
     44        }
     45    }
    3846    return column;
    3947}
    4048
    41 int fold_main(int argc, char **argv);
    42 int fold_main(int argc, char **argv)
     49/* Note that this function can write NULs, unlike fputs etc. */
     50static void write2stdout(const void *buf, unsigned size)
     51{
     52    fwrite(buf, 1, size, stdout);
     53}
     54
     55int fold_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     56int fold_main(int argc UNUSED_PARAM, char **argv)
    4357{
    4458    char *line_out = NULL;
    45     int allocated_out = 0;
    46     char *w_opt;
    47     int width = 80;
    48     int i;
    49     int errs = 0;
     59    const char *w_opt = "80";
     60    unsigned width;
     61    smallint exitcode = EXIT_SUCCESS;
     62
     63    init_unicode();
    5064
    5165    if (ENABLE_INCLUDE_SUSv2) {
    5266        /* Turn any numeric options into -w options.  */
    53         for (i = 1; i < argc; i++) {
    54             char const *a = argv[i];
    55 
    56             if (*a++ == '-') {
    57                 if (*a == '-' && !a[1])
     67        int i;
     68        for (i = 1; argv[i]; i++) {
     69            const char *a = argv[i];
     70            if (*a == '-') {
     71                a++;
     72                if (*a == '-' && !a[1]) /* "--" */
    5873                    break;
    59                 if (isdigit(*a)) {
     74                if (isdigit(*a))
    6075                    argv[i] = xasprintf("-w%s", a);
    61                 }
    6276            }
    6377        }
    6478    }
    6579
    66     flags = getopt32(argv, "bsw:", &w_opt);
    67     if (flags & FLAG_WIDTH)
    68         width = xatoul_range(w_opt, 1, 10000);
     80    getopt32(argv, "bsw:", &w_opt);
     81    width = xatou_range(w_opt, 1, 10000);
    6982
    7083    argv += optind;
    71     if (!*argv) {
     84    if (!*argv)
    7285        *--argv = (char*)"-";
    73     }
    7486
    7587    do {
    7688        FILE *istream = fopen_or_warn_stdin(*argv);
    7789        int c;
    78         int column = 0;     /* Screen column where next char will go. */
    79         int offset_out = 0; /* Index in `line_out' for next char. */
     90        unsigned column = 0;     /* Screen column where next char will go */
     91        unsigned offset_out = 0; /* Index in 'line_out' for next char */
    8092
    8193        if (istream == NULL) {
    82             errs |= EXIT_FAILURE;
     94            exitcode = EXIT_FAILURE;
    8395            continue;
    8496        }
    8597
    8698        while ((c = getc(istream)) != EOF) {
    87             if (offset_out + 1 >= allocated_out) {
    88                 allocated_out += 1024;
    89                 line_out = xrealloc(line_out, allocated_out);
     99            /* We grow line_out in chunks of 0x1000 bytes */
     100            if ((offset_out & 0xfff) == 0) {
     101                line_out = xrealloc(line_out, offset_out + 0x1000);
    90102            }
    91 
     103 rescan:
     104            line_out[offset_out] = c;
    92105            if (c == '\n') {
    93                 line_out[offset_out++] = c;
    94                 fwrite(line_out, sizeof(char), (size_t) offset_out, stdout);
     106                write2stdout(line_out, offset_out + 1);
    95107                column = offset_out = 0;
    96108                continue;
    97109            }
    98  rescan:
    99110            column = adjust_column(column, c);
    100 
    101             if (column > width) {
    102                 /* This character would make the line too long.
    103                    Print the line plus a newline, and make this character
    104                    start the next line. */
    105                 if (flags & FLAG_BREAK_SPACES) {
    106                     /* Look for the last blank. */
    107                     int logical_end;
    108 
    109                     for (logical_end = offset_out - 1; logical_end >= 0; logical_end--) {
    110                         if (isblank(line_out[logical_end])) {
    111                             break;
    112                         }
    113                     }
    114                     if (logical_end >= 0) {
    115                         /* Found a blank.  Don't output the part after it. */
    116                         logical_end++;
    117                         fwrite(line_out, sizeof(char), (size_t) logical_end, stdout);
    118                         putchar('\n');
    119                         /* Move the remainder to the beginning of the next line.
    120                            The areas being copied here might overlap. */
    121                         memmove(line_out, line_out + logical_end, offset_out - logical_end);
    122                         offset_out -= logical_end;
    123                         for (column = i = 0; i < offset_out; i++) {
    124                             column = adjust_column(column, line_out[i]);
    125                         }
    126                         goto rescan;
    127                     }
    128                 } else {
    129                     if (offset_out == 0) {
    130                         line_out[offset_out++] = c;
    131                         continue;
    132                     }
    133                 }
    134                 line_out[offset_out++] = '\n';
    135                 fwrite(line_out, sizeof(char), (size_t) offset_out, stdout);
    136                 column = offset_out = 0;
    137                 goto rescan;
     111            if (column <= width || offset_out == 0) {
     112                /* offset_out == 0 case happens
     113                 * with small width (say, 1) and tabs.
     114                 * The very first tab already goes to column 8,
     115                 * but we must not wrap it */
     116                offset_out++;
     117                continue;
    138118            }
    139119
    140             line_out[offset_out++] = c;
     120            /* This character would make the line too long.
     121             * Print the line plus a newline, and make this character
     122             * start the next line */
     123            if (option_mask32 & FLAG_BREAK_SPACES) {
     124                unsigned i;
     125                unsigned logical_end;
     126
     127                /* Look for the last blank. */
     128                for (logical_end = offset_out - 1; (int)logical_end >= 0; logical_end--) {
     129                    if (!isblank(line_out[logical_end]))
     130                        continue;
     131
     132                    /* Found a space or tab.
     133                     * Output up to and including it, and start a new line */
     134                    logical_end++;
     135                    /*line_out[logical_end] = '\n'; - NO! this nukes one buffered character */
     136                    write2stdout(line_out, logical_end);
     137                    putchar('\n');
     138                    /* Move the remainder to the beginning of the next line.
     139                     * The areas being copied here might overlap. */
     140                    memmove(line_out, line_out + logical_end, offset_out - logical_end);
     141                    offset_out -= logical_end;
     142                    for (column = i = 0; i < offset_out; i++) {
     143                        column = adjust_column(column, line_out[i]);
     144                    }
     145                    goto rescan;
     146                }
     147                /* No blank found, wrap will split the overlong word */
     148            }
     149            /* Output what we accumulated up to now, and start a new line */
     150            line_out[offset_out] = '\n';
     151            write2stdout(line_out, offset_out + 1);
     152            column = offset_out = 0;
     153            goto rescan;
     154        } /* while (not EOF) */
     155
     156        if (offset_out) {
     157            write2stdout(line_out, offset_out);
    141158        }
    142159
    143         if (offset_out) {
    144             fwrite(line_out, sizeof(char), (size_t) offset_out, stdout);
    145         }
    146 
    147         if (ferror(istream) || fclose_if_not_stdin(istream)) {
    148             bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */
    149             errs |= EXIT_FAILURE;
     160        if (fclose_if_not_stdin(istream)) {
     161            bb_simple_perror_msg(*argv);
     162            exitcode = EXIT_FAILURE;
    150163        }
    151164    } while (*++argv);
    152165
    153     fflush_stdout_and_exit(errs);
     166    fflush_stdout_and_exit(exitcode);
    154167}
Note: See TracChangeset for help on using the changeset viewer.