-
Notifications
You must be signed in to change notification settings - Fork 66
/
stack.c
363 lines (344 loc) · 11.7 KB
/
stack.c
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
/**
* @author Amin Tahmasebi
* @date 2023
* @class Stack
*/
#include "stack.h"
#include "../fmt/fmt.h"
#include <stdlib.h>
/**
* @brief Creates a new stack.
*
* This function allocates memory for a new stack and initializes its underlying vector.
* If the allocation for the stack or the vector fails, it logs an error and exits the program.
*
* @param itemSize Size of each item that will be stored in the stack. This is used to initialize
* the underlying vector's item size.
*
* @return Pointer to the newly created stack.
*/
Stack* stack_create(size_t itemSize) {
Stack* stk = (Stack*)malloc(sizeof(Stack));
if (!stk) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Allocation failed for Stack in stack_create.\n");
#endif
exit(-1);
}
stk->vec = vector_create(itemSize);
if (!stk->vec) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Vector creation failed in stack_create.\n");
#endif
free(stk);
exit(-1);
}
return stk;
}
/**
* @brief Checks if two stacks are equal.
*
* This function compares two stacks and returns true if they are considered equal based on
* their underlying vector comparison. If either stack is NULL, it logs an error and returns false.
*
* @param stk1 Pointer to the first stack.
* @param stk2 Pointer to the second stack.
*
* @return true if the two stacks are equal, false otherwise.
*/
bool stack_is_equal(const Stack* stk1, const Stack* stk2) {
if (!stk1 || !stk2) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: One or both Stack pointers are NULL in stack_is_equal.\n");
#endif
return false;
}
return vector_is_equal(stk1->vec, stk2->vec);
}
/**
* @brief Checks if the first stack is less than the second stack.
*
* This function compares two stacks and returns true if the first stack is considered less than
* the second stack based on their underlying vector comparison. If either stack is NULL,
* it logs an error and returns false.
*
* @param stk1 Pointer to the first stack.
* @param stk2 Pointer to the second stack.
*
* @return true if the first stack is less than the second, false otherwise.
*/
bool stack_is_less(const Stack* stk1, const Stack* stk2) {
if (!stk1 || !stk2) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: One or both Stack pointers are NULL in stack_is_less.\n");
#endif
return false;
}
return vector_is_less(stk1->vec, stk2->vec);
}
/**
* @brief Checks if the first stack is greater than the second stack.
*
* This function compares two stacks and returns true if the first stack is considered greater than
* the second stack based on their underlying vector comparison. If either stack is NULL,
* it logs an error and returns false.
*
* @param stk1 Pointer to the first stack.
* @param stk2 Pointer to the second stack.
*
* @return true if the first stack is greater than the second, false otherwise.
*/
bool stack_is_greater(const Stack* stk1, const Stack* stk2) {
if (!stk1 || !stk2) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: One or both Stack pointers are NULL in stack_is_greater.\n");
#endif
return false;
}
return vector_is_greater(stk1->vec, stk2->vec);
}
/**
* @brief Checks if the first stack is less than or equal to the second stack.
*
* This function compares two stacks and returns true if the first stack is considered less than
* or equal to the second stack based on their underlying vector comparison. If either stack is NULL,
* it logs an error and returns false.
*
* @param stk1 Pointer to the first stack.
* @param stk2 Pointer to the second stack.
*
* @return true if the first stack is less than or equal to the second, false otherwise.
*/
bool stack_is_less_or_equal(const Stack* stk1, const Stack* stk2) {
if (!stk1 || !stk2) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: One or both Stack pointers are NULL in stack_is_less_or_equal.\n");
#endif
return false;
}
return stack_is_less(stk1, stk2) || stack_is_equal(stk1, stk2);
}
/**
* @brief Checks if the first stack is greater than or equal to the second stack.
*
* This function compares two stacks and returns true if the first stack is considered greater than
* or equal to the second stack based on their underlying vector comparison. If either stack is NULL,
* it logs an error and returns false.
*
* @param stk1 Pointer to the first stack.
* @param stk2 Pointer to the second stack.
*
* @return true if the first stack is greater than or equal to the second, false otherwise.
*/
bool stack_is_greater_or_equal(const Stack* stk1, const Stack* stk2) {
if (!stk1 || !stk2) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: One or both Stack pointers are NULL in stack_is_greater_or_equal.\n");
#endif
return false;
}
return stack_is_greater(stk1, stk2) || stack_is_equal(stk1, stk2);
}
/**
* @brief Checks if two stacks are not equal.
*
* This function compares two stacks and returns true if the two stacks are not equal
* based on their underlying vector comparison. If either stack is NULL,
* it logs an error and returns false.
*
* @param stk1 Pointer to the first stack.
* @param stk2 Pointer to the second stack.
*
* @return true if the two stacks are not equal, false otherwise.
*/
bool stack_is_not_equal(const Stack* stk1, const Stack* stk2) {
if (!stk1 || !stk2) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: One or both Stack pointers are NULL in stack_is_not_equal.\n");
#endif
return false;
}
return !stack_is_equal(stk1, stk2);
}
/**
* @brief Pushes an item onto the stack.
*
* This function pushes a new item onto the stack. If the stack or the item pointer is NULL,
* it logs an error and exits the program.
*
* @param stk Pointer to the stack where the item will be pushed.
* @param item Pointer to the item that will be pushed onto the stack.
*/
void stack_push(Stack* stk, void* item) {
if (stk == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Stack pointer is NULL in stack_push.\n");
#endif
exit(-1);
}
if (item == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Item pointer is NULL in stack_push.\n");
#endif
exit(-1);
}
vector_push_back(stk->vec, item);
}
/**
* @brief Removes the top item from the stack and returns it.
*
* This function pops the top item from the stack and returns a pointer to it.
* If the stack is NULL or empty, it logs an error or warning, respectively, and returns NULL.
*
* @param stk Pointer to the stack from which the item will be popped.
* @return A pointer to the popped item, or NULL if the stack is empty or NULL.
*/
void* stack_pop(Stack* stk) {
if (stk == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Stack pointer is NULL in stack_pop.\n");
#endif
return NULL;
}
if (vector_is_empty(stk->vec)) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Warning: Attempting to pop from an empty stack in stack_pop.\n");
#endif
return NULL;
}
return vector_pop_back(stk->vec);
}
/**
* @brief Returns the top item of the stack without removing it.
*
* This function returns a pointer to the top item of the stack without removing it.
* If the stack is NULL or empty, it logs an error or warning, respectively, and returns NULL.
*
* @param stk Pointer to the stack whose top item will be accessed.
* @return A pointer to the top item of the stack, or NULL if the stack is empty or NULL.
*/
void* stack_top(Stack* stk) {
if (stk == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Stack pointer is NULL in stack_top.\n");
#endif
return NULL;
}
if (vector_is_empty(stk->vec)) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Warning: Attempting to access top of an empty stack in stack_top.\n");
#endif
return NULL;
}
return vector_back(stk->vec);
}
/**
* @brief Returns the number of items in the stack.
*
* This function returns the size of the stack, i.e., the number of items currently in the stack.
* If the stack pointer is NULL, it logs a warning and returns 0.
*
* @param stk Pointer to the stack whose size is to be returned.
* @return The number of items in the stack, or 0 if the stack is NULL.
*/
size_t stack_size(Stack* stk) {
if (stk == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Warning: Stack pointer is NULL in stack_size. Returning 0.\n");
#endif
return 0;
}
return vector_size(stk->vec);
}
/**
* @brief Checks if the stack is empty.
*
* This function checks whether the stack is empty. A NULL stack is considered empty.
*
* @param stk Pointer to the stack to be checked.
* @return true if the stack is empty or NULL, false otherwise.
*/
bool stack_empty(Stack* stk) {
if (stk == NULL) {
return true; // Consider a NULL stack as empty
}
return vector_is_empty(stk->vec);
}
/**
* @brief Emplaces an item at the top of the stack.
*
* This function adds a new item to the top of the stack without copying it. It directly constructs the item
* in place at the top of the stack. If the stack or the item pointer is NULL, an error is logged.
*
* @param stk Pointer to the stack where the item will be emplaced.
* @param item Pointer to the item to be emplaced on the stack.
*/
void stack_emplace(Stack* stk, void* item) {
if (stk == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Stack pointer is NULL in stack_emplace.\n");
#endif
return;
}
if (item == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Item pointer is NULL in stack_emplace.\n");
#endif
return;
}
vector_emplace_back(stk->vec, item, stk->vec->itemSize);
}
/**
* @brief Clears all items from the stack.
*
* This function removes all items from the stack, effectively resetting its size to zero.
* If the stack pointer is NULL, an error is logged.
*
* @param stk Pointer to the stack to be cleared.
*/
void stack_clear(Stack* stk) {
if (stk == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Stack pointer is NULL in stack_clear.\n");
#endif
return;
}
vector_clear(stk->vec);
}
/**
* @brief Swaps the contents of two stacks.
*
* This function exchanges the contents of two stacks. If either of the stack pointers is NULL, an error is logged.
*
* @param stk1 Pointer to the first stack.
* @param stk2 Pointer to the second stack.
*/
void stack_swap(Stack* stk1, Stack* stk2) {
if (stk1 == NULL || stk2 == NULL) {
fmt_fprintf(stderr, "Error: One or both stack pointers are NULL in stack_swap.\n");
return;
}
Vector* tempVec = stk1->vec;
stk1->vec = stk2->vec;
stk2->vec = tempVec;
}
/**
* @brief Deallocates the stack and frees up memory.
*
* This function deallocates the memory used by the stack, including the underlying vector.
* If the stack pointer is NULL, an error is logged.
*
* @param stk Pointer to the stack to be deallocated.
*/
void stack_deallocate(Stack* stk) {
if (stk == NULL) {
#ifdef STACK_LOGGING_ENABLE
fmt_fprintf(stderr, "Error: Stack pointer is NULL in stack_deallocate.\n");
#endif
return;
}
if (stk->vec != NULL) {
vector_deallocate(stk->vec); // Deallocate the underlying vector
}
free(stk); // Free the stack itself
}