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