/* vi: set sw=4 ts=4: */
/*
 * wc implementation for busybox
 *
 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.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
 *
 */

/* BB_AUDIT SUSv3 _NOT_ compliant -- option -m is not currently supported. */
/* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */

/* Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
 *
 * Rewritten to fix a number of problems and do some size optimizations.
 * Problems in the previous busybox implementation (besides bloat) included: 
 *  1) broken 'wc -c' optimization (read note below)
 *  2) broken handling of '-' args
 *  3) no checking of ferror on EOF returns
 *  4) isprint() wasn't considered when word counting.
 *
 * TODO:
 *
 * When locale support is enabled, count multibyte chars in the '-m' case.
 *
 * NOTES:
 *
 * The previous busybox wc attempted an optimization using stat for the
 * case of counting chars only.  I omitted that because it was broken.
 * It didn't take into account the possibility of input coming from a
 * pipe, or input from a file with file pointer not at the beginning.
 *
 * To implement such a speed optimization correctly, not only do you
 * need the size, but also the file position.  Note also that the
 * file position may be past the end of file.  Consider the example
 * (adapted from example in gnu wc.c)
 *
 *      echo hello > /tmp/testfile &&
 *      (dd ibs=1k skip=1 count=0 &> /dev/null ; wc -c) < /tmp/testfile
 *
 * for which 'wc -c' should output '0'.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "busybox.h"

#ifdef CONFIG_LOCALE_SUPPORT
#include <locale.h>
#include <ctype.h>
#define isspace_given_isprint(c) isspace(c)
#else
#undef isspace
#undef isprint
#define isspace(c) ((((c) == ' ') || (((unsigned int)((c) - 9)) <= (13 - 9))))
#define isprint(c) (((unsigned int)((c) - 0x20)) <= (0x7e - 0x20))
#define isspace_given_isprint(c) ((c) == ' ')
#endif

enum {
	WC_LINES	= 0,
	WC_WORDS	= 1,
	WC_CHARS	= 2,
	WC_LENGTH	= 3
};

/* Note: If this changes, remember to change the initialization of
 *       'name' in wc_main.  It needs to point to the terminating nul. */
static const char wc_opts[] = "lwcL";	/* READ THE WARNING ABOVE! */

enum {
	OP_INC_LINE	= 1, /* OP_INC_LINE must be 1. */
	OP_SPACE	= 2,
	OP_NEWLINE	= 4,
	OP_TAB		= 8,
	OP_NUL		= 16,
};

/* Note: If fmt_str changes, the offsets to 's' in the OUTPUT section
 *       will need to be updated. */
static const char fmt_str[] = " %7u\0 %s\n";
static const char total_str[] = "total";

int wc_main(int argc, char **argv)
{
	FILE *fp;
	const char *s;
	unsigned int *pcounts;
	unsigned int counts[4];
	unsigned int totals[4];
	unsigned int linepos;
	unsigned int u;
	int num_files = 0;
	int c;
	char status = EXIT_SUCCESS;
	char in_word;
	char print_type;
		
	print_type = bb_getopt_ulflags(argc, argv, wc_opts);
	
	if (print_type == 0) {
		print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_CHARS);
	}
	
	argv += optind;
	if (!*argv) {
		*--argv = (char *) bb_msg_standard_input;
	}
	
	memset(totals, 0, sizeof(totals));
	
	pcounts = counts;
	
	do {
		++num_files;
		if (!(fp = bb_wfopen_input(*argv))) {
			status = EXIT_FAILURE;
			continue;
		}
		
		memset(counts, 0, sizeof(counts));
		linepos = 0;
		in_word = 0;
		
		do {
			++counts[WC_CHARS];
			c = getc(fp);
			if (isprint(c)) {
				++linepos;
				if (!isspace_given_isprint(c)) {
					in_word = 1;
					continue;
				}
			} else if (((unsigned int)(c - 9)) <= 4) {
				/* \t  9
				 * \n 10
				 * \v 11
				 * \f 12
				 * \r 13
				 */
				if (c == '\t') {
					linepos = (linepos | 7) + 1;
				} else {			/* '\n', '\r', '\f', or '\v' */
				DO_EOF:
					if (linepos > counts[WC_LENGTH]) {
						counts[WC_LENGTH] = linepos;
					}
					if (c == '\n') {
						++counts[WC_LINES];
					}
					if (c != '\v') {
						linepos = 0;
					}
				}
			} else if (c == EOF) {
				if (ferror(fp)) {
					bb_perror_msg("%s", *argv);
					status = EXIT_FAILURE;
				}
				--counts[WC_CHARS];
				goto DO_EOF;		/* Treat an EOF as '\r'. */
			} else {
				continue;
			}
			
			counts[WC_WORDS] += in_word;
			in_word = 0;
			if (c == EOF) {
				break;
			}
		} while (1);
		
		if (totals[WC_LENGTH] < counts[WC_LENGTH]) {
			totals[WC_LENGTH] = counts[WC_LENGTH];
		}
		totals[WC_LENGTH] -= counts[WC_LENGTH];
		
		bb_fclose_nonstdin(fp);
		
	OUTPUT:
		s = fmt_str + 1;			/* Skip the leading space on 1st pass. */
		u = 0;
		do {
			if (print_type & (1 << u)) {
				bb_printf(s, pcounts[u]);
				s = fmt_str;		/* Ok... restore the leading space. */
			}
			totals[u] += pcounts[u];
		} while (++u < 4);
		
		s += 8;						/* Set the format to the empty string. */
		
		if (*argv != bb_msg_standard_input) {
			s -= 3;					/* We have a name, so do %s conversion. */
		}
		bb_printf(s, *argv);
		
	} while (*++argv);
	
	/* If more than one file was processed, we want the totals.  To save some
	 * space, we set the pcounts ptr to the totals array.  This has the side
	 * effect of trashing the totals array after outputting it, but that's
	 * irrelavent since we no longer need it. */
	if (num_files > 1) {
		num_files = 0;				/* Make sure we don't get here again. */
		*--argv = (char *) total_str;
		pcounts = totals;
		goto OUTPUT;
	}
	
	bb_fflush_stdout_and_exit(status);
}
