1 /*
2 * lists.c -- Functions to implement a double linked list XBoard
3 *
4 * Copyright 1995, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free
5 * Software Foundation, Inc.
6 *
7 * Enhancements Copyright 2005 Alessandro Scotti
8 *
9 * ------------------------------------------------------------------------
10 *
11 * GNU XBoard is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or (at
14 * your option) any later version.
15 *
16 * GNU XBoard is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see http://www.gnu.org/licenses/. *
23 *
24 *------------------------------------------------------------------------
25 ** See the file ChangeLog for a revision history. */
26
27 /*
28 * This file could well be a part of backend.c, but I prefer it this
29 * way.
30 */
31
32 #include "config.h"
33
34 #include <stdio.h>
35 #if STDC_HEADERS
36 # include <stdlib.h>
37 #endif /* not STDC_HEADERS */
38
39 #include "common.h"
40 #include "lists.h"
41
42
43
44 /* Check, if List l is empty; returns TRUE, if it is, FALSE
45 * otherwise.
46 */
47 int
ListEmpty(List * l)48 ListEmpty (List *l)
49 {
50 return(l->head == (ListNode *) &l->tail);
51 }
52
53
54 /* Initialize a list. Must be executed before list is used.
55 */
56 void
ListNew(List * l)57 ListNew (List *l)
58 {
59 l->head = (ListNode *) &l->tail;
60 l->tail = NULL;
61 l->tailPred = (ListNode *) l;
62 }
63
64
65 /* Remove node n from the list it is inside.
66 */
67 void
ListRemove(ListNode * n)68 ListRemove (ListNode *n)
69 {
70 if (n->succ != NULL) { /* Be safe */
71 n->pred->succ = n->succ;
72 n->succ->pred = n->pred;
73 n->succ = NULL; /* Mark node as no longer being member */
74 n->pred = NULL; /* of a list. */
75 }
76 }
77
78
79 /* Delete node n.
80 */
81 void
ListNodeFree(ListNode * n)82 ListNodeFree (ListNode *n)
83 {
84 if (n) {
85 ListRemove(n);
86 free(n);
87 }
88 }
89
90
91 /* Create a list node with size s. Returns NULL, if out of memory.
92 */
93 ListNode *
ListNodeCreate(size_t s)94 ListNodeCreate (size_t s)
95 {
96 ListNode *n;
97
98 if ((n = (ListNode*) malloc(s))) {
99 n->succ = NULL; /* Mark node as not being member of a list. */
100 n->pred = NULL;
101 }
102 return(n);
103 }
104
105
106 /* Insert node n into the list of node m after m.
107 */
108 void
ListInsert(ListNode * m,ListNode * n)109 ListInsert (ListNode *m, ListNode *n)
110 {
111 n->succ = m->succ;
112 n->pred = m;
113 m->succ = n;
114 n->succ->pred = n;
115 }
116
117
118 /* Add node n to the head of list l.
119 */
120 void
ListAddHead(List * l,ListNode * n)121 ListAddHead (List *l, ListNode *n)
122 {
123 ListInsert((ListNode *) &l->head, n);
124 }
125
126
127 /* Add node n to the tail of list l.
128 */
129 void
ListAddTail(List * l,ListNode * n)130 ListAddTail (List *l, ListNode *n)
131 {
132 ListInsert((ListNode *) l->tailPred, n);
133 }
134
135
136 /* Return element with number n of list l. (NULL, if n doesn't exist.)
137 * Counting starts with 0.
138 */
139 ListNode *
ListElem(List * l,int n)140 ListElem (List *l, int n)
141 {
142 ListNode *ln;
143
144 for (ln = l->head; ln->succ; ln = ln->succ) {
145 if (!n--) {
146 return (ln);
147 }
148 }
149
150 return(NULL);
151 }
152