Following the previous post about Queues, In this post i publish a simple modular stack written in C which can be used either by assigning a static space for the elements of a dynamic one (malloc etc).
In computer science, a stack is an abstract data type that serves as a collection of elements, with two principal operations:
- push, which adds an element to the collection, and
- pop, which removes the most recently added element that was not yet removed.
The order in which elements come off a stack gives rise to its alternative name, LIFO (last in, first out). Additionally, a peek operation may give access to the top without modifying the stack.
/******************************************************************************
* SOF - Header | By: Io.D
******************************************************************************/
#ifndef LIBRARIES_IQUEUE_H_
/******************************************************************************
* Definitions
******************************************************************************/
#define LIBRARIES_IQUEUE_H_
/******************************************************************************
* Includes
******************************************************************************/
#include <stdint.h>
#include <string.h>
/******************************************************************************
* Enumerations, structures & External Variables
******************************************************************************/
typedef enum
{
I_OK = 0x00,
I_ERROR = 0x01,
I_FULL = 0x60,
I_EMPTY = 0x61
}I_Status_Stack;
typedef struct
{
volatile void * storage;
volatile void * last;
volatile void * next;
volatile size_t element_size;
volatile uint32_t max_elements;
}
istack_t;
/******************************************************************************
* Public Functions (API)
******************************************************************************/
I_Status_Stack istack_init(istack_t * _stack, int _max_elements, size_t _element_size, void * _storage);
I_Status_Stack istack_push(istack_t * _stack, void * _element);
I_Status_Stack istack_pop(istack_t * _stack, void * _element);
I_Status_Stack istack_size(istack_t * _stack, uint32_t * _size);
/******************************************************************************
* EOF - Header
******************************************************************************/
#endif/******************************************************************************
* SOF - Source | By: Io.D
******************************************************************************/
/******************************************************************************
* Includes
******************************************************************************/
#include "istack.h"
/******************************************************************************
* Declarations
******************************************************************************/
/******************************************************************************
* Public functions
******************************************************************************/
I_Status_Stack istack_init(istack_t * _stack, int _max_elements, size_t _element_size, void * _storage)
{
if (_stack == NULL)
return I_ERROR;
memset(_storage, 0x00, _element_size*_max_elements);
_stack->element_size = _element_size;
_stack->max_elements = _max_elements;
_stack->storage = _storage;
_stack->last = (void *)0;
_stack->next = (uint8_t *)_stack->storage + ((_max_elements - 1) * _element_size);
return I_OK;
}
I_Status_Stack istack_push(istack_t * _stack, void * _element)
{
if (_stack->last == _stack->next)
return I_FULL;
memmove((void*)_stack->next, (void*)_element, _stack->element_size);
_stack->last = _stack->last == (void*)0 ? _stack->next : _stack->last;
_stack->next = (uint8_t *)_stack->next == (uint8_t *)_stack->storage
? (uint8_t *)_stack->storage + ((_stack->max_elements - 1) * _stack->element_size) : (uint8_t *)_stack->next - _stack->element_size;
return I_OK;
}
I_Status_Stack istack_pop(istack_t * _stack, void * _element)
{
if (_stack->last == (void*)0)
return I_EMPTY;
_stack->next = (uint8_t *)_stack->next == (uint8_t *)_stack->storage + ((_stack->max_elements - 1) * _stack->element_size)
? (uint8_t *)_stack->storage : (uint8_t *)_stack->next + _stack->element_size;
memmove((void*)_element, (void*)_stack->next, _stack->element_size);
memset((uint8_t*)_stack->next, 0x00, _stack->element_size);
_stack->last = _stack->last == _stack->next ? (void*)0 : _stack->last;
return I_OK;
}
I_Status_Stack istack_size(istack_t * _stack, uint32_t * _size)
{
*_size = _stack->last == (void*)0
? 0
: _stack->last > _stack->next
? ((uintptr_t)_stack->last - (uintptr_t)_stack->next) / _stack->element_size
: _stack->max_elements - (((uintptr_t)_stack->next - (uintptr_t)_stack->last) / _stack->element_size);
return I_OK;
}
/******************************************************************************
* Static functions
******************************************************************************/
/******************************************************************************
* EOF - Source
******************************************************************************/Usage:
// Create a stack handle
istack_t stack;
// Set a memory space to save the elements
uint32_t storage[5];
// Initialize the stack
istack_init(&stack, 5, sizeof(uint32_t), storage);
..
..
// Add an element
uint32_t element = 31;
if (istack_push(&stack, &element) == I_FULL)
{
// Stack is full condition
}
..
..
// Retrieve an element
uint32_t element;
if (istack_pop(&stack, &element) == I_EMPTY)
{
// Stack is full empty
}
..
..
// Get the size
uint32_t size;
istack_size(&stack, &size);






