diff options
Diffstat (limited to '')
-rw-r--r-- | mysys/list.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/mysys/list.c b/mysys/list.c new file mode 100644 index 00000000..2efe53c0 --- /dev/null +++ b/mysys/list.c @@ -0,0 +1,114 @@ +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + + This program 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; version 2 of the License. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +/* + Code for handling doubly linked lists in C +*/ + +#include "mysys_priv.h" +#include <my_list.h> + + + + /* Add an element to start of list */ + +LIST *list_add(LIST *root, LIST *element) +{ + DBUG_ENTER("list_add"); + DBUG_PRINT("enter",("root: %p element: %p", root, element)); + if (root) + { + if (root->prev) /* If add in mid of list */ + root->prev->next= element; + element->prev=root->prev; + root->prev=element; + } + else + element->prev=0; + element->next=root; + DBUG_RETURN(element); /* New root */ +} + + +LIST *list_delete(LIST *root, LIST *element) +{ + if (element->prev) + element->prev->next=element->next; + else + root=element->next; + if (element->next) + element->next->prev=element->prev; + return root; +} + + +void list_free(LIST *root, uint free_data) +{ + LIST *next; + while (root) + { + next=root->next; + if (free_data) + my_free(root->data); + my_free(root); + root=next; + } +} + + +LIST *list_cons(void *data, LIST *list) +{ + LIST *new_charset=(LIST*) my_malloc(key_memory_LIST, sizeof(LIST),MYF(MY_FAE)); + if (!new_charset) + return 0; + new_charset->data=data; + return list_add(list,new_charset); +} + + +LIST *list_reverse(LIST *root) +{ + LIST *last; + + last=root; + while (root) + { + last=root; + root=root->next; + last->next=last->prev; + last->prev=root; + } + return last; +} + +uint list_length(LIST *list) +{ + uint count; + for (count=0 ; list ; list=list->next, count++) ; + return count; +} + + +int list_walk(LIST *list, list_walk_action action, uchar* argument) +{ + int error=0; + while (list) + { + if ((error = (*action)(list->data,argument))) + return error; + list=list_rest(list); + } + return 0; +} |