/*
 * This program demonstrates the use of function pointers
 * to provide type-specific functionalities to a generic
 * function.
 *
 * The quicksort function implements the quicksort algorithm
 * with a custom comparator function as well as a custom
 * data type size.
 *
 * The custom comparator is a function pointer parameter.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>

int chrcmp(char *a, char *b){
	if (*a<*b) return -1;
	else if (*a==*b) return 0;
	else return 1;
}

int intcmp(int *a, int *b){
	return *b-*a;
}

int main(int argc, char **argv){
	int i;
	int array[8] = { 2, 5, 3, 2, 1, 4, 0, 7 };
	char *string;

  void *handle;
  void (*quicksort)(void *, size_t, int, int, 
                    void *(*)(void *, void *));
  char *error;

  handle = dlopen("libdqsortl.so", RTLD_LAZY);
  if (!handle) {
      fprintf(stderr, "%s\n", dlerror());
      exit(EXIT_FAILURE);
  }

  dlerror();    /* Clear any existing error */

  *(void **) (&quicksort) = dlsym(handle, "quicksort");

  if ((error = dlerror()) != NULL)  {
      fprintf(stderr, "%s\n", error);
      exit(EXIT_FAILURE);
  }

	if (argc>1) {		
		(*quicksort)((void **)argv[1], sizeof(char), 
		          0, strlen(argv[1])-1, 
		          (void *(*)(void *, void *)) (chrcmp));
		printf("%s\n", argv[1]);
	}
	(*quicksort)((void **)array, sizeof(int), 0, 7, 
	          (void *(*)(void *, void *)) (intcmp));
	for(i=0; i<8; i++){
		printf("%d", array[i]);
	}
	printf("\n");
  dlclose(handle);
  exit(EXIT_SUCCESS);
}
