aboutsummaryrefslogtreecommitdiff
path: root/coreutils/wc.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-09-29 23:41:04 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-09-29 23:41:04 +0000
commit3ed001ff2631ad6911096148f47a2719a5b6d4f4 (patch)
tree7e329aa83800c77e7a3eb61c7e9c5be93ade5a40 /coreutils/wc.c
parent530c3ef81824d3b83ef0e8a773eaaae3722f00bf (diff)
downloadbusybox-w32-3ed001ff2631ad6911096148f47a2719a5b6d4f4.tar.gz
busybox-w32-3ed001ff2631ad6911096148f47a2719a5b6d4f4.tar.bz2
busybox-w32-3ed001ff2631ad6911096148f47a2719a5b6d4f4.zip
wc: reduce source cruft, make it so that "wc -c" (one option, no filenames)
will not print leading blanks.
Diffstat (limited to 'coreutils/wc.c')
-rw-r--r--coreutils/wc.c75
1 files changed, 31 insertions, 44 deletions
diff --git a/coreutils/wc.c b/coreutils/wc.c
index 4aea7d826..78a5105da 100644
--- a/coreutils/wc.c
+++ b/coreutils/wc.c
@@ -41,10 +41,6 @@
41 * for which 'wc -c' should output '0'. 41 * for which 'wc -c' should output '0'.
42 */ 42 */
43 43
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <unistd.h>
48#include "busybox.h" 44#include "busybox.h"
49 45
50#ifdef CONFIG_LOCALE_SUPPORT 46#ifdef CONFIG_LOCALE_SUPPORT
@@ -59,6 +55,11 @@
59#define isspace_given_isprint(c) ((c) == ' ') 55#define isspace_given_isprint(c) ((c) == ' ')
60#endif 56#endif
61 57
58//#define COUNT_T unsigned long long
59//#define COUNT_FMT "llu"
60#define COUNT_T unsigned
61#define COUNT_FMT "u"
62
62enum { 63enum {
63 WC_LINES = 0, 64 WC_LINES = 0,
64 WC_WORDS = 1, 65 WC_WORDS = 1,
@@ -66,56 +67,45 @@ enum {
66 WC_LENGTH = 3 67 WC_LENGTH = 3
67}; 68};
68 69
69/* Note: If this changes, remember to change the initialization of
70 * 'name' in wc_main. It needs to point to the terminating nul. */
71static const char wc_opts[] = "lwcL"; /* READ THE WARNING ABOVE! */
72
73enum {
74 OP_INC_LINE = 1, /* OP_INC_LINE must be 1. */
75 OP_SPACE = 2,
76 OP_NEWLINE = 4,
77 OP_TAB = 8,
78 OP_NUL = 16,
79};
80
81/* Note: If fmt_str changes, the offsets to 's' in the OUTPUT section
82 * will need to be updated. */
83static const char fmt_str[] = " %7u\0 %s\n";
84static const char total_str[] = "total";
85
86int wc_main(int argc, char **argv) 70int wc_main(int argc, char **argv)
87{ 71{
88 FILE *fp; 72 FILE *fp;
89 const char *s; 73 const char *s, *arg;
90 unsigned int *pcounts; 74 const char *start_fmt = "%9"COUNT_FMT;
91 unsigned int counts[4]; 75 const char *fname_fmt = " %s\n";
92 unsigned int totals[4]; 76 COUNT_T *pcounts;
93 unsigned int linepos; 77 COUNT_T counts[4];
94 unsigned int u; 78 COUNT_T totals[4];
79 unsigned linepos;
80 unsigned u;
95 int num_files = 0; 81 int num_files = 0;
96 int c; 82 int c;
97 char status = EXIT_SUCCESS; 83 char status = EXIT_SUCCESS;
98 char in_word; 84 char in_word;
99 char print_type; 85 char print_type;
100 86
101 print_type = bb_getopt_ulflags(argc, argv, wc_opts); 87 print_type = bb_getopt_ulflags(argc, argv, "lwcL");
102 88
103 if (print_type == 0) { 89 if (print_type == 0) {
104 print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_CHARS); 90 print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_CHARS);
105 } 91 }
106 92
107 argv += optind; 93 argv += optind;
108 if (!*argv) { 94 if (!argv[0]) {
109 *--argv = (char *) bb_msg_standard_input; 95 *--argv = (char *) bb_msg_standard_input;
96 fname_fmt = "\n";
97 if (!((print_type-1) & print_type)) /* exactly one option? */
98 start_fmt = "%"COUNT_FMT;
110 } 99 }
111 100
112 memset(totals, 0, sizeof(totals)); 101 memset(totals, 0, sizeof(totals));
113 102
114 pcounts = counts; 103 pcounts = counts;
115 104
116 do { 105 while ((arg = *argv++) != 0) {
117 ++num_files; 106 ++num_files;
118 if (!(fp = bb_wfopen_input(*argv))) { 107 fp = bb_wfopen_input(arg);
108 if (!fp) {
119 status = EXIT_FAILURE; 109 status = EXIT_FAILURE;
120 continue; 110 continue;
121 } 111 }
@@ -156,7 +146,7 @@ int wc_main(int argc, char **argv)
156 } 146 }
157 } else if (c == EOF) { 147 } else if (c == EOF) {
158 if (ferror(fp)) { 148 if (ferror(fp)) {
159 bb_perror_msg("%s", *argv); 149 bb_perror_msg("%s", arg);
160 status = EXIT_FAILURE; 150 status = EXIT_FAILURE;
161 } 151 }
162 --counts[WC_CHARS]; 152 --counts[WC_CHARS];
@@ -180,24 +170,20 @@ int wc_main(int argc, char **argv)
180 bb_fclose_nonstdin(fp); 170 bb_fclose_nonstdin(fp);
181 171
182 OUTPUT: 172 OUTPUT:
183 s = fmt_str + 1; /* Skip the leading space on 1st pass. */ 173 /* coreutils wc tries hard to print pretty columns
174 * (saves results for all files, find max col len etc...)
175 * we won't try that hard, it will bloat us too much */
176 s = start_fmt;
184 u = 0; 177 u = 0;
185 do { 178 do {
186 if (print_type & (1 << u)) { 179 if (print_type & (1 << u)) {
187 bb_printf(s, pcounts[u]); 180 bb_printf(s, pcounts[u]);
188 s = fmt_str; /* Ok... restore the leading space. */ 181 s = " %9"COUNT_FMT; /* Ok... restore the leading space. */
189 } 182 }
190 totals[u] += pcounts[u]; 183 totals[u] += pcounts[u];
191 } while (++u < 4); 184 } while (++u < 4);
192 185 bb_printf(fname_fmt, arg);
193 s += 8; /* Set the format to the empty string. */ 186 }
194
195 if (*argv != bb_msg_standard_input) {
196 s -= 3; /* We have a name, so do %s conversion. */
197 }
198 bb_printf(s, *argv);
199
200 } while (*++argv);
201 187
202 /* If more than one file was processed, we want the totals. To save some 188 /* If more than one file was processed, we want the totals. To save some
203 * space, we set the pcounts ptr to the totals array. This has the side 189 * space, we set the pcounts ptr to the totals array. This has the side
@@ -205,8 +191,9 @@ int wc_main(int argc, char **argv)
205 * irrelavent since we no longer need it. */ 191 * irrelavent since we no longer need it. */
206 if (num_files > 1) { 192 if (num_files > 1) {
207 num_files = 0; /* Make sure we don't get here again. */ 193 num_files = 0; /* Make sure we don't get here again. */
208 *--argv = (char *) total_str; 194 arg = "total";
209 pcounts = totals; 195 pcounts = totals;
196 --argv;
210 goto OUTPUT; 197 goto OUTPUT;
211 } 198 }
212 199