blob: 4b240fecd122308d2bc88b0ac2d2c85cecff833a [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
Benny Prijono32177c02008-06-20 22:44:47 +00003 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono9033e312005-11-21 02:08:39 +00004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20
21/* Internal */
Benny Prijono8ab968f2007-07-20 08:08:30 +000022PJ_INLINE(void) pj_link_node(pj_list_type *prev, pj_list_type *next)
Benny Prijono9033e312005-11-21 02:08:39 +000023{
24 ((pj_list*)prev)->next = next;
25 ((pj_list*)next)->prev = prev;
26}
27
Benny Prijono8ab968f2007-07-20 08:08:30 +000028PJ_IDEF(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node)
Benny Prijono9033e312005-11-21 02:08:39 +000029{
30 ((pj_list*)node)->prev = pos;
31 ((pj_list*)node)->next = ((pj_list*)pos)->next;
32 ((pj_list*) ((pj_list*)pos)->next) ->prev = node;
33 ((pj_list*)pos)->next = node;
34}
35
36
Benny Prijono8ab968f2007-07-20 08:08:30 +000037PJ_IDEF(void) pj_list_insert_before(pj_list_type *pos, pj_list_type *node)
Benny Prijono9033e312005-11-21 02:08:39 +000038{
39 pj_list_insert_after(((pj_list*)pos)->prev, node);
40}
41
42
Benny Prijono8ab968f2007-07-20 08:08:30 +000043PJ_IDEF(void) pj_list_insert_nodes_after(pj_list_type *pos, pj_list_type *lst)
Benny Prijono9033e312005-11-21 02:08:39 +000044{
45 pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev;
46 pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next;
47
48 pj_link_node(pos, lst);
49 pj_link_node(lst_last, pos_next);
50}
51
Benny Prijono8ab968f2007-07-20 08:08:30 +000052PJ_IDEF(void) pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst)
Benny Prijono9033e312005-11-21 02:08:39 +000053{
54 pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst);
55}
56
Benny Prijono8ab968f2007-07-20 08:08:30 +000057PJ_IDEF(void) pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2)
Benny Prijono9033e312005-11-21 02:08:39 +000058{
Benny Prijono8badb012006-11-22 14:47:45 +000059 if (!pj_list_empty(lst2)) {
60 pj_link_node(((pj_list*)lst1)->prev, ((pj_list*)lst2)->next);
61 pj_link_node(((pj_list*)lst2)->prev, lst1);
62 pj_list_init(lst2);
63 }
Benny Prijono9033e312005-11-21 02:08:39 +000064}
65
Benny Prijono8ab968f2007-07-20 08:08:30 +000066PJ_IDEF(void) pj_list_merge_first(pj_list_type *lst1, pj_list_type *lst2)
Benny Prijono9033e312005-11-21 02:08:39 +000067{
Benny Prijono8badb012006-11-22 14:47:45 +000068 if (!pj_list_empty(lst2)) {
69 pj_link_node(((pj_list*)lst2)->prev, ((pj_list*)lst1)->next);
70 pj_link_node(((pj_list*)lst1), ((pj_list*)lst2)->next);
71 pj_list_init(lst2);
72 }
Benny Prijono9033e312005-11-21 02:08:39 +000073}
74
Benny Prijono8ab968f2007-07-20 08:08:30 +000075PJ_IDEF(void) pj_list_erase(pj_list_type *node)
Benny Prijono9033e312005-11-21 02:08:39 +000076{
77 pj_link_node( ((pj_list*)node)->prev, ((pj_list*)node)->next);
Benny Prijono9969d182008-04-02 18:36:35 +000078
79 /* It'll be safer to init the next/prev fields to itself, to
80 * prevent multiple erase() from corrupting the list. See
81 * ticket #520 for one sample bug.
82 */
83 pj_list_init(node);
Benny Prijono9033e312005-11-21 02:08:39 +000084}
85
86
Benny Prijono8ab968f2007-07-20 08:08:30 +000087PJ_IDEF(pj_list_type*) pj_list_find_node(pj_list_type *list, pj_list_type *node)
Benny Prijono9033e312005-11-21 02:08:39 +000088{
89 pj_list *p = (pj_list *) ((pj_list*)list)->next;
90 while (p != list && p != node)
91 p = (pj_list *) p->next;
92
93 return p==node ? p : NULL;
94}
95
96
Benny Prijono8ab968f2007-07-20 08:08:30 +000097PJ_IDEF(pj_list_type*) pj_list_search(pj_list_type *list, void *value,
98 int (*comp)(void *value, const pj_list_type *node))
Benny Prijono9033e312005-11-21 02:08:39 +000099{
100 pj_list *p = (pj_list *) ((pj_list*)list)->next;
101 while (p != list && (*comp)(value, p) != 0)
102 p = (pj_list *) p->next;
103
104 return p==list ? NULL : p;
105}
106
Benny Prijonoa5f4ff22006-02-19 01:28:21 +0000107
Benny Prijonob58b3e42008-05-16 13:27:46 +0000108PJ_IDEF(pj_size_t) pj_list_size(const pj_list_type *list)
Benny Prijonoa5f4ff22006-02-19 01:28:21 +0000109{
Benny Prijonob58b3e42008-05-16 13:27:46 +0000110 const pj_list *node = (const pj_list*) ((const pj_list*)list)->next;
Benny Prijonoa5f4ff22006-02-19 01:28:21 +0000111 pj_size_t count = 0;
112
113 while (node != list) {
114 ++count;
Benny Prijonof260e462007-04-30 21:03:32 +0000115 node = (pj_list*)node->next;
Benny Prijonoa5f4ff22006-02-19 01:28:21 +0000116 }
117
118 return count;
119}
120