1 /* list.c
2
3 Written by D.R.Maszle
4 28 October 1991
5
6 Copyright (c) 1991-2017 Free Software Foundation, Inc.
7
8 This file is part of GNU MCSim.
9
10 GNU MCSim is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 3
13 of the License, or (at your option) any later version.
14
15 GNU MCSim is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GNU MCSim; if not, see <http://www.gnu.org/licenses/>
22
23 A LIST data type utility.
24 */
25
26 #include <stdlib.h>
27
28 #include "lexerr.h"
29 #include "list.h"
30
31
32 /* -----------------------------------------------------------------------------
33 InitList
34
35 Initialized a list header structure and returns the pointer. This
36 LIST may then be used in other exciting list functions.
37 */
38
InitList(void)39 PLIST InitList (void)
40 {
41 /* Allocate header record */
42 PLIST plist = (PLIST) malloc (sizeof(LIST));
43
44 if (plist) { /* If allocation succeeds, */
45 plist->pleHead = NULL; /* .. initialize all to 0 */
46 plist->pleTail = NULL;
47 plist->iSize = 0;
48 }
49 else
50 ReportError (NULL, RE_OUTOFMEM | RE_FATAL, "InitList", NULL);
51
52 return (plist);
53
54 } /* InitList */
55
56
57 /* -----------------------------------------------------------------------------
58 FreeList
59
60 Frees the memory allocated to a LIST, incrementing through each
61 element sequentially. Allows user to free data with a provided
62 callback function, or to specify free'ing of data in this routine.
63
64 If the pfvFreeData function is non-NULL, the function is called
65 with each data pointer in the list, and bAndData is ignored.
66
67 If the callback is NULL and the boolean bAndData is set, free() is
68 called with each user data pointer before freeing the list element.
69
70 NOTE: ppList is a pointer to a LIST structure which is itself a pointer.
71 */
72
FreeList(PLIST * pplist,PFV_FREELISTCALLBACK pfvFreeData,BOOL bAndData)73 void FreeList (PLIST *pplist, PFV_FREELISTCALLBACK pfvFreeData, BOOL bAndData)
74 {
75 PLIST plist = *pplist; /* Get single pointer to work with */
76
77 if (!plist)
78 return;
79
80 while (plist->pleHead) {
81 if (pfvFreeData)
82 (*pfvFreeData)(plist->pleHead->pData); /* Call user free routine */
83
84 else if (bAndData && plist->pleHead->pData)
85 free (plist->pleHead->pData); /* Free user data block */
86
87 plist->pleTail = plist->pleHead; /* Save p to current elem */
88 plist->pleHead = plist->pleHead->pleNext; /* Next list item */
89 free (plist->pleTail); /* Free saved current elem */
90
91 } /* while */
92
93 free (plist); /* Free the list header */
94 *pplist = NULL; /* Reset the user's pointer */
95
96 } /* FreeList */
97
98
99 /* -----------------------------------------------------------------------------
100 QueueListItem
101
102 Adds a new list item to the tail of the list.
103 */
104
QueueListItem(PLIST plist,PVOID pData)105 void QueueListItem (PLIST plist, PVOID pData)
106 {
107 PLISTELEM pNewElem;
108
109 if (!plist)
110 return;
111
112 if (!(pNewElem = (PLISTELEM) malloc (sizeof(LISTELEM))))
113 ReportError (NULL, RE_OUTOFMEM | RE_FATAL, "QueueListItem", NULL);
114
115 pNewElem->pData = pData; /* Init new element */
116 pNewElem->pleNext = NULL;
117
118 if (plist->pleTail)
119 plist->pleTail->pleNext = pNewElem; /* Link new element */
120 else
121 plist->pleHead = pNewElem; /* Link first element */
122
123 plist->pleTail = pNewElem; /* Reset tail to new elem */
124 plist->iSize++; /* Increment size of list */
125
126 } /* QueueListItem */
127
128
129 /* -----------------------------------------------------------------------------
130 ForAllList
131
132 Takes a PLIST, a PFI_LISTCALLBACK function, and PVOID to user
133 information, and calls the callback function for each of the list
134 elems in sequence.
135
136 The PFI_LISTCALLBACK takes the user's data point at each list
137 element and the pointer to user information as arguments. It
138 returns an integer. The sum of the integers of all calls to the
139 callback is returned from ForAllList().
140 */
141
ForAllList(PLIST plist,PFI_FORLISTCALLBACK pfiCallback,PVOID pUserInfo)142 int ForAllList (PLIST plist, PFI_FORLISTCALLBACK pfiCallback, PVOID pUserInfo)
143 {
144 int iTotal = 0;
145 PLISTELEM ple;
146
147 if (!plist || !pfiCallback)
148 return 0;
149
150 ple = plist->pleHead;
151
152 while (ple) {
153 iTotal += (*pfiCallback) (ple->pData, pUserInfo);
154 ple = ple->pleNext; /* Increment to next elem */
155 }
156
157 return (iTotal);
158
159 } /* ForAllList */
160
161 /* -----------------------------------------------------------------------------
162 ForAllList3
163
164 Like ForAllList, but takes three user arguments
165 Included temporarily to avoid rewriting a lot of code
166 */
167
ForAllList3(PLIST plist,PFI_FORLISTCALLBACK3 pfiCallback,PVOID pUserInfo1,PVOID pUserInfo2,PVOID pUserInfo3)168 void ForAllList3(PLIST plist, PFI_FORLISTCALLBACK3 pfiCallback,
169 PVOID pUserInfo1, PVOID pUserInfo2, PVOID pUserInfo3)
170 {
171 PLISTELEM ple;
172
173 if (!plist || !pfiCallback)
174 return;
175
176 ple = plist->pleHead;
177
178 while (ple) {
179 (*pfiCallback) (ple->pData, pUserInfo1, pUserInfo2, pUserInfo3);
180 ple = ple->pleNext; /* Increment to next elem */
181 }
182
183 } /* ForAllList3 */
184