Listing 5

/* ----------------- PHLIST1.H ---------------*/
#include "arrylist.h"

typedef struct phone_entry {
   char last_name[21], first_name[11], phone_no[14];
} PHONE_ENTRY;

#define PHONE_LIST_CLASS ARRAY_LIST_CLASS \
           PHONE_ENTRY *data; \
           void (*sort)(struct phone_list *);

typedef struct phone_list {
   PHONE_LIST_CLASS
} PHONE_LIST;

PHONE_LIST *new_phone_list();
void destroy_phone_list(PHONE_LIST *);

/* ------------------ PHLIST1.C ---------------- */
#include "phlist1.h"
#include <string.h>
#include <conio.h>
#include <stdlib.h>

static void phone_list_memory_error(char *fun) {
   fprintf(stderr,
   "\nMemory Error in Function %s <Press a Key>\n", fun);
   getch(); exit(1);
}

static unsigned find(PHONE_LIST *this,char *srch_last_name) {
   PHONE_ENTRY *pe;
   int orig;
   
   orig = this->curr;
   while(! this->at_end(this)) {
      pe = this->current(this);
      if ( stricmp(pe->last_name,srch_last_name) == 0)
         return(TRUE);
      else if (stricmp(pe->last_name,srch_last_name) > 0) {
         this->curr = orig;
         return(FALSE);
      }
      else
          this->next(this);
   }
   pe = this->current(this);
   if ( stricmp(pe->last_name,srch_last_name) == 0)
      return(TRUE);
   this->curr = orig;
   return(FALSE);
}

static display(PHONE_LIST *this) {
   PHONE_ENTRY *pe;
   
   pe = this->current(this);
   if (pe ! = NULL) {
      printf("%-20s, %-10s - %-13s\n", pe->last_name,
      pe->first_name, pe->phone_no);
   }
}

static void add_member(PHONE_LIST *this, PHONE_ENTRY *pe) {
   this->data = realloc(this->data,
   sizeof(PHONE_ENTRY) * (this->tot_members + 1));
   
   if (this->data == NULL)
      phone_list_memory_error("phone_list: add_member");
   
   memmove(this->data + this->tot_members, pe,
   sizeof(PHONE_ENTRY));
   ++(this->tot_members);
   this->sort(this);
}

static void replace_member(PHONE_LIST *this,
PHONE_ENTRY *pe) {
 if (this->data != NULL)
  memmove(this->data + this->curr, pe,sizeof(PHONE_ENTRY));
}

static PHONE_LIST *current(PHONE_LIST *this) {
   if (! this->at_end(this) && this->data != NULL)
      return(this->data + this->curr);
   else
      return(NULL);
}

static int pe_comp(PHONE_ENTRY *pe1, PHONE_ENTRY *pe2) {
   int ret;
   ret = stricmp(pe1->last_name, pe2->last_name);
   if (ret == 0)
      return(stricmp(pe1->first_name, pe2->first_name));
   return(ret);
}

static sort(PHONE_LIST *this) {
   qsort(this->data, (size_t) this->tot_members,
   sizeof(PHONE_ENTRY), pe_comp);
}

   PHONE_LIST *new_phone_list() {
   ARRAY_LIST *al;
   PHONE_LIST *this;
 
   al = new_array_list();
   if (al == NULL)
         return(NULL);
   
   this = calloc(1,sizeof(PHONE_LIST));
   if (this == NULL) {
   destroy_array_list(al);
      return(NULL);
   }
   memmove(this,al,sizeof(ARRAY_LIST));
   free(al);
   
   this->find = find; this->display = display;
   this->add_member = add_member;
   this->replace_member = replace_member;
   this->current = current; this->sort = sort;
   return(this);
   }
   
   void destroy_phone_list(PHONE_LIST *this) {
   if (this->data)
      free(this->data);
   destroy_array_list(this);
   }