summaryrefslogtreecommitdiff
path: root/sort.c
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-10-05 17:05:41 -0400
committerJakob Kaivo <jkk@ung.org>2020-10-05 17:05:41 -0400
commit641fdaf04114b71ffd5c769d2943b2f84d76c42f (patch)
tree048a7446ab7935a326ca3cd2d7b27b050398e532 /sort.c
parentba93be74f37ecaa4d08bcaff437d8a260e4775bc (diff)
outline basic sorting
Diffstat (limited to 'sort.c')
-rw-r--r--sort.c90
1 files changed, 86 insertions, 4 deletions
diff --git a/sort.c b/sort.c
index 05cbbf3..eff1f0d 100644
--- a/sort.c
+++ b/sort.c
@@ -28,6 +28,7 @@
#include <locale.h>
#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -35,10 +36,16 @@
#define LINE_MAX _POSIX_LINE_MAX
#endif
+struct line {
+ FILE *file;
+ fpos_t pos;
+};
+
static int sort_check(const char *input, char sep, const char *key, unsigned int flags)
{
(void)sep;
(void)key;
+ (void)flags;
char prev[LINE_MAX] = "";
char cur[LINE_MAX] = "";
@@ -68,6 +75,78 @@ static int sort_check(const char *input, char sep, const char *key, unsigned int
return 0;
}
+static void sort_add_pos(struct line **lines, size_t *nlines, FILE *f)
+{
+ struct line *tmp = realloc(*lines, (*nlines + 1) * sizeof(**lines));
+ if (tmp == NULL) {
+ perror("sort");
+ exit(1);
+ }
+ *lines = tmp;
+ (*lines)[*nlines].file = f;
+ fgetpos(f, &((*lines)[*nlines].pos));
+}
+
+static int sort_read(const char *path, struct line **lines, size_t *nlines)
+{
+ FILE *f = stdin;
+ if (strcmp(path, "-")) {
+ f = fopen(path, "r");
+ }
+ if (f == NULL) {
+ fprintf(stderr, "sort: %s: %s\n", path, strerror(errno));
+ return 1;
+ }
+
+ char cur[LINE_MAX] = "";
+
+ sort_add_pos(lines, nlines, f);
+ while (fgets(cur, sizeof(cur), f) != NULL) {
+ }
+
+ /* ignore EOF position */
+ (*nlines)--;
+
+ /* do *NOT* close f */
+ return 0;
+}
+
+static int sort_compar(const void *a, const void *b)
+{
+ const struct line *l1 = a;
+ const struct line *l2 = b;
+ char line1[LINE_MAX] = "";
+ char line2[LINE_MAX] = "";
+
+ fsetpos(l1->file, &l1->pos);
+ fgets(line1, sizeof(line1), l1->file);
+
+ fsetpos(l2->file, &l2->pos);
+ fgets(line2, sizeof(line2), l2->file);
+
+ return strcoll(line1, line2);
+}
+
+static int sort_sort(char *files[], int nfiles, char sep, const char *key, unsigned int flags)
+{
+ (void)sep;
+ (void)key;
+ (void)flags;
+
+ struct line *lines = NULL;
+ size_t nlines = 0;
+
+ for (int i = 0; i < nfiles; i++) {
+ if (sort_read(files[i], &lines, &nlines) != 0) {
+ return 1;
+ }
+ }
+
+ qsort(lines, nlines, sizeof(*lines), sort_compar);
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
@@ -124,9 +203,12 @@ int main(int argc, char *argv[])
return sort_check(argv[optind], separator, key, flags);
}
- /* add lines from all inputs */
- /* sort */
- /* print */
+ #if 0
+ if (mode == MERGE) {
+ /* optimize to assume sorted input */
+ return sort_merge(argv + optind, argc - optind, separator, key, flags);
+ }
+ #endif
- return 0;
+ return sort_sort(argv + optind, argc - optind, separator, key, flags);
}