wc.c (201181) | wc.c (208170) |
---|---|
1/* 2 * Copyright (c) 1980, 1987, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 30 unchanged lines hidden (view full) --- 39 40#if 0 41#ifndef lint 42static char sccsid[] = "@(#)wc.c 8.1 (Berkeley) 6/6/93"; 43#endif /* not lint */ 44#endif 45 46#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 1980, 1987, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 30 unchanged lines hidden (view full) --- 39 40#if 0 41#ifndef lint 42static char sccsid[] = "@(#)wc.c 8.1 (Berkeley) 6/6/93"; 43#endif /* not lint */ 44#endif 45 46#include <sys/cdefs.h> |
47__FBSDID("$FreeBSD: head/usr.bin/wc/wc.c 201181 2009-12-29 08:54:03Z ed $"); | 47__FBSDID("$FreeBSD: head/usr.bin/wc/wc.c 208170 2010-05-16 21:06:26Z pjd $"); |
48 49#include <sys/param.h> 50#include <sys/stat.h> 51 52#include <ctype.h> 53#include <err.h> 54#include <errno.h> 55#include <fcntl.h> 56#include <locale.h> 57#include <stdint.h> 58#include <stdio.h> 59#include <stdlib.h> 60#include <string.h> 61#include <unistd.h> 62#include <wchar.h> 63#include <wctype.h> 64 65uintmax_t tlinect, twordct, tcharct, tlongline; | 48 49#include <sys/param.h> 50#include <sys/stat.h> 51 52#include <ctype.h> 53#include <err.h> 54#include <errno.h> 55#include <fcntl.h> 56#include <locale.h> 57#include <stdint.h> 58#include <stdio.h> 59#include <stdlib.h> 60#include <string.h> 61#include <unistd.h> 62#include <wchar.h> 63#include <wctype.h> 64 65uintmax_t tlinect, twordct, tcharct, tlongline; |
66int doline, doword, dochar, domulti, dolongline; | 66int doline, doword, dochar, domulti, dolongline, siginfo; |
67 | 67 |
68static void show_cnt(const char *file, uintmax_t linect, uintmax_t wordct, 69 uintmax_t charct, uintmax_t llct); |
|
68static int cnt(const char *); 69static void usage(void); 70 | 70static int cnt(const char *); 71static void usage(void); 72 |
73static void 74siginfo_handler(int sig __unused) 75{ 76 77 siginfo = 1; 78} 79 |
|
71int 72main(int argc, char *argv[]) 73{ 74 int ch, errors, total; 75 76 (void) setlocale(LC_CTYPE, ""); 77 78 while ((ch = getopt(argc, argv, "clmwL")) != -1) --- 17 unchanged lines hidden (view full) --- 96 break; 97 case '?': 98 default: 99 usage(); 100 } 101 argv += optind; 102 argc -= optind; 103 | 80int 81main(int argc, char *argv[]) 82{ 83 int ch, errors, total; 84 85 (void) setlocale(LC_CTYPE, ""); 86 87 while ((ch = getopt(argc, argv, "clmwL")) != -1) --- 17 unchanged lines hidden (view full) --- 105 break; 106 case '?': 107 default: 108 usage(); 109 } 110 argv += optind; 111 argc -= optind; 112 |
113 (void)signal(SIGINFO, siginfo_handler); 114 |
|
104 /* Wc's flags are on by default. */ 105 if (doline + doword + dochar + domulti + dolongline == 0) 106 doline = doword = dochar = 1; 107 108 errors = 0; 109 total = 0; 110 if (!*argv) { 111 if (cnt((char *)NULL) != 0) 112 ++errors; | 115 /* Wc's flags are on by default. */ 116 if (doline + doword + dochar + domulti + dolongline == 0) 117 doline = doword = dochar = 1; 118 119 errors = 0; 120 total = 0; 121 if (!*argv) { 122 if (cnt((char *)NULL) != 0) 123 ++errors; |
113 else 114 (void)printf("\n"); | 124 } else { 125 do { 126 if (cnt(*argv) != 0) 127 ++errors; 128 ++total; 129 } while(*++argv); |
115 } | 130 } |
116 else do { 117 if (cnt(*argv) != 0) 118 ++errors; 119 else 120 (void)printf(" %s\n", *argv); 121 ++total; 122 } while(*++argv); | |
123 | 131 |
124 if (total > 1) { 125 if (doline) 126 (void)printf(" %7ju", tlinect); 127 if (doword) 128 (void)printf(" %7ju", twordct); 129 if (dochar || domulti) 130 (void)printf(" %7ju", tcharct); 131 if (dolongline) 132 (void)printf(" %7ju", tlongline); 133 (void)printf(" total\n"); 134 } | 132 if (total > 1) 133 show_cnt("total", tlinect, twordct, tcharct, tlongline); |
135 exit(errors == 0 ? 0 : 1); 136} 137 | 134 exit(errors == 0 ? 0 : 1); 135} 136 |
137static void 138show_cnt(const char *file, uintmax_t linect, uintmax_t wordct, 139 uintmax_t charct, uintmax_t llct) 140{ 141 FILE *out; 142 143 if (!siginfo) 144 out = stdout; 145 else { 146 out = stderr; 147 siginfo = 0; 148 } 149 150 if (doline) 151 (void)fprintf(out, " %7ju", linect); 152 if (doword) 153 (void)fprintf(out, " %7ju", wordct); 154 if (dochar || domulti) 155 (void)fprintf(out, " %7ju", charct); 156 if (dolongline) 157 (void)fprintf(out, " %7ju", llct); 158 if (file != NULL) 159 (void)fprintf(out, " %s\n", file); 160 else 161 (void)fprintf(out, "\n"); 162} 163 |
|
138static int 139cnt(const char *file) 140{ 141 struct stat sb; 142 uintmax_t linect, wordct, charct, llct, tmpll; 143 int fd, len, warned; 144 size_t clen; 145 short gotsp; 146 u_char *p; 147 u_char buf[MAXBSIZE]; 148 wchar_t wch; 149 mbstate_t mbs; 150 151 linect = wordct = charct = llct = tmpll = 0; | 164static int 165cnt(const char *file) 166{ 167 struct stat sb; 168 uintmax_t linect, wordct, charct, llct, tmpll; 169 int fd, len, warned; 170 size_t clen; 171 short gotsp; 172 u_char *p; 173 u_char buf[MAXBSIZE]; 174 wchar_t wch; 175 mbstate_t mbs; 176 177 linect = wordct = charct = llct = tmpll = 0; |
152 if (file == NULL) { 153 file = "stdin"; | 178 if (file == NULL) |
154 fd = STDIN_FILENO; | 179 fd = STDIN_FILENO; |
155 } else { | 180 else { |
156 if ((fd = open(file, O_RDONLY, 0)) < 0) { 157 warn("%s: open", file); 158 return (1); 159 } 160 if (doword || (domulti && MB_CUR_MAX != 1)) 161 goto word; 162 /* 163 * Line counting is split out because it's a lot faster to get 164 * lines than to get words, since the word count requires some 165 * logic. 166 */ 167 if (doline) { 168 while ((len = read(fd, buf, MAXBSIZE))) { 169 if (len == -1) { 170 warn("%s: read", file); 171 (void)close(fd); 172 return (1); 173 } | 181 if ((fd = open(file, O_RDONLY, 0)) < 0) { 182 warn("%s: open", file); 183 return (1); 184 } 185 if (doword || (domulti && MB_CUR_MAX != 1)) 186 goto word; 187 /* 188 * Line counting is split out because it's a lot faster to get 189 * lines than to get words, since the word count requires some 190 * logic. 191 */ 192 if (doline) { 193 while ((len = read(fd, buf, MAXBSIZE))) { 194 if (len == -1) { 195 warn("%s: read", file); 196 (void)close(fd); 197 return (1); 198 } |
199 if (siginfo) { 200 show_cnt(file, linect, wordct, charct, 201 llct); 202 } |
|
174 charct += len; 175 for (p = buf; len--; ++p) 176 if (*p == '\n') { 177 if (tmpll > llct) 178 llct = tmpll; 179 tmpll = 0; 180 ++linect; 181 } else 182 tmpll++; 183 } 184 tlinect += linect; | 203 charct += len; 204 for (p = buf; len--; ++p) 205 if (*p == '\n') { 206 if (tmpll > llct) 207 llct = tmpll; 208 tmpll = 0; 209 ++linect; 210 } else 211 tmpll++; 212 } 213 tlinect += linect; |
185 (void)printf(" %7ju", linect); 186 if (dochar) { | 214 if (dochar) |
187 tcharct += charct; | 215 tcharct += charct; |
188 (void)printf(" %7ju", charct); 189 } | |
190 if (dolongline) { 191 if (llct > tlongline) 192 tlongline = llct; | 216 if (dolongline) { 217 if (llct > tlongline) 218 tlongline = llct; |
193 (void)printf(" %7ju", tlongline); | |
194 } | 219 } |
220 show_cnt(file, linect, wordct, charct, llct); |
|
195 (void)close(fd); 196 return (0); 197 } 198 /* 199 * If all we need is the number of characters and it's a 200 * regular file, just stat the puppy. 201 */ 202 if (dochar || domulti) { 203 if (fstat(fd, &sb)) { 204 warn("%s: fstat", file); 205 (void)close(fd); 206 return (1); 207 } 208 if (S_ISREG(sb.st_mode)) { | 221 (void)close(fd); 222 return (0); 223 } 224 /* 225 * If all we need is the number of characters and it's a 226 * regular file, just stat the puppy. 227 */ 228 if (dochar || domulti) { 229 if (fstat(fd, &sb)) { 230 warn("%s: fstat", file); 231 (void)close(fd); 232 return (1); 233 } 234 if (S_ISREG(sb.st_mode)) { |
209 (void)printf(" %7lld", (long long)sb.st_size); 210 tcharct += sb.st_size; | 235 charct = sb.st_size; 236 show_cnt(file, linect, wordct, charct, llct); 237 tcharct += charct; |
211 (void)close(fd); 212 return (0); 213 } 214 } 215 } 216 217 /* Do it the hard way... */ 218word: gotsp = 1; 219 warned = 0; 220 memset(&mbs, 0, sizeof(mbs)); 221 while ((len = read(fd, buf, MAXBSIZE)) != 0) { 222 if (len == -1) { | 238 (void)close(fd); 239 return (0); 240 } 241 } 242 } 243 244 /* Do it the hard way... */ 245word: gotsp = 1; 246 warned = 0; 247 memset(&mbs, 0, sizeof(mbs)); 248 while ((len = read(fd, buf, MAXBSIZE)) != 0) { 249 if (len == -1) { |
223 warn("%s: read", file); | 250 warn("%s: read", file != NULL ? file : "stdin"); |
224 (void)close(fd); 225 return (1); 226 } 227 p = buf; 228 while (len > 0) { | 251 (void)close(fd); 252 return (1); 253 } 254 p = buf; 255 while (len > 0) { |
256 if (siginfo) 257 show_cnt(file, linect, wordct, charct, llct); |
|
229 if (!domulti || MB_CUR_MAX == 1) { 230 clen = 1; 231 wch = (unsigned char)*p; 232 } else if ((clen = mbrtowc(&wch, p, len, &mbs)) == 233 (size_t)-1) { 234 if (!warned) { 235 errno = EILSEQ; | 258 if (!domulti || MB_CUR_MAX == 1) { 259 clen = 1; 260 wch = (unsigned char)*p; 261 } else if ((clen = mbrtowc(&wch, p, len, &mbs)) == 262 (size_t)-1) { 263 if (!warned) { 264 errno = EILSEQ; |
236 warn("%s", file); | 265 warn("%s", 266 file != NULL ? file : "stdin"); |
237 warned = 1; 238 } 239 memset(&mbs, 0, sizeof(mbs)); 240 clen = 1; 241 wch = (unsigned char)*p; 242 } else if (clen == (size_t)-2) 243 break; 244 else if (clen == 0) --- 14 unchanged lines hidden (view full) --- 259 else if (gotsp) { 260 gotsp = 0; 261 ++wordct; 262 } 263 } 264 } 265 if (domulti && MB_CUR_MAX > 1) 266 if (mbrtowc(NULL, NULL, 0, &mbs) == (size_t)-1 && !warned) | 267 warned = 1; 268 } 269 memset(&mbs, 0, sizeof(mbs)); 270 clen = 1; 271 wch = (unsigned char)*p; 272 } else if (clen == (size_t)-2) 273 break; 274 else if (clen == 0) --- 14 unchanged lines hidden (view full) --- 289 else if (gotsp) { 290 gotsp = 0; 291 ++wordct; 292 } 293 } 294 } 295 if (domulti && MB_CUR_MAX > 1) 296 if (mbrtowc(NULL, NULL, 0, &mbs) == (size_t)-1 && !warned) |
267 warn("%s", file); 268 if (doline) { | 297 warn("%s", file != NULL ? file : "stdin"); 298 if (doline) |
269 tlinect += linect; | 299 tlinect += linect; |
270 (void)printf(" %7ju", linect); 271 } 272 if (doword) { | 300 if (doword) |
273 twordct += wordct; | 301 twordct += wordct; |
274 (void)printf(" %7ju", wordct); 275 } 276 if (dochar || domulti) { | 302 if (dochar || domulti) |
277 tcharct += charct; | 303 tcharct += charct; |
278 (void)printf(" %7ju", charct); 279 } | |
280 if (dolongline) { 281 if (llct > tlongline) 282 tlongline = llct; | 304 if (dolongline) { 305 if (llct > tlongline) 306 tlongline = llct; |
283 (void)printf(" %7ju", llct); | |
284 } | 307 } |
308 show_cnt(file, linect, wordct, charct, llct); |
|
285 (void)close(fd); 286 return (0); 287} 288 289static void 290usage(void) 291{ 292 (void)fprintf(stderr, "usage: wc [-Lclmw] [file ...]\n"); 293 exit(1); 294} | 309 (void)close(fd); 310 return (0); 311} 312 313static void 314usage(void) 315{ 316 (void)fprintf(stderr, "usage: wc [-Lclmw] [file ...]\n"); 317 exit(1); 318} |