Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_list.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
28#include "nilorea/n_log.h"
29#include "nilorea/n_list.h"
30#include "nilorea/n_str.h"
31
32#define LIST_LIMIT 10
33#define NB_TEST_ELEM 15
34
35void print_list_info(LIST* list) {
36 __n_assert(list, return);
37 n_log(LOG_NOTICE, "List: %p, %d max_elements , %d elements", list, list->nb_max_items, list->nb_items);
38}
39
40int nstrcmp(const void* a, const void* b) {
41 const N_STR* s1 = a;
42 const N_STR* s2 = b;
43
44 if (!s1 || !s1->data)
45 return 1;
46 if (!s2 || !s2->data)
47 return -1;
48
49 return strcmp(s1->data, s2->data);
50}
51
52int main(void) {
54
56
57 __n_assert(list, return FALSE);
58
59 N_STR* nstr = NULL;
60
61 n_log(LOG_NOTICE, "Testing empty list cleaning");
62
63 list_destroy(&list);
64
65 n_log(LOG_NOTICE, "list list: adding %d element in list element (%d) list, empty the list at the end", NB_TEST_ELEM, LIST_LIMIT);
67 for (int it = 0; it < NB_TEST_ELEM; it++) {
68 nstrprintf(nstr, "Nombre aleatoire : %d", rand() % 1000);
69 if (nstr) {
70 int func = rand() % 4;
71 switch (func) {
72 case 0:
73 n_log(LOG_NOTICE, "list_push");
74 if (list_push(list, nstr, free_nstr_ptr) == FALSE)
75 free_nstr(&nstr);
76 break;
77 case 1:
78 n_log(LOG_NOTICE, "list_unshift");
79 if (list_unshift(list, nstr, free_nstr_ptr) == FALSE)
80 free_nstr(&nstr);
81 break;
82 case 2:
83 n_log(LOG_NOTICE, "list_push_sorted");
84 if (list_push_sorted(list, nstr, nstrcmp, free_nstr_ptr) == FALSE)
85 free_nstr(&nstr);
86 break;
87 case 3:
88 n_log(LOG_NOTICE, "list_unshift");
89 if (list_unshift_sorted(list, nstr, nstrcmp, free_nstr_ptr) == FALSE)
90 free_nstr(&nstr);
91 break;
92 default:
93 n_log(LOG_ERR, "should never happen: no func %d !", func);
94 break;
95 }
96 nstr = NULL;
97 print_list_info(list);
98 }
99 }
100 n_log(LOG_NOTICE, "Emptying the list and setting nb_max_item to unlimit");
101 list_empty(list);
102 /* setiing no item limit in list */
104 for (int it = 0; it < NB_TEST_ELEM; it++) {
105 nstrprintf(nstr, "Nombre aleatoire : %d", rand() % 1000);
106 if (nstr) {
107 int func = rand() % 4;
108 switch (func) {
109 case 0:
110 n_log(LOG_NOTICE, "list_push");
111 if (list_push(list, nstr, free_nstr_ptr) == FALSE)
112 free_nstr(&nstr);
113 break;
114 case 1:
115 n_log(LOG_NOTICE, "list_unshift");
116 if (list_unshift(list, nstr, free_nstr_ptr) == FALSE)
117 free_nstr(&nstr);
118 break;
119 case 2:
120 n_log(LOG_NOTICE, "list_push_sorted");
121 if (list_push_sorted(list, nstr, nstrcmp, free_nstr_ptr) == FALSE)
122 free_nstr(&nstr);
123 break;
124 case 3:
125 n_log(LOG_NOTICE, "list_unshift sorted");
126 if (list_unshift_sorted(list, nstr, nstrcmp, free_nstr_ptr) == FALSE)
127 free_nstr(&nstr);
128 break;
129 default:
130 n_log(LOG_ERR, "should never happen: no func %d !", func);
131 break;
132 }
133 nstr = NULL;
134 print_list_info(list);
135 }
136 }
137 list_foreach(node, list) {
138 N_STR* nodestr = (N_STR*)node->ptr;
139 n_log(LOG_INFO, "Listnode: %p item: %s", node, nodestr->data);
140 }
141
142 /* test list_pop and list_shift */
143 N_STR* popped = list_pop(list, N_STR);
144 if (popped) {
145 n_log(LOG_INFO, "list_pop: %s", _nstr(popped));
146 free_nstr_ptr(popped);
147 }
148 N_STR* shifted = list_shift(list, N_STR);
149 if (shifted) {
150 n_log(LOG_INFO, "list_shift: %s", _nstr(shifted));
151 free_nstr_ptr(shifted);
152 }
153
154 /* test list_search */
155 if (list->nb_items > 0) {
156 LIST_NODE* first = list->start;
157 LIST_NODE* found = list_search(list, first->ptr);
158 if (found) {
159 n_log(LOG_INFO, "list_search found node: %p", found);
160 }
161 }
162
163 /* test remove_list_node */
164 if (list->nb_items > 0) {
165 LIST_NODE* target = list->start;
166 void* removed_ptr = remove_list_node(list, target, void);
167 if (removed_ptr) {
168 n_log(LOG_INFO, "remove_list_node: removed %p", removed_ptr);
169 free_nstr_ptr(removed_ptr);
170 }
171 }
172
173 /* test new_list_node and list_node_push / list_node_pop */
174 nstrprintf(nstr, "Manual node test");
175 if (nstr) {
176 LIST_NODE* manual_node = new_list_node(nstr, free_nstr_ptr);
177 if (manual_node) {
178 list_node_push(list, manual_node);
179 n_log(LOG_INFO, "list_node_push: pushed manual node");
180 }
181 LIST_NODE* popped_node = list_node_pop(list);
182 if (popped_node) {
183 N_STR* popped_nstr = (N_STR*)popped_node->ptr;
184 n_log(LOG_INFO, "list_node_pop: %s", _nstr(popped_nstr));
185 if (popped_node->destroy_func) {
186 popped_node->destroy_func(popped_node->ptr);
187 }
188 Free(popped_node);
189 }
190 nstr = NULL;
191 }
192
193 /* test list_node_unshift / list_node_shift */
194 nstrprintf(nstr, "Unshift node test");
195 if (nstr) {
196 LIST_NODE* manual_node2 = new_list_node(nstr, free_nstr_ptr);
197 if (manual_node2) {
198 list_node_unshift(list, manual_node2);
199 n_log(LOG_INFO, "list_node_unshift: unshifted manual node");
200 }
201 LIST_NODE* shifted_node = list_node_shift(list);
202 if (shifted_node) {
203 N_STR* shifted_nstr = (N_STR*)shifted_node->ptr;
204 n_log(LOG_INFO, "list_node_shift: %s", _nstr(shifted_nstr));
205 if (shifted_node->destroy_func) {
206 shifted_node->destroy_func(shifted_node->ptr);
207 }
208 Free(shifted_node);
209 }
210 nstr = NULL;
211 }
212
213 list_destroy(&list);
214
215 exit(0);
216} /* END_OF_MAIN */
int main(void)
#define NB_TEST_ELEM
Definition ex_list.c:33
#define LIST_LIMIT
Definition ex_list.c:32
void print_list_info(LIST *list)
Definition ex_list.c:35
int nstrcmp(const void *a, const void *b)
Definition ex_list.c:40
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:279
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:263
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
Definition n_common.h:199
void * ptr
void pointer to store
Definition n_list.h:46
size_t nb_max_items
Maximum number of items in the list.
Definition n_list.h:63
LIST_NODE * start
pointer to the start of the list
Definition n_list.h:66
size_t nb_items
number of item currently in the list
Definition n_list.h:61
void(* destroy_func)(void *ptr)
pointer to destructor function if any, else NULL
Definition n_list.h:49
#define UNLIMITED_LIST_ITEMS
flag to pass to new_generic_list for an unlimited number of item in the list.
Definition n_list.h:73
#define list_shift(__LIST_, __TYPE_)
Shift macro helper for void pointer casting.
Definition n_list.h:96
#define list_pop(__LIST_, __TYPE_)
Pop macro helper for void pointer casting.
Definition n_list.h:94
int list_empty(LIST *list)
Empty a LIST list of pointers.
Definition n_list.c:501
LIST_NODE * list_search(LIST *list, const void *ptr)
search ptr in list
Definition n_list.c:469
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
Definition n_list.c:228
int list_node_unshift(LIST *list, LIST_NODE *node)
Add a pointer at the start of the list.
Definition n_list.c:200
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper, safe for node removal during iteration.
Definition n_list.h:89
#define remove_list_node(__LIST_, __NODE_, __TYPE_)
Remove macro helper for void pointer casting.
Definition n_list.h:98
int list_unshift(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer at the start of the list.
Definition n_list.c:317
LIST_NODE * list_node_shift(LIST *list)
Get a LIST_NODE pointer from the start of the list.
Definition n_list.c:170
LIST_NODE * new_list_node(void *ptr, void(*destructor)(void *ptr))
Allocate a new node to link in a list.
Definition n_list.c:57
int list_destroy(LIST **list)
Empty and Free a list container.
Definition n_list.c:548
int list_unshift_sorted(LIST *list, void *ptr, int(*comparator)(const void *a, const void *b), void(*destructor)(void *ptr))
Add a pointer sorted in the list , starting by the start of the list.
Definition n_list.c:349
LIST_NODE * list_node_pop(LIST *list)
Get a LIST_NODE pointer from the end of the list.
Definition n_list.c:143
LIST * new_generic_list(size_t max_items)
Initialiaze a generic list container to max_items pointers.
Definition n_list.c:37
int list_push_sorted(LIST *list, void *ptr, int(*comparator)(const void *a, const void *b), void(*destructor)(void *ptr))
Add a pointer sorted in the list , starting by the end of the list.
Definition n_list.c:261
int list_node_push(LIST *list, LIST_NODE *node)
Add a filled node to the end of the list.
Definition n_list.c:117
Structure of a generic LIST container.
Definition n_list.h:59
Structure of a generic list node.
Definition n_list.h:44
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_DEBUG
debug-level messages
Definition n_log.h:84
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_NOTICE
normal but significant condition
Definition n_log.h:80
#define LOG_INFO
informational
Definition n_log.h:82
char * data
the string
Definition n_str.h:63
void free_nstr_ptr(void *ptr)
Free a N_STR pointer structure.
Definition n_str.c:70
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:203
#define nstrprintf(__nstr_var, __format,...)
Macro to quickly allocate and sprintf to N_STR.
Definition n_str.h:117
A box including a string and his lenght.
Definition n_str.h:61
List structures and definitions.
Generic log system.
N_STR and string function declaration.