Untitled

 avatar
unknown
plain_text
10 months ago
3.7 kB
16
Indexable
#include "types.h"
#include "stat.h"
#include "user.h"

#define MAX_LINES 1000
#define MAX_LINE_LENGTH 512

char lines[MAX_LINES][MAX_LINE_LENGTH];
int line_count = 0;

// Global flags
int reverse_order = 0;
int numerical_sort = 0;
int unique_lines = 0;

// Function prototypes
void read_lines(int fd);
void sort_lines(void);
void print_lines(void);
int compare_lines(char *a, char *b);
int is_numeric(char *s);
int atoi_custom(char *s);

// Read all lines from file descriptor
void
read_lines(int fd)
{
  char buf[1024];
  int n, m;
  char *p, *q;
  
  m = 0;
  while((n = read(fd, buf+m, sizeof(buf)-m-1)) > 0 && line_count < MAX_LINES){
    m += n;
    buf[m] = '\0';
    p = buf;
    while((q = strchr(p, '\n')) != 0 && line_count < MAX_LINES){
      *q = 0;
      strcpy(lines[line_count], p);
      line_count++;
      p = q+1;
    }
    if(p == buf)
      m = 0;
    if(m > 0){
      m -= p - buf;
      memmove(buf, p, m);
    }
  }
}

// Custom atoi function
int
atoi_custom(char *s)
{
  int n = 0;
  while('0' <= *s && *s <= '9')
    n = n*10 + *s++ - '0';
  return n;
}

// Check if string is numeric
int
is_numeric(char *s)
{
  if(*s == '-' || *s == '+')
    s++;
  if(*s == '\0')
    return 0;
  while(*s) {
    if(*s < '0' || *s > '9')
      return 0;
    s++;
  }
  return 1;
}

// Compare two lines for sorting
int
compare_lines(char *a, char *b)
{
  int result;
  
  if(numerical_sort && is_numeric(a) && is_numeric(b)) {
    int num_a = atoi_custom(a);
    int num_b = atoi_custom(b);
    result = num_a - num_b;
  } else {
    result = strcmp(a, b);
  }
  
  if(reverse_order)
    result = -result;
    
  return result;
}

// Sort lines using bubble sort (simple but sufficient for this purpose)
void
sort_lines(void)
{
  int i, j;
  char temp[MAX_LINE_LENGTH];
  
  for(i = 0; i < line_count - 1; i++) {
    for(j = 0; j < line_count - i - 1; j++) {
      if(compare_lines(lines[j], lines[j+1]) > 0) {
        strcpy(temp, lines[j]);
        strcpy(lines[j], lines[j+1]);
        strcpy(lines[j+1], temp);
      }
    }
  }
  
  // Remove duplicates if -u flag is set
  if(unique_lines) {
    int write_pos = 0;
    for(i = 1; i < line_count; i++) {
      if(strcmp(lines[write_pos], lines[i]) != 0) {
        write_pos++;
        if(write_pos != i) {
          strcpy(lines[write_pos], lines[i]);
        }
      }
    }
    line_count = write_pos + 1;
  }
}

// Print all lines
void
print_lines(void)
{
  int i;
  for(i = 0; i < line_count; i++) {
    printf(1, "%s\n", lines[i]);
  }
}

int
main(int argc, char *argv[])
{
  int fd, i;
  int pattern_arg = 1;

  // Parse flags
  for(i = 1; i < argc; i++) {
    if(argv[i][0] == '-') {
      char *flags = argv[i] + 1;
      while(*flags) {
        switch(*flags) {
          case 'r':
            reverse_order = 1;
            break;
          case 'n':
            numerical_sort = 1;
            break;
          case 'u':
            unique_lines = 1;
            break;
          default:
            printf(2, "sort: unknown flag -%c\n", *flags);
            exit();
        }
        flags++;
      }
      pattern_arg++;
    } else {
      break;
    }
  }

  // Read from stdin if no file specified
  if(argc <= pattern_arg){
    read_lines(0);
  } else {
    // Read from file
    if((fd = open(argv[pattern_arg], 0)) < 0){
      printf(2, "sort: cannot open %s\n", argv[pattern_arg]);
      exit();
    }
    read_lines(fd);
    close(fd);
  }

  // Sort and print lines
  sort_lines();
  print_lines();
  
  exit();
}
Editor is loading...
Leave a Comment