aboutsummaryrefslogblamecommitdiff
path: root/5.16.c
blob: 39e8f964b6fd7caa978e314fde43ed3923d17cc5 (plain) (tree)











































































































































































































                                                                                            
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.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)(const char *, const char *));
int numcmp(const char to[], const char from[]);
int strcmp_ignore_case(const char str1[], const char str2[]);
int reverse(const char str1[], const char str2[]);
int mystcmp(const char to[], const char from[]);
int (*compare)(const char str1[], const char str2[]);
int (*strcmp_base)(const char to[], const char from[]);
int isdirectory(char input);

int directory_order_bool;


int 
main(int argc, char *argv[])
{
  char flag;
  int numeric = 0, reverse_bool = 0, ignore_case_bool = 0;
  int nlins;

  while (--argc > 0 && **++argv == '-')
    while ((flag = *++*argv))
      switch (flag) {
        case 'n' :
          numeric = 1;
          break;
        case 'r' :
          reverse_bool = 1;
          break;
        case 'f' :
          ignore_case_bool = 1;
          break;
        case 'd' :
          directory_order_bool = 1;
          break;
        default :
          printf("Err: illigial option %c\n", flag);
      }

  if (argc)
    printf("Usage: sort -nrf\n");
  else if ((nlins = realines(lineptr, MAXLINES)) > 0) {

    strcmp_base = ignore_case_bool ? strcmp_ignore_case : mystcmp;
    compare = numeric ? numcmp : strcmp_base;

    my_qsort(lineptr, 0, nlins - 1, 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)(const char *, const char *))
{
  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(const char str1[], const char str2[])
{
  return (*compare)(str2, str1);
}

int 
strcmp_ignore_case(const char to[], const char from[])
{
  if (directory_order_bool) {
    for (; *to && *from; to++, from++)
      if (isdirectory(tolower(*from)) && tolower(*from) != tolower(*to))
        break;
  }

  else
    for (; *to && *from && tolower(*to) == tolower(*from); to++, from++)
      ;

  return tolower(*to) - tolower(*from);
}

int 
isdirectory(char input)
{
  if (isalpha(input) || isdigit(input) || isblank(input))
    return 1;
  else 
    return 0;
}

int 
mystcmp(const char to[], const char from[])
{
  if (directory_order_bool) {
    for (; *to && *from; to++, from++)
      if (isdirectory(*from) && *from != *to)
        break;
  }

  else
    for (; *to && *from && *to == *from; to++, from++)
      ;

  return *to - *from;
}