/
main.c
397 lines (312 loc) · 10 KB
/
main.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
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
/*
* main.c
* This file is part of dbsglinked
*
* Copyright (C) 2012 - Darcy Brás da Silva
*
* dbsglinked is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* dbsglinked is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dbsglinked. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "glinked_list.h"
/*
returns a copy of a string, can be
considered as node->data allocator
this is a user defined function.
*/
char *sstrdup(const char * str)
{
size_t l = strlen(str);
char *new;
if( (new = malloc(l+1))== NULL)
{
fprintf(stderr,"sstrdup malloc failed\n");
return NULL;
}
memcpy(new,str,l); new[l] ='\0';
return new;
}
/*
the node->data deallocator,
for node->data created by sstrdup
used along with libglinked_create_node
this is a user defined function
*/
void delete_data(void *data)
{
free(data);
}
/*
shows node->data when data is
a string.
used along show_node and show_list
functions.
this is a user defined function
*/
void printstr(void *data)
{
printf("%s\n", (char *)data);
}
/*
shows node->data when data is an
int.
used along with show_node and show_list
functions.
this is a user defined function.
*/
void printint(void *data)
{
printf("%d\n", *(int*)data);
}
/*
returns a copy of a int, can be
considered as node->data allocator
this is a user defined function.
*/
int *icopy(int data)
{
int *new;
size_t sz = sizeof(int);
if( (new = malloc( sz )) == NULL )
{
fprintf(stderr,"icopy malloc failed\n");
return NULL;
}
memcpy(new, &data, sz);
return new;
}
/*
frees node->data allocated by
icopy.
used along with libglinked_create_node
function, as the deallocator parameter
this is a user defined function.
*/
void ideallocator(void *data)
{
free(data);
}
/*
this is the function that is triggered for each item
of the linked list.
for more info check the readme file, but in short,
the return of this function is usually to remark the last
operation made.
state to go accross calls between elements,
data is the node->data
param is for/if you need to pass something else.
used with the libglinked_foreach_node function.
this is a user defined function.
*/
void *sum_int_list(void *state, void *data, void *param)
{
//return value. this can be used to return the last
void *ret = NULL;
(*(int*)state) += ( (*(int*)data) * (*(int*)param) );
(*(int*)data) *= (*(int*)param);
return ret = data;
}
/*
this is a user defined function, however it
needs to respect the given prototype
bool (void*, void *); and needs to return true,
when both are equal.
this is for sample the use of
libglinked_find_node function
*/
bool int_compare(void *data, void *key)
{
return (*(int*)data) == (*(int*)key);
}
int main(int argc, char **argv)
{
//our sample constants
char *str = "Hello World";
char *str2 = "World Hello";
libglinked_node_t *node;
//handle fifo list sample
//the list used to sample a fifo implementation
libglinked_list_t list_fifo;
/*iniciate the list, NULL will set the
default allocator and default deallocator for
libglinked_node_t structures.
default ones are malloc and free.
you can set you own allocators by passing a allocator
of void *(*allocator)(void *)
and a deallocator of void (*deallocator)(void *);
*/
libglinked_init_list(&list_fifo, NULL, NULL);
/*create the node and put it in a temporary node,
the list is used because of the libglinked_node_t
structures allocators
returns null in failure
*/
node = libglinked_create_node(&list_fifo,
(void*) sstrdup(str), delete_data);
//check for failure
if(node == NULL )
fprintf(stderr,"failed to create node %d\n", __LINE__);
//check for failure while trying to add to the fifo list
if(NULL == libglinked_enqueue_node(&list_fifo, node) )
fprintf(stderr,"failed to enqueue node %d\n", __LINE__);
node = libglinked_create_node(&list_fifo,
(void *)sstrdup(str2), delete_data);
if(node == NULL)
fprintf(stderr,"failed to create node %d\n", __LINE__);
if(NULL == libglinked_enqueue_node(&list_fifo, node) )
fprintf(stderr,"failed to enqueue node %d\n", __LINE__);
puts("show fifo results");
libglinked_show_list(&list_fifo, printstr);
puts("the reverse list");
libglinked_reverse_list(&list_fifo);
libglinked_show_list(&list_fifo, printstr);
puts("\n");
//clean the node just to make sure
node = NULL;
libglinked_list_t list_lifo;
//hanlde lifo sample
libglinked_init_list(&list_lifo, NULL, NULL);
node = libglinked_create_node(&list_lifo,
(void*) sstrdup(str), delete_data);
if(node == NULL)
fprintf(stderr,"failed to create node %d\n", __LINE__);
if( NULL == libglinked_push_node(&list_lifo, node) )
fprintf(stderr,"failed to push node %d\n", __LINE__);
node = libglinked_create_node(&list_lifo,
(void *) sstrdup(str2), delete_data);
if(node == NULL)
fprintf(stderr,"failed create node %d\n", __LINE__);
if( NULL == libglinked_push_node(&list_lifo, node) )
fprintf(stderr,"failed to push node %d\n", __LINE__);
puts("show lifo results");
libglinked_show_list(&list_lifo, printstr);
puts("show reverse list");
libglinked_reverse_list(&list_lifo);
libglinked_show_list(&list_lifo, printstr);
puts("\n");
//erase both lists
libglinked_delete_list(&list_fifo);
libglinked_delete_list(&list_lifo);
//handle sample int list
libglinked_list_t list_int;
libglinked_init_list(&list_int, NULL, NULL);
//clean node just to make sure
node = NULL;
node = libglinked_create_node(&list_int,
(void *)icopy(15), ideallocator);
if( node == NULL )
fprintf(stderr,"failed to create list_int node %d\n", __LINE__);
if(NULL == libglinked_enqueue_node(&list_int, node) )
fprintf(stderr,"failed to enqueue node %d\n", __LINE__);
node = libglinked_create_node(&list_fifo,
(void*)icopy(30), ideallocator);
if(node == NULL)
fprintf(stderr,"failed to create node %d\n", __LINE__);
if(NULL == libglinked_enqueue_node(&list_int, node) )
fprintf(stderr,"failed to enqueue node %d\n", __LINE__);
node = libglinked_create_node(&list_int,
(void *)icopy(45), ideallocator);
if(node == NULL )
fprintf(stderr,"failed to create node %d\n", __LINE__);
if(NULL == libglinked_enqueue_node(&list_int, node) )
fprintf(stderr,"failed to enqueue node %d\n", __LINE__);
puts("show int list");
libglinked_show_list(&list_int, printint);
puts("reverse list");
libglinked_reverse_list(&list_int);
libglinked_show_list(&list_int, printint);
//foreach user input
int n = 10,
res=0; // result
//returns of libglinked_foreach_node
void *ret = NULL; //return
void *stateh = &res; //state handler
ret = libglinked_foreach_node(&list_int, stateh, sum_int_list, &n);
puts("showing ret value and state handler value");
printf("ret = %d\n", *(int*)ret);
printf("stateh = %d\n", *(int*)stateh);
puts("\nshowing processed list");
libglinked_show_list(&list_int, printint);
//the value we are looking for in the list
int key = 300;
printf("trying to find node :\n\t");
node = libglinked_find_node(&list_int, (void*)&key, int_compare);
//check if we found the node or not
if(node == NULL )
printf("couldn't find node\n");
else
{
printf("found: ");
libglinked_show_node(node, printint);
}
puts("\ntrying to remove node");
node = libglinked_remove_node(&list_int, (void*)&key, int_compare);
if(node == NULL)
puts("\tfailed to remove");
else
{
printf("found: ");
libglinked_show_node(node, printint);
printf("deleting node - - - -");
libglinked_delete_node(&list_int, node);
printf("DONE\n");
puts("\nshow list after removal");
libglinked_show_list(&list_int, printint);
}
//create some more nodes to sample split list function
node = libglinked_create_node(&list_int, (void*)icopy(500),ideallocator);
if(node == NULL)
fprintf(stderr,"\nfailed to create node %d\n", __LINE__);
libglinked_enqueue_node(&list_int, node);
node = libglinked_create_node(&list_int, (void*)icopy(600),ideallocator);
if(node == NULL)
fprintf(stderr,"\nfailed to create node %d\n", __LINE__);
libglinked_enqueue_node(&list_int, node);
node = libglinked_create_node(&list_int, (void*)icopy(700),ideallocator);
if(node == NULL)
fprintf(stderr,"\nfailed to create node %d\n", __LINE__);
libglinked_enqueue_node(&list_int, node);
node = libglinked_create_node(&list_int, (void*)icopy(800),ideallocator);
if(node == NULL)
fprintf(stderr,"\nfailed to create node %d\n", __LINE__);
libglinked_enqueue_node(&list_int, node);
node = libglinked_create_node(&list_int, (void*)icopy(900),ideallocator);
if(node == NULL)
fprintf(stderr,"\nfailed to create node %d\n", __LINE__);
libglinked_enqueue_node(&list_int, node);
puts("\nshow the current list before the split");
libglinked_show_list(&list_int, printint);
printf("has %zu items\n", libglinked_get_num_items(&list_int));
libglinked_list_t new_list;
puts("\nmaking split at 600");
key = 600;
if(libglinked_split_list(&list_int, &new_list, (void*)&key, int_compare) == NULL)
fprintf(stderr,"split failed %d\n", __LINE__);
puts("\nshow list after split");
libglinked_show_list(&list_int, printint);
printf("has %zu items\n", libglinked_get_num_items(&list_int));
puts("\nshow new list, from split");
libglinked_show_list(&new_list, printint);
printf("has %zu items\n", libglinked_get_num_items(&new_list));
puts("\njoining new list with list at 150");
key = 150;
libglinked_join_list(&list_int, &new_list, (void*)&key, int_compare);
puts("show list after join");
libglinked_show_list(&list_int, printint);
printf("has %zu items\n", libglinked_get_num_items(&list_int));
//clean all allocated memory
libglinked_delete_list(&list_int);
return 0;
}