[BACK]Return to wc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / wc

Annotation of src/usr.bin/wc/wc.c, Revision 1.1

1.1     ! deraadt     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, 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
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. All advertising materials mentioning features or use of this software
        !            14:  *    must display the following acknowledgement:
        !            15:  *     This product includes software developed by the University of
        !            16:  *     California, Berkeley and its contributors.
        !            17:  * 4. Neither the name of the University nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: #ifndef lint
        !            35: char copyright[] =
        !            36: "@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\
        !            37:  All rights reserved.\n";
        !            38: #endif /* not lint */
        !            39:
        !            40: #ifndef lint
        !            41: /*static char sccsid[] = "from: @(#)wc.c       5.7 (Berkeley) 3/2/91";*/
        !            42: static char rcsid[] = "$Id: wc.c,v 1.9 1994/01/03 03:11:06 andrew Exp $";
        !            43: #endif /* not lint */
        !            44:
        !            45: /* wc line, word and char count */
        !            46:
        !            47: #include <stdio.h>
        !            48: #include <stdlib.h>
        !            49: #include <string.h>
        !            50: #include <locale.h>
        !            51: #include <ctype.h>
        !            52: #include <errno.h>
        !            53: #include <sys/param.h>
        !            54: #include <sys/stat.h>
        !            55: #include <sys/file.h>
        !            56: #include <unistd.h>
        !            57: #include <err.h>
        !            58:
        !            59: static void    print_counts();
        !            60: static void    cnt();
        !            61: static long    tlinect, twordct, tcharct;
        !            62: static int     doline, doword, dochar;
        !            63: static int     rval = 0;
        !            64:
        !            65: int
        !            66: main(argc, argv)
        !            67:        int argc;
        !            68:        char **argv;
        !            69: {
        !            70:        extern int optind;
        !            71:        register int ch;
        !            72:
        !            73:        setlocale(LC_ALL, "");
        !            74:
        !            75:        while ((ch = getopt(argc, argv, "lwcm")) != -1)
        !            76:                switch((char)ch) {
        !            77:                case 'l':
        !            78:                        doline = 1;
        !            79:                        break;
        !            80:                case 'w':
        !            81:                        doword = 1;
        !            82:                        break;
        !            83:                case 'c':
        !            84:                case 'm':
        !            85:                        dochar = 1;
        !            86:                        break;
        !            87:                case '?':
        !            88:                default:
        !            89:                        fprintf(stderr, "usage: wc [-c | -m] [-lw] [file ...]\n");
        !            90:                        exit(1);
        !            91:                }
        !            92:        argv += optind;
        !            93:        argc -= optind;
        !            94:
        !            95:        /*
        !            96:         * wc is unusual in that its flags are on by default, so,
        !            97:         * if you don't get any arguments, you have to turn them
        !            98:         * all on.
        !            99:         */
        !           100:        if (!doline && !doword && !dochar) {
        !           101:                doline = doword = dochar = 1;
        !           102:        }
        !           103:
        !           104:        if (!*argv) {
        !           105:                cnt((char *)NULL);
        !           106:        } else {
        !           107:                int dototal = (argc > 1);
        !           108:
        !           109:                do {
        !           110:                        cnt(*argv);
        !           111:                } while(*++argv);
        !           112:
        !           113:                if (dototal) {
        !           114:                        print_counts (tlinect, twordct, tcharct, "total");
        !           115:                }
        !           116:        }
        !           117:
        !           118:        exit(rval);
        !           119: }
        !           120:
        !           121:
        !           122: static void
        !           123: cnt(file)
        !           124:        char *file;
        !           125: {
        !           126:        register u_char *C;
        !           127:        register short gotsp;
        !           128:        register int len;
        !           129:        register long linect, wordct, charct;
        !           130:        struct stat sbuf;
        !           131:        int fd;
        !           132:        u_char buf[MAXBSIZE];
        !           133:
        !           134:        linect = wordct = charct = 0;
        !           135:        if (file) {
        !           136:                if ((fd = open(file, O_RDONLY, 0)) < 0) {
        !           137:                        warn ("%s", file);
        !           138:                        rval = 1;
        !           139:                        return;
        !           140:                }
        !           141:        } else  {
        !           142:                fd = STDIN_FILENO;
        !           143:        }
        !           144:
        !           145:        if (!doword) {
        !           146:                /*
        !           147:                 * line counting is split out because it's a lot
        !           148:                 * faster to get lines than to get words, since
        !           149:                 * the word count requires some logic.
        !           150:                 */
        !           151:                if (doline) {
        !           152:                        while((len = read(fd, buf, MAXBSIZE)) > 0) {
        !           153:                                charct += len;
        !           154:                                for (C = buf; len--; ++C)
        !           155:                                        if (*C == '\n')
        !           156:                                                ++linect;
        !           157:                        }
        !           158:                        if (len == -1) {
        !           159:                                warn ("%s", file);
        !           160:                                rval = 1;
        !           161:                        }
        !           162:                }
        !           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:                else if (dochar) {
        !           172:                        int ifmt;
        !           173:
        !           174:                        if (fstat(fd, &sbuf)) {
        !           175:                                warn ("%s", file);
        !           176:                                rval = 1;
        !           177:                        } else {
        !           178:                                ifmt = sbuf.st_mode & S_IFMT;
        !           179:                                if (ifmt == S_IFREG || ifmt == S_IFLNK
        !           180:                                        || ifmt == S_IFDIR) {
        !           181:                                        charct = sbuf.st_size;
        !           182:                                } else {
        !           183:                                        while((len = read(fd, buf, MAXBSIZE)) > 0)
        !           184:                                                charct += len;
        !           185:                                        if (len == -1) {
        !           186:                                                warn ("%s", file);
        !           187:                                                rval = 1;
        !           188:                                        }
        !           189:                                }
        !           190:                        }
        !           191:                }
        !           192:        }
        !           193:        else
        !           194:        {
        !           195:                /* do it the hard way... */
        !           196:                gotsp = 1;
        !           197:                while ((len = read(fd, buf, MAXBSIZE)) > 0) {
        !           198:                        charct += len;
        !           199:                        for (C = buf; len--; ++C) {
        !           200:                                if (isspace (*C)) {
        !           201:                                        gotsp = 1;
        !           202:                                        if (*C == '\n') {
        !           203:                                                ++linect;
        !           204:                                        }
        !           205:                                } else {
        !           206:                                        /*
        !           207:                                         * This line implements the POSIX
        !           208:                                         * spec, i.e. a word is a "maximal
        !           209:                                         * string of characters delimited by
        !           210:                                         * whitespace."  Notice nothing was
        !           211:                                         * said about a character being
        !           212:                                         * printing or non-printing.
        !           213:                                         */
        !           214:                                        if (gotsp) {
        !           215:                                                gotsp = 0;
        !           216:                                                ++wordct;
        !           217:                                        }
        !           218:                                }
        !           219:                        }
        !           220:                }
        !           221:                if (len == -1) {
        !           222:                        warn ("%s", file);
        !           223:                        rval = 1;
        !           224:                }
        !           225:        }
        !           226:
        !           227:        print_counts (linect, wordct, charct, file ? file : "");
        !           228:
        !           229:        /* don't bother checkint doline, doword, or dochar --- speeds
        !           230:            up the common case */
        !           231:        tlinect += linect;
        !           232:        twordct += wordct;
        !           233:        tcharct += charct;
        !           234:
        !           235:        if (close(fd)) {
        !           236:                warn ("%s", file);
        !           237:                rval = 1;
        !           238:        }
        !           239: }
        !           240:
        !           241:
        !           242: void
        !           243: print_counts (lines, words, chars, name)
        !           244:        long lines;
        !           245:        long words;
        !           246:        long chars;
        !           247:        char *name;
        !           248: {
        !           249:
        !           250:        if (doline)
        !           251:                printf(" %7ld", lines);
        !           252:        if (doword)
        !           253:                printf(" %7ld", words);
        !           254:        if (dochar)
        !           255:                printf(" %7ld", chars);
        !           256:
        !           257:        printf (" %s\n", name);
        !           258: }