source: git/omalloc/omList.c @ 3b7b36

spielwiese
Last change on this file since 3b7b36 was be127e, checked in by Oleksandr Motsak <motsak@…>, 10 years ago
Omalloc should not reference itself in include pathes
  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*******************************************************************
2 *  File:    omList.c
3 *  Purpose: implementation of routines for operations on linked lists
4 *  Author:  obachman (Olaf Bachmann)
5 *  Created: 11/99
6 *******************************************************************/
7#include "omConfig.h"
8
9#ifndef NULL
10#define NULL ((void*) 0)
11#endif
12
13#define _VALUE(list, offset) *((void**) ((char *)list + offset))
14#define VALUE(list, offset) (unsigned long) _VALUE(list, offset)
15#define NEXT(list) _VALUE(list, next)
16#define ITER(list) list = NEXT(list)
17
18int _omListLength(void* list, int next)
19{
20  int l = 0;
21  while (list != NULL)
22  {
23    l++;
24    ITER(list);
25  }
26  return l;
27}
28
29
30void* _omListLast(void* list, int next)
31{
32  if (list == NULL) return NULL;
33
34  while (NEXT(list) != NULL) ITER(list);
35
36  return list;
37}
38
39
40void* _omListHasCycle(void* list, int next)
41{
42  void* l1 = list;
43  void* l2;
44
45  int l = 0, i;
46
47  while (l1 != NULL)
48  {
49    i = 0;
50    l2 = list;
51    while (l1 != l2)
52    {
53      i++;
54      ITER(l2);
55    }
56    if (i != l) return l1;
57    ITER(l1);
58    l++;
59  }
60  return NULL;
61}
62
63
64void* _omIsOnList(void* list, int next, void* addr)
65{
66  if (addr == NULL)
67    return (NULL);
68
69  while (list != NULL)
70  {
71    if (addr == list) return addr;
72    ITER(list);
73  }
74  return 0;
75}
76
77void* _omRemoveFromList(void* list, int next, void* addr)
78{
79  void* nlist;
80  void* olist;
81
82  if (list == NULL) return NULL;
83
84  nlist = NEXT(list);
85  if (list == addr) return nlist;
86
87  olist = list;
88  while (nlist != NULL && nlist != addr)
89  {
90    list = nlist;
91    ITER(nlist);
92  }
93
94  if (nlist != NULL) NEXT(list) = NEXT(nlist);
95  return olist;
96}
97
98void* _omFindInList(void* list, int next, int long_field, unsigned long what)
99{
100  while (list != NULL)
101  {
102    if (VALUE(list, long_field) == what) return list;
103    ITER(list);
104  }
105  return NULL;
106}
107
108void* _omFindInSortedList(void* list, int next, int long_field,
109                          unsigned long what)
110{
111  while (list != NULL)
112  {
113    if (VALUE(list, long_field) >= what)
114    {
115      if (VALUE(list, long_field) == what) return list;
116      return NULL;
117    }
118    ITER(list);
119  }
120  return NULL;
121}
122
123void* _omRemoveFromSortedList(void* list, int next, int long_field, void* addr)
124{
125  void* nlist;
126  void* olist;
127  unsigned long what = VALUE(addr, long_field);
128
129  if (list == NULL) return NULL;
130  nlist = NEXT(list);
131  if (list == addr) return nlist;
132  if (VALUE(list, long_field) > what) return list;
133
134  olist = list;
135  while (nlist != NULL && nlist != addr)
136  {
137    if (VALUE(list, long_field) > what) return olist;
138    list = nlist;
139    ITER(nlist);
140  }
141
142  if (nlist != NULL) NEXT(list) = NEXT(nlist);
143  return olist;
144}
145
146void* _omInsertInSortedList(void* list, int next, int long_field, void* addr)
147{
148  unsigned long what = VALUE(addr, long_field);
149
150  if (list == NULL || what <= VALUE(list, long_field))
151  {
152    NEXT(addr) = list;
153    return addr;
154  }
155  else
156  {
157    void* prev = list;
158    void* curr = NEXT(list);
159
160    while (curr != NULL && VALUE(curr, long_field) < what)
161    {
162      prev = curr;
163      ITER(curr);
164    }
165    NEXT(prev) = addr;
166    NEXT(addr) = curr;
167    return list;
168  }
169}
170
171
172#ifndef OM_NDEBUG
173#include "omalloc.h"
174#include "omDebug.h"
175
176omError_t _omCheckList(void* list, int next, int level, omError_t report, OM_FLR_DECL)
177{
178  if (level < 1) return omError_NoError;
179
180  if (level == 1)
181  {
182    while (list != NULL)
183    {
184      omCheckReturn(omCheckPtr(list, report, OM_FLR_VAL));
185      ITER(list);
186    }
187  }
188  else
189  {
190    void* l1 = list;
191    void* l2;
192    int l = 0, i;
193
194    l1 = list;
195    while (l1 != NULL)
196    {
197      omCheckReturn(omCheckPtr(l1, report, OM_FLR_VAL));
198      i = 0;
199      l2 = list;
200      while (l1 != l2)
201      {
202        i++;
203        ITER(l2);
204      }
205      if (i != l)
206        return omReportError(omError_ListCycleError, report, OM_FLR_VAL, "");
207      ITER(l1);
208      l++;
209    }
210  }
211  return omError_NoError;
212}
213
214omError_t _omCheckSortedList(void* list, int next, int long_field, int level, omError_t report, OM_FLR_DECL)
215{
216  void* prev = NULL;
217
218  if (level <= 1) return omError_NoError;
219
220  if (level == 1)
221  {
222    while (list != NULL)
223    {
224      omCheckReturn(omCheckPtr(list, report, OM_FLR_VAL));
225      if (prev != NULL && VALUE(prev, long_field) > VALUE(list, long_field))
226        return omReportError(omError_SortedListError, report, OM_FLR_VAL,
227                             "%d > %d", VALUE(prev, long_field), VALUE(list, long_field));
228      prev = list;
229      ITER(list);
230    }
231  }
232  else
233  {
234    void* l1 = list;
235    void* l2;
236    int l = 0, i;
237
238    while (l1 != NULL)
239    {
240      omCheckReturn(omCheckPtr(l1, report, OM_FLR_VAL));
241      if (prev != NULL && VALUE(prev, long_field) > VALUE(l1, long_field))
242        return omReportError(omError_SortedListError, report, OM_FLR_VAL,
243                             "%d > %d", VALUE(prev, long_field), VALUE(l1, long_field));
244      i = 0;
245      l2 = list;
246      while (l1 != l2)
247      {
248        i++;
249        ITER(l2);
250      }
251      omCheckReturnError(i != l, omError_ListCycleError);
252      prev = l1;
253      ITER(l1);
254      l++;
255    }
256  }
257  return omError_NoError;
258}
259#endif
Note: See TracBrowser for help on using the repository browser.