#include "pilhasm.h"

struct PilhaMStr
{
    size_t tamanho, topo;
    void **m;
};


PilhaM *PMcria(size_t tamanho)

{
    PilhaM *p;
    
    if((p = malloc(sizeof(*p))) == 0)
	return 0;
    if(tamanho == 0)
	p->tamanho = PMTAMANHO;
    else
	p->tamanho = tamanho;
    if((p->m = calloc(p->tamanho, sizeof(void *))) == 0)
    {
	free(p);
	return 0;
    }
    p->topo = 0;
    return p;
}


void PMdestroi(PilhaM *p)

{
    if(p == 0)
	return;
    free(p->m);
    free(p);
}


PilhaM *PMesvazia(PilhaM *p)

{
    if(p != 0)
	p->topo = 0;
    return p;
}


size_t PMquantos(PilhaM *p)

{
    if(p == 0)
	return 0;
    return p->topo;
}


int PMcheia(PilhaM *p)

{
    if(p == 0)
	return 0;
    return p->topo == p->tamanho;
}


PilhaM *PMpoe(PilhaM *p, void *d)

{
    if(p == 0 || p->topo == p->tamanho)
	return 0;
    p->m[p->topo++] = d;
    return p;
}


void *PMtira(PilhaM *p)

{
    if(p == 0 || p->topo == 0)
	return 0;
    return p->m[--(p->topo)];
}


#ifdef TESTE

#include <stdio.h>

int main(void)

{
    PilhaM *p;
    int val, *pval;
    
    p = PMcria(7);
    
    do
    {
	printf("Valor a inserir (0 para sair, negativo para retirar): ");
	if(scanf("%d", &val) != 1)
	    return EXIT_FAILURE;
	if(val < 0)
	{
	    printf("Retirando: ");
	    if((pval = PMtira(p)) == 0)
		puts("pilha vazia!");
	    else
	    {
		printf("Retirei %d.\n", *pval);
		free(pval);
	    }
	}
	else if(val > 0)
	{
	    printf("Inserindo: ");
	    if((pval = malloc(sizeof(int))) == 0)
		return EXIT_FAILURE;
	    *pval = val;
	    if(PMpoe(p, pval) == 0)
		puts("pilha cheia!");
	    else
		printf("Inseri %d.\n", val);
	}
    }
    while(val != 0);

    if(PMcheia(p))
	puts("Esta' cheia!");
    
    if(PMquantos(p) != 0)
    {
	printf("Retirando:");
	while((pval = PMtira(p)) != 0)
	{
	    printf(" %d", *pval);
	    free(pval);
	}
	putchar('\n');
    }
    
    PMdestroi(p);

    return EXIT_SUCCESS;
}

#endif