|
|
1.1 ! root 1: /* Copyright (c) 1982 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)lists.c 1.2 12/15/82"; ! 4: ! 5: /* ! 6: * General list definitions. ! 7: * ! 8: * The assumption is that the elements in a list are words, ! 9: * usually pointers to the actual information. ! 10: */ ! 11: ! 12: #include "defs.h" ! 13: #include "lists.h" ! 14: ! 15: #ifndef public ! 16: ! 17: typedef struct List *List; ! 18: typedef struct ListItem *ListItem; ! 19: typedef char *ListElement; ! 20: ! 21: #define list_item(element) generic_list_item((ListElement) (element)) ! 22: #define list_element(type, item) ((type) (item == nil ? nil : (item)->element)) ! 23: #define list_head(list) ((list == nil) ? nil : (list)->head) ! 24: #define list_tail(list) ((list == nil) ? nil : (list)->tail) ! 25: #define list_next(item) ((item == nil) ? nil : (item)->next) ! 26: #define list_prev(item) ((item == nil) ? nil : (item)->prev) ! 27: #define list_size(list) (((list) == nil) ? 0 : (list)->nitems) ! 28: ! 29: #define foreach(type, i, list) \ ! 30: { \ ! 31: register ListItem _item; \ ! 32: \ ! 33: _item = list_head(list); \ ! 34: while (_item != nil) { \ ! 35: i = list_element(type, _item); \ ! 36: _item = list_next(_item); ! 37: ! 38: #define endfor \ ! 39: } \ ! 40: } ! 41: ! 42: /* ! 43: * Iterate through two equal-sized lists. ! 44: */ ! 45: ! 46: #define foreach2(type1, i, list1, type2, j, list2) \ ! 47: { \ ! 48: register ListItem _item1, _item2; \ ! 49: \ ! 50: _item1 = list_head(list1); \ ! 51: _item2 = list_head(list2); \ ! 52: while (_item1 != nil) { \ ! 53: i = list_element(type1, _item1); \ ! 54: j = list_element(type2, _item2); \ ! 55: _item1 = list_next(_item1); \ ! 56: _item2 = list_next(_item2); ! 57: ! 58: #define list_islast() (_item == nil) ! 59: #define list_curitem(list) (_item == nil ? list_tail(list) : list_prev(_item)) ! 60: ! 61: /* ! 62: * Representation should not be used outside except through macros. ! 63: */ ! 64: ! 65: struct List { ! 66: Integer nitems; ! 67: ListItem head; ! 68: ListItem tail; ! 69: }; ! 70: ! 71: struct ListItem { ! 72: ListElement element; ! 73: ListItem next; ! 74: ListItem prev; ! 75: }; ! 76: ! 77: #endif ! 78: ! 79: /* ! 80: * Allocate and initialize a list. ! 81: */ ! 82: ! 83: public List list_alloc() ! 84: { ! 85: List list; ! 86: ! 87: list = new(List); ! 88: list->nitems = 0; ! 89: list->head = nil; ! 90: list->tail = nil; ! 91: return list; ! 92: } ! 93: ! 94: /* ! 95: * Create a list item from an object (represented as pointer or integer). ! 96: */ ! 97: ! 98: public ListItem generic_list_item(element) ! 99: ListElement element; ! 100: { ! 101: ListItem i; ! 102: ! 103: i = new(ListItem); ! 104: i->element = element; ! 105: i->next = nil; ! 106: i->prev = nil; ! 107: return i; ! 108: } ! 109: ! 110: /* ! 111: * Insert an item before the item in a list. ! 112: */ ! 113: ! 114: public list_insert(item, after, list) ! 115: ListItem item; ! 116: ListItem after; ! 117: List list; ! 118: { ! 119: ListItem a; ! 120: ! 121: checkref(list); ! 122: list->nitems = list->nitems + 1; ! 123: if (list->head == nil) { ! 124: list->head = item; ! 125: list->tail = item; ! 126: } else { ! 127: if (after == nil) { ! 128: a = list->head; ! 129: } else { ! 130: a = after; ! 131: } ! 132: item->next = a; ! 133: item->prev = a->prev; ! 134: if (a->prev != nil) { ! 135: a->prev->next = item; ! 136: } else { ! 137: list->head = item; ! 138: } ! 139: a->prev = item; ! 140: } ! 141: } ! 142: ! 143: /* ! 144: * Append an item after the given item in a list. ! 145: */ ! 146: ! 147: public list_append(item, before, list) ! 148: ListItem item; ! 149: ListItem before; ! 150: List list; ! 151: { ! 152: ListItem b; ! 153: ! 154: checkref(list); ! 155: list->nitems = list->nitems + 1; ! 156: if (list->head == nil) { ! 157: list->head = item; ! 158: list->tail = item; ! 159: } else { ! 160: if (before == nil) { ! 161: b = list->tail; ! 162: } else { ! 163: b = before; ! 164: } ! 165: item->next = b->next; ! 166: item->prev = b; ! 167: if (b->next != nil) { ! 168: b->next->prev = item; ! 169: } else { ! 170: list->tail = item; ! 171: } ! 172: b->next = item; ! 173: } ! 174: } ! 175: ! 176: /* ! 177: * Delete an item from a list. ! 178: */ ! 179: ! 180: public list_delete(item, list) ! 181: ListItem item; ! 182: List list; ! 183: { ! 184: checkref(item); ! 185: checkref(list); ! 186: assert(list->nitems > 0); ! 187: if (item->next == nil) { ! 188: list->tail = item->prev; ! 189: } else { ! 190: item->next->prev = item->prev; ! 191: } ! 192: if (item->prev == nil) { ! 193: list->head = item->next; ! 194: } else { ! 195: item->prev->next = item->next; ! 196: } ! 197: list->nitems = list->nitems - 1; ! 198: } ! 199: ! 200: /* ! 201: * Concatenate one list onto the end of another. ! 202: */ ! 203: ! 204: public List list_concat(first, second) ! 205: List first, second; ! 206: { ! 207: List r; ! 208: ! 209: if (first == nil) { ! 210: r = second; ! 211: } else if (second == nil) { ! 212: r = first; ! 213: } else { ! 214: second->head->prev = first->tail; ! 215: first->tail->next = second->head; ! 216: first->tail = second->tail; ! 217: first->nitems = first->nitems + second->nitems; ! 218: r = first; ! 219: } ! 220: return r; ! 221: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.