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
10
11
17STACK *new_stack( size_t size )
18{
19 STACK *stack = NULL ;
20
21 Malloc( stack , STACK , 1 );
22 __n_assert( stack , return NULL );
23 Malloc( stack -> stack_array , STACK_ITEM , size );
24 __n_assert( stack -> stack_array , Free( stack); return NULL; );
25
26 stack -> size = size ;
27 stack -> head = stack -> tail = 0 ;
28 stack -> nb_items = 0 ;
29 return stack ;
30}
31
32
38bool delete_stack( STACK **stack )
39{
40 __n_assert( (*stack) , return FALSE );
41 Free( (*stack) -> stack_array );
42 Free( (*stack) );
43 return TRUE ;
44}
45
51bool stack_is_full( STACK *stack )
52{
53 return ( stack -> nb_items == stack -> size );
54}
55
61bool stack_is_empty( STACK *stack )
62{
63 return ( stack -> nb_items == 0 );
64}
65
72STACK_ITEM *stack_peek( STACK *stack , size_t position )
73{
74 STACK_ITEM *item = NULL ;
75 __n_assert( stack , return NULL );
76
77 if( stack_is_empty( stack ) )
78 {
79 return FALSE ;
80 }
81
82 if( stack -> tail < stack -> head )
83 {
84 if( position >= stack -> tail && position <= stack -> head && position < stack -> size && stack -> stack_array[ position ] . is_set )
85 {
86 item = &stack -> stack_array[ position ];
87 }
88 }
89 else if( stack -> tail > stack -> head )
90 {
91 if( position >= stack -> head && position <= stack -> tail && position < stack -> size && stack -> stack_array[ position ] . is_set )
92 {
93 item = &stack -> stack_array[ position ];
94 }
95 }
96 return item ;
97}
98
99
100
107size_t __stack_push( STACK *stack , uint8_t *status )
108{
109 (*status) = STACK_IS_UNDEFINED ;
110 __n_assert( stack , return 0 );
111
112 (*status) = STACK_IS_FULL ;
113 if( stack_is_full( stack ) )
114 return 0 ;
115
116 size_t next_pos = ( stack -> head + 1 ) % stack -> size ;
117
118 // if next_pos == tail, the stack is full
119 if( next_pos == stack -> tail )
120 {
121 // status already set to (*status) = STACK_IS_FULL ;
122 return 0 ;
123 }
124
125 // set data, move, set item status, inc counter
126 (*status) = STACK_ITEM_OK ;
127 stack -> stack_array[ stack -> head ] . is_set = 1 ;
128 stack -> stack_array[ stack -> head ] . is_empty = 0 ;
129 // inc
130 stack -> nb_items ++ ;
131 return next_pos ;
132}
133
140size_t __stack_pop( STACK *stack , uint8_t *status )
141{
142 (*status) = STACK_IS_UNDEFINED ;
143 __n_assert( stack , return FALSE );
144
145 size_t next_pos = 0;
146 size_t prev_pos = 0;
147
148 // if the head == tail, the stack is empty
149 if( stack -> head == stack -> tail )
150 {
151 (*status) = STACK_IS_EMPTY ;
152 return 0;
153 }
154
155 // item is here and read
156 (*status) = STACK_ITEM_OK ;
157
158 // next is where tail will point to after this read
159 next_pos = (stack -> tail + 1) % stack -> size;
160
161 // set item status, dec counter, move, return value
162 stack -> stack_array[ stack -> tail ] . is_set = 0 ;
163 stack -> stack_array[ stack -> tail ] . is_empty = 1 ;
164 prev_pos = stack -> tail ;
165 // tail to next offset.
166 stack -> tail = next_pos ;
167 // dec
168 stack -> nb_items -- ;
169 return prev_pos ;
170}
171
178bool stack_push_b( STACK *stack , bool b )
179{
180 uint8_t status = STACK_ITEM_OK ;
181 size_t next_pos = __stack_push( stack , &status );
182 if( status != STACK_ITEM_OK )
183 return FALSE ;
184 stack -> stack_array[ stack -> head ] . data . b = b;
185 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_BOOL ;
186 stack -> head = next_pos ;
187
188 return TRUE ;
189}
190
197bool stack_pop_b( STACK *stack , uint8_t *status )
198{
199 (*status) = STACK_IS_UNDEFINED ;
200 __n_assert( stack , return FALSE );
201
202 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_BOOL )
203 {
204 (*status) = STACK_ITEM_WRONG_TYPE ;
205 return 0 ;
206 }
207
208 uint8_t pop_status = STACK_IS_UNDEFINED ;
209 size_t prev_pos = __stack_pop( stack , &pop_status );
210 if( pop_status != STACK_ITEM_OK )
211 {
212 (*status) = pop_status ;
213 return 0 ;
214 }
215 return stack -> stack_array[ prev_pos ] . data . b ;
216}
217
218
225bool stack_push_c( STACK *stack , char c )
226{
227 uint8_t status = STACK_ITEM_OK ;
228
229 size_t next_pos = __stack_push( stack , &status );
230 if( status != STACK_ITEM_OK )
231 return FALSE ;
232
233 stack -> stack_array[ stack -> head ] . data . c = c;
234 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_CHAR ;
235 stack -> head = next_pos ;
236
237 return TRUE ;
238}
239
246char stack_pop_c( STACK *stack , uint8_t *status )
247{
248 (*status) = STACK_IS_UNDEFINED ;
249 __n_assert( stack , return FALSE );
250
251 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_CHAR )
252 {
253 (*status) = STACK_ITEM_WRONG_TYPE ;
254 return 0 ;
255 }
256
257 uint8_t pop_status = STACK_IS_UNDEFINED ;
258 size_t prev_pos = __stack_pop( stack , &pop_status );
259 if( pop_status != STACK_ITEM_OK )
260 {
261 (*status) = pop_status ;
262 return 0 ;
263 }
264 return stack -> stack_array[ prev_pos ] . data . c ;
265}
266
267
268
275bool stack_push_ui8( STACK *stack , uint8_t ui8 )
276{
277 uint8_t status = STACK_ITEM_OK ;
278
279 size_t next_pos = __stack_push( stack , &status );
280 if( status != STACK_ITEM_OK )
281 return FALSE ;
282
283 stack -> stack_array[ stack -> head ] . data . ui8 = ui8;
284 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_UINT8 ;
285 stack -> head = next_pos ;
286
287 return TRUE ;
288}
289
296uint8_t stack_pop_ui8( STACK *stack , uint8_t *status )
297{
298 (*status) = STACK_IS_UNDEFINED ;
299 __n_assert( stack , return FALSE );
300
301 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_UINT8 )
302 {
303 (*status) = STACK_ITEM_WRONG_TYPE ;
304 return 0 ;
305 }
306
307 uint8_t pop_status = STACK_IS_UNDEFINED ;
308 size_t prev_pos = __stack_pop( stack , &pop_status );
309 if( pop_status != STACK_ITEM_OK )
310 {
311 (*status) = pop_status ;
312 return 0 ;
313 }
314 return stack -> stack_array[ prev_pos ] . data . ui8 ;
315}
316
323bool stack_push_i8( STACK *stack , int8_t i8 )
324{
325 uint8_t status = STACK_ITEM_OK ;
326
327 size_t next_pos = __stack_push( stack , &status );
328 if( status != STACK_ITEM_OK )
329 return FALSE ;
330
331 stack -> stack_array[ stack -> head ] . data . i8 = i8;
332 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_INT8 ;
333 stack -> head = next_pos ;
334
335 return TRUE ;
336}
337
344int8_t stack_pop_i8( STACK *stack , uint8_t *status )
345{
346 (*status) = STACK_IS_UNDEFINED ;
347 __n_assert( stack , return FALSE );
348
349 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_INT8 )
350 {
351 (*status) = STACK_ITEM_WRONG_TYPE ;
352 return 0 ;
353 }
354
355 uint8_t pop_status = STACK_IS_UNDEFINED ;
356 size_t prev_pos = __stack_pop( stack , &pop_status );
357 if( pop_status != STACK_ITEM_OK )
358 {
359 (*status) = pop_status ;
360 return 0 ;
361 }
362 return stack -> stack_array[ prev_pos ] . data . i8 ;
363}
364
371bool stack_push_ui32( STACK *stack , uint32_t ui32 )
372{
373 uint8_t status = STACK_ITEM_OK ;
374
375 size_t next_pos = __stack_push( stack , &status );
376 if( status != STACK_ITEM_OK )
377 return FALSE ;
378
379 stack -> stack_array[ stack -> head ] . data . ui32 = ui32;
380 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_UINT32 ;
381 stack -> head = next_pos ;
382
383 return TRUE ;
384}
385
392uint32_t stack_pop_ui32( STACK *stack , uint8_t *status )
393{
394 (*status) = STACK_IS_UNDEFINED ;
395 __n_assert( stack , return FALSE );
396
397 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_UINT32 )
398 {
399 (*status) = STACK_ITEM_WRONG_TYPE ;
400 return 0 ;
401 }
402
403 uint8_t pop_status = STACK_IS_UNDEFINED ;
404 size_t prev_pos = __stack_pop( stack , &pop_status );
405 if( pop_status != STACK_ITEM_OK )
406 {
407 (*status) = pop_status ;
408 return 0 ;
409 }
410 return stack -> stack_array[ prev_pos ] . data . ui32 ;
411}
412
419bool stack_push_i32( STACK *stack , int32_t i32 )
420{
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 . i32 = i32;
428 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_INT32 ;
429 stack -> head = next_pos ;
430
431 return TRUE ;
432}
433
440int32_t stack_pop_i32( STACK *stack , uint8_t *status )
441{
442 (*status) = STACK_IS_UNDEFINED ;
443 __n_assert( stack , return FALSE );
444
445 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_INT32 )
446 {
447 (*status) = STACK_ITEM_WRONG_TYPE ;
448 return 0 ;
449 }
450
451 uint8_t pop_status = STACK_IS_UNDEFINED ;
452 size_t prev_pos = __stack_pop( stack , &pop_status );
453 if( pop_status != STACK_ITEM_OK )
454 {
455 (*status) = pop_status ;
456 return 0 ;
457 }
458 return stack -> stack_array[ prev_pos ] . data . i32 ;
459}
460
467bool stack_push_f( STACK *stack , float f )
468{
469 uint8_t status = STACK_ITEM_OK ;
470
471 size_t next_pos = __stack_push( stack , &status );
472 if( status != STACK_ITEM_OK )
473 return FALSE ;
474
475 stack -> stack_array[ stack -> head ] . data . f = f ;
476 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_FLOAT ;
477 stack -> head = next_pos ;
478
479 return TRUE ;
480}
481
488float stack_pop_f( STACK *stack , uint8_t *status )
489{
490 (*status) = STACK_IS_UNDEFINED ;
491 __n_assert( stack , return FALSE );
492
493 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_FLOAT )
494 {
495 (*status) = STACK_ITEM_WRONG_TYPE ;
496 return 0 ;
497 }
498
499 uint8_t pop_status = STACK_IS_UNDEFINED ;
500 size_t prev_pos = __stack_pop( stack , &pop_status );
501 if( pop_status != STACK_ITEM_OK )
502 {
503 (*status) = pop_status ;
504 return 0 ;
505 }
506 return stack -> stack_array[ prev_pos ] . data . f ;
507}
508
515bool stack_push_d( STACK *stack , double d )
516{
517 uint8_t status = STACK_ITEM_OK ;
518
519 size_t next_pos = __stack_push( stack , &status );
520 if( status != STACK_ITEM_OK )
521 return FALSE ;
522
523 stack -> stack_array[ stack -> head ] . data . d = d ;
524 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_DOUBLE ;
525 stack -> head = next_pos ;
526
527 return TRUE ;
528}
529
536double stack_pop_d( STACK *stack , uint8_t *status )
537{
538 (*status) = STACK_IS_UNDEFINED ;
539 __n_assert( stack , return FALSE );
540
541 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_DOUBLE )
542 {
543 (*status) = STACK_ITEM_WRONG_TYPE ;
544 return 0 ;
545 }
546
547 uint8_t pop_status = STACK_IS_UNDEFINED ;
548 size_t prev_pos = __stack_pop( stack , &pop_status );
549 if( pop_status != STACK_ITEM_OK )
550 {
551 (*status) = pop_status ;
552 return 0 ;
553 }
554 return stack -> stack_array[ prev_pos ] . data . d ;
555}
556
557
565bool stack_push_p( STACK *stack , void *p , uint16_t p_type )
566{
567 uint8_t status = STACK_ITEM_OK ;
568
569 size_t next_pos = __stack_push( stack , &status );
570 if( status != STACK_ITEM_OK )
571 return FALSE ;
572
573 stack -> stack_array[ stack -> head ] . data . p = p ;
574 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_PTR ;
575 stack -> stack_array[ stack -> head ] . p_type = p_type ;
576 stack -> head = next_pos ;
577
578 return TRUE ;
579}
580
581
588void *stack_pop_p( STACK *stack , uint8_t *status )
589{
590 (*status) = STACK_IS_UNDEFINED ;
591 __n_assert( stack , return FALSE );
592
593 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_PTR )
594 {
595 (*status) = STACK_ITEM_WRONG_TYPE ;
596 return 0 ;
597 }
598
599 uint8_t pop_status = STACK_IS_UNDEFINED ;
600 size_t prev_pos = __stack_pop( stack , &pop_status );
601 if( pop_status != STACK_ITEM_OK )
602 {
603 (*status) = pop_status ;
604 return 0 ;
605 }
606 return stack -> stack_array[ prev_pos ] . data . p ;
607}
608
609#ifdef ENV_64BITS
616bool stack_push_ui64( STACK *stack , uint64_t ui64 )
617{
618 uint8_t status = STACK_ITEM_OK ;
619
620 size_t next_pos = __stack_push( stack , &status );
621 if( status != STACK_ITEM_OK )
622 return FALSE ;
623
624 stack -> stack_array[ stack -> head ] . data . ui64 = ui64;
625 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_UINT64 ;
626 stack -> head = next_pos ;
627
628 return TRUE ;
629}
630
637uint64_t stack_pop_ui64( STACK *stack , uint8_t *status )
638{
639 (*status) = STACK_IS_UNDEFINED ;
640 __n_assert( stack , return FALSE );
641
642 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_UINT64 )
643 {
644 (*status) = STACK_ITEM_WRONG_TYPE ;
645 return 0 ;
646 }
647
648 uint8_t pop_status = STACK_IS_UNDEFINED ;
649 size_t prev_pos = __stack_pop( stack , &pop_status );
650 if( pop_status != STACK_ITEM_OK )
651 {
652 (*status) = pop_status ;
653 return 0 ;
654 }
655 return stack -> stack_array[ prev_pos ] . data . ui64 ;
656}
657
658
665bool stack_push_i64( STACK *stack , int64_t i64 )
666{
667 uint8_t status = STACK_ITEM_OK ;
668
669 size_t next_pos = __stack_push( stack , &status );
670 if( status != STACK_ITEM_OK )
671 return FALSE ;
672
673 stack -> stack_array[ stack -> head ] . data . i64 = i64;
674 stack -> stack_array[ stack -> head ] . v_type = STACK_ITEM_INT64 ;
675 stack -> head = next_pos ;
676
677 return TRUE ;
678}
679
686int64_t stack_pop_i64( STACK *stack , uint8_t *status )
687{
688 (*status) = STACK_IS_UNDEFINED ;
689 __n_assert( stack , return FALSE );
690
691 if( stack -> stack_array[ stack -> tail ] . v_type != STACK_ITEM_INT64 )
692 {
693 (*status) = STACK_ITEM_WRONG_TYPE ;
694 return 0 ;
695 }
696
697 uint8_t pop_status = STACK_IS_UNDEFINED ;
698 size_t prev_pos = __stack_pop( stack , &pop_status );
699 if( pop_status != STACK_ITEM_OK )
700 {
701 (*status) = pop_status ;
702 return 0 ;
703 }
704 return stack -> stack_array[ prev_pos ] . data . i64 ;
705}
706#endif
707
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:191
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:284
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:264
bool stack_push_f(STACK *stack, float f)
helper to push a float
Definition n_stack.c:467
#define STACK_ITEM_UINT64
v_type value for a uint64_t
Definition n_stack.h:36
bool stack_is_empty(STACK *stack)
test if the stack is empty
Definition n_stack.c:61
double stack_pop_d(STACK *stack, uint8_t *status)
helper to pop a double
Definition n_stack.c:536
bool stack_pop_b(STACK *stack, uint8_t *status)
helper to pop a bool
Definition n_stack.c:197
bool stack_push_d(STACK *stack, double d)
helper to push a double
Definition n_stack.c:515
bool stack_push_ui8(STACK *stack, uint8_t ui8)
helper to push an uint8_t
Definition n_stack.c:275
#define STACK_ITEM_UINT32
v_type value for a uint32_t
Definition n_stack.h:32
STACK_ITEM * stack_peek(STACK *stack, size_t position)
peek in the stack with un stacking the stack item
Definition n_stack.c:72
bool stack_is_full(STACK *stack)
test if the stack is full
Definition n_stack.c:51
bool stack_push_ui32(STACK *stack, uint32_t ui32)
helper to push an uint32_t
Definition n_stack.c:371
int8_t stack_pop_i8(STACK *stack, uint8_t *status)
helper to pop a int8_t
Definition n_stack.c:344
#define STACK_ITEM_INT8
v_type value for a int8_t
Definition n_stack.h:30
char stack_pop_c(STACK *stack, uint8_t *status)
helper to pop a char
Definition n_stack.c:246
float stack_pop_f(STACK *stack, uint8_t *status)
helper to pop a float
Definition n_stack.c:488
#define STACK_ITEM_PTR
v_type value for a void *pointer
Definition n_stack.h:44
uint8_t stack_pop_ui8(STACK *stack, uint8_t *status)
helper to pop a uint8_t
Definition n_stack.c:296
bool stack_push_c(STACK *stack, char c)
helper to push a char
Definition n_stack.c:225
#define STACK_IS_EMPTY
code for an empty stack state
Definition n_stack.h:49
#define STACK_ITEM_INT64
v_type value for a int64_t
Definition n_stack.h:38
#define STACK_ITEM_INT32
v_type value for a int32_t
Definition n_stack.h:34
#define STACK_IS_FULL
code for a full stack state
Definition n_stack.h:47
#define STACK_ITEM_CHAR
v_type value for a char
Definition n_stack.h:26
#define STACK_ITEM_OK
code for a successfully retrieved item
Definition n_stack.h:55
uint32_t stack_pop_ui32(STACK *stack, uint8_t *status)
helper to pop a uint32_t
Definition n_stack.c:392
bool stack_push_b(STACK *stack, bool b)
helper to push a bool
Definition n_stack.c:178
#define STACK_ITEM_BOOL
v_type value for a bool
Definition n_stack.h:24
#define STACK_IS_UNDEFINED
code for a NULL stack state
Definition n_stack.h:51
#define STACK_ITEM_UINT8
v_type value for a uint8_t
Definition n_stack.h:28
bool stack_push_i32(STACK *stack, int32_t i32)
helper to push an int32_t
Definition n_stack.c:419
int32_t stack_pop_i32(STACK *stack, uint8_t *status)
helper to pop a int32_t
Definition n_stack.c:440
#define STACK_ITEM_WRONG_TYPE
code for a bad item type
Definition n_stack.h:53
#define STACK_ITEM_DOUBLE
v_type value for a double
Definition n_stack.h:42
bool delete_stack(STACK **stack)
delete a STACK *stack
Definition n_stack.c:38
bool stack_push_i8(STACK *stack, int8_t i8)
helper to push an int8_t
Definition n_stack.c:323
#define STACK_ITEM_FLOAT
v_type value for a float
Definition n_stack.h:40
STACK * new_stack(size_t size)
allocate a new STACK
Definition n_stack.c:17
bool stack_push_p(STACK *stack, void *p, uint16_t p_type)
helper to push a pointer
Definition n_stack.c:565
void * stack_pop_p(STACK *stack, uint8_t *status)
helper to pop a pointer
Definition n_stack.c:588
STACK structure.
Definition n_stack.h:104
structure of a STACK item
Definition n_stack.h:88
size_t __stack_push(STACK *stack, uint8_t *status)
helper for stack_push.
Definition n_stack.c:107
size_t __stack_pop(STACK *stack, uint8_t *status)
helper for stack_pop.
Definition n_stack.c:140