Generic stack in C Program

How to Declares a stack structure and functions generically using a C macro in C Programming Language ?


Solution:


#ifndef __ETS_STACK__
#define __ETS_STACK__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbg.h>	// Contains function exitWithMessage

/*

DESCRIPTION:
	Declares a stack structure and functions generically using a C macro.


NORMAL TYPE USAGE:	(int, char, float, ...)
	DEFINE_STACK(float) // Put this in the correct scope (global probably).

	Stack_float stack1;
	Stack_float_init( &stack1 , 10 );	// Initialize with maximum capacity being 10.

	Stack_float_push( &stack1, (float)5);  // Pushes the float value into stack1
	float a = Stack_float_pop( &stack1 );

	printf("%f", a); // Will print 5.0000...

	Stack_float_free( &stack1 );


POINTER TYPE USAGE:	(char*, string, ...)
	typedef char* string
	DEFINE_STACK(string)	// TYPE can't contain a '*' token, so typedef to bypass restriction.

	Stack_string this_is_another_stack;
	Stack_string_init( &this_is_another_stack, 1 ); // Initialize with maximum capacity being 1.

	string test = (string) malloc(5 * sizeof(char)); // If not on heap then BAD things can happen, (but whatever i don't judge).
	test[0] = 'h';					 // (Just don't free a variable on the stack)
	test[1] = 'e';
	test[2] = 'y';
	test[3] = '\0';

	Stack_string_push( &this_is_another_stack, test);
	string temp = Stack_string_pop( &this_is_another_stack);

	printf("%s", temp);		// Prints "hey"

	free(temp);		// REMEMBER to free elements after poping to prevent memory leaks.

	Stack_string_free( &this_is_another_stack );


*/

#define DEFINE_STACK(TYPE) \
	\
typedef struct{	\
	TYPE *array; \
	int top; \
	int capacity; \
}Stack_##TYPE##; \
 \
void Stack_##TYPE##_init(Stack_##TYPE *stack, int capacity){ \
	stack->top=-1; \
	stack->capacity = capacity; \
	stack->array = ( TYPE *)calloc(stack->capacity, sizeof( TYPE )); \
} \
 \
void Stack_##TYPE##_push(Stack_##TYPE *stack, TYPE data){ \
	if(stack->top < stack->capacity)	stack->array[++(stack->top)] = data; \
		else	exitWithMessage("ERROR: too many items for stack."); \
} \
 \
TYPE Stack_##TYPE##_pop(Stack_##TYPE *stack){ \
	if(stack->top >= 0)	{	\
		TYPE var = stack->array[stack->top--]; \
		stack->array[stack->top+1] = 0;	\
		return var; \
		} else	exitWithMessage("ERROR: can't pop, no items in stack."); \
} \
	\
void Stack_##TYPE##_free(Stack_##TYPE *stack){	\
	free(stack->array);	\
}	\


#endif // !__ETS_STACK__


Learn More :