Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/coreutils/wc.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/coreutils/wc.c
r821 r1770 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 50 37 * 51 38 * echo hello > /tmp/testfile && 52 * (dd ibs=1k skip=1 count=0 &> /dev/null 39 * (dd ibs=1k skip=1 count=0 &> /dev/null; wc -c) < /tmp/testfile 53 40 * 54 41 * for which 'wc -c' should output '0'. 55 42 */ 56 43 57 #include <stdio.h> 58 #include <stdlib.h> 59 #include <string.h> 60 #include <unistd.h> 61 #include "busybox.h" 62 63 #ifdef CONFIG_LOCALE_SUPPORT 64 #include <locale.h> 65 #include <ctype.h> 44 #include "libbb.h" 45 46 #if ENABLE_LOCALE_SUPPORT 66 47 #define isspace_given_isprint(c) isspace(c) 67 48 #else … … 73 54 #endif 74 55 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 75 64 enum { 76 65 WC_LINES = 0, … … 80 69 }; 81 70 82 /* Note: If this changes, remember to change the initialization of 83 * 'name' in wc_main. It needs to point to the terminating nul. */ 84 static const char wc_opts[] = "lwcL"; /* READ THE WARNING ABOVE! */ 85 86 enum { 87 OP_INC_LINE = 1, /* OP_INC_LINE must be 1. */ 88 OP_SPACE = 2, 89 OP_NEWLINE = 4, 90 OP_TAB = 8, 91 OP_NUL = 16, 92 }; 93 94 /* Note: If fmt_str changes, the offsets to 's' in the OUTPUT section 95 * will need to be updated. */ 96 static const char fmt_str[] = " %7u\0 %s\n"; 97 static const char total_str[] = "total"; 98 71 int wc_main(int argc, char **argv); 99 72 int wc_main(int argc, char **argv) 100 73 { 101 74 FILE *fp; 102 const char *s; 103 unsigned int *pcounts; 104 unsigned int counts[4]; 105 unsigned int totals[4]; 106 unsigned int linepos; 107 unsigned int u; 75 const char *s, *arg; 76 const char *start_fmt = "%9"COUNT_FMT; 77 const char *fname_fmt = " %s\n"; 78 COUNT_T *pcounts; 79 COUNT_T counts[4]; 80 COUNT_T totals[4]; 81 unsigned linepos; 82 unsigned u; 108 83 int num_files = 0; 109 84 int c; 110 charstatus = EXIT_SUCCESS;111 charin_word;112 charprint_type;113 114 print_type = bb_getopt_ulflags(argc, argv, wc_opts);85 smallint status = EXIT_SUCCESS; 86 smallint in_word; 87 unsigned print_type; 88 89 print_type = getopt32(argv, "lwcL"); 115 90 116 91 if (print_type == 0) { … … 119 94 120 95 argv += optind; 121 if (! *argv) {96 if (!argv[0]) { 122 97 *--argv = (char *) bb_msg_standard_input; 98 fname_fmt = "\n"; 99 if (!((print_type-1) & print_type)) /* exactly one option? */ 100 start_fmt = "%"COUNT_FMT; 123 101 } 124 102 … … 127 105 pcounts = counts; 128 106 129 do{107 while ((arg = *argv++) != 0) { 130 108 ++num_files; 131 if (!(fp = bb_wfopen_input(*argv))) { 109 fp = fopen_or_warn_stdin(arg); 110 if (!fp) { 132 111 status = EXIT_FAILURE; 133 112 continue; … … 139 118 140 119 do { 120 /* Our -w doesn't match GNU wc exactly... oh well */ 121 141 122 ++counts[WC_CHARS]; 142 123 c = getc(fp); … … 170 151 } else if (c == EOF) { 171 152 if (ferror(fp)) { 172 bb_perror_msg("%s", *argv);153 bb_perror_msg("%s", arg); 173 154 status = EXIT_FAILURE; 174 155 } … … 191 172 totals[WC_LENGTH] -= counts[WC_LENGTH]; 192 173 193 bb_fclose_nonstdin(fp);174 fclose_if_not_stdin(fp); 194 175 195 176 OUTPUT: 196 s = fmt_str + 1; /* Skip the leading space on 1st pass. */ 177 /* coreutils wc tries hard to print pretty columns 178 * (saves results for all files, find max col len etc...) 179 * we won't try that hard, it will bloat us too much */ 180 s = start_fmt; 197 181 u = 0; 198 182 do { 199 183 if (print_type & (1 << u)) { 200 bb_printf(s, pcounts[u]);201 s = fmt_str;/* Ok... restore the leading space. */184 printf(s, pcounts[u]); 185 s = " %9"COUNT_FMT; /* Ok... restore the leading space. */ 202 186 } 203 187 totals[u] += pcounts[u]; 204 188 } while (++u < 4); 205 206 s += 8; /* Set the format to the empty string. */ 207 208 if (*argv != bb_msg_standard_input) { 209 s -= 3; /* We have a name, so do %s conversion. */ 210 } 211 bb_printf(s, *argv); 212 213 } while (*++argv); 189 printf(fname_fmt, arg); 190 } 214 191 215 192 /* If more than one file was processed, we want the totals. To save some … … 219 196 if (num_files > 1) { 220 197 num_files = 0; /* Make sure we don't get here again. */ 221 *--argv = (char *) total_str;198 arg = "total"; 222 199 pcounts = totals; 200 --argv; 223 201 goto OUTPUT; 224 202 } 225 203 226 bb_fflush_stdout_and_exit(status);204 fflush_stdout_and_exit(status); 227 205 }
Note:
See TracChangeset
for help on using the changeset viewer.