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__