1 /*
2  * iter.h
3  * Linked lists and iterators.
4  *
5  * Copyright (c) 2013 pkgconf authors (see AUTHORS).
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * This software is provided 'as is' and without any warranty, express or
12  * implied.  In no event shall the authors be liable for any damages arising
13  * from the use of this software.
14  */
15 
16 #ifndef LIBPKGCONF_ITER_H
17 #define LIBPKGCONF_ITER_H
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 typedef struct pkgconf_node_ pkgconf_node_t;
24 
25 struct pkgconf_node_ {
26 	pkgconf_node_t *prev, *next;
27 	void *data;
28 };
29 
30 typedef struct {
31 	pkgconf_node_t *head, *tail;
32 	size_t length;
33 } pkgconf_list_t;
34 
35 #define PKGCONF_LIST_INITIALIZER		{ NULL, NULL, 0 }
36 
37 static inline void
pkgconf_node_insert(pkgconf_node_t * node,void * data,pkgconf_list_t * list)38 pkgconf_node_insert(pkgconf_node_t *node, void *data, pkgconf_list_t *list)
39 {
40 	pkgconf_node_t *tnode;
41 
42 	node->data = data;
43 
44 	if (list->head == NULL)
45 	{
46 		list->head = node;
47 		list->tail = node;
48 		list->length = 1;
49 		return;
50 	}
51 
52 	tnode = list->head;
53 
54 	node->next = tnode;
55 	tnode->prev = node;
56 
57 	list->head = node;
58 	list->length++;
59 }
60 
61 static inline void
pkgconf_node_insert_tail(pkgconf_node_t * node,void * data,pkgconf_list_t * list)62 pkgconf_node_insert_tail(pkgconf_node_t *node, void *data, pkgconf_list_t *list)
63 {
64 	pkgconf_node_t *tnode;
65 
66 	node->data = data;
67 
68 	if (list->tail == NULL)
69 	{
70 		list->head = node;
71 		list->tail = node;
72 		list->length = 1;
73 		return;
74 	}
75 
76 	tnode = list->tail;
77 
78 	node->prev = tnode;
79 	tnode->next = node;
80 
81 	list->tail = node;
82 	list->length++;
83 }
84 
85 static inline void
pkgconf_node_delete(pkgconf_node_t * node,pkgconf_list_t * list)86 pkgconf_node_delete(pkgconf_node_t *node, pkgconf_list_t *list)
87 {
88 	list->length--;
89 
90 	if (node->prev == NULL)
91 		list->head = node->next;
92 	else
93 		node->prev->next = node->next;
94 
95 	if (node->next == NULL)
96 		list->tail = node->prev;
97 	else
98 		node->next->prev = node->prev;
99 }
100 
101 #ifdef __cplusplus
102 }
103 #endif
104 
105 #endif
106