This is follow up question regarding merge-sort implementation to the previous post.
Recently I have implemented a command-line argument based merge-sort sorting algorithm.
Format for command-line-arguments:
name_of_the_output_program size_of_sequence sequence in ""
The fourth argument is optional, if -r or -reverse is passed then sort the sequence in decreasing order else by default sort the sequence in increasing order.
For Example:
./merge_sort 5 "25 41 11 32 45"
11 25 32 41 45
./merge_sort 5 "25 41 11 32 45" -r
45 41 32 25 11
./merge_sort 5 "25 41 11 32 45" -reverse
45 41 32 25 11
./merge_sort 3 "1 2 0" -reverse
2 1 0
Source Code:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<assert.h>
bool reverse_order = false;
typedef unsigned long long int64;
typedef long long uint64;
static const bool check_sorted(const int64 *const,const size_t,const bool);
static void merge_sort_integer_sequence(int64 *const,const size_t,const size_t);
static void merge_integer_data(int64 *const,const size_t,const size_t,const size_t,const bool (*comparator)(const void*,const void*));
static void display_sequence(const int64 *const,const size_t);
static const bool integer_comparator(const void*,const void*);
int main(int argc,char *const argv[]) {
if(argc == 3 || argc == 4) {
const size_t n = atoi(argv[1]);
assert(n > 0); // Length of the array must be > 0.
int64 sequence[n];
char *const parse_seq = argv[2];
char *parse_ptr = parse_seq;
size_t data_count = 1;
for(size_t i = 0, j = 0; (j < n && parse_seq[i] != '\0'); ++i) {
if(parse_seq[i] == ' ') {
++data_count;
sequence[j++] = atoi(parse_ptr);
parse_ptr = parse_seq + i + 1;
}
}
if((strlen(parse_seq) > 0) && (data_count == n)) {
sequence[n - 1] = atoi(parse_ptr);
parse_ptr = NULL;
if((argc == 4) && ((!strcmp(argv[3],"-reverse")) || (!strcmp(argv[3],"-r")))) {
reverse_order = true;
}
if(reverse_order) {
if(!check_sorted(sequence,n,false)) {
merge_sort_integer_sequence(sequence,0,(n - 1));
}
} else {
if(!check_sorted(sequence,n,true)) {
merge_sort_integer_sequence(sequence,0,(n - 1));
}
}
display_sequence(sequence,n);
} else {
if(data_count > n) {
fprintf(stderr,"Line number: %u: n value is less than array length.\n", __LINE__);
return EXIT_FAILURE;
} else {
fprintf(stderr,"Line number: %u: n value is more than array length.\n", __LINE__);
return EXIT_FAILURE;
}
}
} else {
if(argc > 4) {
fprintf(stderr,"Line number: %u: More than %u arguments are passed\n", __LINE__,argc);
} else {
fprintf(stderr,"Line number: %u: Insufficient Number of Arguments passed\n", __LINE__);
}
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
static void display_sequence(const int64 *const data,const size_t n) {
for(size_t i = 0; i < n; ++i) {
printf("%lld ", data[i]);
}
printf("\n");
}
static const bool check_sorted(const int64 *const data,const size_t n,const bool order) {
bool is_sorted = true;
if(!order) {
for(size_t i = 0; i < (n - 1); ++i) {
if(data[i] < data[i + 1]) {
is_sorted = false;
break;
}
}
} else {
for(size_t i = 0; i < (n - 1); ++i) {
if(data[i] > data[i + 1]) {
is_sorted = false;
break;
}
}
}
return is_sorted;
}
static void merge_sort_integer_sequence(int64 *const data,const size_t start,const size_t end) {
if(start < end) {
const size_t mid = ((end - start) >> 1) + start;
merge_sort_integer_sequence(data,start,mid);
merge_sort_integer_sequence(data,(mid + 1),end);
merge_integer_data(data,start,mid,end,integer_comparator);
}
}
static void merge_integer_data(int64 *const data,size_t start,size_t mid,size_t end,const bool (*comparator)(const void *,const void *)) {
size_t left_size = (mid - start) + 1;
int64 left_data[left_size];
memmove(left_data,&data[start],(sizeof(int64) * left_size));
size_t right_size = end - mid;
int64 right_data[right_size];
memmove(right_data,&data[mid + 1],(sizeof(int64) * right_size));
for(size_t k = start, i = 0, j = 0; k <= end; ++k) {
if(i == left_size) {
data[k] = right_data[j++];
} else if(j == right_size) {
data[k] = left_data[i++];
} else if(comparator(&left_data[i],&right_data[j])) {
if(reverse_order) {
data[k] = right_data[j++];
} else {
data[k] = left_data[i++];
}
} else {
if(reverse_order) {
data[k] = left_data[i++];
} else {
data[k] = right_data[j++];
}
}
}
}
static const bool integer_comparator(const void *a,const void *b) {
return (*(int64*)a) < (*(int64*)b);
}
Does the above code need more improvement in terms of security, loopholes, buffer-overflows, maintainability, readability, robustness, to be production-ready?
How can I use conditional macros/directives like #if #elif #else #defined #ifndef #ifdef to make the code more compact if possible?
./merge_sort 3 "1 2 0" -reverse 2 1 0This does not match the criteria in the question, Per the OPs question, the output should be: 0 2 1. Therefore, the posted code does not work. in codereview, the code has to work \$\endgroup\$-reverseorrflag is passed then sort in descending order. \$\endgroup\$