
Interface Structure
#include <stdio.h>
#include <stdlib.h>
/**************************** Array-based stack ******************************/
struct arr_stack {
int top;
int contents[100];
};
int arr_init(stk)
struct arr_stack *stk;
{
stk->top = -1;
}
int arr_push(stk,i)
struct arr_stack *stk;
int i;
{
stk->contents[++stk->top] = i;
}
int arr_pop(stk)
struct arr_stack *stk;
{
return stk->contents[stk->top--];
}
/******************************* Linked stack *********************************/
struct stk_node {
int cont;
struct stk_node *next;
};
int lnk_init(stk)
struct stk_node **stk;
{
*stk = NULL;
}
int lnk_push(stk, i)
struct stk_node **stk;
int i;
{
struct stk_node *newnode = malloc(sizeof (struct stk_node));
newnode->cont = i;
newnode->next = *stk;
*stk = newnode;
}
int lnk_pop(stk)
struct stk_node **stk;
{
struct stk_node *zombie = *stk;
int ret = zombie->cont;
*stk = zombie->next;
free(zombie);
return ret;
}
/**************************** Interface Structures ***************************/
/* This is based on Fig. 3, where interface object points to the component. */
struct interface {
char *intername;
struct method *methods;
void *object;
};
struct method {
char *methname;
int (*method)();
};
/* Find a named method in an interface. */
int error()
{
fprintf(stderr, "Unknown method\n");
abort();
}
typedef int (*meth_t)();
meth_t find(struct interface *inter, char *name)
{
int i;
for(i = 0; 1; ++i) {
if(inter->methods[i].methname == NULL) return error;
if(strcmp(inter->methods[i].methname, name) == 0)
return inter->methods[i].method;
}
}
/*************************** Interface Creators *******************************/
/* Array stack. */
struct interface *mk_arr_stck_iface(struct arr_stack *stk)
{
struct interface *iface = malloc(sizeof (struct interface));
iface->intername = "stack";
iface->object = stk;
iface->methods = malloc(4*sizeof(struct method));
iface->methods[0].methname = "init";
iface->methods[0].method = arr_init;
iface->methods[1].methname = "push";
iface->methods[1].method = arr_push;
iface->methods[2].methname = "pop";
iface->methods[2].method = arr_pop;
iface->methods[3].methname = NULL;
iface->methods[3].method = NULL;
return iface;
}
/* Linked stack. */
struct interface *mk_lnk_stck_iface(struct stk_node **stk)
{
struct interface *iface = malloc(sizeof (struct interface));
iface->intername = "stack";
iface->object = stk;
iface->methods = malloc(4*sizeof(struct method));
iface->methods[0].methname = "init";
iface->methods[0].method = lnk_init;
iface->methods[1].methname = "push";
iface->methods[1].method = lnk_push;
iface->methods[2].methname = "pop";
iface->methods[2].method = lnk_pop;
iface->methods[3].methname = NULL;
iface->methods[3].method = NULL;
return iface;
}
/* Doace some stuff with an interface. */
void runstack(struct interface *i)
{
int j;
/* Initialize. */
find(i, "init")(i->object);
/* Push stuff. */
for(j = 0; j < 4; j++)
find(i, "push")(i->object, 2*j + 3);
/* Pop and print. */
for(j = 0; j < 4; j++)
printf("%d ", find(i, "pop")(i->object));
putchar('\n');
}
main()
{
/* The two objects, or "components" */
struct arr_stack arr_stack;
struct stk_node *lnk_stack;
/* Create interfaces for each. */
struct interface *arr_inter = mk_arr_stck_iface(&arr_stack);
struct interface *lnk_inter = mk_lnk_stck_iface(&lnk_stack);
/* Run something with each. */
runstack(arr_inter);
runstack(lnk_inter);
}