#include <stdio.h>
#include <malloc.h>
#include "ADTStack.h"
struct Stack_t {
void** array;
int top;
int maxCapacity;
void* (*cp_elm)(void*);
void (*fr_elm)(void*);
char* (*lbl_elm)(void*);
};
Stack init(int max_size, void* (*cpy_elm)(void*), void (*free_elm)(void*), char* (*label_elm)(void*)) {
Stack ps;
if ((max_size<=0)||(!cpy_elm)||(!free_elm)||(!label_elm)) {
fprintf(stderr,"Fatal error
");
return NULL;
}
ps = (Stack)malloc(sizeof(struct Stack_t));
if (!ps) {
fprintf(stderr,"Fatal error
");
return NULL;
}
ps->array = malloc(max_size*sizeof(void*));
if (!(ps->array)) {
free(ps);
fprintf(stderr,"Fatal error
");
return NULL;
}
ps->top = 0;
ps->maxCapacity = max_size;
ps->cp_elm = cpy_elm;
ps->fr_elm = free_elm;
ps->lbl_elm = label_elm;
return ps;
}
int push (Stack s, void* elm) {
if((!s)||(s->top==s->maxCapacity)) {
fprintf(stderr,"Fatal error
");
return 0;
}
s->array[s->top] = s->cp_elm(elm);
s->top++;
return 1;
}
void* pop (Stack s) {
if ((!s)||(s->top==0)) {
fprintf(stderr,"Fatal error
");
return NULL;
}
s->top--;
return s->array[s->top];
}
void clear (Stack s) {
if (!s) {
fprintf(stderr,"Fatal error
");
return;
}
while (s->top > 0)
s->fr_elm(s->array[--s->top]);
}
int size(Stack s) {
if (!s) {
fprintf(stderr,"Fatal error
");
return -1;
}
return s->top;
}
void print(Stack s) {
int cur;
char* label = NULL;
if (!s) {
fprintf(stderr,"Fatal error
");
return;
}
cur = s->top;
while (cur > 0) {
label = s->lbl_elm(s->array[--cur]);
if (!label) {
fprintf(stderr,"Fatal error
");
return;
} else {
printf("%s
",label);
free(label);
}
}
}
void destroy (Stack s) {
if (!s) {
fprintf(stderr,"Fatal error
");
return;
}
clear(s);
free(s->array);
free(s);
}
#ifndef _ADTSTACK_H
#define _ADTSTACK_H
typedef struct Stack_t* Stack;
/* initializes the Stack; sets the maximal capacity to max_size
returns a pointer to a record on the HEAP
*/
Stack init(int max_size, void* (*cpy_elm)(void*), void (*free_elm)(void*), char* (*label_elm)(void*));
/* inserts a copy of the element to the top of the stack.
returns a non-zero value upon success, zero on fail.
fails if init was not called prior to that, or if the stack is full. */
int push (Stack s, void* elm);
/* removes the element at the top of the stack and returns it.
fails either if init was not called prior to that, or if the stack is empty */
void* pop (Stack s);
/* removes all elements from the stack; all elements are freed.
fails if init was not called prior to that */
void clear (Stack s);
/* returns the number of elements in the stack, or a negative value when fails.
fails either if init was not called prior to that, or if the stack is empty */
int size(Stack s);
/* prints the contents of the stack.
fails if init was not called prior to that */
void print(Stack s);
/* releases all the resources of the stack */
void destroy (Stack s);
#endif