|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)lists.c 5.3 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: * General list definitions. ! 26: * ! 27: * The assumption is that the elements in a list are words, ! 28: * usually pointers to the actual information. ! 29: */ ! 30: ! 31: #include "defs.h" ! 32: #include "lists.h" ! 33: ! 34: #ifndef public ! 35: ! 36: typedef struct List *List; ! 37: typedef struct ListItem *ListItem; ! 38: typedef char *ListElement; ! 39: ! 40: #define list_item(element) generic_list_item((ListElement) (element)) ! 41: #define list_element(type, item) ((type) (item == nil ? nil : (item)->element)) ! 42: #define list_head(list) ((list == nil) ? nil : (list)->head) ! 43: #define list_tail(list) ((list == nil) ? nil : (list)->tail) ! 44: #define list_next(item) ((item == nil) ? nil : (item)->next) ! 45: #define list_prev(item) ((item == nil) ? nil : (item)->prev) ! 46: #define list_size(list) (((list) == nil) ? 0 : (list)->nitems) ! 47: ! 48: #define foreach(type, i, list) \ ! 49: { \ ! 50: register ListItem _item; \ ! 51: \ ! 52: _item = list_head(list); \ ! 53: while (_item != nil) { \ ! 54: i = list_element(type, _item); \ ! 55: _item = list_next(_item); ! 56: ! 57: #define endfor \ ! 58: } \ ! 59: } ! 60: ! 61: /* ! 62: * Iterate through two equal-sized lists. ! 63: */ ! 64: ! 65: #define foreach2(type1, i, list1, type2, j, list2) \ ! 66: { \ ! 67: register ListItem _item1, _item2; \ ! 68: \ ! 69: _item1 = list_head(list1); \ ! 70: _item2 = list_head(list2); \ ! 71: while (_item1 != nil) { \ ! 72: i = list_element(type1, _item1); \ ! 73: j = list_element(type2, _item2); \ ! 74: _item1 = list_next(_item1); \ ! 75: _item2 = list_next(_item2); ! 76: ! 77: #define list_islast() (_item == nil) ! 78: #define list_curitem(list) (_item == nil ? list_tail(list) : list_prev(_item)) ! 79: ! 80: /* ! 81: * Representation should not be used outside except through macros. ! 82: */ ! 83: ! 84: struct List { ! 85: Integer nitems; ! 86: ListItem head; ! 87: ListItem tail; ! 88: }; ! 89: ! 90: struct ListItem { ! 91: ListElement element; ! 92: ListItem next; ! 93: ListItem prev; ! 94: }; ! 95: ! 96: #endif ! 97: ! 98: /* ! 99: * Allocate and initialize a list. ! 100: */ ! 101: ! 102: public List list_alloc() ! 103: { ! 104: List list; ! 105: ! 106: list = new(List); ! 107: list->nitems = 0; ! 108: list->head = nil; ! 109: list->tail = nil; ! 110: return list; ! 111: } ! 112: ! 113: /* ! 114: * Create a list item from an object (represented as pointer or integer). ! 115: */ ! 116: ! 117: public ListItem generic_list_item(element) ! 118: ListElement element; ! 119: { ! 120: ListItem i; ! 121: ! 122: i = new(ListItem); ! 123: i->element = element; ! 124: i->next = nil; ! 125: i->prev = nil; ! 126: return i; ! 127: } ! 128: ! 129: /* ! 130: * Insert an item before the item in a list. ! 131: */ ! 132: ! 133: public list_insert(item, after, list) ! 134: ListItem item; ! 135: ListItem after; ! 136: List list; ! 137: { ! 138: ListItem a; ! 139: ! 140: checkref(list); ! 141: list->nitems = list->nitems + 1; ! 142: if (list->head == nil) { ! 143: list->head = item; ! 144: list->tail = item; ! 145: } else { ! 146: if (after == nil) { ! 147: a = list->head; ! 148: } else { ! 149: a = after; ! 150: } ! 151: item->next = a; ! 152: item->prev = a->prev; ! 153: if (a->prev != nil) { ! 154: a->prev->next = item; ! 155: } else { ! 156: list->head = item; ! 157: } ! 158: a->prev = item; ! 159: } ! 160: } ! 161: ! 162: /* ! 163: * Append an item after the given item in a list. ! 164: */ ! 165: ! 166: public list_append(item, before, list) ! 167: ListItem item; ! 168: ListItem before; ! 169: List list; ! 170: { ! 171: ListItem b; ! 172: ! 173: checkref(list); ! 174: list->nitems = list->nitems + 1; ! 175: if (list->head == nil) { ! 176: list->head = item; ! 177: list->tail = item; ! 178: } else { ! 179: if (before == nil) { ! 180: b = list->tail; ! 181: } else { ! 182: b = before; ! 183: } ! 184: item->next = b->next; ! 185: item->prev = b; ! 186: if (b->next != nil) { ! 187: b->next->prev = item; ! 188: } else { ! 189: list->tail = item; ! 190: } ! 191: b->next = item; ! 192: } ! 193: } ! 194: ! 195: /* ! 196: * Delete an item from a list. ! 197: */ ! 198: ! 199: public list_delete(item, list) ! 200: ListItem item; ! 201: List list; ! 202: { ! 203: checkref(item); ! 204: checkref(list); ! 205: assert(list->nitems > 0); ! 206: if (item->next == nil) { ! 207: list->tail = item->prev; ! 208: } else { ! 209: item->next->prev = item->prev; ! 210: } ! 211: if (item->prev == nil) { ! 212: list->head = item->next; ! 213: } else { ! 214: item->prev->next = item->next; ! 215: } ! 216: list->nitems = list->nitems - 1; ! 217: } ! 218: ! 219: /* ! 220: * Concatenate one list onto the end of another. ! 221: */ ! 222: ! 223: public List list_concat(first, second) ! 224: List first, second; ! 225: { ! 226: List r; ! 227: ! 228: if (first == nil) { ! 229: r = second; ! 230: } else if (second == nil) { ! 231: r = first; ! 232: } else { ! 233: second->head->prev = first->tail; ! 234: first->tail->next = second->head; ! 235: first->tail = second->tail; ! 236: first->nitems = first->nitems + second->nitems; ! 237: r = first; ! 238: } ! 239: return r; ! 240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.