From bdf409e42efcd5d9fda6219629b4f2d2b3a6856d Mon Sep 17 00:00:00 2001 From: Aaron Helton Date: Wed, 30 Oct 2019 23:46:04 -0400 Subject: [PATCH] Added Descending Option and Command Line Parsing I also added some appropriate tests. It appears to work, but tests 5 and 6 appear to fail due to a problem parsing the long --descending option. --- src/main.c | 74 +++++++++++++++++++++++++++++++++++++++++++---- test/Sorted 3.txt | 50 ++++++++++++++++++++++++++++++++ test/Sorted 4.txt | 10 +++++++ test/Test.cmd | 12 ++++++++ test/Test.sh | 40 +++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 test/Sorted 3.txt create mode 100644 test/Sorted 4.txt diff --git a/src/main.c b/src/main.c index 6d90aac..ef0c85a 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,13 @@ #include #include +#define ASCENDING 1 +#define DESCENDING 0 + +// Nasty global variable needed here as there is no other way to pass state to the compare function. +// This variable should be kept static so no other unit may see it. +static int global_sort_order = ASCENDING; + /* * Compare function to be used by qsort. Due to the implementation in the C * Standard Library, this function necessarily accepts void * and must cast to @@ -15,10 +22,16 @@ int compare(const void *str1, const void *str2) const string *second = *(const string **) str2; int res = compare_on_length(first, second); - if(res == 0) + if(0 == res) { return compare_on_alphabet(first, second); } + + // The user may have requested we sort in the other direction on length + if(global_sort_order == DESCENDING) + { + res = -res; + } return res; } @@ -27,24 +40,73 @@ int compare(const void *str1, const void *str2) * 1. Strings are sorted by length first, not alphabet. * 2. Strings are sorted by alphabet only if they are the same length. */ -void perform_length_alphabet_sort(string_vector *vector) +void perform_length_alphabet_sort(string_vector *vector, int ascending) { + if(!ascending) + { + global_sort_order = DESCENDING; + } qsort((void *) vector->array, vector->size, sizeof(string *), compare); } +void print_usage() +{ + fprintf(stderr, "Usage: name_sort [-d|--descending] \n"); +} + int main(int argc, char **argv) { if(argc < 2) { - fprintf(stderr, "Usage: name_sort \n"); + print_usage(); return 1; } - FILE *file = fopen(argv[1], "r"); + int ascending = 1; + int double_dash_found = 0; + string *long_descending_option = create_from_cstr("descending"); + + //Parse our command line options + size_t option_index; + for(option_index = 1; option_index < argc && argv[option_index][0] == '-' && !double_dash_found; option_index++) + { + switch(argv[option_index][1]) { + case 'd': ascending = 0; break; + case '-': + if(argv[2] == '\0') { + //Double Dash with no other characters is traditional unix symbol of no more options, so we stop. + double_dash_found = 1; + } else { + string *option = create_from_cstr(argv[2]); //Pass in the remainder of the string + if(compare_on_alphabet(option, long_descending_option) == 0) + { + ascending = 1; + } + else + { + print_usage(); + return 1; + } + } + break; + default: + print_usage(); + return 1; + } + } + + // At the end of our loop, option_index should be pointing to all non-option arguments. In this case it should + // only be one argument. + if(option_index != argc-1) + { + print_usage(); + return 1; + } + char *input_file = argv[option_index]; + FILE *file = fopen(input_file, "r"); string_vector *vector = create_vector(0); read_file_into_vector(file, vector); - - perform_length_alphabet_sort(vector); + perform_length_alphabet_sort(vector, ascending); vector_print(vector); destroy_vector(vector); fclose(file); diff --git a/test/Sorted 3.txt b/test/Sorted 3.txt new file mode 100644 index 0000000..f1c6a63 --- /dev/null +++ b/test/Sorted 3.txt @@ -0,0 +1,50 @@ +Fitzjerrell +Hendrickson +Clevenger +Bostwick +Cachedon +Giddings +Guenther +Hatfield +Kalivoda +Kirkland +Phillips +Reynolds +Sullivan +Williams +Byfield +Dulaney +Hagberg +Hillman +McCrave +Michael +Padgett +Routson +Starkey +Stegman +Adkins +Broome +Hickey +Laymon +Rogers +Tanton +Taylor +Baker +Ellis +Evans +Foley +Glock +Graff +Heigl +Lundy +McVey +Nylon +Peery +Reyes +White +Asby +Bain +Dean +Fife +Wile +Kha diff --git a/test/Sorted 4.txt b/test/Sorted 4.txt new file mode 100644 index 0000000..d01c20b --- /dev/null +++ b/test/Sorted 4.txt @@ -0,0 +1,10 @@ +Zachariah +Arnold +Barney +George +johnny +Jordan +Aaron +abbie +Jimmy +Liz diff --git a/test/Test.cmd b/test/Test.cmd index 6f932a0..fe274d1 100644 --- a/test/Test.cmd +++ b/test/Test.cmd @@ -2,6 +2,8 @@ echo off SET OUTPUT="output.txt" SET OUTPUT2="output2.txt" +SET OUTPUT3="output3.txt" +SET OUTPUT4="output4.txt" if exist %OUTPUT% del /f %OUTPUT% NameSort.exe "Sort Me.txt" > %OUTPUT% @@ -12,3 +14,13 @@ if exist %OUTPUT2% del /f %OUTPUT2% NameSort.exe "Sort Me 2.txt" > %OUTPUT2% fc %OUTPUT2% "Sorted 2.txt" if %errorlevel% EQU 0 (echo "Success") else ( echo "Failure") + +if exist %OUTPUT3% del /f %OUTPUT3% +NameSort.exe "Sort Me.txt" > %OUTPUT3% +fc %OUTPUT3% "Sorted 3.txt" +if %errorlevel% EQU 0 (echo "Success") else ( echo "Failure") + +if exist %OUTPUT4% del /f %OUTPUT4% +NameSort.exe "Sort Me 2.txt" > %OUTPUT4% +fc %OUTPUT4% "Sorted 4.txt" +if %errorlevel% EQU 0 (echo "Success") else ( echo "Failure") diff --git a/test/Test.sh b/test/Test.sh index 9928a7c..4291efb 100755 --- a/test/Test.sh +++ b/test/Test.sh @@ -2,12 +2,24 @@ OUTPUT="output.txt" OUTPUT2="output2.txt" +OUTPUT3="output3.txt" +OUTPUT4="output4.txt" +OUTPUT5="output5.txt" +OUTPUT6="output6.txt" rm -f $OUTPUT rm -f $OUTPUT2 +rm -f $OUTPUT3 +rm -f $OUTPUT4 +rm -f $OUTPUT5 +rm -f $OUTPUT6 ./NameSort "Sort Me.txt" > $OUTPUT ./NameSort "Sort Me 2.txt" > $OUTPUT2 +./NameSort -d "Sort Me.txt" > $OUTPUT3 +./NameSort -d "Sort Me 2.txt" > $OUTPUT4 +./NameSort --descending "Sort Me.txt" > $OUTPUT5 +./NameSort --descending "Sort Me 2.txt" > $OUTPUT6 diff "Sorted.txt" $OUTPUT if [ $? -eq 0 ]; then @@ -22,3 +34,31 @@ if [ $? -eq 0 ]; then else echo "Test 2 Failure" fi + +diff "Sorted 3.txt" $OUTPUT3 +if [ $? -eq 0 ]; then + echo "Test 3 Success" +else + echo "Test 3 Failure" +fi + +diff "Sorted 4.txt" $OUTPUT4 +if [ $? -eq 0 ]; then + echo "Test 4 Success" +else + echo "Test 4 Failure" +fi + +diff "Sorted 3.txt" $OUTPUT5 +if [ $? -eq 0 ]; then + echo "Test 5 Success" +else + echo "Test 5 Failure" +fi + +diff "Sorted 4.txt" $OUTPUT6 +if [ $? -eq 0 ]; then + echo "Test 6 Success" +else + echo "Test 6 Failure" +fi