00001
00002
00003
00004
00005
00006
00007 #ifndef lint
00008 static char vcid[] = "$Id: list.c,v 1.2 1994/12/08 23:28:16 duchier Exp $";
00009 #endif
00010
00011
00012
00013
00014
00015
00016
00017 #include "list.h"
00018
00019
00020
00021
00022
00023
00024
00025 void List_SetLinkProc (header, getLinks)
00026 RefListHeader header;
00027 RefListGetLinksProc getLinks;
00028 {
00029 header->First = NULL;
00030 header->Last = NULL;
00031
00032 #ifdef prlDEBUG
00033 header->Lock = 0;
00034 #endif
00035
00036 header->GetLinks = getLinks;
00037 }
00038
00039
00040
00041
00042
00043 void List_InsertAhead (header, atom)
00044 RefListHeader header;
00045 Ref atom;
00046 {
00047 RefListGetLinksProc getLinks = header->GetLinks;
00048
00049
00050
00051 (*getLinks)(atom)->Next = header->First;
00052 (*getLinks)(atom)->Prev = NULL;
00053
00054
00055
00056 if (header->First != NULL)
00057 (*getLinks)(header->First)->Prev = atom;
00058
00059 else
00060 header->Last = atom;
00061
00062 header->First = atom;
00063 }
00064
00065
00066
00067 void List_Append (header, atom)
00068 RefListHeader header;
00069 Ref atom;
00070 {
00071 RefListGetLinksProc getLinks = header->GetLinks;
00072
00073
00074
00075 if (header->Last != NULL)
00076 (*getLinks)(header->Last)->Next = atom;
00077
00078 else
00079 header->First = atom;
00080
00081
00082
00083 (*getLinks)(atom)->Prev = header->Last;
00084 (*getLinks)(atom)->Next = NULL;
00085
00086
00087
00088 header->Last = atom;
00089 }
00090
00091
00092
00093 void List_InsertBefore (header, atom, mark)
00094 RefListHeader header;
00095 Ref atom;
00096 Ref mark;
00097 {
00098 RefListGetLinksProc getLinks = header->GetLinks;
00099
00100 if (mark != NULL)
00101 {
00102 (*getLinks)(atom)->Next = mark;
00103
00104 if (mark != header->First)
00105 {
00106 (*getLinks)(atom)->Prev = (*getLinks)(mark)->Prev;
00107 (*getLinks)((*getLinks)(mark)->Prev)->Next = atom;
00108 }
00109 else
00110 {
00111 (*getLinks)(atom)->Prev = NULL;
00112 header->First = atom;
00113 }
00114
00115 (*getLinks)(mark)->Prev = atom;
00116 }
00117 else
00118 List_Append (header, atom);
00119 }
00120
00121
00122
00123 void List_InsertAfter (header, atom, mark)
00124 RefListHeader header;
00125 Ref atom;
00126 Ref mark;
00127 {
00128 RefListGetLinksProc getLinks = header->GetLinks;
00129
00130 #ifdef prlDEBUG
00131 if (header->Lock > 1)
00132 OS_PrintMessage ("List_InsertAfter: Warning insert after on recursive List_Enum call !!\n");
00133 #endif
00134
00135 if (mark != NULL)
00136 {
00137 (*getLinks)(atom)->Prev = mark;
00138
00139 if (mark != header->Last)
00140 {
00141 (*getLinks)(atom)->Next = (*getLinks)(mark)->Next;
00142 (*getLinks)((*getLinks)(mark)->Next)->Prev = atom;
00143 }
00144 else
00145 {
00146 (*getLinks)(atom)->Next = NULL;
00147 header->Last = atom;
00148 }
00149
00150 (*getLinks)(mark)->Next = atom;
00151 }
00152 else
00153 List_InsertAhead (header, atom);
00154 }
00155
00156
00157
00158 void List_Swap (header, first, second)
00159 RefListHeader header;
00160 Ref first;
00161 Ref second;
00162 {
00163 RefListGetLinksProc getLinks = header->GetLinks;
00164
00165
00166
00167 if ((*getLinks)(first)->Next != second)
00168 {
00169 #ifdef prlDEBUG
00170 OS_PrintMessage ("List_Swap: WARNING wrong input data, swap not done..\n");
00171 #endif
00172 return;
00173 }
00174
00175
00176
00177 if (header->First == first)
00178 header->First = second;
00179 else
00180 (*getLinks)((*getLinks)(first)->Prev)->Next = second;
00181
00182 if (header->Last == second)
00183 header->Last = first;
00184 else
00185 (*getLinks)((*getLinks)(second)->Next)->Prev = first;
00186
00187
00188
00189 (*getLinks)(second)->Prev = (*getLinks)(first)->Prev;
00190 (*getLinks)(first)->Next = (*getLinks)(second)->Next;
00191 (*getLinks)(first)->Prev = second;
00192 (*getLinks)(second)->Next = first;
00193 }
00194
00195
00196
00197 static long List_SwapLinks (header, atom)
00198 RefListHeader header;
00199 Ref atom;
00200 {
00201 Ref save;
00202
00203 save = (*header->GetLinks)(atom)->Next;
00204 (*header->GetLinks)(atom)->Next = (*header->GetLinks)(atom)->Prev;
00205 (*header->GetLinks)(atom)->Prev = save;
00206
00207 return TRUE;
00208 }
00209
00210 void List_Reverse (header)
00211 RefListHeader header;
00212 {
00213 Ref cur, next;
00214 RefListGetLinksProc getLinks = header->GetLinks;
00215
00216
00217
00218 cur = header->First;
00219
00220
00221 header->First = header->Last;
00222 header->Last = cur;
00223
00224 while (cur != NULL)
00225 {
00226 next = (*getLinks)(cur)->Next;
00227 List_SwapLinks (header, cur);
00228 cur = next;
00229 }
00230 }
00231
00232
00233
00234 void List_Remove (header, atom)
00235 RefListHeader header;
00236 Ref atom;
00237 {
00238
00239
00240
00241
00242
00243
00244
00245
00246 RefListGetLinksProc getLinks = header->GetLinks;
00247
00248 #ifdef prlDEBUG
00249 if (header->Lock > 1)
00250 OS_PrintMessage ("List_Remove: Warning remove on recursive List_Enum call !!\n");
00251 #endif
00252
00253
00254
00255 if ((*getLinks)(atom)->Prev != NULL)
00256 {
00257 (*getLinks)((*getLinks)(atom)->Prev)->Next =
00258 (*getLinks)(atom)->Next;
00259 }
00260 else
00261 header->First = (*getLinks)(atom)->Next;
00262
00263
00264
00265 if ((*getLinks)(atom)->Next != NULL)
00266 {
00267 (*getLinks)((*getLinks)(atom)->Next)->Prev =
00268 (*getLinks)(atom)->Prev;
00269 }
00270 else
00271 header->Last = (*getLinks)(atom)->Prev;
00272
00273
00274
00275 (*getLinks)(atom)->Prev = NULL;
00276 (*getLinks)(atom)->Next = NULL;
00277 }
00278
00279
00280
00281 void List_Concat (header1, header2)
00282 RefListHeader header1;
00283 RefListHeader header2;
00284 {
00285 RefListGetLinksProc getLinks = header1->GetLinks;
00286
00287 if (header1->GetLinks == header2->GetLinks)
00288 {
00289 #ifdef prlDEBUG
00290 OS_PrintMessage ("List_Concat: ERROR concat different lists\n");
00291 #endif
00292 return;
00293 }
00294
00295
00296
00297 if (header2->First != NULL)
00298 {
00299
00300
00301 if (header1->First == NULL)
00302 header1->First = header2->First;
00303
00304 else
00305 {
00306 (*getLinks)(header1->Last)->Next = header2->First;
00307 (*getLinks)(header2->First)->Prev = header1->Last;
00308 }
00309 header1->Last = header2->Last;
00310 }
00311 }
00312
00313
00314
00315 long List_EnumFrom (header, atom, proc, closure)
00316 RefListHeader header;
00317 Ref atom;
00318 RefListEnumProc proc;
00319 Ref closure;
00320 {
00321 Ref cur, next;
00322 int notInterrupted = TRUE;
00323
00324 #ifdef prlDEBUG
00325 header->Lock += 1;
00326 #endif
00327
00328 cur = atom;
00329 while (cur != NULL && notInterrupted)
00330 {
00331 next = List_Next (header, cur);
00332 notInterrupted = (*proc)(cur, closure);
00333 cur = next;
00334 }
00335
00336 #ifdef prlDEBUG
00337 header->Lock -=1;
00338 #endif
00339
00340 return (notInterrupted);
00341 }
00342
00343
00344
00345 long List_Enum (header, proc, closure)
00346 RefListHeader header;
00347 RefListEnumProc proc;
00348 Ref closure;
00349
00350
00351
00352
00353
00354
00355
00356
00357 {
00358 return (List_EnumFrom (header, header->First, proc, closure));
00359 }
00360
00361
00362
00363 long List_EnumBackFrom (header, atom, proc, closure)
00364 RefListHeader header;
00365 Ref atom;
00366 RefListEnumProc proc;
00367 Ref closure;
00368 {
00369 Ref cur, prev;
00370 int notInterrupted = TRUE;
00371
00372 #ifdef prlDEBUG
00373 header->Lock += 1;
00374 #endif
00375
00376 cur = atom;
00377 while (cur != NULL && notInterrupted)
00378 {
00379 prev = List_Prev (header, cur);
00380 notInterrupted = (*proc)(cur, closure);
00381 cur = prev;
00382 }
00383
00384 #ifdef prlDEBUG
00385 header->Lock -=1;
00386 #endif
00387
00388 return (notInterrupted);
00389 }
00390
00391
00392
00393 long List_EnumBack (header, proc, closure)
00394 RefListHeader header;
00395 RefListEnumProc proc;
00396 Ref closure;
00397 {
00398 return (List_EnumBackFrom (header, header->Last, proc, closure));
00399 }
00400
00401
00402
00403
00404 static long List_CountAtom (p, nbR)
00405 Ref p;
00406 Ref nbR;
00407 {
00408 long *nb = (long *)nbR;
00409
00410 ++*nb;
00411 return TRUE;
00412 }
00413
00414 long List_Card (header)
00415 RefListHeader header;
00416 {
00417 long n = 0;
00418
00419 List_Enum (header, List_CountAtom, &n);
00420 return n;
00421 }
00422
00423
00424
00425 long List_IsUnlink (links)
00426 RefListLinks links;
00427 {
00428 return (links->Next == NULL && links->Prev == NULL);
00429 }
00430
00431
00432
00433 void List_Cut (header, atom, newHeader)
00434 RefListHeader header;
00435 Ref atom;
00436 RefListHeader newHeader;
00437 {
00438 RefListGetLinksProc getLinks = header->GetLinks;
00439
00440 if (atom != List_Last (header))
00441 {
00442 newHeader->First = List_Next (header, atom);
00443 newHeader->Last = header->Last;
00444
00445 header->Last = atom;
00446
00447
00448 (*getLinks)(atom)->Next = NULL;
00449 (*getLinks)(newHeader->First)->Prev = NULL;
00450 }
00451 }
00452
00453