mirror of
				https://gitlab.labs.nic.cz/labs/bird.git
				synced 2024-05-11 16:54:54 +00:00 
			
		
		
		
	- Unit Testing Framework (BirdTest) - Integration of BirdTest into the BIRD build system - Tests for several BIRD modules Based on squashed Pavel Tvrdik's int-test branch, updated for current int-new branch.
		
			
				
	
	
		
			153 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 *	BIRD Library -- Safe Linked Lists
 | 
						|
 *
 | 
						|
 *	(c) 1998 Martin Mares <mj@ucw.cz>
 | 
						|
 *
 | 
						|
 *	Can be freely distributed and used under the terms of the GNU GPL.
 | 
						|
 */
 | 
						|
 | 
						|
#define _BIRD_SLISTS_C_
 | 
						|
 | 
						|
#include "nest/bird.h"
 | 
						|
#include "lib/slists.h"
 | 
						|
 | 
						|
static inline void
 | 
						|
s_merge(snode *from, snode *to)
 | 
						|
{
 | 
						|
  siterator *f, *g;
 | 
						|
 | 
						|
  if (!(f = from->readers))
 | 
						|
    return;
 | 
						|
  if (!(g = to->readers))
 | 
						|
    {
 | 
						|
      /* Fast path */
 | 
						|
      to->readers = f;
 | 
						|
      f->prev = (siterator *) to;
 | 
						|
    fixup:
 | 
						|
      while (f && f->node)
 | 
						|
	{
 | 
						|
	  f->node = NULL;
 | 
						|
	  f = f->next;
 | 
						|
	}
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  /* Really merging */
 | 
						|
  while (g->next)
 | 
						|
    g = g->next;
 | 
						|
  g->next = f;
 | 
						|
  f->prev = g;
 | 
						|
  goto fixup;
 | 
						|
}
 | 
						|
 | 
						|
snode *
 | 
						|
s_get(siterator *i)
 | 
						|
{
 | 
						|
  siterator *f, *g;
 | 
						|
  snode *n;
 | 
						|
 | 
						|
  if (!(n = i->node))
 | 
						|
    {
 | 
						|
      /*
 | 
						|
       * No node found. We have to walk the iterator list backwards
 | 
						|
       * to find where are we linked.
 | 
						|
       */
 | 
						|
      f = i;
 | 
						|
      while (!f->null)
 | 
						|
	f = f->prev;
 | 
						|
      n = (snode *) f;
 | 
						|
    }
 | 
						|
  f = i->prev;				/* Maybe the snode itself */
 | 
						|
  g = i->next;
 | 
						|
  f->next = g;
 | 
						|
  if (g)
 | 
						|
    g->prev = f;
 | 
						|
 | 
						|
  i->prev = NULL;
 | 
						|
  i->next = NULL;
 | 
						|
  return n;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
s_put(siterator *i, snode *n)
 | 
						|
{
 | 
						|
  siterator *f;
 | 
						|
 | 
						|
  i->node = n;
 | 
						|
  if (f = n->readers)
 | 
						|
    f->prev = i;
 | 
						|
  i->next = f;
 | 
						|
  n->readers = i;
 | 
						|
  i->prev = (siterator *) n;
 | 
						|
  i->null = NULL;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
s_add_tail(slist *l, snode *n)
 | 
						|
{
 | 
						|
  snode *z = l->tail;
 | 
						|
 | 
						|
  n->next = (snode *) &l->null;
 | 
						|
  n->prev = z;
 | 
						|
  z->next = n;
 | 
						|
  l->tail = n;
 | 
						|
  n->readers = NULL;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
s_add_head(slist *l, snode *n)
 | 
						|
{
 | 
						|
  snode *z = l->head;
 | 
						|
 | 
						|
  n->next = z;
 | 
						|
  n->prev = (snode *) &l->head;
 | 
						|
  z->prev = n;
 | 
						|
  l->head = n;
 | 
						|
  n->readers = NULL;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
s_insert_node(snode *n, snode *after)
 | 
						|
{
 | 
						|
  snode *z = after->next;
 | 
						|
 | 
						|
  n->next = z;
 | 
						|
  n->prev = after;
 | 
						|
  after->next = n;
 | 
						|
  z->prev = n;
 | 
						|
  n->readers = NULL;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
s_rem_node(snode *n)
 | 
						|
{
 | 
						|
  snode *z = n->prev;
 | 
						|
  snode *x = n->next;
 | 
						|
 | 
						|
  z->next = x;
 | 
						|
  x->prev = z;
 | 
						|
  s_merge(n, x);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
s_init_list(slist *l)
 | 
						|
{
 | 
						|
  l->head = (snode *) &l->null;
 | 
						|
  l->null = NULL;
 | 
						|
  l->tail = (snode *) &l->head;
 | 
						|
  l->tail_readers = NULL;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
s_add_tail_list(slist *to, slist *l)
 | 
						|
{
 | 
						|
  snode *p = to->tail;
 | 
						|
  snode *q = l->head;
 | 
						|
 | 
						|
  p->next = q;
 | 
						|
  q->prev = p;
 | 
						|
  q = l->tail;
 | 
						|
  q->next = (snode *) &to->null;
 | 
						|
  to->tail = q;
 | 
						|
  s_merge((snode *) &l->null, (snode *) &to->null);
 | 
						|
}
 |