/* program to demonstrate use of pointers to pointers
 * in connection with modular use of addresses as objects.
 * Richard Kay, Jan 2006 */

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

typedef char DATA;

typedef struct stack {
	DATA d;
	struct stack *next;
} STACK;

DATA pop(STACK **s); /* removes and returns top record on stack s */

void push(STACK **s, DATA d); /* puts record d onto stack s */

int main(void){
	STACK *s=NULL;
	char c,test[]="tset a si sihT"; /* this is a test reversed */
	int i;
	printf("%s\n",test);
	/* push test string into stack */
	for(i=0;test[i];i++){
		push(&s,(DATA)test[i]);
	}
	/* pop and print chars from stack */
        while(s){
		c=(char)pop(&s);
		putchar(c);
	}
	putchar('\n');
	return 1;
}


DATA pop(STACK **s){
       	/* removes and returns top record on stack s */
	STACK *oldtop,*newtop;
	DATA da;
	oldtop=*s; /* make oldtop thing pointed at by s */ 
	if(!oldtop){
		fprintf(stderr,"can't pop empty stack!\n");
		exit(1);
	}
	da=oldtop->d;
	newtop=oldtop->next;
	*s=newtop; /* make thing pointed at by s the new top */
	free(oldtop); /* free space used by popped node */
	return da;
}

void push(STACK **s, DATA da){
       	/* puts record d onto stack s */
	STACK *oldtop, *newtop;
	oldtop=*s;
	/* create new stack node and insert at list head */
	newtop=(STACK*)malloc(sizeof(STACK));
	newtop->d=da;
	newtop->next=oldtop;
	/* update list head */
	*s=newtop; /* make thing pointed at by s the new top */
}

