Listing 3

/* -------------------- List.H------------------ */
#include <stdio.h>
#include <stdlib.h>

#define LIST_CLASS unsigned (*at_top)(struct list*), \
           (*at_end)(struct list*), \
           (*is_empty)(struct list*), \
           (*find)(struct list *, ...); \
   void      (*prev)(struct list*), \
           (*next)(struct list *), \
           (*top)(struct list *), \
           (*seek)(struct list *, long, int), \
           (*end)(struct list *), \
           (*display)(struct list*), \
           (*add_member)(struct list*, void *), \
           (*replace_member)(struct list *, void *), \
   void      *(*current)(struct list *); \
   long      (*total_members)(struct list *), \
           (*tell)(struct list *);

typedef struct list {
   LIST_CLASS
} LIST;

LIST *new_list();
destroy_list(LIST *);

#define TRUE 1
#define FALSE 0

/* --------------------  LIST.C ------------------*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "list.h"

static void not_valid() {
   fprintf(stderr,"Operation is not valid for this list\n");
   getch();
}

static unsigned is_empty(LIST *this) {
   return( this->total_members(this) == 0L);
}

static void seek(LIST *this, long where, int start) {
   long count;
   
   switch(start) {
      case SEEK_SET:
         this->top(this);
         for (count = 0; count < where; ++count) {
            if ( this->at_end(this) )
                break;
            this->next(this);
         }
      break;
      case SEEK_CUR:
         if (where > 0) {
            for (count = 0; count < where; ++count) {
                if ( this->at_end(this) )
                   break;
                this->next(this);
            }
         }
         else {
            for(count = 0; count > where; ++count) {
                if (this->at_top(this) )
                   break;
                this->prev(this);
            }
         }
   break;
   case SEEK_END:
      
      this->end(this);
      for(count = 0; count > where; ++count) {
          if ( this->at_top(this) )
                 break;
          this->prev(this);
      }
   break;
   }
}

static long total_members(LIST *this)
{
   long thisone, count;
   thisone = this->tell(this); this->top(this);
   count = 0;
   do {
      if ( ! this->at_end(this) ) {
         ++count;
         this->next(this);
      }
   } while( ! this->at_end(this) );
   this->seek{ this, thisone,SEEK_SET);
   return(count);
}

LIST *new_list() {
LIST *this;

/*  Allocate Memory for this Object */
this = calloc(1,sizeof(LIST));
if (this == NULL)
   return(NULL);

/*  Assign Methods */
this->at_top = not_valid;   this->at_end = not_valid;
this->is_empty = is_empty;  this->find = not_valid;
this->prev = not_valid;     this->next = not_valid;
this->seek = seek;          this->top = not_valid;
this->end = not_valid;      this->display = not_valid;
this->replace_member = not_valid;
this->add_member = not_valid;
this->current = not_valid;
this->total_members = total_members;
this->tell = not_valid;

return(this);
}

destroy_list{LIST *this) {
   free(this);
}