/*
 * Mini wc implementation for busybox
 *
 * by Edward Betts <edward@debian.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include "internal.h"
#include <stdio.h>

static const char wc_usage[] = "wc [OPTION]... [FILE]...\n\n"
"Print line, word, and byte counts for each FILE, and a total line if\n"
"more than one FILE is specified.  With no FILE, read standard input.\n"
"\t-c\tprint the byte counts\n"
"\t-l\tprint the newline counts\n"
"\t-L\tprint the length of the longest line\n"
"\t-w\tprint the word counts\n";

static int total_lines, total_words, total_chars, max_length;
static int print_lines, print_words, print_chars, print_length;

void print_counts (int lines, int words, int chars, int length, 
		const char *name) {
	char const *space = "";
	if (print_lines) {
		printf ("%7d", lines);
		space = " ";
	}
	if (print_words) {
		printf ("%s%7d", space, words);
		space = " ";
	}
	if (print_chars) {
		printf ("%s%7d", space, chars);
		space = " ";
	}
	if (print_length)
		printf ("%s%7d", space, length);
	if (*name)
		printf (" %s", name);
	putchar ('\n');
}

static void wc_file(FILE *file, const char *name) 
{
	int lines, words, chars, length;
	int in_word = 0, linepos = 0;
	int c;
	lines = words = chars = length = 0;
	while ((c = getc(file)) != EOF) {
		chars++;
		switch (c) {
			case '\n': 
				lines++;
			case '\r':
			case '\f': 
				if (linepos > length)
					length = linepos;
				linepos = 0;
				goto word_separator;
			case '\t':
				linepos += 8 - (linepos % 8);
				goto word_separator;
			case ' ':
				linepos++;
			case '\v':
			word_separator:
				if (in_word) {
					in_word = 0;
					words++;
				}
				break;
			default:
				linepos++;
				in_word = 1;
				break;
		}
	}
	if (linepos > length)
		length = linepos;
	if (in_word)
		words++;
	print_counts (lines, words, chars, length, name);
	total_lines += lines;
	total_words += words;
	total_chars += chars;
	if (length > max_length)
		max_length = length;
	fclose(file);
	fflush(stdout);
}

int wc_main(int argc, char **argv) {
	FILE *file;
	total_lines = total_words = total_chars = max_length = 0;
	print_lines = print_words = print_chars = print_length = 0;

	while (--argc && **(++argv) == '-') {
		while (*++(*argv))
			switch (**argv) {
				case 'c':
					print_chars = 1;
					break;
				case 'l':
					print_lines = 1;
					break;
				case 'L':
					print_length = 1;
					break;
				case 'w':
					print_words = 1;
					break;
				default:
					usage (wc_usage);
			}
	}

	if (!print_lines && !print_words && !print_chars && !print_length)
		print_lines = print_words = print_chars = 1;

	if (argc == 0) {
		wc_file(stdin, "");
		exit(TRUE);
	}
	else if (argc == 1) {
		file = fopen(*argv, "r");
		if (file == NULL) {
			perror(*argv);
			exit(FALSE);
		}
		wc_file(file, *argv);
	}
	else {
		while (argc-- > 0 && *argv != '\0' && strlen(*argv)) {
			file = fopen(*argv, "r");
			if (file == NULL) {
				perror(*argv);
				exit(FALSE);
			}
			wc_file(file, *argv);
			argv++;
		}
		print_counts (total_lines, total_words, total_chars, 
				max_length, "total");
	}
	exit(TRUE);
}
