/* vi: set sw=4 ts=4: */
/*
 * Mini sort implementation for busybox
 *
 *
 * Copyright (C) 1999,2000 by Lineo, inc.
 * Written by John Beppu <beppu@lineo.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 "busybox.h"
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>

#ifdef BB_FEATURE_SORT_REVERSE
#define APPLY_REVERSE(x) (reverse ? -(x) : (x))
static int reverse = 0;
#else
#define APPLY_REVERSE(x) (x)
#endif

/* typedefs _______________________________________________________________ */

/* line node */
typedef struct Line {
	char *data;					/* line data */
	struct Line *next;			/* pointer to next line node */
} Line;

/* singly-linked list of lines */
typedef struct {
	int len;					/* number of Lines */
	Line **sorted;				/* array fed to qsort */
	Line *head;					/* head of List */
	Line *current;				/* current Line */
} List;

/* comparison function */
typedef int (Compare) (const void *, const void *);


/* methods ________________________________________________________________ */

static const int max = 1024;

/* mallocate Line */
static Line *line_alloc()
{
	Line *self;
	self = xmalloc(1 * sizeof(Line));
	return self;
}

/* Construct Line from FILE* */
static Line *line_newFromFile(FILE * src)
{
	Line *self;
	char *cstring = NULL;

	if ((cstring = get_line_from_file(src))) {
		self = line_alloc();
		self->data = cstring;
		self->next = NULL;
		return self;
	}
	return NULL;
}

/* Line destructor */
static Line *line_release(Line * self)
{
	if (self->data) {
		free(self->data);
		free(self);
	}
	return self;
}


/* Comparison */

/* ascii order */
static int compare_ascii(const void *a, const void *b)
{
	Line **doh;
	Line *x, *y;

	doh = (Line **) a;
	x = *doh;
	doh = (Line **) b;
	y = *doh;

	// fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data);
	return APPLY_REVERSE(strcmp(x->data, y->data));
}

/* numeric order */
static int compare_numeric(const void *a, const void *b)
{
	Line **doh;
	Line *x, *y;
	int xint, yint;

	doh = (Line **) a;
	x = *doh;
	doh = (Line **) b;
	y = *doh;

	xint = strtoul(x->data, NULL, 10);
	yint = strtoul(y->data, NULL, 10);

	return APPLY_REVERSE(xint - yint);
}


/* List */

/* */
static List *list_init(List * self)
{
	self->len = 0;
	self->sorted = NULL;
	self->head = NULL;
	self->current = NULL;
	return self;
}

/* for simplicity, the List gains ownership of the line */
static List *list_insert(List * self, Line * line)
{
	if (line == NULL) {
		return NULL;
	}

	/* first insertion */
	if (self->head == NULL) {
		self->head = line;
		self->current = line;

	/* all subsequent insertions */
	} else {
		self->current->next = line;
		self->current = line;
	}
	self->len++;
	return self;
}

/* order the list according to compare() */
static List *list_sort(List * self, Compare * compare)
{
	int i;
	Line *line;

	/* mallocate array of Line*s */
	self->sorted = (Line **) xmalloc(self->len * sizeof(Line *));

	/* fill array w/ List's contents */
	i = 0;
	line = self->head;
	while (line) {
		self->sorted[i++] = line;
		line = line->next;
	}

	/* apply qsort */
	qsort(self->sorted, self->len, sizeof(Line *), compare);
	return self;
}

/* precondition:  list must be sorted */
static List *list_writeToFile(List * self, FILE * dst)
{
	int i;
	Line **line = self->sorted;

	if (self->sorted == NULL) {
		return NULL;
	}
	for (i = 0; i < self->len; i++) {
		fprintf(dst, "%s", line[i]->data);
	}
	return self;
}

/* deallocate */
static void list_release(List * self)
{
	Line *i;
	Line *die;

	i = self->head;
	while (i) {
		die = i;
		i = die->next;
		line_release(die);
	}
}



int sort_main(int argc, char **argv)
{
	int i;
	char opt;
	List list;
	Line *l;
	Compare *compare;

	/* init */
	compare = compare_ascii;
	list_init(&list);

	/* parse argv[] */
	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			opt = argv[i][1];
			switch (opt) {
			case 'h':
				usage(sort_usage);
				break;
			case 'n':
				/* numeric comparison */
				compare = compare_numeric;
				break;
#ifdef BB_FEATURE_SORT_REVERSE
			case 'r':
				/* reverse */
				reverse = 1;
				break;
#endif
			default:
				errorMsg("invalid option -- %c\n", opt);
				usage(sort_usage);
			}
		} else {
			break;
		}
	}

	/* this could be factored better */

	/* work w/ stdin */
	if (i >= argc) {
		while ((l = line_newFromFile(stdin))) {
			list_insert(&list, l);
		}
		list_sort(&list, compare);
		list_writeToFile(&list, stdout);
		list_release(&list);

		/* work w/ what's left in argv[] */
	} else {
		FILE *src;

		for (; i < argc; i++) {
			src = fopen(argv[i], "r");
			if (src == NULL) {
				break;
			}
			while ((l = line_newFromFile(src))) {
				list_insert(&list, l);
			}
			fclose(src);
		}
		list_sort(&list, compare);
		list_writeToFile(&list, stdout);
		list_release(&list);
	}

	return(0);
}

/* $Id: sort.c,v 1.22 2000/09/25 21:45:58 andersen Exp $ */
