Annotation of 43BSDReno/usr.bin/wc/wc.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.