-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathstack.c
More file actions
101 lines (88 loc) · 2.63 KB
/
stack.c
File metadata and controls
101 lines (88 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
* Copyright (c) 2017 Jackson Gable
*
* This file is released under the MIT License.
*/
#include <stdlib.h>
#include <string.h>
#include "stack.h"
typedef struct stack {
/*
* Points to the top of the stack.
*
* Push elements to 'stack_origin + stack_ptr'.
* Pop elements from 'stack_origin + stack_ptr - 1.'
*
* The value of stack_ptr will always be equivalent to the number of
* elements on the stack.
*/
unsigned int stack_ptr;
/*
* The maximum capacity of the stack
*/
unsigned int max_capacity;
/*
* The memory address of the bottom of the stack. Note: This stack grows upwards.
*/
void **stack_origin;
} stack;
/*
* Allocates a new stack with size 'capacity' on the heap and
* returns a pointer to the new stack
*/
stack *alloc_stack(unsigned int capacity) {
stack *stack = malloc(sizeof(stack));
stack->stack_ptr = 0;
stack->max_capacity = capacity;
stack->stack_origin = (void**) calloc(capacity, sizeof(void*));
return stack;
}
/*
* Pushes a pointer to an element to the stack.
*
* Returns the pointer to the stack element on success, or STACK_OVERFLOW_ERR on failure.
*/
void *push(stack *stack, const void *element_ptr) {
if (stack->stack_ptr + 1 > stack->max_capacity)
return STACK_OVERFLOW_ERR; //Stack overflow!
void *push_address = stack->stack_origin + stack->stack_ptr++;
memcpy(push_address, element_ptr, sizeof(void*));
return push_address;
}
/*
* Returns a pointer to the element on the top of the stack. If the stack is empty,
* returns STACK_UNDERFLOW_ERR.
*
* Note: Be sure to cast this function's return value into a pointer of the
* element's type before dereferencing.
*/
void *peek(const stack *stack) {
if ((signed)stack->stack_ptr - 1 < 0)
return STACK_UNDERFLOW_ERR; //Stack underflow!
return stack->stack_ptr + stack->stack_origin - 1;
}
/*
* Returns a pointer to the element on the top of the stack, and
* removes the element from the stack. If the stack is empty,
* returns STACK_UNDERFLOW_ERR
*
* Note: Be sure to cast this function's return value into a pointer of the
* element's type before dereferencing.
*/
void *pop(stack *stack) {
if ((signed)stack->stack_ptr - 1 < 0)
return STACK_UNDERFLOW_ERR; //Stack underflow!
return stack->stack_origin + --stack->stack_ptr;
}
/*
* Returns the number of elements currently on the stack
*/
unsigned int stack_size(const stack *stack) {
return stack->stack_ptr;
}
/*
* Returns the number of elements this stack can hold
*/
unsigned int stack_capacity(const stack *stack) {
return stack->max_capacity;
}