/* Copyright (c) 1982 Regents of the University of California */
static char sccsid
[] = "@(#)lists.c 1.3 (Berkeley) %G%";
* General list definitions.
* The assumption is that the elements in a list are words,
* usually pointers to the actual information.
typedef struct List
*List
;
typedef struct ListItem
*ListItem
;
typedef char *ListElement
;
#define list_item(element) generic_list_item((ListElement) (element))
#define list_element(type, item) ((type) (item == nil ? nil : (item)->element))
#define list_head(list) ((list == nil) ? nil : (list)->head)
#define list_tail(list) ((list == nil) ? nil : (list)->tail)
#define list_next(item) ((item == nil) ? nil : (item)->next)
#define list_prev(item) ((item == nil) ? nil : (item)->prev)
#define list_size(list) (((list) == nil) ? 0 : (list)->nitems)
#define foreach(type, i, list) \
register ListItem _item; \
_item = list_head(list); \
i = list_element(type, _item); \
_item = list_next(_item);
* Iterate through two equal-sized lists.
#define foreach2(type1, i, list1, type2, j, list2) \
register ListItem _item1, _item2; \
_item1 = list_head(list1); \
_item2 = list_head(list2); \
while (_item1 != nil) { \
i = list_element(type1, _item1); \
j = list_element(type2, _item2); \
_item1 = list_next(_item1); \
_item2 = list_next(_item2);
#define list_islast() (_item == nil)
#define list_curitem(list) (_item == nil ? list_tail(list) : list_prev(_item))
* Representation should not be used outside except through macros.
* Allocate and initialize a list.
* Create a list item from an object (represented as pointer or integer).
public ListItem
generic_list_item(element
)
* Insert an item before the item in a list.
public list_insert(item
, after
, list
)
list
->nitems
= list
->nitems
+ 1;
* Append an item after the given item in a list.
public list_append(item
, before
, list
)
list
->nitems
= list
->nitems
+ 1;
* Delete an item from a list.
public list_delete(item
, list
)
assert(list
->nitems
> 0);
item
->next
->prev
= item
->prev
;
item
->prev
->next
= item
->next
;
list
->nitems
= list
->nitems
- 1;
* Concatenate one list onto the end of another.
public List
list_concat(first
, second
)
} else if (second
== nil
) {
second
->head
->prev
= first
->tail
;
first
->tail
->next
= second
->head
;
first
->tail
= second
->tail
;
first
->nitems
= first
->nitems
+ second
->nitems
;