43 |
|
|
44 |
#include "libbb.h" |
#include "libbb.h" |
45 |
|
|
46 |
#if ENABLE_LOCALE_SUPPORT |
#if !ENABLE_LOCALE_SUPPORT |
47 |
#define isspace_given_isprint(c) isspace(c) |
# undef isprint |
48 |
#else |
# undef isspace |
49 |
#undef isspace |
# define isprint(c) ((unsigned)((c) - 0x20) <= (0x7e - 0x20)) |
50 |
#undef isprint |
# define isspace(c) ((c) == ' ') |
|
#define isspace(c) ((((c) == ' ') || (((unsigned int)((c) - 9)) <= (13 - 9)))) |
|
|
#define isprint(c) (((unsigned int)((c) - 0x20)) <= (0x7e - 0x20)) |
|
|
#define isspace_given_isprint(c) ((c) == ' ') |
|
51 |
#endif |
#endif |
52 |
|
|
53 |
#if ENABLE_FEATURE_WC_LARGE |
#if ENABLE_FEATURE_WC_LARGE |
54 |
#define COUNT_T unsigned long long |
# define COUNT_T unsigned long long |
55 |
#define COUNT_FMT "llu" |
# define COUNT_FMT "llu" |
56 |
#else |
#else |
57 |
#define COUNT_T unsigned |
# define COUNT_T unsigned |
58 |
#define COUNT_FMT "u" |
# define COUNT_FMT "u" |
59 |
#endif |
#endif |
60 |
|
|
61 |
enum { |
enum { |
68 |
int wc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
int wc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
69 |
int wc_main(int argc UNUSED_PARAM, char **argv) |
int wc_main(int argc UNUSED_PARAM, char **argv) |
70 |
{ |
{ |
71 |
FILE *fp; |
const char *arg; |
|
const char *s, *arg; |
|
72 |
const char *start_fmt = " %9"COUNT_FMT + 1; |
const char *start_fmt = " %9"COUNT_FMT + 1; |
73 |
const char *fname_fmt = " %s\n"; |
const char *fname_fmt = " %s\n"; |
74 |
COUNT_T *pcounts; |
COUNT_T *pcounts; |
75 |
COUNT_T counts[4]; |
COUNT_T counts[4]; |
76 |
COUNT_T totals[4]; |
COUNT_T totals[4]; |
77 |
unsigned linepos; |
int num_files; |
|
unsigned u; |
|
|
int num_files = 0; |
|
|
int c; |
|
78 |
smallint status = EXIT_SUCCESS; |
smallint status = EXIT_SUCCESS; |
|
smallint in_word; |
|
79 |
unsigned print_type; |
unsigned print_type; |
80 |
|
|
81 |
print_type = getopt32(argv, "lwcL"); |
print_type = getopt32(argv, "lwcL"); |
88 |
if (!argv[0]) { |
if (!argv[0]) { |
89 |
*--argv = (char *) bb_msg_standard_input; |
*--argv = (char *) bb_msg_standard_input; |
90 |
fname_fmt = "\n"; |
fname_fmt = "\n"; |
91 |
|
} |
92 |
|
if (!argv[1]) { /* zero or one filename? */ |
93 |
if (!((print_type-1) & print_type)) /* exactly one option? */ |
if (!((print_type-1) & print_type)) /* exactly one option? */ |
94 |
start_fmt = "%"COUNT_FMT; |
start_fmt = "%"COUNT_FMT; |
95 |
} |
} |
98 |
|
|
99 |
pcounts = counts; |
pcounts = counts; |
100 |
|
|
101 |
|
num_files = 0; |
102 |
while ((arg = *argv++) != 0) { |
while ((arg = *argv++) != 0) { |
103 |
|
FILE *fp; |
104 |
|
const char *s; |
105 |
|
unsigned u; |
106 |
|
unsigned linepos; |
107 |
|
smallint in_word; |
108 |
|
|
109 |
++num_files; |
++num_files; |
110 |
fp = fopen_or_warn_stdin(arg); |
fp = fopen_or_warn_stdin(arg); |
111 |
if (!fp) { |
if (!fp) { |
118 |
in_word = 0; |
in_word = 0; |
119 |
|
|
120 |
do { |
do { |
121 |
|
int c; |
122 |
/* Our -w doesn't match GNU wc exactly... oh well */ |
/* Our -w doesn't match GNU wc exactly... oh well */ |
123 |
|
|
124 |
++counts[WC_CHARS]; |
++counts[WC_CHARS]; |
125 |
c = getc(fp); |
c = getc(fp); |
126 |
if (isprint(c)) { |
if (c == EOF) { |
127 |
|
if (ferror(fp)) { |
128 |
|
bb_simple_perror_msg(arg); |
129 |
|
status = EXIT_FAILURE; |
130 |
|
} |
131 |
|
--counts[WC_CHARS]; |
132 |
|
goto DO_EOF; /* Treat an EOF as '\r'. */ |
133 |
|
} |
134 |
|
if (isprint_asciionly(c)) { |
135 |
++linepos; |
++linepos; |
136 |
if (!isspace_given_isprint(c)) { |
if (!isspace(c)) { |
137 |
in_word = 1; |
in_word = 1; |
138 |
continue; |
continue; |
139 |
} |
} |
140 |
} else if (((unsigned int)(c - 9)) <= 4) { |
} else if ((unsigned)(c - 9) <= 4) { |
141 |
/* \t 9 |
/* \t 9 |
142 |
* \n 10 |
* \n 10 |
143 |
* \v 11 |
* \v 11 |
147 |
if (c == '\t') { |
if (c == '\t') { |
148 |
linepos = (linepos | 7) + 1; |
linepos = (linepos | 7) + 1; |
149 |
} else { /* '\n', '\r', '\f', or '\v' */ |
} else { /* '\n', '\r', '\f', or '\v' */ |
150 |
DO_EOF: |
DO_EOF: |
151 |
if (linepos > counts[WC_LENGTH]) { |
if (linepos > counts[WC_LENGTH]) { |
152 |
counts[WC_LENGTH] = linepos; |
counts[WC_LENGTH] = linepos; |
153 |
} |
} |
158 |
linepos = 0; |
linepos = 0; |
159 |
} |
} |
160 |
} |
} |
|
} else if (c == EOF) { |
|
|
if (ferror(fp)) { |
|
|
bb_simple_perror_msg(arg); |
|
|
status = EXIT_FAILURE; |
|
|
} |
|
|
--counts[WC_CHARS]; |
|
|
goto DO_EOF; /* Treat an EOF as '\r'. */ |
|
161 |
} else { |
} else { |
162 |
continue; |
continue; |
163 |
} |
} |
176 |
|
|
177 |
fclose_if_not_stdin(fp); |
fclose_if_not_stdin(fp); |
178 |
|
|
179 |
OUTPUT: |
OUTPUT: |
180 |
/* coreutils wc tries hard to print pretty columns |
/* coreutils wc tries hard to print pretty columns |
181 |
* (saves results for all files, find max col len etc...) |
* (saves results for all files, find max col len etc...) |
182 |
* we won't try that hard, it will bloat us too much */ |
* we won't try that hard, it will bloat us too much */ |