summaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorMatt Kraai <kraai@debian.org>2000-12-20 20:49:56 +0000
committerMatt Kraai <kraai@debian.org>2000-12-20 20:49:56 +0000
commit5e8c0ffb75f5578069d75988abc2657e9f2a2bc8 (patch)
tree206b720a8cd62da502baac79484a7464b8003639 /coreutils
parente75f6a972c3307881adc1bb2aacc4b1e21417883 (diff)
downloadbusybox-w32-5e8c0ffb75f5578069d75988abc2657e9f2a2bc8.tar.gz
busybox-w32-5e8c0ffb75f5578069d75988abc2657e9f2a2bc8.tar.bz2
busybox-w32-5e8c0ffb75f5578069d75988abc2657e9f2a2bc8.zip
Rewrote.
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/sort.c276
1 files changed, 37 insertions, 239 deletions
diff --git a/coreutils/sort.c b/coreutils/sort.c
index b0bf6e494..efff6b653 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -3,8 +3,7 @@
3 * Mini sort implementation for busybox 3 * Mini sort implementation for busybox
4 * 4 *
5 * 5 *
6 * Copyright (C) 1999,2000 by Lineo, inc. 6 * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
7 * Written by John Beppu <beppu@lineo.com>
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * 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 9 * it under the terms of the GNU General Public License as published by
@@ -23,267 +22,66 @@
23 */ 22 */
24 23
25#include "busybox.h" 24#include "busybox.h"
26#include <sys/types.h>
27#include <fcntl.h>
28#include <dirent.h>
29#include <stdio.h>
30#include <errno.h>
31 25
32#ifdef BB_FEATURE_SORT_REVERSE 26int compare_ascii(const void *x, const void *y)
33#define APPLY_REVERSE(x) (reverse ? -(x) : (x))
34static int reverse = 0;
35#else
36#define APPLY_REVERSE(x) (x)
37#endif
38
39/* typedefs _______________________________________________________________ */
40
41/* line node */
42typedef struct Line {
43 char *data; /* line data */
44 struct Line *next; /* pointer to next line node */
45} Line;
46
47/* singly-linked list of lines */
48typedef struct {
49 int len; /* number of Lines */
50 Line **sorted; /* array fed to qsort */
51 Line *head; /* head of List */
52 Line *current; /* current Line */
53} List;
54
55/* comparison function */
56typedef int (Compare) (const void *, const void *);
57
58
59/* methods ________________________________________________________________ */
60
61static const int max = 1024;
62
63/* mallocate Line */
64static Line *line_alloc()
65{
66 Line *self;
67 self = xmalloc(1 * sizeof(Line));
68 return self;
69}
70
71/* Construct Line from FILE* */
72static Line *line_newFromFile(FILE * src)
73{
74 Line *self;
75 char *cstring = NULL;
76
77 if ((cstring = get_line_from_file(src))) {
78 self = line_alloc();
79 self->data = cstring;
80 self->next = NULL;
81 return self;
82 }
83 return NULL;
84}
85
86/* Line destructor */
87static Line *line_release(Line * self)
88{
89 if (self->data) {
90 free(self->data);
91 free(self);
92 }
93 return self;
94}
95
96
97/* Comparison */
98
99/* ascii order */
100static int compare_ascii(const void *a, const void *b)
101{
102 Line **val;
103 Line *x, *y;
104
105 val = (Line **) a;
106 x = *val;
107 val = (Line **) b;
108 y = *val;
109
110 // fprintf(stdout, "> %p: %s< %p: %s", x, x->data, y, y->data);
111 return APPLY_REVERSE(strcmp(x->data, y->data));
112}
113
114/* numeric order */
115static int compare_numeric(const void *a, const void *b)
116{
117 Line **val;
118 Line *x, *y;
119 int xint, yint;
120
121 val = (Line **) a;
122 x = *val;
123 val = (Line **) b;
124 y = *val;
125
126 xint = strtoul(x->data, NULL, 10);
127 yint = strtoul(y->data, NULL, 10);
128
129 return APPLY_REVERSE(xint - yint);
130}
131
132
133/* List */
134
135/* */
136static List *list_init(List * self)
137{
138 self->len = 0;
139 self->sorted = NULL;
140 self->head = NULL;
141 self->current = NULL;
142 return self;
143}
144
145/* for simplicity, the List gains ownership of the line */
146static List *list_insert(List * self, Line * line)
147{
148 if (line == NULL) {
149 return NULL;
150 }
151
152 /* first insertion */
153 if (self->head == NULL) {
154 self->head = line;
155 self->current = line;
156
157 /* all subsequent insertions */
158 } else {
159 self->current->next = line;
160 self->current = line;
161 }
162 self->len++;
163 return self;
164}
165
166/* order the list according to compare() */
167static List *list_sort(List * self, Compare * compare)
168{ 27{
169 int i; 28 return strcmp(*(char **)x, *(char **)y);
170 Line *line;
171
172 /* mallocate array of Line*s */
173 self->sorted = (Line **) xmalloc(self->len * sizeof(Line *));
174
175 /* fill array w/ List's contents */
176 i = 0;
177 line = self->head;
178 while (line) {
179 self->sorted[i++] = line;
180 line = line->next;
181 }
182
183 /* apply qsort */
184 qsort(self->sorted, self->len, sizeof(Line *), compare);
185 return self;
186}
187
188/* precondition: list must be sorted */
189static List *list_writeToFile(List * self, FILE * dst)
190{
191 int i;
192 Line **line = self->sorted;
193
194 if (self->sorted == NULL) {
195 return NULL;
196 }
197 for (i = 0; i < self->len; i++) {
198 fprintf(dst, "%s", line[i]->data);
199 }
200 return self;
201} 29}
202 30
203/* deallocate */ 31int compare_numeric(const void *x, const void *y)
204static void list_release(List * self)
205{ 32{
206 Line *i; 33 return atoi(*(char **)x) - atoi(*(char **)y);
207 Line *die;
208
209 i = self->head;
210 while (i) {
211 die = i;
212 i = die->next;
213 line_release(die);
214 }
215} 34}
216 35
217
218
219int sort_main(int argc, char **argv) 36int sort_main(int argc, char **argv)
220{ 37{
221 int i; 38 FILE *fp;
222 char opt; 39 char *line, **lines = NULL;
223 List list; 40 int i, opt, nlines = 0;
224 Line *l; 41 int (*compare)(const void *, const void *) = compare_ascii;
225 Compare *compare; 42#ifdef BB_FEATURE_SORT_REVERSE
226 43 int reverse = FALSE;
227 /* init */ 44#endif
228 compare = compare_ascii;
229 list_init(&list);
230 45
231 /* parse argv[] */ 46 while ((opt = getopt(argc, argv, "nr")) != -1) {
232 for (i = 1; i < argc; i++) { 47 switch (opt) {
233 if (argv[i][0] == '-') {
234 opt = argv[i][1];
235 switch (opt) {
236 case 'h':
237 usage(sort_usage);
238 break;
239 case 'n': 48 case 'n':
240 /* numeric comparison */
241 compare = compare_numeric; 49 compare = compare_numeric;
242 break; 50 break;
243#ifdef BB_FEATURE_SORT_REVERSE 51#ifdef BB_FEATURE_SORT_REVERSE
244 case 'r': 52 case 'r':
245 /* reverse */ 53 reverse = TRUE;
246 reverse = 1;
247 break; 54 break;
248#endif 55#endif
249 default: 56 default:
250 error_msg("invalid option -- %c\n", opt);
251 usage(sort_usage); 57 usage(sort_usage);
252 }
253 } else {
254 break;
255 } 58 }
256 } 59 }
257 60
258 if (i >= argc) { 61 /* read the input */
62 for (i = optind; i == optind || i < argc; i++) {
63 if (argv[i] == NULL)
64 fp = stdin;
65 else
66 fp = xfopen(argv[i], "r");
259 67
260 /* work w/ stdin */ 68 while ((line = get_line_from_file(fp)) != NULL) {
261 while ((l = line_newFromFile(stdin))) { 69 lines = xrealloc(lines, sizeof(char *) * (nlines + 1));
262 list_insert(&list, l); 70 lines[nlines++] = line;
263 } 71 }
264
265 } else {
266
267 /* work w/ what's left in argv[] */
268 FILE *src;
269
270 for (; i < argc; i++) {
271 src = fopen(argv[i], "r");
272 if (src == NULL) {
273 break;
274 }
275 while ((l = line_newFromFile(src))) {
276 list_insert(&list, l);
277 }
278 fclose(src);
279 }
280
281 } 72 }
282 list_sort(&list, compare);
283 list_writeToFile(&list, stdout);
284 list_release(&list);
285 73
286 return(0); 74 /* sort it */
287} 75 qsort(lines, nlines, sizeof(char *), compare);
288 76
289/* $Id: sort.c,v 1.24 2000/12/07 19:56:48 markw Exp $ */ 77 /* print it */
78#ifdef BB_FEATURE_SORT_REVERSE
79 if (reverse)
80 for (i = nlines - 1; 0 <= i; i--)
81 fputs(lines[i], stdout);
82 else
83#endif
84 for (i = 0; i < nlines; i++)
85 fputs(lines[i], stdout);
86 return EXIT_SUCCESS;
87}