|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980, 1987 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: char copyright[] = ! 20: "@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)wc.c 5.4 (Berkeley) 6/29/88"; ! 26: #endif /* not lint */ ! 27: ! 28: /* wc line, word and char count */ ! 29: ! 30: #include <sys/param.h> ! 31: #include <sys/stat.h> ! 32: #include <sys/file.h> ! 33: #include <stdio.h> ! 34: ! 35: #define DEL 0177 /* del char */ ! 36: #define NL 012 /* newline char */ ! 37: #define SPACE 040 /* space char */ ! 38: #define TAB 011 /* tab char */ ! 39: ! 40: static long tlinect, twordct, tcharct; ! 41: static int doline, doword, dochar; ! 42: ! 43: main(argc,argv) ! 44: int argc; ! 45: char **argv; ! 46: { ! 47: extern int optind; ! 48: register int ch; ! 49: ! 50: /* ! 51: * wc is unusual in that its flags are on by default, so, ! 52: * if you don't get any arguments, you have to turn them ! 53: * all on. ! 54: */ ! 55: if (argc > 1 && argv[1][0] == '-' && argv[1][1]) { ! 56: while ((ch = getopt(argc,argv,"lwc")) != EOF) ! 57: switch((char)ch) { ! 58: case 'l': ! 59: doline = 1; ! 60: break; ! 61: case 'w': ! 62: doword = 1; ! 63: break; ! 64: case 'c': ! 65: dochar = 1; ! 66: break; ! 67: case '?': ! 68: default: ! 69: fputs("usage: wc [-lwc] [files]\n",stderr); ! 70: exit(1); ! 71: } ! 72: argv += optind; ! 73: argc -= optind; ! 74: } ! 75: else { ! 76: ++argv; ! 77: --argc; ! 78: doline = doword = dochar = 1; ! 79: } ! 80: ! 81: /* should print "stdin" as the file name, here */ ! 82: if (argc <= 1) { ! 83: if (!*argv || !strcmp(*argv, "-")) { ! 84: cnt((char *)NULL); ! 85: putchar('\n'); ! 86: } ! 87: else { ! 88: cnt(*argv); ! 89: printf(" %s\n", *argv); ! 90: } ! 91: exit(0); ! 92: } ! 93: ! 94: /* ! 95: * cat allows "-" as stdin anywhere in the arg list, ! 96: * might as well here, too. Again, should use "stdin" ! 97: * as the file name. ! 98: */ ! 99: do { ! 100: if (!strcmp(*argv, "-")) { ! 101: cnt((char *)NULL); ! 102: putchar('\n'); ! 103: } ! 104: else { ! 105: cnt(*argv); ! 106: printf(" %s\n", *argv); ! 107: } ! 108: } while(*++argv); ! 109: ! 110: if (doline) ! 111: printf(" %7ld", tlinect); ! 112: if (doword) ! 113: printf(" %7ld", twordct); ! 114: if (dochar) ! 115: printf(" %7ld", tcharct); ! 116: puts(" total"); ! 117: exit(0); ! 118: } ! 119: ! 120: static ! 121: cnt(file) ! 122: char *file; ! 123: { ! 124: register u_char *C; ! 125: register short gotsp; ! 126: register int len; ! 127: register long linect, wordct,charct; ! 128: struct stat sbuf; ! 129: int fd; ! 130: u_char buf[MAXBSIZE]; ! 131: ! 132: linect = wordct = charct = 0; ! 133: if (file) { ! 134: if ((fd = open(file, O_RDONLY, 0)) < 0) { ! 135: perror(file); ! 136: exit(1); ! 137: } ! 138: if (!doword) { ! 139: /* ! 140: * line counting is split out because it's a lot ! 141: * faster to get lines than to get words, since ! 142: * the word count requires some logic. ! 143: */ ! 144: if (doline) { ! 145: while(len = read(fd, buf, MAXBSIZE)) { ! 146: if (len == -1) { ! 147: perror(file); ! 148: exit(1); ! 149: } ! 150: charct += len; ! 151: for (C = buf; len--; ++C) ! 152: if (*C == '\n') ! 153: ++linect; ! 154: } ! 155: tlinect += linect; ! 156: printf(" %7ld", linect); ! 157: if (dochar) { ! 158: tcharct += charct; ! 159: printf(" %7ld", sbuf.st_size); ! 160: } ! 161: close(fd); ! 162: return; ! 163: } ! 164: /* ! 165: * if all we need is the number of characters and ! 166: * it's a directory or a regular or linked file, just ! 167: * stat the puppy. We avoid testing for it not being ! 168: * a special device in case someone adds a new type ! 169: * of inode. ! 170: */ ! 171: if (dochar) { ! 172: if (fstat(fd, &sbuf)) { ! 173: perror(file); ! 174: exit(1); ! 175: } ! 176: if (sbuf.st_mode & (S_IFREG | S_IFLNK | S_IFDIR)) { ! 177: printf(" %7ld", sbuf.st_size); ! 178: tcharct += sbuf.st_size; ! 179: close(fd); ! 180: return; ! 181: } ! 182: } ! 183: } ! 184: } ! 185: else ! 186: fd = 0; ! 187: /* do it the hard way... */ ! 188: for (gotsp = 1; len = read(fd, buf, MAXBSIZE);) { ! 189: if (len == -1) { ! 190: perror(file); ! 191: exit(1); ! 192: } ! 193: charct += len; ! 194: for (C = buf; len--; ++C) ! 195: switch(*C) { ! 196: case NL: ! 197: ++linect; ! 198: case TAB: ! 199: case SPACE: ! 200: gotsp = 1; ! 201: continue; ! 202: default: ! 203: #ifdef notdef ! 204: /* ! 205: * This line of code implements the ! 206: * original V7 wc algorithm, i.e. ! 207: * a non-printing character doesn't ! 208: * toggle the "word" count, so that ! 209: * " ^D^F " counts as 6 spaces, ! 210: * while "foo^D^Fbar" counts as 8 ! 211: * characters. ! 212: * ! 213: * test order is important -- gotsp ! 214: * will normally be NO, so test it ! 215: * first ! 216: */ ! 217: if (gotsp && *C > SPACE && *C < DEL) { ! 218: #endif ! 219: /* ! 220: * This line implements the manual ! 221: * page, i.e. a word is a "maximal ! 222: * string of characters delimited by ! 223: * spaces, tabs or newlines." Notice ! 224: * nothing was said about a character ! 225: * being printing or non-printing. ! 226: */ ! 227: if (gotsp) { ! 228: gotsp = 0; ! 229: ++wordct; ! 230: } ! 231: } ! 232: } ! 233: if (doline) { ! 234: tlinect += linect; ! 235: printf(" %7ld", linect); ! 236: } ! 237: if (doword) { ! 238: twordct += wordct; ! 239: printf(" %7ld", wordct); ! 240: } ! 241: if (dochar) { ! 242: tcharct += charct; ! 243: printf(" %7ld", charct); ! 244: } ! 245: close(fd); ! 246: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.