Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/coreutils/wc.c


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/wc.c

    r1765 r2725  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    8  */
    9 
    10 /* BB_AUDIT SUSv3 _NOT_ compliant -- option -m is not currently supported. */
     7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
     8 */
     9
     10/* BB_AUDIT SUSv3 compliant. */
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */
    1212
     
    2020 *  4) isprint() wasn't considered when word counting.
    2121 *
    22  * TODO:
    23  *
    24  * When locale support is enabled, count multibyte chars in the '-m' case.
    25  *
    2622 * NOTES:
    2723 *
     
    4137 * for which 'wc -c' should output '0'.
    4238 */
    43 
    4439#include "libbb.h"
    45 
    46 #if ENABLE_LOCALE_SUPPORT
    47 #define isspace_given_isprint(c) isspace(c)
     40#include "unicode.h"
     41
     42#if !ENABLE_LOCALE_SUPPORT
     43# undef isprint
     44# undef isspace
     45# define isprint(c) ((unsigned)((c) - 0x20) <= (0x7e - 0x20))
     46# define isspace(c) ((c) == ' ')
     47#endif
     48
     49#if ENABLE_FEATURE_WC_LARGE
     50# define COUNT_T unsigned long long
     51# define COUNT_FMT "llu"
    4852#else
    49 #undef isspace
    50 #undef isprint
    51 #define isspace(c) ((((c) == ' ') || (((unsigned int)((c) - 9)) <= (13 - 9))))
    52 #define isprint(c) (((unsigned int)((c) - 0x20)) <= (0x7e - 0x20))
    53 #define isspace_given_isprint(c) ((c) == ' ')
     53# define COUNT_T unsigned
     54# define COUNT_FMT "u"
    5455#endif
    5556
    56 #if ENABLE_FEATURE_WC_LARGE
    57 #define COUNT_T unsigned long long
    58 #define COUNT_FMT "llu"
    59 #else
    60 #define COUNT_T unsigned
    61 #define COUNT_FMT "u"
    62 #endif
    63 
     57/* We support -m even when UNICODE_SUPPORT is off,
     58 * we just don't advertise it in help text,
     59 * since it is the same as -c in this case.
     60 */
     61
     62//usage:#define wc_trivial_usage
     63//usage:       "[-c"IF_UNICODE_SUPPORT("m")"lwL] [FILE]..."
     64//usage:
     65//usage:#define wc_full_usage "\n\n"
     66//usage:       "Count lines, words, and bytes for each FILE (or stdin)\n"
     67//usage:     "\nOptions:"
     68//usage:     "\n    -c  Count bytes"
     69//usage:    IF_UNICODE_SUPPORT(
     70//usage:     "\n    -m  Count characters"
     71//usage:    )
     72//usage:     "\n    -l  Count newlines"
     73//usage:     "\n    -w  Count words"
     74//usage:     "\n    -L  Print longest line length"
     75//usage:
     76//usage:#define wc_example_usage
     77//usage:       "$ wc /etc/passwd\n"
     78//usage:       "     31      46    1365 /etc/passwd\n"
     79
     80/* Order is important if we want to be compatible with
     81 * column order in "wc -cmlwL" output:
     82 */
    6483enum {
    65     WC_LINES    = 0,
    66     WC_WORDS    = 1,
    67     WC_CHARS    = 2,
    68     WC_LENGTH   = 3
     84    WC_LINES    = 0, /* -l */
     85    WC_WORDS    = 1, /* -w */
     86    WC_UNICHARS = 2, /* -m */
     87    WC_BYTES    = 3, /* -c */
     88    WC_LENGTH   = 4, /* -L */
     89    NUM_WCS     = 5,
    6990};
    7091
    71 int wc_main(int argc, char **argv);
    72 int wc_main(int argc, char **argv)
     92int wc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     93int wc_main(int argc UNUSED_PARAM, char **argv)
    7394{
    74     FILE *fp;
    75     const char *s, *arg;
    76     const char *start_fmt = "%9"COUNT_FMT;
     95    const char *arg;
     96    const char *start_fmt = " %9"COUNT_FMT + 1;
    7797    const char *fname_fmt = " %s\n";
    7898    COUNT_T *pcounts;
    79     COUNT_T counts[4];
    80     COUNT_T totals[4];
    81     unsigned linepos;
    82     unsigned u;
    83     int num_files = 0;
    84     int c;
     99    COUNT_T counts[NUM_WCS];
     100    COUNT_T totals[NUM_WCS];
     101    int num_files;
    85102    smallint status = EXIT_SUCCESS;
    86     smallint in_word;
    87103    unsigned print_type;
    88104
    89     print_type = getopt32(argv, "lwcL");
     105    init_unicode();
     106
     107    print_type = getopt32(argv, "lwmcL");
    90108
    91109    if (print_type == 0) {
    92         print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_CHARS);
     110        print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_BYTES);
    93111    }
    94112
     
    97115        *--argv = (char *) bb_msg_standard_input;
    98116        fname_fmt = "\n";
     117    }
     118    if (!argv[1]) { /* zero or one filename? */
    99119        if (!((print_type-1) & print_type)) /* exactly one option? */
    100120            start_fmt = "%"COUNT_FMT;
     
    105125    pcounts = counts;
    106126
    107     while ((arg = *argv++) != 0) {
     127    num_files = 0;
     128    while ((arg = *argv++) != NULL) {
     129        FILE *fp;
     130        const char *s;
     131        unsigned u;
     132        unsigned linepos;
     133        smallint in_word;
     134
    108135        ++num_files;
    109136        fp = fopen_or_warn_stdin(arg);
     
    117144        in_word = 0;
    118145
    119         do {
     146        while (1) {
     147            int c;
    120148            /* Our -w doesn't match GNU wc exactly... oh well */
    121149
    122             ++counts[WC_CHARS];
    123150            c = getc(fp);
    124             if (isprint(c)) {
     151            if (c == EOF) {
     152                if (ferror(fp)) {
     153                    bb_simple_perror_msg(arg);
     154                    status = EXIT_FAILURE;
     155                }
     156                goto DO_EOF;  /* Treat an EOF as '\r'. */
     157            }
     158
     159            /* Cater for -c and -m */
     160            ++counts[WC_BYTES];
     161            if (unicode_status != UNICODE_ON /* every byte is a new char */
     162             || (c & 0xc0) != 0x80 /* it isn't a 2nd+ byte of a Unicode char */
     163            ) {
     164                ++counts[WC_UNICHARS];
     165            }
     166
     167            if (isprint_asciionly(c)) { /* FIXME: not unicode-aware */
    125168                ++linepos;
    126                 if (!isspace_given_isprint(c)) {
     169                if (!isspace(c)) {
    127170                    in_word = 1;
    128171                    continue;
    129172                }
    130             } else if (((unsigned int)(c - 9)) <= 4) {
     173            } else if ((unsigned)(c - 9) <= 4) {
    131174                /* \t  9
    132175                 * \n 10
     
    137180                if (c == '\t') {
    138181                    linepos = (linepos | 7) + 1;
    139                 } else {            /* '\n', '\r', '\f', or '\v' */
    140                 DO_EOF:
     182                } else {  /* '\n', '\r', '\f', or '\v' */
     183 DO_EOF:
    141184                    if (linepos > counts[WC_LENGTH]) {
    142185                        counts[WC_LENGTH] = linepos;
     
    149192                    }
    150193                }
    151             } else if (c == EOF) {
    152                 if (ferror(fp)) {
    153                     bb_perror_msg("%s", arg);
    154                     status = EXIT_FAILURE;
    155                 }
    156                 --counts[WC_CHARS];
    157                 goto DO_EOF;        /* Treat an EOF as '\r'. */
    158194            } else {
    159195                continue;
     
    165201                break;
    166202            }
    167         } while (1);
     203        }
     204
     205        fclose_if_not_stdin(fp);
    168206
    169207        if (totals[WC_LENGTH] < counts[WC_LENGTH]) {
     
    172210        totals[WC_LENGTH] -= counts[WC_LENGTH];
    173211
    174         fclose_if_not_stdin(fp);
    175 
    176     OUTPUT:
     212 OUTPUT:
    177213        /* coreutils wc tries hard to print pretty columns
    178          * (saves results for all files, find max col len etc...)
     214         * (saves results for all files, finds max col len etc...)
    179215         * we won't try that hard, it will bloat us too much */
    180216        s = start_fmt;
     
    186222            }
    187223            totals[u] += pcounts[u];
    188         } while (++u < 4);
     224        } while (++u < NUM_WCS);
    189225        printf(fname_fmt, arg);
    190226    }
     
    195231     * irrelavent since we no longer need it. */
    196232    if (num_files > 1) {
    197         num_files = 0;              /* Make sure we don't get here again. */
     233        num_files = 0;  /* Make sure we don't get here again. */
    198234        arg = "total";
    199235        pcounts = totals;
Note: See TracChangeset for help on using the changeset viewer.