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

/* Macro Bool */
typedef enum{false,true}bool;

/***
* Structure Simple d'une Pile
***/
typedef struct _Pile{
	
	unsigned int iVal;
 	struct _Pile *pPrec;
}ts_Pile;

/***
*	Fonction vérification 
*   de la pile
***/
bool f_isEmpty(ts_Pile **pIn){
	
	return ( (*pIn == NULL ) ? true : false );
}

/***
* Fonction qui ajoute un élement
* dans la Pile
***/
void f_addPile(ts_Pile **pIn, unsigned int const iVal){
	
	ts_Pile *tmp = malloc( sizeof( ts_Pile ) );
 	if( !tmp ){
  		perror( "Erreur interne d'allocation\n" );
  		exit( 1 );
 	}
	
	/*	Ajout de l'élément	*/
 	tmp->iVal = iVal;
 	tmp->pPrec = *pIn;
 	*pIn = tmp;
}

/***
* fonction qui retire un élement
* de la Pile
***/
unsigned const int f_PopPile(ts_Pile **pIn){
	
	unsigned int iVal = 0;
 	
 	ts_Pile *tmp = NULL;
 	if( !*pIn  )
  		return ( -1 );
 	
 	tmp  = (*pIn)->pPrec;
 	iVal = (*pIn)->iVal;
 	
 	free( *pIn );
 	*pIn = tmp;
 	
 	return ( iVal );
}

/***
* Fonction qui libère
* la mémoire allouer
***/
void f_FreeAlloc( ts_Pile **pIn){
	
	ts_Pile *tmp = NULL;
	
	if( f_isEmpty( pIn ) != true ){
		
		while( *pIn ){
			tmp = (*pIn)->pPrec;
			free ( *pIn );
			*pIn = tmp;
		}
	
		*pIn = NULL;
		tmp = NULL;
	}
}


/***
* Fonction principale
***/
int main( void ) {
	
	int i = 0;	
	
	/* Déclaration des piles & initialisation */
	
 	ts_Pile *pile_1 = NULL;	/*	Pile (1)	*/
 	ts_Pile *pile_2 = NULL;	/*	Pile (2) 	*/
 	ts_Pile *pile_3 = NULL;	/*	Pile (3)	*/
 	
 	/*	tableau de Pointeur */
 	ts_Pile (*pTabAddr[3]) = { &pile_1, &pile_2, &pile_3 };
 	
 	/*	Ajouts des valeurs à la pile	*/
 	for(; i < 20 ; i++){
 		f_addPile(	pTabAddr[0], i );
 		f_addPile(	pTabAddr[1], (i*2) );
 		f_addPile( 	pTabAddr[2], (i*4) );
 	}
 	
 	/*	Affichage des Piles	*/
 	for(i = 0; i < 20 ; i++)
 		printf("Pile (1)\t= %d\n", f_PopPile(&pile_1) );
 		
 	for(i = 0; i < 20 ; i++)
 		printf("Pile (2)\t= %d\n", f_PopPile(&pile_2) );

 	for(i = 0; i < 20 ; i++)
 		printf("Pile (3)\t= %d\n", f_PopPile(&pile_3) );
 		
 		
 	for( i = 0; i < 20 ; i++){
 		f_addPile(	pTabAddr[0], i );
 		f_addPile(	pTabAddr[1], (i*2) );
 		f_addPile( 	pTabAddr[2], (i*4) );
 	}
 	
 	/*	Désalocation mémoire */
 	f_FreeAlloc( pTabAddr[0] );
 	f_FreeAlloc( pTabAddr[1] );
 	f_FreeAlloc( pTabAddr[2] );
 	
 	/*	Affichage des Piles	*/
 	for(i = 0; i < 20 ; i++)
 		printf("Pile (1)\t= %d\n", f_PopPile(&pile_1) );

 	return ( 0 );
}