#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
void
qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));

void *
bsearch(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar) (const void *, const void *));
*/

int
compare(const void * arg1, 
        const void * arg2)
{
   long a1 = *((long*)arg1);
   long a2 = *((long*)arg2);
   return a1 - a2;
}

int
str_compare(const void * arg1,
            const void * arg2)
{
   const char * a1 = *((const char**)arg1);
   const char * a2 = *((const char**)arg2);
   return strcmp(a1, a2);
}

struct _Person {
   const char * name;
   int age;
};

typedef struct _Person Person;

void 
person__print(Person * p)
{
   printf("name: %s\n", p->name);
   printf("age: %d\n", p->age);
}


int
person_compare(const void * arg1,
               const void * arg2)
{
   Person * a1 = ((Person*)arg1);
   Person * a2 = ((Person*)arg2);
   return strcmp(a1->name, a2->name);
}
int
main()
{
   long array[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
   const char * array2[] = { "one", "two", "three", "four", "five" };
   Person array3[] = {
      {"Matthew W. Coan", 42},
      {"Phoebe", 71},
      {"John Smith", 33},
      {"John Boy", 32},
      {"Elisibeth Corn", 40},
   };
   long key;
   long r;
   Person pkey;
   Person * p;
   int i;
   const char * skey;
   void * result;

   qsort((void*)array, 10, sizeof(long), compare);
   printf("---\n");
   for(int i = 0; i < 10; i++) {
      printf("array[%d] == %ld\n", i, array[i]);
   }
   printf("---\n");
   key = 3;
   result = bsearch((const void*)&key, (const void*)array, 10, sizeof(long), compare);
   if(result != NULL) {
      r = *((long*)result);
      printf("key=%ld\n", key);
      printf("r=%ld\n", r);
   }
   printf("---\n");
   qsort((void*)array2, 5, sizeof(const char*), str_compare);
   for(i = 0; i < 5; i++) {
      printf("array2[%d] == %s\n", i, array2[i]);
   }
   printf("---\n");
   skey = "four";
   result = bsearch((const void*)&skey, (const void*)array2, 5, sizeof(const char *), str_compare);
   if(result != NULL) {
      const char * sr = *((const char **)result);
      printf("sr=%s\n", sr);
   }
   printf("---\n");
   qsort((void*)array3, 5, sizeof(Person), person_compare);
   for(i = 0; i < 5; i++) {
      person__print(&array3[i]);
      printf("--------------------\n");
   }
   printf("---\n");
   pkey.name = "Matthew W. Coan";
   p = &pkey;
   result = bsearch((const void*)p, (const void*)array3, 5, sizeof(Person), person_compare);
   if(result != NULL) {
      p = ((Person*)result);
      person__print(p);
   }
   printf("---\n");
   return 0;
}
