1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1992-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * *
20da2e3ebdSchin ***********************************************************************/
21da2e3ebdSchin #pragma prototyped
22da2e3ebdSchin /*
23da2e3ebdSchin * David Korn
24da2e3ebdSchin * AT&T Bell Laboratories
25da2e3ebdSchin *
26da2e3ebdSchin * count the number of bytes, words, and lines in a file
27da2e3ebdSchin */
28da2e3ebdSchin
29da2e3ebdSchin static const char usage[] =
30*3e14f97fSRoger A. Faulkner "[-?\n@(#)$Id: wc (AT&T Research) 2009-11-28 $\n]"
31da2e3ebdSchin USAGE_LICENSE
32da2e3ebdSchin "[+NAME?wc - print the number of bytes, words, and lines in files]"
33da2e3ebdSchin "[+DESCRIPTION?\bwc\b reads one or more input files and, by default, "
34da2e3ebdSchin "for each file writes a line containing the number of newlines, "
35da2e3ebdSchin "\aword\as, and bytes contained in each file followed by the "
36da2e3ebdSchin "file name to standard output in that order. A \aword\a is "
37da2e3ebdSchin "defined to be a non-zero length string delimited by \bisspace\b(3) "
38da2e3ebdSchin "characters.]"
39da2e3ebdSchin "[+?If more than one file is specified, \bwc\b writes a total count "
40da2e3ebdSchin "for all of the named files with \btotal\b written instead "
41da2e3ebdSchin "of the file name.]"
42da2e3ebdSchin "[+?By default, \bwc\b writes all three counts. Options can specified "
43da2e3ebdSchin "so that only certain counts are written. The options \b-c\b "
44da2e3ebdSchin "and \b-m\b are mutually exclusive.]"
45da2e3ebdSchin "[+?If no \afile\a is given, or if the \afile\a is \b-\b, \bwc\b "
46da2e3ebdSchin "reads from standard input and no filename is written to standard "
47da2e3ebdSchin "output. The start of the file is defined as the current offset.]"
48da2e3ebdSchin "[l:lines?List the line counts.]"
49da2e3ebdSchin "[w:words?List the word counts.]"
50da2e3ebdSchin "[c:bytes|chars:chars?List the byte counts.]"
51da2e3ebdSchin "[m|C:multibyte-chars?List the character counts.]"
52da2e3ebdSchin "[q:quiet?Suppress invalid multibyte character warnings.]"
5334f9b3eeSRoland Mainz "[L:longest-line|max-line-length?List the longest line length; the newline,"
5434f9b3eeSRoland Mainz "if any, is not counted in the length.]"
5534f9b3eeSRoland Mainz "[N!:utf8?For \bUTF-8\b locales \b--noutf8\b disables \bUTF-8\b "
5634f9b3eeSRoland Mainz "optimzations and relies on the native \bmbtowc\b(3).]"
57da2e3ebdSchin "\n"
58da2e3ebdSchin "\n[file ...]\n"
59da2e3ebdSchin "\n"
60da2e3ebdSchin "[+EXIT STATUS?]{"
61da2e3ebdSchin "[+0?All files processed successfully.]"
62da2e3ebdSchin "[+>0?One or more files failed to open or could not be read.]"
63da2e3ebdSchin "}"
64da2e3ebdSchin "[+SEE ALSO?\bcat\b(1), \bisspace\b(3)]"
65da2e3ebdSchin ;
66da2e3ebdSchin
67da2e3ebdSchin
68da2e3ebdSchin #include <cmd.h>
69da2e3ebdSchin #include <wc.h>
70da2e3ebdSchin #include <ls.h>
71da2e3ebdSchin
72da2e3ebdSchin #define ERRORMAX 125
73da2e3ebdSchin
printout(register Wc_t * wp,register char * name,register int mode)74da2e3ebdSchin static void printout(register Wc_t *wp, register char *name,register int mode)
75da2e3ebdSchin {
76da2e3ebdSchin if (mode&WC_LINES)
77da2e3ebdSchin sfprintf(sfstdout," %7I*d",sizeof(wp->lines),wp->lines);
78da2e3ebdSchin if (mode&WC_WORDS)
79da2e3ebdSchin sfprintf(sfstdout," %7I*d",sizeof(wp->words),wp->words);
80da2e3ebdSchin if (mode&WC_CHARS)
81da2e3ebdSchin sfprintf(sfstdout," %7I*d",sizeof(wp->chars),wp->chars);
82da2e3ebdSchin if (mode&WC_LONGEST)
83da2e3ebdSchin sfprintf(sfstdout," %7I*d",sizeof(wp->chars),wp->longest);
84da2e3ebdSchin if (name)
85da2e3ebdSchin sfprintf(sfstdout," %s",name);
86da2e3ebdSchin sfputc(sfstdout,'\n');
87da2e3ebdSchin }
88da2e3ebdSchin
89da2e3ebdSchin int
b_wc(int argc,register char ** argv,void * context)90da2e3ebdSchin b_wc(int argc,register char **argv, void* context)
91da2e3ebdSchin {
92da2e3ebdSchin register char *cp;
93da2e3ebdSchin register int mode=0, n;
94da2e3ebdSchin register Wc_t *wp;
95da2e3ebdSchin Sfio_t *fp;
96da2e3ebdSchin Sfoff_t tlines=0, twords=0, tchars=0;
97da2e3ebdSchin struct stat statb;
98da2e3ebdSchin
99da2e3ebdSchin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
10034f9b3eeSRoland Mainz for (;;)
10134f9b3eeSRoland Mainz {
10234f9b3eeSRoland Mainz switch (optget(argv, usage))
103da2e3ebdSchin {
104da2e3ebdSchin case 'c':
105da2e3ebdSchin mode |= WC_CHARS;
10634f9b3eeSRoland Mainz continue;
107da2e3ebdSchin case 'l':
108da2e3ebdSchin mode |= WC_LINES;
10934f9b3eeSRoland Mainz continue;
110da2e3ebdSchin case 'L':
111da2e3ebdSchin mode |= WC_LONGEST;
11234f9b3eeSRoland Mainz continue;
11334f9b3eeSRoland Mainz case 'N':
11434f9b3eeSRoland Mainz if (!opt_info.num)
11534f9b3eeSRoland Mainz mode |= WC_NOUTF8;
11634f9b3eeSRoland Mainz continue;
117da2e3ebdSchin case 'm':
118da2e3ebdSchin case 'C':
119da2e3ebdSchin mode |= WC_MBYTE;
12034f9b3eeSRoland Mainz continue;
121da2e3ebdSchin case 'q':
122da2e3ebdSchin mode |= WC_QUIET;
12334f9b3eeSRoland Mainz continue;
124da2e3ebdSchin case 'w':
125da2e3ebdSchin mode |= WC_WORDS;
12634f9b3eeSRoland Mainz continue;
127da2e3ebdSchin case ':':
128da2e3ebdSchin error(2, "%s", opt_info.arg);
129da2e3ebdSchin break;
130da2e3ebdSchin case '?':
131da2e3ebdSchin error(ERROR_usage(2), "%s", opt_info.arg);
132da2e3ebdSchin break;
133da2e3ebdSchin }
13434f9b3eeSRoland Mainz break;
13534f9b3eeSRoland Mainz }
136da2e3ebdSchin argv += opt_info.index;
137da2e3ebdSchin if (error_info.errors)
138da2e3ebdSchin error(ERROR_usage(2), "%s", optusage(NiL));
139da2e3ebdSchin if (mode&WC_MBYTE)
140da2e3ebdSchin {
141da2e3ebdSchin if (mode&WC_CHARS)
142da2e3ebdSchin error(2, "-c and -C are mutually exclusive");
143da2e3ebdSchin if (!mbwide())
144da2e3ebdSchin mode &= ~WC_MBYTE;
14534f9b3eeSRoland Mainz mode |= WC_CHARS;
146da2e3ebdSchin }
147da2e3ebdSchin if (!(mode&(WC_WORDS|WC_CHARS|WC_LINES|WC_MBYTE|WC_LONGEST)))
148da2e3ebdSchin mode |= (WC_WORDS|WC_CHARS|WC_LINES);
149da2e3ebdSchin if (!(wp = wc_init(mode)))
150da2e3ebdSchin error(3,"internal error");
151da2e3ebdSchin if (cp = *argv)
152da2e3ebdSchin argv++;
15334f9b3eeSRoland Mainz n = 0;
154da2e3ebdSchin do
155da2e3ebdSchin {
156da2e3ebdSchin if (!cp || streq(cp,"-"))
157da2e3ebdSchin fp = sfstdin;
158da2e3ebdSchin else if (!(fp = sfopen(NiL,cp,"r")))
159da2e3ebdSchin {
160da2e3ebdSchin error(ERROR_system(0),"%s: cannot open",cp);
161da2e3ebdSchin continue;
162da2e3ebdSchin }
163da2e3ebdSchin if (cp)
164da2e3ebdSchin n++;
165da2e3ebdSchin if (!(mode&(WC_WORDS|WC_LINES|WC_MBYTE|WC_LONGEST)) && fstat(sffileno(fp),&statb)>=0
166da2e3ebdSchin && S_ISREG(statb.st_mode))
167da2e3ebdSchin {
168da2e3ebdSchin wp->chars = statb.st_size - lseek(sffileno(fp),0L,1);
169da2e3ebdSchin lseek(sffileno(fp),0L,2);
170da2e3ebdSchin }
171da2e3ebdSchin else
172da2e3ebdSchin wc_count(wp, fp, cp);
173da2e3ebdSchin if (fp!=sfstdin)
174da2e3ebdSchin sfclose(fp);
175da2e3ebdSchin tchars += wp->chars;
176da2e3ebdSchin twords += wp->words;
177da2e3ebdSchin tlines += wp->lines;
178da2e3ebdSchin printout(wp,cp,mode);
17934f9b3eeSRoland Mainz } while (cp= *argv++);
180da2e3ebdSchin if (n > 1)
181da2e3ebdSchin {
182da2e3ebdSchin wp->lines = tlines;
183da2e3ebdSchin wp->chars = tchars;
184da2e3ebdSchin wp->words = twords;
185da2e3ebdSchin printout(wp,"total",mode);
186da2e3ebdSchin }
18734f9b3eeSRoland Mainz return error_info.errors<ERRORMAX?error_info.errors:ERRORMAX;
188da2e3ebdSchin }
189