#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* #include "xmalloc.h" */
#define xmalloc malloc
#define xfree free
#define xrealloc realloc
#define BUFFSIZE 3 /* >= 2 */
char *mygetline(FILE *fp) {
static char inbuff[BUFFSIZE];
char *outbuff_malloc, *tmpbuff;
char *p, *r;
int fEOL;
if ((outbuff_malloc = xmalloc(1)) == NULL) {
return NULL;
}
*outbuff_malloc = '\0';
fEOL = 0;
do {
r = fgets(inbuff, BUFFSIZE, fp);
if (r == NULL)
break;
for (p = inbuff; *p != '\0'; p++)
;
if (*(p - 1) == '\n')
fEOL = 1;
if ((tmpbuff = xrealloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1)) == NULL) {
xfree(outbuff_malloc);
return NULL;
}
strcat(tmpbuff, inbuff);
outbuff_malloc = tmpbuff;
} while (!fEOL);
if (strlen(outbuff_malloc) > 0) {
for (p = outbuff_malloc; *p != '\0'; p++)
;
if (*(p - 1) == '\n')
*(p - 1) = '\0';
return outbuff_malloc;
}
xfree(outbuff_malloc);
return NULL;
}
static int flagS = 0;
struct node {
void *data;
struct node *left;
struct node *right;
};
void push(struct node **root, void *data, int (*cmp)(void *, void *)) {
struct node *p;
if (!*root) {
if ((p = xmalloc(sizeof(struct node))) == NULL) {
fprintf(stderr, "cannot allocate enough memory(struct node), aborted\n");
exit(-1);
}
p->data = data;
p->left = p->right = NULL;
*root = p;
return;
}
if ((*cmp)(data, (*root)->data) < 0) {
push(&((*root)->left), data, cmp);
} else {
push(&((*root)->right), data, cmp);
}
}
void *pop(struct node **root) {
struct node *p;
void *data;
if (*root == NULL) {
return NULL;
}
if ((*root)->left) {
data = pop(&((*root)->left));
return data;
}
p = *root;
data = p->data;
*root = p->right;
xfree(p);
return data;
}
int cmp1(char *a, char *b) {
return strcmp(a, b);
}
int cmp2(char *a, char *b) {
return -strcmp(a, b);
}
void task_sort(FILE *fp) {
struct node *root;
char *p;
root = NULL;
while ((p = mygetline(fp))) {
if (flagS)
push(&root, p, (int (*)(void *, void *))cmp1);
else
push(&root, p, (int (*)(void *, void *))cmp2);
}
while ((p = pop(&root))) {
printf("%s\n", p);
xfree(p);
}
}
void usage(char *cmd) {
fprintf(stderr, "usage: %s <flag:> <file>\n", cmd);
fprintf(stderr, " flag: 0:descending order\n");
fprintf(stderr, " 1:ascending order\n");
}
int main(int argc, char *argv[]) {
FILE *fp;
if (argc != 3) {
usage(argv[0]);
exit(-1);
}
if (*argv[1] == '1')
flagS = 1;
if ((fp = fopen(argv[2], "r")) == NULL) {
fprintf(stderr, "cannot open the file '%s', aborted\n", argv[2]);
usage(argv[0]);
exit(-1);
}
task_sort(fp);
fclose(fp);
/* xmallocdump(); */
return 0;
}
/* end */