X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fsort.c;h=127d683198039470a1623aeff360a8924d8b5476;hb=ee512a3f8620ab535716b8aa016b33610010920c;hp=f3f9fca1d671a9b249a6c97b4f1b8165edfc85c7;hpb=019513a59ffd966cca51d6616757295a46869e4a;p=oweals%2Fbusybox.git diff --git a/coreutils/sort.c b/coreutils/sort.c index f3f9fca1d..127d68319 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -1,5 +1,5 @@ /* - * Mini find implementation for busybox + * Mini sort implementation for busybox * * * Copyright (C) 1999 by Lineo, inc. @@ -32,23 +32,26 @@ static const char sort_usage[] = "Usage: sort [OPTION]... [FILE]...\n\n" ; -/* structs ________________________________________________________________ */ +/* typedefs _______________________________________________________________ */ /* line node */ -typedef struct { - char *data; /* line data */ - struct Line *next; /* pointer to next 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 */ + int len; /* number of Lines */ + Line **sorted; /* array fed to qsort */ - Line *head; /* head of List */ - Line *current /* current Line */ + Line *head; /* head of List */ + Line *current; /* current Line */ } List; +/* comparison function */ +typedef int (Compare)(const void *, const void *); + /* methods ________________________________________________________________ */ @@ -104,11 +107,40 @@ line_release(Line *self) /* Comparison */ +/* ascii order */ static int -compare_ascii(const void *, const void *); +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 strcmp(x->data, y->data); +} + +/* numeric order */ static int -compare_numeric(const void *, const void *); +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 (xint - yint); +} /* List */ @@ -125,7 +157,7 @@ list_init(List *self) } /* for simplicity, the List gains ownership of the line */ -static void +static List * list_insert(List *self, Line *line) { if (line == NULL) { return NULL; } @@ -137,26 +169,53 @@ list_insert(List *self, Line *line) /* all subsequent insertions */ } else { - self->current->next = line; + self->current->next = line; self->current = line; } self->len++; return self; } -/* */ +/* order the list according to compare() */ static List * -list_sort(List *self); +list_sort(List *self, Compare *compare) +{ + int i; + Line *line; + + /* mallocate array of Line*s */ + self->sorted = (Line **) malloc(self->len * sizeof(Line*)); + if (self->sorted == NULL) { return NULL; } + + /* 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 List * +static void list_release(List *self) { Line *i; @@ -166,9 +225,8 @@ list_release(List *self) while (i) { die = i; i = die->next; - line_delete(die); + line_release(die); } - return self; /* bad poetry? */ } @@ -182,16 +240,24 @@ list_release(List *self) int sort_main(int argc, char **argv) { - int i; - char opt; + int i; + char opt; + List list; + Line *l; + Compare *compare; - /* default behaviour */ + /* 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 'g': + compare = compare_numeric; + break; case 'h': usage(sort_usage); break; @@ -206,7 +272,12 @@ sort_main(int argc, char **argv) /* go through remaining args (if any) */ if (i >= argc) { - + while ( (l = line_newFromFile(stdin))) { + list_insert(&list, l); + } + list_sort(&list, compare); + list_writeToFile(&list, stdout); + list_release(&list); } else { for ( ; i < argc; i++) { } @@ -215,4 +286,24 @@ sort_main(int argc, char **argv) exit(0); } -/* $Id: sort.c,v 1.3 1999/12/22 17:57:31 beppu Exp $ */ +/* $Id: sort.c,v 1.7 1999/12/23 00:02:49 beppu Exp $ */ +/* + * $Log: sort.c,v $ + * Revision 1.7 1999/12/23 00:02:49 beppu + * implemented numeric sort (sort -g) + * + * Revision 1.6 1999/12/22 23:02:12 beppu + * oops.. qsort(2) misunderstanding on my part. + * it's ok, now. + * + * Revision 1.5 1999/12/22 22:27:01 beppu + * playing w/ $Log: sort.c,v $ + * playing w/ Revision 1.7 1999/12/23 00:02:49 beppu + * playing w/ implemented numeric sort (sort -g) + * playing w/ + * playing w/ Revision 1.6 1999/12/22 23:02:12 beppu + * playing w/ oops.. qsort(2) misunderstanding on my part. + * playing w/ it's ok, now. + * playing w/ + * + */