wc.c (1589B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <ctype.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 7 #include "util.h" 8 9 static void output(const char *, long, long, long); 10 static void wc(FILE *, const char *); 11 12 static int lflag = 0; 13 static int wflag = 0; 14 static char cmode = 0; 15 static long tc = 0, tl = 0, tw = 0; 16 17 static void 18 usage(void) 19 { 20 eprintf("usage: %s [-clmw] [files...]\n", argv0); 21 } 22 23 int 24 main(int argc, char *argv[]) 25 { 26 FILE *fp; 27 int i; 28 29 ARGBEGIN { 30 case 'c': 31 cmode = 'c'; 32 break; 33 case 'm': 34 cmode = 'm'; 35 break; 36 case 'l': 37 lflag = 1; 38 break; 39 case 'w': 40 wflag = 1; 41 break; 42 default: 43 usage(); 44 } ARGEND; 45 46 if (argc == 0) { 47 wc(stdin, NULL); 48 } else { 49 for (i = 0; i < argc; i++) { 50 if (!(fp = fopen(argv[i], "r"))) { 51 weprintf("fopen %s:", argv[i]); 52 continue; 53 } 54 wc(fp, argv[i]); 55 fclose(fp); 56 } 57 if (argc > 1) 58 output("total", tc, tl, tw); 59 } 60 return 0; 61 } 62 63 void 64 output(const char *str, long nc, long nl, long nw) 65 { 66 int noflags = !cmode && !lflag && !wflag; 67 68 if (lflag || noflags) 69 printf(" %5ld", nl); 70 if (wflag || noflags) 71 printf(" %5ld", nw); 72 if (cmode || noflags) 73 printf(" %5ld", nc); 74 if (str) 75 printf(" %s", str); 76 putchar('\n'); 77 } 78 79 void 80 wc(FILE *fp, const char *str) 81 { 82 int word = 0; 83 int c; 84 long nc = 0, nl = 0, nw = 0; 85 86 while ((c = getc(fp)) != EOF) { 87 if (cmode != 'm' || UTF8_POINT(c)) 88 nc++; 89 if (c == '\n') 90 nl++; 91 if (!isspace(c)) 92 word = 1; 93 else if (word) { 94 word = 0; 95 nw++; 96 } 97 } 98 if (word) 99 nw++; 100 tc += nc; 101 tl += nl; 102 tw += nw; 103 output(str, nc, nl, nw); 104 }