Annotation of embedaddon/bird2/lib/lists.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     BIRD Library -- Linked Lists
                      3:  *
                      4:  *     (c) 1998 Martin Mares <mj@ucw.cz>
                      5:  *
                      6:  *     Can be freely distributed and used under the terms of the GNU GPL.
                      7:  */
                      8: 
                      9: /**
                     10:  * DOC: Linked lists
                     11:  *
                     12:  * The BIRD library provides a set of functions for operating on linked
                     13:  * lists. The lists are internally represented as standard doubly linked
                     14:  * lists with synthetic head and tail which makes all the basic operations
                     15:  * run in constant time and contain no extra end-of-list checks. Each list
                     16:  * is described by a &list structure, nodes can have any format as long
                     17:  * as they start with a &node structure. If you want your nodes to belong
                     18:  * to multiple lists at once, you can embed multiple &node structures in them
                     19:  * and use the SKIP_BACK() macro to calculate a pointer to the start of the
                     20:  * structure from a &node pointer, but beware of obscurity.
                     21:  *
                     22:  * There also exist safe linked lists (&slist, &snode and all functions
                     23:  * being prefixed with |s_|) which support asynchronous walking very
                     24:  * similar to that used in the &fib structure.
                     25:  */
                     26: 
                     27: #define _BIRD_LISTS_C_
                     28: 
                     29: #include "nest/bird.h"
                     30: #include "lib/lists.h"
                     31: 
                     32: /**
                     33:  * add_tail - append a node to a list
                     34:  * @l: linked list
                     35:  * @n: list node
                     36:  *
                     37:  * add_tail() takes a node @n and appends it at the end of the list @l.
                     38:  */
                     39: LIST_INLINE void
                     40: add_tail(list *l, node *n)
                     41: {
                     42:   node *z = l->tail;
                     43: 
                     44:   n->next = &l->tail_node;
                     45:   n->prev = z;
                     46:   z->next = n;
                     47:   l->tail = n;
                     48: }
                     49: 
                     50: /**
                     51:  * add_head - prepend a node to a list
                     52:  * @l: linked list
                     53:  * @n: list node
                     54:  *
                     55:  * add_head() takes a node @n and prepends it at the start of the list @l.
                     56:  */
                     57: LIST_INLINE void
                     58: add_head(list *l, node *n)
                     59: {
                     60:   node *z = l->head;
                     61: 
                     62:   n->next = z;
                     63:   n->prev = &l->head_node;
                     64:   z->prev = n;
                     65:   l->head = n;
                     66: }
                     67: 
                     68: /**
                     69:  * insert_node - insert a node to a list
                     70:  * @n: a new list node
                     71:  * @after: a node of a list
                     72:  *
                     73:  * Inserts a node @n to a linked list after an already inserted
                     74:  * node @after.
                     75:  */
                     76: LIST_INLINE void
                     77: insert_node(node *n, node *after)
                     78: {
                     79:   node *z = after->next;
                     80: 
                     81:   n->next = z;
                     82:   n->prev = after;
                     83:   after->next = n;
                     84:   z->prev = n;
                     85: }
                     86: 
                     87: /**
                     88:  * rem_node - remove a node from a list
                     89:  * @n: node to be removed
                     90:  *
                     91:  * Removes a node @n from the list it's linked in. Afterwards, node @n is cleared.
                     92:  */
                     93: LIST_INLINE void
                     94: rem_node(node *n)
                     95: {
                     96:   node *z = n->prev;
                     97:   node *x = n->next;
                     98: 
                     99:   z->next = x;
                    100:   x->prev = z;
                    101:   n->next = NULL;
                    102:   n->prev = NULL;
                    103: }
                    104: 
                    105: /**
                    106:  * replace_node - replace a node in a list with another one
                    107:  * @old: node to be removed
                    108:  * @new: node to be inserted
                    109:  *
                    110:  * Replaces node @old in the list it's linked in with node @new.  Node
                    111:  * @old may be a copy of the original node, which is not accessed
                    112:  * through the list. The function could be called with @old == @new,
                    113:  * which just fixes neighbors' pointers in the case that the node
                    114:  * was reallocated.
                    115:  */
                    116: LIST_INLINE void
                    117: replace_node(node *old, node *new)
                    118: {
                    119:   old->next->prev = new;
                    120:   old->prev->next = new;
                    121: 
                    122:   new->prev = old->prev;
                    123:   new->next = old->next;
                    124: }
                    125: 
                    126: /**
                    127:  * init_list - create an empty list
                    128:  * @l: list
                    129:  *
                    130:  * init_list() takes a &list structure and initializes its
                    131:  * fields, so that it represents an empty list.
                    132:  */
                    133: LIST_INLINE void
                    134: init_list(list *l)
                    135: {
                    136:   l->head = &l->tail_node;
                    137:   l->null = NULL;
                    138:   l->tail = &l->head_node;
                    139: }
                    140: 
                    141: /**
                    142:  * add_tail_list - concatenate two lists
                    143:  * @to: destination list
                    144:  * @l: source list
                    145:  *
                    146:  * This function appends all elements of the list @l to
                    147:  * the list @to in constant time.
                    148:  */
                    149: LIST_INLINE void
                    150: add_tail_list(list *to, list *l)
                    151: {
                    152:   node *p = to->tail;
                    153:   node *q = l->head;
                    154: 
                    155:   p->next = q;
                    156:   q->prev = p;
                    157:   q = l->tail;
                    158:   q->next = &to->tail_node;
                    159:   to->tail = q;
                    160: }
                    161: 
                    162: LIST_INLINE uint
                    163: list_length(list *l)
                    164: {
                    165:   uint len = 0;
                    166:   node *n;
                    167: 
                    168:   WALK_LIST(n, *l)
                    169:     len++;
                    170: 
                    171:   return len;
                    172: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>