#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_LINES 1024
int state;
enum
{
MODE = 0xf,
NUM = 0x1,
RE = 0X2,
FREE = 0X4,
DIGIT = 0X8
};
int getlines(char **line, int max_lines);
void lines_qsort(void *line, int left, int right, int ( comp)(void *, void *));
int numcmp(char *a, char *b);
void print(char **line, int lines);
int deal_command(int argc, char *argv[]);
main(int argc, char *argv[])
{
char *line[MAX_LINES];
int lines;
state = 0;
state = deal_command(argc, argv);
if ((lines = getlines(line, MAX_LINES)) > 0)
{
lines_qsort((void **) line, 0, lines - 1, (int (*) (void *, void *))(state & NUM ? numcmp : strcmp));
print(line, lines);
}
else
{
printf("input too big to sort\n");
return 1;
}
return 0;
}
#define MAX_LEN 1024
int getline(char *s, int max_len);
int getlines(char **line, int max_lines)
{
int lines, len;
char s[MAX_LEN];
lines = 0;
while ((len = getline(s, MAX_LEN)) > 0)
{
if (max_lines-- && (line[lines] = (char *)malloc(len + 1)) == NULL)
{
printf("there are no memory!\n");
exit(1);
}
strcpy(line[lines++], s);
}
return lines;
}
int getline(char *s, int max_len)
{
int c, i;
i = 0;
while ((c = getchar()) != '\n' && c != EOF)
{
s[i++] = c;
}
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
void swap(void **s, int a, int b);
void save_part(char *s);
void save_name(char *s);
void save_page(char *s);
void save_free(char *s);
void lines_qsort(void *line, int left, int right, int ( comp)(void *, void *))
{
int last, i;
if (left >= right)
return;
swap(line, left, (left + right) / 2);
last = left;
for (i = left + 1; i <= right; i++)
{
char s1[MAX_LEN], s2[MAX_LEN];
strcpy(s1, line[i]);
strcpy(s2, line[left]);
if ((state & DIGIT) && (state & FREE))
{
save_name(s1);
save_name(s2);
}
if (state & NUM)
{
save_page(s1);
save_page(s2);
}
if (state & DIGIT)
{
save_part(s1);
save_part(s2);
}
if (state & FREE)
{
save_free(s1);
save_free(s2);
}
if (state & RE ? ((*comp)(s1, s2) > 0) : ((*comp)(s1, s2) < 0))
swap(line, i, ++last);
}
swap(line, left, last);
lines_qsort(line, left, last - 1, comp);
lines_qsort(line, last + 1, right, comp);
}
int numcmp(char *a, char *b)
{
float val1, val2;
val1 = atof(a);
val2 = atof(b);
if (val1 > val2)
return 1;
if (val1 < val2)
return -1;
if (val1 == val2)
return 0;
}
void print(char **line, int lines)
{
int i;
for (i = 0; i < lines; i++)
{
printf("%s", line[i]);
}
}
void swap(void **s, int a, int b)
{
void *temp;
temp = s[a];
s[a] = s[b];
s[b] = temp;
}
int deal_command(int argc, char *argv[])
{
int state;
state = 0;
if (argc >= 2 && *argv[1] == '-')
{
int i;
char *p = argv[1];
for (i = 0; p[i]; i++)
{
if (p[i] == 'n')
state |= NUM;
if (p[i] == 'f')
state |= FREE;
if (p[i] == 'd')
state |= DIGIT;
if (p[i] == 'r')
state |= RE;
}
}
return state;
}
void save_part(char *s)
{
int i, j;
for (i = 0, j = 0; s[i]; i++)
{
if (isalpha(s[i]) || isdigit(s[i]) || s[i] == ' ')
s[j++] = s[i];
}
s[j] = '\0';
}
void save_name(char *s)
{
char *p;
int j;
p = strstr(s, "name");
p += 4;
while (!isalnum(*p))
p++;
for (j = 0; isalnum(*p); p++)
s[j++] = *p;
s[j] = '\0';
}
void save_page(char *s)
{
char *p;
int j;
p = strstr(s, "page");
p += 4;
while(!isdigit(*p))
{
p++;
}
for (j = 0; isdigit(*p); p++)
{
s[j++] = *p;
}
s[j] = '\0';
}
void save_free(char *s)
{
int i;
for (i = 0; s[i]; i++)
{
if (isupper(s[i]))
s[i] = tolower(s[i]);
}
}