commit fb2cc147c900d213cff819c4581befe225ea39db
parent 530b47040cddd955142feaaeec150737452b1723
Author: phoebos <ben@bvnf.space>
Date: Mon, 11 Oct 2021 23:14:42 +0100
sort: initial with -r
Diffstat:
M | Makefile | | | 1 | + |
M | PROGRESS | | | 2 | +- |
A | sort.c | | | 115 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 117 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -8,6 +8,7 @@ BINS = \
head \
ls \
mkdir \
+ sort \
tee \
true \
tty \
diff --git a/PROGRESS b/PROGRESS
@@ -34,7 +34,7 @@
[ ] rmdir
[ ] shred
[ ] sleep
-[ ] sort
+[ ] sort [-r]
[ ] split
[ ] strings
[ ] tail
diff --git a/sort.c b/sort.c
@@ -0,0 +1,115 @@
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+enum FLAGS {
+ FLAG_r = 1 << 0,
+};
+
+int flags;
+
+int
+alphacompare(const void *s1, const void *s2) {
+ int ret = strcmp(*(const char **) s1, *(const char **) s2);
+ if (flags & FLAG_r)
+ ret *= -1;
+ return ret;
+}
+
+int
+sort(FILE *f) {
+ char **lines = malloc(sizeof(char *));
+ if (lines == NULL) {
+ fprintf(stderr, "sort: %s\n", strerror(errno));
+ return 1;
+ }
+ size_t lsize = sizeof(char *);
+ size_t lused = 0;
+ int i = 0;
+ char *buf = malloc(LINE_MAX);
+ if (buf == NULL) {
+ fprintf(stderr, "sort: %s\n", strerror(errno));
+ free(lines);
+ return 1;
+ }
+ ssize_t bufused = 0;
+ size_t bufsize = LINE_MAX;
+ while ((bufused = getline(&buf, &bufsize, f)) != -1) {
+ if (bufused + lused > lsize) {
+ char **tmp = realloc(lines, bufused + lused);
+ if (tmp == NULL) {
+ fprintf(stderr, "sort: %s\n", strerror(errno));
+ return 1;
+ }
+ lused += bufused;
+ lines = tmp;
+ }
+ lines[i] = strndup(buf, bufused);
+ //strncpy(lines[i], buf, bufused);
+ lines[i][bufused] = '\0';
+ i++;
+ bufused = 0;
+ }
+ if (ferror(f)) {
+ fprintf(stderr, "sort: %s\n", strerror(errno));
+ free(lines);
+ free(buf);
+ return 1;
+ }
+
+ qsort(lines, i, sizeof lines[0], alphacompare);
+
+ for (int j = 0; j < i; j++) {
+ printf("%s", lines[j]);
+ }
+
+ free(lines);
+ free(buf);
+ return 0;
+}
+
+int
+main(int argc, char **argv) {
+ int c;
+ int ret = 0;
+ flags = 0;
+ while ((c = getopt(argc, argv, "r")) != -1) {
+ switch (c) {
+ case 'r':
+ flags |= FLAG_r;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind - 1;
+
+ if (argc == 0)
+ return sort(stdin);
+
+ while (*++argv) {
+ FILE *f;
+ if (**argv == '-' && *(*argv + 1) == '\0')
+ f = stdin;
+ else {
+ f = fopen(*argv, "r");
+ if (f == NULL) {
+ fprintf(stderr, "sort: %s: %s\n", *argv, strerror(errno));
+ ret = 1;
+ continue;
+ }
+ }
+ if (sort(f) != 0)
+ ret = 1;
+
+ if (f != stdin && fclose(f) == EOF) {
+ fprintf(stderr, "sort: %s: %s\n", *argv, strerror(errno));
+ ret = 1;
+ continue;
+ }
+ }
+ return ret;
+}
+