Fix multi-leg promotions
[xboard.git] / lists.c
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
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
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
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
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 *
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
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
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
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 *
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 }