/*
 * cut.c - minimalist version of cut
 *
 * Copyright (C) 1999,2000 by Lineo, inc.
 * Written by Mark Whitley <markw@lineo.com>, <markw@enol.com>
 *
 * 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* getopt */
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "internal.h"


/* globals from other files */
extern int optind;
extern char *optarg;


/* globals in this file only */
static char part = 0; /* (b)yte, (c)har, (f)ields */
static int startpos = 1;
static int endpos = -1;
static char delim = '\t'; /* delimiter, default is tab */
static unsigned int supress_non_delimited_lines = 0;


/*
 * decompose_list() - parses a list and puts values into startpos and endpos.
 * valid list formats: N, N-, N-M, -M 
 */
static void decompose_list(const char *list)
{
	unsigned int nminus = 0;
	char *ptr;

	/* the list must contain only digits and no more than one minus sign */
	for (ptr = (char *)list; *ptr; ptr++) {
		if (!isdigit(*ptr) && *ptr != '-') {
			fatalError("invalid byte or field list\n");
		}
		if (*ptr == '-') {
			nminus++;
			if (nminus > 1) {
				fatalError("invalid byte or field list\n");
			}
		}
	}

	/* handle single value 'N' case */
	if (nminus == 0) {
		startpos = strtol(list, &ptr, 10);
		if (startpos == 0) {
			fatalError("missing list of fields\n");
		}
		endpos = startpos;
	}
	/* handle multi-value cases */
	else if (nminus == 1) {
		/* handle 'N-' case */
		if (list[strlen(list) - 1] == '-') {
			startpos = strtol(list, &ptr, 10);
		}
		/* handle '-M' case */
		else if (list[0] == '-') {
			endpos = strtol(&list[1], NULL, 10);
		}
		/* handle 'N-M' case */
		else {
			startpos = strtol(list, &ptr, 10);
			endpos = strtol(ptr+1, &ptr, 10);
		}

		/* a sanity check */
		if (startpos == 0) {
			startpos = 1;
		}
	}
}


/*
 * snippy-snip
 */
static void cut_file(FILE *file)
{
	char *line;

	/* go through every line in the file */
	for (line = NULL; (line = get_line_from_file(file)) != NULL; free(line)) {

		/* cut based on chars/bytes */
		if (part == 'c' || part == 'b') {
			int i;
			/* a valid end position has been specified */
			if (endpos > 0) {
				for (i = startpos-1; i < endpos; i++) {
					fputc(line[i], stdout);
				}
				fputc('\n', stdout);
			}
			/* otherwise, just go to the end of the line */
			else {
				for (i = startpos-1; line[i]; i++) {
					fputc(line[i], stdout);
				}
			}
		} 
		/* cut based on fields */
		else if (part == 'f') {
			char *ptr;
			char *start = line;
			unsigned int delims_hit = 0;

			for (ptr = line; (ptr = strchr(ptr, delim)) != NULL; ptr++) {
				delims_hit++;
				if (delims_hit == (startpos - 1)) {
					start = ptr+1;
				}
				if (delims_hit == endpos) {
					break;
				}
			}
			/* we didn't hit any delimeters */
			if (delims_hit == 0 && !supress_non_delimited_lines) {
				fputs(line, stdout);
			}
			/* we =did= hit some delimiters */
			else if (delims_hit > 0) {
				/* we have a fixed end point */
				if (ptr) {
					while (start < ptr) {
						fputc(*start, stdout);
						start++;
					}
					fputc('\n', stdout);
				}
				/* or we're just going til the end of the line */
				else {
					while (*start) {
						fputc(*start, stdout);
						start++;
					}
				}
			}
		}
	}
}

extern int cut_main(int argc, char **argv)
{
	int opt;

	while ((opt = getopt(argc, argv, "b:c:d:f:ns")) > 0) {
		switch (opt) {
			case 'b':
			case 'c':
			case 'f':
				/* make sure they didn't ask for two types of lists */
				if (part != 0) {
					fatalError("only one type of list may be specified");
				}
				part = (char)opt;
				decompose_list(optarg);
				break;
			case 'd':
				if (strlen(optarg) > 1) {
					fatalError("the delimiter must be a single character\n");
				}
				delim = optarg[0];
				break;
			case 'n':
				/* no-op */
				break;
			case 's':
				supress_non_delimited_lines++;
				break;
		}
	}

	if (part == 0) {
		fatalError("you must specify a list of bytes, characters, or fields\n");
	}

	if (supress_non_delimited_lines && part != 'f') {
		fatalError("suppressing non-delimited lines makes sense
	only when operating on fields\n");
	}

	if (delim != '\t' && part != 'f') {
		fatalError("a delimiter may be specified only when operating on fields\n");
	}

	/* argv[(optind)..(argc-1)] should be names of file to process. If no
	 * files were specified or '-' was specified, take input from stdin.
	 * Otherwise, we process all the files specified. */
	if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
		cut_file(stdin);
	}
	else {
		int i;
		FILE *file;
		for (i = optind; i < argc; i++) {
			file = fopen(argv[i], "r");
			if (file == NULL) {
				errorMsg("%s: %s\n", argv[i], strerror(errno));
			} else {
				cut_file(file);
				fclose(file);
			}
		}
	}

	return 0;
}
