#include <stdlib.h>
#include "c-stack.h"

typedef struct node {
	void * value;
	struct node * next;
} node;

void copy_stack( stack * s, const stack * t, void * (*copy)( const void * ) ) {
	node ** cr = &s->head;
	for ( node * nx = t->head; nx; nx = nx->next ) {
		*cr = malloc( sizeof(node) ); /***/
		(*cr)->value = copy( nx->value );
		cr = &(*cr)->next;
	}
	*cr = NULL;
}

void clear_stack( stack * s, void (* free_el)( void * ) ) {
	for ( node * nx = s->head; nx; ) {
		node * cr = nx;
		nx = cr->next;
		free_el( cr->value );
		free( cr );
	}
	s->head = NULL;
}

stack new_stack() {
	return (stack){ NULL }; /***/
}

stack * assign_stack( stack * s, const stack * t, 
		void * (*copy_el)( const void * ), void (*free_el)( void * ) ) {
	if ( s->head == t->head ) return s;
	clear_stack( s, free_el ); /***/
	copy_stack( s, t, copy_el ); /***/
	return s;
}

_Bool stack_empty( const stack * s ) {
	return s->head == NULL;
}

void push_stack( stack * s, void * v ) {
	node * n = malloc( sizeof(node) ); /***/
	*n = (node){ v, s->head }; /***/
	s->head = n;
}

void * pop_stack( stack * s ) {
	node * n = s->head;
	s->head = n->next;
	void * v = n->value;
	free( n );
	return v;
}
