/*
* Copyright 2011 Steven Gribble
*
* This file is part of the UW CSE 333 course project sequence
* (333proj).
*
* 333proj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 333proj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 333proj. If not, see .
*/
// Lecture 10 exercise 2
#include
#include
#include
#include
#include
#include "sort.h"
// This declares comparator function we pass in to
// our sort routines.
static int IntComparator(void *el1, void *el2);
// This function reads a file into memory and returns
// a pointer to the allocated memory buffer.
static unsigned char *ReadFile(char *fname, int *retlen);
// Converts the string to an int array, and returns a
// pointer to the allocated int array.
static int *StringToIntArray(unsigned char *filecontent, int *arrlen);
#define BUBBLESORT 0
#define QUICKSORT 1
static void SortFile(char *fname, int whichsort);
// Reads the file in, converts to int array, bubblesorts, frees
// all of the resources.
static void BubbleSortFile(char *fname) {
SortFile(fname, BUBBLESORT);
}
// Reads the file in, converts to int array, quicksorts, frees
// all of the resources.
static void QuickSortFile(char *fname) {
SortFile(fname, QUICKSORT);
}
int main(int argc, char **argv) {
if (argc != 2)
return EXIT_FAILURE;
printf("Running quicksort on '%s'\n", argv[1]);
QuickSortFile(argv[1]);
printf("Running bubblesort on '%s'; this may take a while.\n", argv[1]);
BubbleSortFile(argv[1]);
printf("Done!\n");
return EXIT_SUCCESS;
}
static int IntComparator(void *el1, void *el2) {
int *i1 = (int *) el1;
int *i2 = (int *) el2;
if (*i1 > *i2)
return 1;
if (*i1 == *i2)
return 0;
return -1;
}
#define READSIZE 1000
static unsigned char *ReadFile(char *fname, int *retlen) {
unsigned char *buf = NULL;
FILE *f;
int readlen, count = 0;
// Open up the file.
f = fopen(fname, "rb");
if (f == NULL)
return NULL;
// Slurp in the file, READSIZE bytes at a time.
buf = (unsigned char *) realloc(buf, READSIZE + 1);
assert(buf != NULL);
while ((readlen = fread(buf+count, 1, READSIZE, f)) > 0) {
count += readlen;
buf = (unsigned char *) realloc(buf, count + READSIZE + 1);
assert(buf != NULL);
}
// Did we break because of an error?
if (ferror(f)) {
// Yes, so clean up and arrange to return NULL.
free(buf);
buf = NULL;
count = 0;
}
// Clean up, null terminate, return.
fclose(f);
buf[count] = '\0';
*retlen = count;
return buf;
}
static int *StringToIntArray(unsigned char *filecontent, int *arrlen) {
int count = 0;
int *retarray = NULL;
char *nexttok = NULL;
// Start by using strtok ("man strtok") to get the first newline-
// separated token.
nexttok = strtok((char *) filecontent, "\n");
// Then, loop through, converting the previously found token to
// an integer, growing the array, and adding it. After this,
// look for the next token.
while(nexttok != NULL) {
int nextint = 0;
// Convert the line to an integer, growing the array to store it.
retarray = (int *) realloc(retarray, sizeof(int) * (count + 1));
assert(retarray != NULL);
assert(sscanf(nexttok, "%d", &nextint) == 1);
retarray[count] = nextint;
count++;
// Look for the next token.
nexttok = strtok(NULL, "\n");
}
// Done! Return the array and count.
*arrlen = count;
return retarray;
}
static void SortFile(char *fname, int whichsort) {
unsigned char *filecontent = NULL;
int *intarray = NULL;
int arrlen = 0, filelen = 0;
// Read in the file.
filecontent = ReadFile(fname, &filelen);
if (filecontent == NULL) {
fprintf(stderr, "Readfile returned empty content.\n");
exit(EXIT_FAILURE);
}
// Convert to an int array.
intarray = StringToIntArray(filecontent, &arrlen);
free(filecontent);
if (intarray == NULL) {
fprintf(stderr, "StringToIntArray returned empty array.\n");
exit(EXIT_FAILURE);
}
// Sort in place.
if (whichsort == QUICKSORT) {
QuickSort(intarray, arrlen, sizeof(int), &IntComparator);
} else {
BubbleSort(intarray, arrlen, sizeof(int), &IntComparator);
}
// Clean up.
free(intarray);
}