00001
00002
00003
00004
00005 #include "common.h"
00006 #include "dlist.h"
00007
00008 static char const rcsid[] = "$Id: dlist.c,v 1.11 2005/07/04 18:44:09 markd Exp $";
00009
00010 void dlListInit(struct dlList *dl)
00011
00012 {
00013 dl->head = (struct dlNode *)(&dl->nullMiddle);
00014 dl->nullMiddle = NULL;
00015 dl->tail = (struct dlNode *)(&dl->head);
00016 }
00017
00018 struct dlList *newDlList()
00019
00020 {
00021 struct dlList *dl;
00022 AllocVar(dl);
00023 dl->head = (struct dlNode *)(&dl->nullMiddle);
00024 dl->tail = (struct dlNode *)(&dl->head);
00025 return dl;
00026 }
00027
00028 void dlListReset(struct dlList *dl)
00029
00030 {
00031 struct dlNode *node, *next;
00032 for (node = dl->head; node->next != NULL; node = next)
00033 {
00034 next = node->next;
00035 freeMem(node);
00036 }
00037 dl->head = (struct dlNode *)(&dl->nullMiddle);
00038 dl->nullMiddle = NULL;
00039 dl->tail = (struct dlNode *)(&dl->head);
00040 }
00041
00042 void freeDlList(struct dlList **pList)
00043
00044 {
00045 struct dlList *list = *pList;
00046 if (list != NULL)
00047 {
00048 dlListReset(list);
00049 freez(pList);
00050 }
00051 }
00052
00053 void freeDlListAndVals(struct dlList **pList)
00054
00055
00056 {
00057 struct dlList *list = *pList;
00058 if (list != NULL)
00059 {
00060 struct dlNode *node;
00061 for (node = list->head; node->next != NULL; node = node->next)
00062 freeMem(node->val);
00063 freeDlList(pList);
00064 }
00065 }
00066
00067
00068 void dlInsertBetween(struct dlNode *before, struct dlNode *after, struct dlNode *newNode)
00069 {
00070 before->next = newNode;
00071 newNode->prev = before;
00072 newNode->next = after;
00073 after->prev = newNode;
00074 }
00075
00076 void dlAddBefore(struct dlNode *anchor, struct dlNode *newNode)
00077
00078 {
00079 dlInsertBetween(anchor->prev, anchor, newNode);
00080 }
00081
00082 void dlAddAfter(struct dlNode *anchor, struct dlNode *newNode)
00083
00084 {
00085 dlInsertBetween(anchor, anchor->next, newNode);
00086 }
00087
00088 void dlAddHead(struct dlList *list, struct dlNode *newNode)
00089
00090 {
00091 struct dlNode *head = list->head;
00092 dlInsertBetween(head->prev, head, newNode);
00093 }
00094
00095 void dlAddTail(struct dlList *list, struct dlNode *newNode)
00096
00097 {
00098 struct dlNode *tail = list->tail;
00099 dlInsertBetween(tail, tail->next, newNode);
00100 }
00101
00102 struct dlNode *dlAddValBefore(struct dlNode *anchor, void *val)
00103
00104 {
00105 struct dlNode *node = AllocA(struct dlNode);
00106 node->val = val;
00107 dlAddBefore(anchor, node);
00108 return node;
00109 }
00110
00111 struct dlNode *dlAddValAfter(struct dlNode *anchor, void *val)
00112
00113 {
00114 struct dlNode *node = AllocA(struct dlNode);
00115 node->val = val;
00116 dlAddAfter(anchor, node);
00117 return node;
00118 }
00119
00120 struct dlNode *dlAddValHead(struct dlList *list, void *val)
00121
00122 {
00123 struct dlNode *node = AllocA(struct dlNode);
00124 node->val = val;
00125 dlAddHead(list, node);
00126 return node;
00127 }
00128
00129 struct dlNode *dlAddValTail(struct dlList *list, void *val)
00130
00131 {
00132 struct dlNode *node = AllocA(struct dlNode);
00133 node->val = val;
00134 dlAddTail(list, node);
00135 return node;
00136 }
00137
00138 void dlRemove(struct dlNode *node)
00139
00140 {
00141 struct dlNode *before = node->prev;
00142 struct dlNode *after = node->next;
00143 before->next = after;
00144 after->prev = before;
00145 node->prev = NULL;
00146 node->next = NULL;
00147 }
00148
00149 void dlRemoveHead(struct dlList *list)
00150
00151 {
00152 dlRemove(list->head);
00153 }
00154
00155 void dlRemoveTail(struct dlList *list)
00156
00157 {
00158 dlRemove(list->tail);
00159 }
00160
00161 struct dlNode *dlPopHead(struct dlList *list)
00162
00163 {
00164 struct dlNode *node = list->head;
00165 if (node->next == NULL)
00166 return NULL;
00167 dlRemove(node);
00168 return node;
00169 }
00170
00171 struct dlNode *dlPopTail(struct dlList *list)
00172
00173 {
00174 struct dlNode *node = list->tail;
00175 if (node->prev == NULL)
00176 return NULL;
00177 dlRemove(node);
00178 return node;
00179 }
00180
00181 void dlDelete(struct dlNode **nodePtr)
00182
00183 {
00184 struct dlNode *node = *nodePtr;
00185 if (node != NULL)
00186 {
00187 dlRemove(node);
00188 freeMem(node);
00189 }
00190 }
00191
00192 int dlCount(struct dlList *list)
00193
00194 {
00195 return slCount(list->head) - 1;
00196 }
00197
00198
00199 struct dlSorter
00200
00201 {
00202 struct dlNode *node;
00203 };
00204
00205 static int (*compareFunc)(const void *elem1, const void *elem2);
00206
00207
00208 static int dlNodeCmp(const void *elem1, const void *elem2)
00209
00210 {
00211 struct dlSorter *a = (struct dlSorter *)elem1;
00212 struct dlSorter *b = (struct dlSorter *)elem2;
00213 return compareFunc(&a->node->val, &b->node->val);
00214 }
00215
00216 void dlSort(struct dlList *list,
00217 int (*compare )(const void *elem1, const void *elem2))
00218
00219
00220
00221
00222 {
00223 int len = dlCount(list);
00224
00225 if (len > 1)
00226 {
00227
00228 struct dlSorter *sorter = needLargeMem(len * sizeof(sorter[0])), *s;
00229 struct dlNode *node;
00230 int i;
00231
00232 for (i=0, node = list->head; i<len; ++i, node = node->next)
00233 {
00234 s = &sorter[i];
00235 s->node = node;
00236 }
00237 compareFunc = compare;
00238 qsort(sorter, len, sizeof(sorter[0]), dlNodeCmp);
00239 dlListInit(list);
00240 for (i=0; i<len; ++i)
00241 dlAddTail(list, sorter[i].node);
00242 freeMem(sorter);
00243 }
00244 }
00245
00246
00247 boolean dlEmpty(struct dlList *list)
00248
00249 {
00250 return dlIsEmpty(list);
00251 }
00252
00253 struct dlNode *dlGetBeforeHead(struct dlList *list)
00254
00255 {
00256 if (dlEmpty(list))
00257 return list->head;
00258 else
00259 return list->head->prev;
00260 }
00261
00262 struct dlNode *dlGetAfterTail(struct dlList *list)
00263
00264 {
00265 if (dlEmpty(list))
00266 return list->tail;
00267 else
00268 return list->tail->next;
00269 }
00270
00271 void *dlListToSlList(struct dlList *dList)
00272
00273 {
00274 struct slList *list = NULL, *el;
00275 struct dlNode *node;
00276
00277 for (node = dList->tail; node->prev != NULL; node = node->prev)
00278 {
00279 el = node->val;
00280 slAddHead(&list, el);
00281 }
00282 return list;
00283 }
00284
00285 void dlCat(struct dlList *a, struct dlList *b)
00286
00287 {
00288 struct dlNode *node;
00289 while ((node = dlPopHead(b)) != NULL)
00290 dlAddTail(a, node);
00291 }
00292
00293 struct dlNode *dlValInList(struct dlList *list, void *val)
00294
00295 {
00296 struct dlNode *node;
00297 for (node = list->head; !dlEnd(node); node = node->next)
00298 if (node->val == val)
00299 return node;
00300 return NULL;
00301 }