1/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
2 2016 MariaDB Corporation AB
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with this library; if not, write to the Free
16 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 MA 02111-1301, USA */
18
19/*
20 Code for handling dubble-linked lists in C
21*/
22
23#include <ma_global.h>
24#include <ma_sys.h>
25#include <ma_list.h>
26
27 /* Add a element to start of list */
28
29LIST *list_add(LIST *root, LIST *element)
30{
31 if (root)
32 {
33 if (root->prev) /* If add in mid of list */
34 root->prev->next= element;
35 element->prev=root->prev;
36 root->prev=element;
37 }
38 else
39 element->prev=0;
40 element->next=root;
41 return(element); /* New root */
42}
43
44
45LIST *list_delete(LIST *root, LIST *element)
46{
47 if (element->prev)
48 element->prev->next=element->next;
49 else
50 root=element->next;
51 if (element->next)
52 element->next->prev=element->prev;
53 return root;
54}
55
56
57void list_free(LIST *root, unsigned int free_data)
58{
59 LIST *next;
60 while (root)
61 {
62 next=root->next;
63 if (free_data)
64 free(root->data);
65 free(root);
66 root=next;
67 }
68}
69
70
71LIST *list_cons(void *data, LIST *list)
72{
73 LIST *new_charset=(LIST*) malloc(sizeof(LIST));
74 if (!new_charset)
75 return 0;
76 new_charset->data=data;
77 return list_add(list,new_charset);
78}
79
80
81LIST *list_reverse(LIST *root)
82{
83 LIST *last;
84
85 last=root;
86 while (root)
87 {
88 last=root;
89 root=root->next;
90 last->next=last->prev;
91 last->prev=root;
92 }
93 return last;
94}
95
96uint list_length(LIST *list)
97{
98 uint count;
99 for (count=0 ; list ; list=list->next, count++) ;
100 return count;
101}
102
103
104int list_walk(LIST *list, list_walk_action action, gptr argument)
105{
106 int error=0;
107 while (list)
108 {
109 if ((error = (*action)(list->data,argument)))
110 return error;
111 list= list_rest(list);
112 }
113 return 0;
114}
115