/* expand - convert tabs to spaces
 * unexpand - convert spaces to tabs
 *
 * Copyright (C) 89, 91, 1995-2006 Free Software Foundation, Inc.
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 *
 * David MacKenzie <djm@gnu.ai.mit.edu>
 *
 * Options for expand:
 * -t num  --tabs=NUM      Convert tabs to num spaces (default 8 spaces).
 * -i      --initial       Only convert initial tabs on each line to spaces.
 *
 * Options for unexpand:
 * -a      --all           Convert all blanks, instead of just initial blanks.
 * -f      --first-only    Convert only leading sequences of blanks (default).
 * -t num  --tabs=NUM      Have tabs num characters apart instead of 8.
 *
 *  Busybox version (C) 2007 by Tito Ragusa <farmatito@tiscali.it>
 *
 *  Caveat: this versions of expand and unexpand don't accept tab lists.
 */

#include "libbb.h"

enum {
	OPT_INITIAL     = 1 << 0,
	OPT_TABS        = 1 << 1,
	OPT_ALL         = 1 << 2,
};

static void xputchar(char c)
{
	if (putchar(c) < 0)
		bb_error_msg_and_die(bb_msg_write_error);
}

#if ENABLE_EXPAND
static void expand(FILE *file, unsigned tab_size, unsigned opt)
{
	char *line;
	char *ptr;
	int convert;
	int pos;

	/* Increment tab_size by 1 locally.*/
	tab_size++;

	while ((line = xmalloc_fgets(file)) != NULL) {
		convert = 1;
		pos = 0;
		ptr = line;
		while (*line) {
			pos++;
			if (*line == '\t' && convert) {
				for (; pos < tab_size; pos++) {
					xputchar(' ');
				}
			} else {
				if ((opt & OPT_INITIAL) && !isblank(*line)) {
					convert = 0;
				}
				xputchar(*line);
			}
			if (pos == tab_size) {
				pos = 0;
			}
			line++;
		}
		free(ptr);
	}
}
#endif

#if ENABLE_UNEXPAND
static void unexpand(FILE *file, unsigned int tab_size, unsigned opt)
{
	char *line;
	char *ptr;
	int convert;
	int pos;
	int i = 0;
	int column = 0;

	while ((line = xmalloc_fgets(file)) != NULL) {
		convert = 1;
		pos = 0;
		ptr = line;
		while (*line) {
			while ((*line == ' ' || *line == '\t') && convert) {
				pos += (*line == ' ') ? 1 : tab_size;
				line++;
				column++;
				if ((opt & OPT_ALL) && column == tab_size) {
					column = 0;
					goto put_tab;
				}
			}
			if (pos) {
				i = pos / tab_size;
				if (i) {
					for (; i > 0; i--) {
 put_tab:
						xputchar('\t');
					}
				} else {
					for (i = pos % tab_size; i > 0; i--) {
						xputchar(' ');
					}
				}
				pos = 0;
			} else {
				if (opt & OPT_INITIAL) {
					convert = 0;
				}
				if (opt & OPT_ALL) {
					column++;
				}
				xputchar(*line);
				line++;
			}
		}
		free(ptr);
	}
}
#endif

int expand_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int expand_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
	/* Default 8 spaces for 1 tab */
	const char *opt_t = "8";
	FILE *file;
	unsigned tab_size;
	unsigned opt;
	int exit_status = EXIT_SUCCESS;

#if ENABLE_FEATURE_EXPAND_LONG_OPTIONS
	static const char expand_longopts[] ALIGN1 =
		/* name, has_arg, val */
		"initial\0"          No_argument       "i"
		"tabs\0"             Required_argument "t"
	;
#endif
#if ENABLE_FEATURE_UNEXPAND_LONG_OPTIONS
	static const char unexpand_longopts[] ALIGN1 =
		/* name, has_arg, val */
		"first-only\0"       No_argument       "i"
		"tabs\0"             Required_argument "t"
		"all\0"              No_argument       "a"
	;
#endif

	if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e')) {
		USE_FEATURE_EXPAND_LONG_OPTIONS(applet_long_options = expand_longopts);
		opt = getopt32(argv, "it:", &opt_t);
	} else if (ENABLE_UNEXPAND) {
		USE_FEATURE_UNEXPAND_LONG_OPTIONS(applet_long_options = unexpand_longopts);
		/* -t NUM sets also -a */
		opt_complementary = "ta";
		opt = getopt32(argv, "ft:a", &opt_t);
		/* -f --first-only is the default */
		if (!(opt & OPT_ALL)) opt |= OPT_INITIAL;
	}
	tab_size = xatou_range(opt_t, 1, UINT_MAX);

	argv += optind;

	/* If no args are given, read from stdin */
	if (!*argv) {
		*--argv = (char*)bb_msg_standard_input;
		goto use_stdin;
	}

	do {
		if (NOT_LONE_CHAR(*argv, '-')) {
			file = fopen_or_warn(*argv, "r");
			if (!file) {
				exit_status = EXIT_FAILURE;
				continue;
			}
		} else {
 use_stdin:
			file = stdin;
		}

		if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e'))
			USE_EXPAND(expand(file, tab_size, opt));
		else if (ENABLE_UNEXPAND)
			USE_UNEXPAND(unexpand(file, tab_size, opt));

		/* Check and close the file */
		/* We do want all of them to execute, thus | instead of || */
		if (ferror(file) | fclose_if_not_stdin(file)) {
			bb_simple_perror_msg(*argv);
			exit_status = EXIT_FAILURE;
		}
		/* If stdin also clear EOF */
		if (file == stdin)
			clearerr(file);
	} while (*++argv);

	/* Now close stdin also */
	/* (if we didn't read from it, it's a no-op) */
	if (fclose(stdin))
		bb_perror_msg_and_die(bb_msg_standard_input);

	fflush_stdout_and_exit(exit_status);
}
