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