Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_stack.c
Go to the documentation of this file.
1
8#include "nilorea/n_stack.h"
9
15STACK* new_stack(size_t size) {
16 STACK* stack = NULL;
17
18 Malloc(stack, STACK, 1);
19 __n_assert(stack, return NULL);
20 Malloc(stack->stack_array, STACK_ITEM, size);
21 __n_assert(stack->stack_array, Free(stack); return NULL;);
22
23 stack->size = size;
24 stack->head = stack->tail = 0;
25 stack->nb_items = 0;
26 return stack;
27}
28
34bool delete_stack(STACK** stack) {
35 __n_assert((*stack), return FALSE);
36 Free((*stack)->stack_array);
37 Free((*stack));
38 return TRUE;
39}
40
46bool stack_is_full(STACK* stack) {
47 return (stack->nb_items == stack->size);
48}
49
55bool stack_is_empty(STACK* stack) {
56 return (stack->nb_items == 0);
57}
58
65STACK_ITEM* stack_peek(STACK* stack, size_t position) {
66 STACK_ITEM* item = NULL;
67 __n_assert(stack, return NULL);
68
69 if (stack_is_empty(stack)) {
70 return FALSE;
71 }
72
73 if (stack->tail < stack->head) {
74 if (position >= stack->tail && position <= stack->head && position < stack->size && stack->stack_array[position].is_set) {
75 item = &stack->stack_array[position];
76 }
77 } else if (stack->tail > stack->head) {
78 if (position >= stack->head && position <= stack->tail && position < stack->size && stack->stack_array[position].is_set) {
79 item = &stack->stack_array[position];
80 }
81 }
82 return item;
83}
84
91size_t __stack_push(STACK* stack, uint8_t* status) {
92 (*status) = STACK_IS_UNDEFINED;
93 __n_assert(stack, return 0);
94
95 (*status) = STACK_IS_FULL;
96 if (stack_is_full(stack))
97 return 0;
98
99 size_t next_pos = (stack->head + 1) % stack->size;
100
101 // if next_pos == tail, the stack is full
102 if (next_pos == stack->tail) {
103 // status already set to (*status) = STACK_IS_FULL ;
104 return 0;
105 }
106
107 // set data, move, set item status, inc counter
108 (*status) = STACK_ITEM_OK;
109 stack->stack_array[stack->head].is_set = 1;
110 stack->stack_array[stack->head].is_empty = 0;
111 // inc
112 stack->nb_items++;
113 return next_pos;
114}
115
122size_t __stack_pop(STACK* stack, uint8_t* status) {
123 (*status) = STACK_IS_UNDEFINED;
124 __n_assert(stack, return FALSE);
125
126 size_t next_pos = 0;
127 size_t prev_pos = 0;
128
129 // if the head == tail, the stack is empty
130 if (stack->head == stack->tail) {
131 (*status) = STACK_IS_EMPTY;
132 return 0;
133 }
134
135 // item is here and read
136 (*status) = STACK_ITEM_OK;
137
138 // next is where tail will point to after this read
139 next_pos = (stack->tail + 1) % stack->size;
140
141 // set item status, dec counter, move, return value
142 stack->stack_array[stack->tail].is_set = 0;
143 stack->stack_array[stack->tail].is_empty = 1;
144 prev_pos = stack->tail;
145 // tail to next offset.
146 stack->tail = next_pos;
147 // dec
148 stack->nb_items--;
149 return prev_pos;
150}
151
158bool stack_push_b(STACK* stack, bool b) {
159 uint8_t status = STACK_ITEM_OK;
160 size_t next_pos = __stack_push(stack, &status);
161 if (status != STACK_ITEM_OK)
162 return FALSE;
163 stack->stack_array[stack->head].data.b = b;
164 stack->stack_array[stack->head].v_type = STACK_ITEM_BOOL;
165 stack->head = next_pos;
166
167 return TRUE;
168}
169
176bool stack_pop_b(STACK* stack, uint8_t* status) {
177 (*status) = STACK_IS_UNDEFINED;
178 __n_assert(stack, return FALSE);
179
180 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_BOOL) {
181 (*status) = STACK_ITEM_WRONG_TYPE;
182 return 0;
183 }
184
185 uint8_t pop_status = STACK_IS_UNDEFINED;
186 size_t prev_pos = __stack_pop(stack, &pop_status);
187 if (pop_status != STACK_ITEM_OK) {
188 (*status) = pop_status;
189 return 0;
190 }
191 return stack->stack_array[prev_pos].data.b;
192}
193
200bool stack_push_c(STACK* stack, char c) {
201 uint8_t status = STACK_ITEM_OK;
202
203 size_t next_pos = __stack_push(stack, &status);
204 if (status != STACK_ITEM_OK)
205 return FALSE;
206
207 stack->stack_array[stack->head].data.c = c;
208 stack->stack_array[stack->head].v_type = STACK_ITEM_CHAR;
209 stack->head = next_pos;
210
211 return TRUE;
212}
213
220char stack_pop_c(STACK* stack, uint8_t* status) {
221 (*status) = STACK_IS_UNDEFINED;
222 __n_assert(stack, return FALSE);
223
224 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_CHAR) {
225 (*status) = STACK_ITEM_WRONG_TYPE;
226 return 0;
227 }
228
229 uint8_t pop_status = STACK_IS_UNDEFINED;
230 size_t prev_pos = __stack_pop(stack, &pop_status);
231 if (pop_status != STACK_ITEM_OK) {
232 (*status) = pop_status;
233 return 0;
234 }
235 return stack->stack_array[prev_pos].data.c;
236}
237
244bool stack_push_ui8(STACK* stack, uint8_t ui8) {
245 uint8_t status = STACK_ITEM_OK;
246
247 size_t next_pos = __stack_push(stack, &status);
248 if (status != STACK_ITEM_OK)
249 return FALSE;
250
251 stack->stack_array[stack->head].data.ui8 = ui8;
252 stack->stack_array[stack->head].v_type = STACK_ITEM_UINT8;
253 stack->head = next_pos;
254
255 return TRUE;
256}
257
264uint8_t stack_pop_ui8(STACK* stack, uint8_t* status) {
265 (*status) = STACK_IS_UNDEFINED;
266 __n_assert(stack, return FALSE);
267
268 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_UINT8) {
269 (*status) = STACK_ITEM_WRONG_TYPE;
270 return 0;
271 }
272
273 uint8_t pop_status = STACK_IS_UNDEFINED;
274 size_t prev_pos = __stack_pop(stack, &pop_status);
275 if (pop_status != STACK_ITEM_OK) {
276 (*status) = pop_status;
277 return 0;
278 }
279 return stack->stack_array[prev_pos].data.ui8;
280}
281
288bool stack_push_i8(STACK* stack, int8_t i8) {
289 uint8_t status = STACK_ITEM_OK;
290
291 size_t next_pos = __stack_push(stack, &status);
292 if (status != STACK_ITEM_OK)
293 return FALSE;
294
295 stack->stack_array[stack->head].data.i8 = i8;
296 stack->stack_array[stack->head].v_type = STACK_ITEM_INT8;
297 stack->head = next_pos;
298
299 return TRUE;
300}
301
308int8_t stack_pop_i8(STACK* stack, uint8_t* status) {
309 (*status) = STACK_IS_UNDEFINED;
310 __n_assert(stack, return FALSE);
311
312 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_INT8) {
313 (*status) = STACK_ITEM_WRONG_TYPE;
314 return 0;
315 }
316
317 uint8_t pop_status = STACK_IS_UNDEFINED;
318 size_t prev_pos = __stack_pop(stack, &pop_status);
319 if (pop_status != STACK_ITEM_OK) {
320 (*status) = pop_status;
321 return 0;
322 }
323 return stack->stack_array[prev_pos].data.i8;
324}
325
332bool stack_push_ui32(STACK* stack, uint32_t ui32) {
333 uint8_t status = STACK_ITEM_OK;
334
335 size_t next_pos = __stack_push(stack, &status);
336 if (status != STACK_ITEM_OK)
337 return FALSE;
338
339 stack->stack_array[stack->head].data.ui32 = ui32;
340 stack->stack_array[stack->head].v_type = STACK_ITEM_UINT32;
341 stack->head = next_pos;
342
343 return TRUE;
344}
345
352uint32_t stack_pop_ui32(STACK* stack, uint8_t* status) {
353 (*status) = STACK_IS_UNDEFINED;
354 __n_assert(stack, return FALSE);
355
356 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_UINT32) {
357 (*status) = STACK_ITEM_WRONG_TYPE;
358 return 0;
359 }
360
361 uint8_t pop_status = STACK_IS_UNDEFINED;
362 size_t prev_pos = __stack_pop(stack, &pop_status);
363 if (pop_status != STACK_ITEM_OK) {
364 (*status) = pop_status;
365 return 0;
366 }
367 return stack->stack_array[prev_pos].data.ui32;
368}
369
376bool stack_push_i32(STACK* stack, int32_t i32) {
377 uint8_t status = STACK_ITEM_OK;
378
379 size_t next_pos = __stack_push(stack, &status);
380 if (status != STACK_ITEM_OK)
381 return FALSE;
382
383 stack->stack_array[stack->head].data.i32 = i32;
384 stack->stack_array[stack->head].v_type = STACK_ITEM_INT32;
385 stack->head = next_pos;
386
387 return TRUE;
388}
389
396int32_t stack_pop_i32(STACK* stack, uint8_t* status) {
397 (*status) = STACK_IS_UNDEFINED;
398 __n_assert(stack, return FALSE);
399
400 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_INT32) {
401 (*status) = STACK_ITEM_WRONG_TYPE;
402 return 0;
403 }
404
405 uint8_t pop_status = STACK_IS_UNDEFINED;
406 size_t prev_pos = __stack_pop(stack, &pop_status);
407 if (pop_status != STACK_ITEM_OK) {
408 (*status) = pop_status;
409 return 0;
410 }
411 return stack->stack_array[prev_pos].data.i32;
412}
413
420bool stack_push_f(STACK* stack, float f) {
421 uint8_t status = STACK_ITEM_OK;
422
423 size_t next_pos = __stack_push(stack, &status);
424 if (status != STACK_ITEM_OK)
425 return FALSE;
426
427 stack->stack_array[stack->head].data.f = f;
428 stack->stack_array[stack->head].v_type = STACK_ITEM_FLOAT;
429 stack->head = next_pos;
430
431 return TRUE;
432}
433
440float stack_pop_f(STACK* stack, uint8_t* status) {
441 (*status) = STACK_IS_UNDEFINED;
442 __n_assert(stack, return FALSE);
443
444 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_FLOAT) {
445 (*status) = STACK_ITEM_WRONG_TYPE;
446 return 0;
447 }
448
449 uint8_t pop_status = STACK_IS_UNDEFINED;
450 size_t prev_pos = __stack_pop(stack, &pop_status);
451 if (pop_status != STACK_ITEM_OK) {
452 (*status) = pop_status;
453 return 0;
454 }
455 return stack->stack_array[prev_pos].data.f;
456}
457
464bool stack_push_d(STACK* stack, double d) {
465 uint8_t status = STACK_ITEM_OK;
466
467 size_t next_pos = __stack_push(stack, &status);
468 if (status != STACK_ITEM_OK)
469 return FALSE;
470
471 stack->stack_array[stack->head].data.d = d;
472 stack->stack_array[stack->head].v_type = STACK_ITEM_DOUBLE;
473 stack->head = next_pos;
474
475 return TRUE;
476}
477
484double stack_pop_d(STACK* stack, uint8_t* status) {
485 (*status) = STACK_IS_UNDEFINED;
486 __n_assert(stack, return FALSE);
487
488 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_DOUBLE) {
489 (*status) = STACK_ITEM_WRONG_TYPE;
490 return 0;
491 }
492
493 uint8_t pop_status = STACK_IS_UNDEFINED;
494 size_t prev_pos = __stack_pop(stack, &pop_status);
495 if (pop_status != STACK_ITEM_OK) {
496 (*status) = pop_status;
497 return 0;
498 }
499 return stack->stack_array[prev_pos].data.d;
500}
501
509bool stack_push_p(STACK* stack, void* p, uint16_t p_type) {
510 uint8_t status = STACK_ITEM_OK;
511
512 size_t next_pos = __stack_push(stack, &status);
513 if (status != STACK_ITEM_OK)
514 return FALSE;
515
516 stack->stack_array[stack->head].data.p = p;
517 stack->stack_array[stack->head].v_type = STACK_ITEM_PTR;
518 stack->stack_array[stack->head].p_type = p_type;
519 stack->head = next_pos;
520
521 return TRUE;
522}
523
530void* stack_pop_p(STACK* stack, uint8_t* status) {
531 (*status) = STACK_IS_UNDEFINED;
532 __n_assert(stack, return FALSE);
533
534 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_PTR) {
535 (*status) = STACK_ITEM_WRONG_TYPE;
536 return 0;
537 }
538
539 uint8_t pop_status = STACK_IS_UNDEFINED;
540 size_t prev_pos = __stack_pop(stack, &pop_status);
541 if (pop_status != STACK_ITEM_OK) {
542 (*status) = pop_status;
543 return 0;
544 }
545 return stack->stack_array[prev_pos].data.p;
546}
547
548#ifdef ENV_64BITS
555bool stack_push_ui64(STACK* stack, uint64_t ui64) {
556 uint8_t status = STACK_ITEM_OK;
557
558 size_t next_pos = __stack_push(stack, &status);
559 if (status != STACK_ITEM_OK)
560 return FALSE;
561
562 stack->stack_array[stack->head].data.ui64 = ui64;
563 stack->stack_array[stack->head].v_type = STACK_ITEM_UINT64;
564 stack->head = next_pos;
565
566 return TRUE;
567}
568
575uint64_t stack_pop_ui64(STACK* stack, uint8_t* status) {
576 (*status) = STACK_IS_UNDEFINED;
577 __n_assert(stack, return FALSE);
578
579 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_UINT64) {
580 (*status) = STACK_ITEM_WRONG_TYPE;
581 return 0;
582 }
583
584 uint8_t pop_status = STACK_IS_UNDEFINED;
585 size_t prev_pos = __stack_pop(stack, &pop_status);
586 if (pop_status != STACK_ITEM_OK) {
587 (*status) = pop_status;
588 return 0;
589 }
590 return stack->stack_array[prev_pos].data.ui64;
591}
592
599bool stack_push_i64(STACK* stack, int64_t i64) {
600 uint8_t status = STACK_ITEM_OK;
601
602 size_t next_pos = __stack_push(stack, &status);
603 if (status != STACK_ITEM_OK)
604 return FALSE;
605
606 stack->stack_array[stack->head].data.i64 = i64;
607 stack->stack_array[stack->head].v_type = STACK_ITEM_INT64;
608 stack->head = next_pos;
609
610 return TRUE;
611}
612
619int64_t stack_pop_i64(STACK* stack, uint8_t* status) {
620 (*status) = STACK_IS_UNDEFINED;
621 __n_assert(stack, return FALSE);
622
623 if (stack->stack_array[stack->tail].v_type != STACK_ITEM_INT64) {
624 (*status) = STACK_ITEM_WRONG_TYPE;
625 return 0;
626 }
627
628 uint8_t pop_status = STACK_IS_UNDEFINED;
629 size_t prev_pos = __stack_pop(stack, &pop_status);
630 if (pop_status != STACK_ITEM_OK) {
631 (*status) = pop_status;
632 return 0;
633 }
634 return stack->stack_array[prev_pos].data.i64;
635}
636#endif
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:187
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:258
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:242
size_t tail
position of tail
Definition n_stack.h:107
bool is_empty
is item set ?
Definition n_stack.h:89
size_t head
position of head
Definition n_stack.h:105
size_t nb_items
number of item inside stack
Definition n_stack.h:109
STACK_ITEM * stack_array
STACK_ITEM array.
Definition n_stack.h:101
int8_t i8
int 8
Definition n_stack.h:65
uint16_t p_type
if v_type is STACK_ITEM_PTR, user defined pointer type
Definition n_stack.h:95
union STACK_DATA data
union of different types
Definition n_stack.h:91
void * p
pointer
Definition n_stack.h:81
double d
double
Definition n_stack.h:79
size_t size
Size of array.
Definition n_stack.h:103
float f
float
Definition n_stack.h:77
char c
single character
Definition n_stack.h:61
int32_t i32
int 32
Definition n_stack.h:69
uint8_t v_type
type of the item
Definition n_stack.h:93
bool b
boolean
Definition n_stack.h:59
bool is_set
is item empty ?
Definition n_stack.h:87
uint32_t ui32
unsigned int 32
Definition n_stack.h:67
uint8_t ui8
unsigned int 8
Definition n_stack.h:63
bool stack_push_f(STACK *stack, float f)
helper to push a float
Definition n_stack.c:420
#define STACK_ITEM_UINT64
v_type value for a uint64_t
Definition n_stack.h:35
bool stack_is_empty(STACK *stack)
test if the stack is empty
Definition n_stack.c:55
double stack_pop_d(STACK *stack, uint8_t *status)
helper to pop a double
Definition n_stack.c:484
bool stack_pop_b(STACK *stack, uint8_t *status)
helper to pop a bool
Definition n_stack.c:176
bool stack_push_d(STACK *stack, double d)
helper to push a double
Definition n_stack.c:464
bool stack_push_ui8(STACK *stack, uint8_t ui8)
helper to push an uint8_t
Definition n_stack.c:244
#define STACK_ITEM_UINT32
v_type value for a uint32_t
Definition n_stack.h:31
STACK_ITEM * stack_peek(STACK *stack, size_t position)
peek in the stack with un stacking the stack item
Definition n_stack.c:65
bool stack_is_full(STACK *stack)
test if the stack is full
Definition n_stack.c:46
bool stack_push_ui32(STACK *stack, uint32_t ui32)
helper to push an uint32_t
Definition n_stack.c:332
int8_t stack_pop_i8(STACK *stack, uint8_t *status)
helper to pop a int8_t
Definition n_stack.c:308
#define STACK_ITEM_INT8
v_type value for a int8_t
Definition n_stack.h:29
char stack_pop_c(STACK *stack, uint8_t *status)
helper to pop a char
Definition n_stack.c:220
float stack_pop_f(STACK *stack, uint8_t *status)
helper to pop a float
Definition n_stack.c:440
#define STACK_ITEM_PTR
v_type value for a void *pointer
Definition n_stack.h:43
uint8_t stack_pop_ui8(STACK *stack, uint8_t *status)
helper to pop a uint8_t
Definition n_stack.c:264
bool stack_push_c(STACK *stack, char c)
helper to push a char
Definition n_stack.c:200
#define STACK_IS_EMPTY
code for an empty stack state
Definition n_stack.h:48
#define STACK_ITEM_INT64
v_type value for a int64_t
Definition n_stack.h:37
#define STACK_ITEM_INT32
v_type value for a int32_t
Definition n_stack.h:33
#define STACK_IS_FULL
code for a full stack state
Definition n_stack.h:46
#define STACK_ITEM_CHAR
v_type value for a char
Definition n_stack.h:25
#define STACK_ITEM_OK
code for a successfully retrieved item
Definition n_stack.h:54
uint32_t stack_pop_ui32(STACK *stack, uint8_t *status)
helper to pop a uint32_t
Definition n_stack.c:352
bool stack_push_b(STACK *stack, bool b)
helper to push a bool
Definition n_stack.c:158
#define STACK_ITEM_BOOL
v_type value for a bool
Definition n_stack.h:23
#define STACK_IS_UNDEFINED
code for a NULL stack state
Definition n_stack.h:50
#define STACK_ITEM_UINT8
v_type value for a uint8_t
Definition n_stack.h:27
bool stack_push_i32(STACK *stack, int32_t i32)
helper to push an int32_t
Definition n_stack.c:376
int32_t stack_pop_i32(STACK *stack, uint8_t *status)
helper to pop a int32_t
Definition n_stack.c:396
#define STACK_ITEM_WRONG_TYPE
code for a bad item type
Definition n_stack.h:52
#define STACK_ITEM_DOUBLE
v_type value for a double
Definition n_stack.h:41
bool delete_stack(STACK **stack)
delete a STACK *stack
Definition n_stack.c:34
bool stack_push_i8(STACK *stack, int8_t i8)
helper to push an int8_t
Definition n_stack.c:288
#define STACK_ITEM_FLOAT
v_type value for a float
Definition n_stack.h:39
STACK * new_stack(size_t size)
allocate a new STACK
Definition n_stack.c:15
bool stack_push_p(STACK *stack, void *p, uint16_t p_type)
helper to push a pointer
Definition n_stack.c:509
void * stack_pop_p(STACK *stack, uint8_t *status)
helper to pop a pointer
Definition n_stack.c:530
STACK structure.
Definition n_stack.h:99
structure of a STACK item
Definition n_stack.h:85
size_t __stack_push(STACK *stack, uint8_t *status)
helper for stack_push.
Definition n_stack.c:91
size_t __stack_pop(STACK *stack, uint8_t *status)
helper for stack_pop.
Definition n_stack.c:122