1 /* vi: set sw=4 ts=4: */
3 * Mini sort implementation for busybox
6 * Copyright (C) 1999 by Lineo, inc.
7 * Written by John Beppu <beppu@lineo.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <sys/types.h>
32 static const char sort_usage[] = "sort [OPTION]... [FILE]...\n\n";
34 /* typedefs _______________________________________________________________ */
38 char *data; /* line data */
39 struct Line *next; /* pointer to next line node */
42 /* singly-linked list of lines */
44 int len; /* number of Lines */
45 Line **sorted; /* array fed to qsort */
47 Line *head; /* head of List */
48 Line *current; /* current Line */
51 /* comparison function */
52 typedef int (Compare) (const void *, const void *);
55 /* methods ________________________________________________________________ */
57 static const int max = 1024;
60 static Line *line_alloc()
64 self = malloc(1 * sizeof(Line));
68 /* Initialize Line with string */
69 static Line *line_init(Line * self, const char *string)
71 self->data = malloc((strlen(string) + 1) * sizeof(char));
73 if (self->data == NULL) {
76 strcpy(self->data, string);
81 /* Construct Line from FILE* */
82 static Line *line_newFromFile(FILE * src)
87 if (fgets(buffer, max, src)) {
92 line_init(self, buffer);
99 static Line *line_release(Line * self)
112 static int compare_ascii(const void *a, const void *b)
122 // fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data);
123 return strcmp(x->data, y->data);
127 static int compare_numeric(const void *a, const void *b)
138 xint = strtoul(x->data, NULL, 10);
139 yint = strtoul(y->data, NULL, 10);
141 return (xint - yint);
148 static List *list_init(List * self)
153 self->current = NULL;
157 /* for simplicity, the List gains ownership of the line */
158 static List *list_insert(List * self, Line * line)
164 /* first insertion */
165 if (self->head == NULL) {
167 self->current = line;
169 /* all subsequent insertions */
171 self->current->next = line;
172 self->current = line;
178 /* order the list according to compare() */
179 static List *list_sort(List * self, Compare * compare)
184 /* mallocate array of Line*s */
185 self->sorted = (Line **) malloc(self->len * sizeof(Line *));
186 if (self->sorted == NULL) {
190 /* fill array w/ List's contents */
194 self->sorted[i++] = line;
199 qsort(self->sorted, self->len, sizeof(Line *), compare);
203 /* precondition: list must be sorted */
204 static List *list_writeToFile(List * self, FILE * dst)
207 Line **line = self->sorted;
209 if (self->sorted == NULL) {
212 for (i = 0; i < self->len; i++) {
213 fprintf(dst, "%s", line[i]->data);
219 static void list_release(List * self)
235 * to insert lines into
236 * then I need to sort this list
237 * and finally print it
240 int sort_main(int argc, char **argv)
249 compare = compare_ascii;
253 for (i = 1; i < argc; i++) {
254 if (argv[i][0] == '-') {
258 /* what's the diff between -g && -n? */
259 compare = compare_numeric;
265 /* what's the diff between -g && -n? */
266 compare = compare_numeric;
272 fprintf(stderr, "sort: invalid option -- %c\n", opt);
280 /* this could be factored better */
284 while ((l = line_newFromFile(stdin))) {
285 list_insert(&list, l);
287 list_sort(&list, compare);
288 list_writeToFile(&list, stdout);
291 /* work w/ what's left in argv[] */
295 for (; i < argc; i++) {
296 src = fopen(argv[i], "r");
300 while ((l = line_newFromFile(src))) {
301 list_insert(&list, l);
305 list_sort(&list, compare);
306 list_writeToFile(&list, stdout);
313 /* $Id: sort.c,v 1.11 2000/02/08 19:58:47 erik Exp $ */