#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLINES 5000
char *lineptr[MAXLINES];
int realines(char *lineptr[], int max);
void writelines(char *lineptr[], int nlins);
void my_qsort(char *lineptr[], int left, int right, int (*cmp)(void *, void *));
int numcmp(const char to[], const char from[]);
int reverse(char str1[], char str2[]);
int (*compare)(char str1[], char str2[]);
int
main(int argc, char *argv[])
{
char flag;
int numeric = 0, reverse_bool = 0;
int nlins;
while (--argc > 0 && **++argv == '-')
while ((flag = *++*argv))
switch (flag) {
case 'n' :
numeric = 1;
break;
case 'r' :
reverse_bool = 1;
break;
default :
printf("Err: illigial option %c\n", flag);
}
if (argc)
printf("Usage: sort -n\n");
else if ((nlins = realines(lineptr, MAXLINES)) > 0) {
compare = numeric ? (int (*)(char *, char *))numcmp : (int (*)(char *, char *))strcmp;
my_qsort(lineptr, 0, nlins - 1, (int (*)(void *, void *)) (reverse_bool ? reverse : compare));
writelines(lineptr, nlins);
}
return 0;
}
void swap(char *lineptr[], int to, int from);
void
my_qsort(char *lineptr[], int left, int right, int (*cmp)(void *, void*))
{
int last, i;
if (left >= right)
return;
swap(lineptr, left, (left+right)/2);
last = left;
for (i = left+1; i <= right; i++) {
if ((*cmp)(lineptr[i], lineptr[left]) < 0)
swap(lineptr, ++last, i);
}
swap(lineptr, left, last);
my_qsort(lineptr, left, last-1, cmp);
my_qsort(lineptr, last+1, right, cmp);
}
int
numcmp(const char to[], const char from[])
{
double n1 = atof(to);
double n2 = atof(from);
if (n1 < n2)
return -1;
else if (n1 > n2)
return 1;
else
return 0;
}
void
swap(char *lineptr[], int to, int from)
{
char *temp;
temp = lineptr[to];
lineptr[to] = lineptr[from];
lineptr[from] = temp;
}
void
writelines(char *lineptr[], int nlins)
{
while (nlins--)
printf("%s", *lineptr++);
}
#define MAXLEN 1000
int sneed_getine(char str[], int max);
int
realines(char *lineptr[], int max)
{
int len, nlins;
char buff[MAXLEN], *temp;
for (nlins = 0; (len = sneed_getine(buff, MAXLEN)) > 0; nlins++) {
if (nlins < max && (temp = malloc(len+1)) != NULL) {
strcpy(temp, buff);
lineptr[nlins] = temp;
}
else
return -1;
}
return nlins;
}
int
sneed_getine(char str[], int max)
{
char input;
char *str_og = str;
while ( --max && (input = getchar()) != EOF && input != '\n')
*str++ = input;
if (max && input == '\n')
*str++ = input;
*str = '\0';
return str - str_og;
}
int
reverse(char str1[], char str2[])
{
return (*compare)(str2, str1);
}