Viewing: sort.c
📄 sort.c (Read Only) ⬅ To go back
/* AdrOS sort utility */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#define MAX_LINES 1024
#define LINE_BUF  65536

static char linebuf[LINE_BUF];
static char* lines[MAX_LINES];
static int nlines = 0;

static int rflag = 0;  /* -r: reverse */
static int nflag = 0;  /* -n: numeric */

static int cmp(const void* a, const void* b) {
    const char* sa = *(const char**)a;
    const char* sb = *(const char**)b;
    int r;
    if (nflag) {
        r = atoi(sa) - atoi(sb);
    } else {
        r = strcmp(sa, sb);
    }
    return rflag ? -r : r;
}

static void read_lines(int fd) {
    int total = 0;
    int r;
    while ((r = read(fd, linebuf + total, (size_t)(LINE_BUF - total - 1))) > 0) {
        total += r;
        if (total >= LINE_BUF - 1) break;
    }
    linebuf[total] = '\0';

    /* Split into lines */
    char* p = linebuf;
    while (*p && nlines < MAX_LINES) {
        lines[nlines++] = p;
        while (*p && *p != '\n') p++;
        if (*p == '\n') *p++ = '\0';
    }
}

int main(int argc, char** argv) {
    int start = 1;
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] == '-') {
            const char* f = argv[i] + 1;
            while (*f) {
                if (*f == 'r') rflag = 1;
                else if (*f == 'n') nflag = 1;
                f++;
            }
            start = i + 1;
        } else break;
    }

    if (start >= argc) {
        read_lines(STDIN_FILENO);
    } else {
        for (int i = start; i < argc; i++) {
            int fd = open(argv[i], O_RDONLY);
            if (fd < 0) {
                fprintf(stderr, "sort: cannot open '%s'\n", argv[i]);
                return 1;
            }
            read_lines(fd);
            close(fd);
        }
    }

    /* Simple insertion sort (no qsort in ulibc yet) */
    for (int i = 1; i < nlines; i++) {
        char* key = lines[i];
        int j = i - 1;
        while (j >= 0 && cmp(&lines[j], &key) > 0) {
            lines[j + 1] = lines[j];
            j--;
        }
        lines[j + 1] = key;
    }

    for (int i = 0; i < nlines; i++)
        printf("%s\n", lines[i]);

    return 0;
}