blob: 728d725a3bc9040d0f2f214777a55c3c62982935 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Erik Andersen31638212000-01-15 22:28:50 +00002/*
3 * Mini wc implementation for busybox
4 *
Eric Andersen1b355eb2000-09-05 17:37:48 +00005 * Copyright (C) 2000 Edward Betts <edward@debian.org>
Erik Andersen31638212000-01-15 22:28:50 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
Erik Andersen31638212000-01-15 22:28:50 +000023#include <stdio.h>
Mark Whitley39505962000-07-20 00:08:10 +000024#include <getopt.h>
Eric Anderseneba8ed72001-03-09 14:36:42 +000025#include <string.h>
Eric Andersened3ef502001-01-27 08:24:39 +000026#include <stdlib.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000027#include "busybox.h"
Erik Andersen31638212000-01-15 22:28:50 +000028
Erik Andersen31638212000-01-15 22:28:50 +000029static int total_lines, total_words, total_chars, max_length;
Glenn L McGrath02d090d2001-11-21 09:17:00 +000030//static int print_lines, print_words, print_chars, print_length;
31static char print_type = 0;
32enum print_e {
33 print_lines = 1,
34 print_words = 2,
35 print_chars = 4,
36 print_length = 8
37};
Erik Andersen31638212000-01-15 22:28:50 +000038
Eric Andersen3e6ff902001-03-09 21:24:12 +000039static void print_counts(int lines, int words, int chars, int length,
40 const char *name)
Erik Andersene49d5ec2000-02-08 19:58:47 +000041{
Glenn L McGrath02d090d2001-11-21 09:17:00 +000042 if (print_type & print_lines) {
Glenn L McGrath1477ad82001-11-21 09:58:29 +000043 printf("%7d ", lines);
Erik Andersen31638212000-01-15 22:28:50 +000044 }
Glenn L McGrath02d090d2001-11-21 09:17:00 +000045 if (print_type & print_words) {
Glenn L McGrath1477ad82001-11-21 09:58:29 +000046 printf("%7d ", words);
Erik Andersen31638212000-01-15 22:28:50 +000047 }
Glenn L McGrath02d090d2001-11-21 09:17:00 +000048 if (print_type & print_chars) {
Glenn L McGrath1477ad82001-11-21 09:58:29 +000049 printf("%7d ", chars);
Erik Andersen31638212000-01-15 22:28:50 +000050 }
Glenn L McGrath1477ad82001-11-21 09:58:29 +000051 if (print_type & print_length) {
52 printf("%7d ", length);
53 }
54 if (*name) {
55 printf("%s", name);
56 }
Erik Andersene49d5ec2000-02-08 19:58:47 +000057 putchar('\n');
Erik Andersen31638212000-01-15 22:28:50 +000058}
59
Erik Andersene49d5ec2000-02-08 19:58:47 +000060static void wc_file(FILE * file, const char *name)
Erik Andersen31638212000-01-15 22:28:50 +000061{
62 int lines, words, chars, length;
63 int in_word = 0, linepos = 0;
64 int c;
Erik Andersene49d5ec2000-02-08 19:58:47 +000065
Erik Andersen31638212000-01-15 22:28:50 +000066 lines = words = chars = length = 0;
67 while ((c = getc(file)) != EOF) {
68 chars++;
69 switch (c) {
Erik Andersene49d5ec2000-02-08 19:58:47 +000070 case '\n':
71 lines++;
72 case '\r':
73 case '\f':
74 if (linepos > length)
75 length = linepos;
76 linepos = 0;
77 goto word_separator;
78 case '\t':
79 linepos += 8 - (linepos % 8);
80 goto word_separator;
81 case ' ':
82 linepos++;
83 case '\v':
84 word_separator:
85 if (in_word) {
86 in_word = 0;
87 words++;
88 }
89 break;
90 default:
91 linepos++;
92 in_word = 1;
93 break;
Erik Andersen31638212000-01-15 22:28:50 +000094 }
95 }
96 if (linepos > length)
97 length = linepos;
98 if (in_word)
99 words++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000100 print_counts(lines, words, chars, length, name);
Erik Andersen31638212000-01-15 22:28:50 +0000101 total_lines += lines;
102 total_words += words;
103 total_chars += chars;
104 if (length > max_length)
105 max_length = length;
106 fclose(file);
107 fflush(stdout);
108}
109
Erik Andersene49d5ec2000-02-08 19:58:47 +0000110int wc_main(int argc, char **argv)
111{
Erik Andersen31638212000-01-15 22:28:50 +0000112 FILE *file;
Mark Whitley39505962000-07-20 00:08:10 +0000113 unsigned int num_files_counted = 0;
Eric Andersen7a86e612000-10-09 18:21:44 +0000114 int opt, status = EXIT_SUCCESS;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000115
Erik Andersen31638212000-01-15 22:28:50 +0000116 total_lines = total_words = total_chars = max_length = 0;
Erik Andersen31638212000-01-15 22:28:50 +0000117
Mark Whitley39505962000-07-20 00:08:10 +0000118 while ((opt = getopt(argc, argv, "clLw")) > 0) {
119 switch (opt) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000120 case 'c':
Glenn L McGrath02d090d2001-11-21 09:17:00 +0000121 print_type |= print_chars;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000122 break;
123 case 'l':
Glenn L McGrath02d090d2001-11-21 09:17:00 +0000124 print_type |= print_lines;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000125 break;
126 case 'L':
Glenn L McGrath02d090d2001-11-21 09:17:00 +0000127 print_type |= print_length;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000128 break;
129 case 'w':
Glenn L McGrath02d090d2001-11-21 09:17:00 +0000130 print_type |= print_words;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000131 break;
132 default:
Eric Andersen67991cf2001-02-14 21:23:06 +0000133 show_usage();
Erik Andersen31638212000-01-15 22:28:50 +0000134 }
135 }
136
Glenn L McGrath02d090d2001-11-21 09:17:00 +0000137 if (print_type == 0) {
138 print_type = print_lines | print_words | print_chars;
139 }
Erik Andersen31638212000-01-15 22:28:50 +0000140
Mark Whitley39505962000-07-20 00:08:10 +0000141 if (argv[optind] == NULL || strcmp(argv[optind], "-") == 0) {
Glenn L McGrath1477ad82001-11-21 09:58:29 +0000142 wc_file(stdin, NULL);
Matt Kraaibbaef662000-09-27 02:43:35 +0000143 return EXIT_SUCCESS;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000144 } else {
Mark Whitley39505962000-07-20 00:08:10 +0000145 while (optind < argc) {
Glenn L McGrath02d090d2001-11-21 09:17:00 +0000146 file = wfopen(argv[optind], "r");
147 if (file != NULL)
Eric Andersen7a86e612000-10-09 18:21:44 +0000148 wc_file(file, argv[optind]);
149 else
150 status = EXIT_FAILURE;
Mark Whitley39505962000-07-20 00:08:10 +0000151 num_files_counted++;
152 optind++;
Erik Andersen31638212000-01-15 22:28:50 +0000153 }
Mark Whitley39505962000-07-20 00:08:10 +0000154 }
155
156 if (num_files_counted > 1)
Erik Andersene49d5ec2000-02-08 19:58:47 +0000157 print_counts(total_lines, total_words, total_chars,
158 max_length, "total");
Mark Whitley39505962000-07-20 00:08:10 +0000159
Eric Andersen7a86e612000-10-09 18:21:44 +0000160 return status;
Erik Andersen31638212000-01-15 22:28:50 +0000161}