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