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); }