Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/coreutils/wc.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/coreutils/wc.c
r1765 r2725 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 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. */ 11 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */ 12 12 … … 20 20 * 4) isprint() wasn't considered when word counting. 21 21 * 22 * TODO:23 *24 * When locale support is enabled, count multibyte chars in the '-m' case.25 *26 22 * NOTES: 27 23 * … … 41 37 * for which 'wc -c' should output '0'. 42 38 */ 43 44 39 #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" 48 52 #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" 54 55 #endif 55 56 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 */ 64 83 enum { 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, 69 90 }; 70 91 71 int wc_main(int argc, char **argv) ;72 int wc_main(int argc , char **argv)92 int wc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 93 int wc_main(int argc UNUSED_PARAM, char **argv) 73 94 { 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; 77 97 const char *fname_fmt = " %s\n"; 78 98 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; 85 102 smallint status = EXIT_SUCCESS; 86 smallint in_word;87 103 unsigned print_type; 88 104 89 print_type = getopt32(argv, "lwcL"); 105 init_unicode(); 106 107 print_type = getopt32(argv, "lwmcL"); 90 108 91 109 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); 93 111 } 94 112 … … 97 115 *--argv = (char *) bb_msg_standard_input; 98 116 fname_fmt = "\n"; 117 } 118 if (!argv[1]) { /* zero or one filename? */ 99 119 if (!((print_type-1) & print_type)) /* exactly one option? */ 100 120 start_fmt = "%"COUNT_FMT; … … 105 125 pcounts = counts; 106 126 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 108 135 ++num_files; 109 136 fp = fopen_or_warn_stdin(arg); … … 117 144 in_word = 0; 118 145 119 do { 146 while (1) { 147 int c; 120 148 /* Our -w doesn't match GNU wc exactly... oh well */ 121 149 122 ++counts[WC_CHARS];123 150 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 */ 125 168 ++linepos; 126 if (!isspace _given_isprint(c)) {169 if (!isspace(c)) { 127 170 in_word = 1; 128 171 continue; 129 172 } 130 } else if (( (unsigned int)(c - 9)) <= 4) {173 } else if ((unsigned)(c - 9) <= 4) { 131 174 /* \t 9 132 175 * \n 10 … … 137 180 if (c == '\t') { 138 181 linepos = (linepos | 7) + 1; 139 } else { 140 182 } else { /* '\n', '\r', '\f', or '\v' */ 183 DO_EOF: 141 184 if (linepos > counts[WC_LENGTH]) { 142 185 counts[WC_LENGTH] = linepos; … … 149 192 } 150 193 } 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'. */158 194 } else { 159 195 continue; … … 165 201 break; 166 202 } 167 } while (1); 203 } 204 205 fclose_if_not_stdin(fp); 168 206 169 207 if (totals[WC_LENGTH] < counts[WC_LENGTH]) { … … 172 210 totals[WC_LENGTH] -= counts[WC_LENGTH]; 173 211 174 fclose_if_not_stdin(fp); 175 176 OUTPUT: 212 OUTPUT: 177 213 /* 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...) 179 215 * we won't try that hard, it will bloat us too much */ 180 216 s = start_fmt; … … 186 222 } 187 223 totals[u] += pcounts[u]; 188 } while (++u < 4);224 } while (++u < NUM_WCS); 189 225 printf(fname_fmt, arg); 190 226 } … … 195 231 * irrelavent since we no longer need it. */ 196 232 if (num_files > 1) { 197 num_files = 0; 233 num_files = 0; /* Make sure we don't get here again. */ 198 234 arg = "total"; 199 235 pcounts = totals;
Note:
See TracChangeset
for help on using the changeset viewer.