Logo Search packages:      
Sourcecode: scigraphica version File versions  Download package

lists.c

/*  lists.c - Zed's Virtual Terminal
 *  Copyright (C) 1998  Michael Zucchi
 *
 *  Partly based on list handling code by Marcus Comstedt in libami
 *  from amiwm (an implementation of Amiga Exec-style doubly-linked lists).
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public License
 *  as published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "lists.h"

#define d(x)

void vt_list_new(struct vt_list *v)
{
  v->head = (struct vt_listnode *)&v->tail;
  v->tail = 0;
  v->tailpred = (struct vt_listnode *)&v->head;
}

/* add node to head of list */
struct vt_listnode *vt_list_addhead(struct vt_list *l, struct vt_listnode *n)
{
  n->next = l->head;
  n->prev = (struct vt_listnode *)&l->head;
  l->head->prev = n;
  l->head = n;
  return n;
}

/* add node to tail of list */
struct vt_listnode *vt_list_addtail(struct vt_list *l, struct vt_listnode *n)
{

  d(printf("adding %08x to tail of list\n", n));
  d(printf("list = \n %08x\n %08x\n %08x\n", l->head, l->tailpred, l->tail));

  n->next = (struct vt_listnode *)&l->tail;
  n->prev = l->tailpred;
  l->tailpred->next = n;
  l->tailpred = n;

  d(printf("list = \n %08x\n %08x\n %08x\n", l->head, l->tailpred, l->tail));

  return n;
}


/* returns true if the list is empty */
int vt_list_empty(struct vt_list *l)
{
  if (l->head == (struct vt_listnode *)&l->tail)
    return 1;
  else
    return 0;
}

/* removes head node of list */
struct vt_listnode *vt_list_remhead(struct vt_list *l)
{
  struct vt_listnode *n;

  if (vt_list_empty(l))
    return 0L;
  else {
    n = l->head;
    n->next->prev = n->prev;
    l->head = n->next;
  }
  return n;
}

/* removes tail node of list */
struct vt_listnode *vt_list_remtail(struct vt_list *l)
{
  struct vt_listnode *n;

  if (vt_list_empty(l)) {
    d(printf("empty list, returning null\n"));
    return 0L;
  } else {
    d(printf("unlinling last element\n"));
    n = l->tailpred;
    n->prev->next = n->next;
    l->tailpred = n->prev;
  }
  return n;
}


/* remove a node from a list 
  must have already been added to the list */
struct vt_listnode *vt_list_remove(struct vt_listnode *n)
{
  n->next->prev = n->prev;
  n->prev->next = n->next;
  return n;
}

/* insert n into list l before node p */
struct vt_listnode *vt_list_insert(struct vt_list *l, struct vt_listnode *p, struct vt_listnode *n)
{
  if (p->next==0L) {    
    vt_list_addtail(l, n);
  } else {
    p->prev->next = n;
    n->prev = p->prev;
    n->next = p;
    p->prev = n;
  }
  return n;
}

/* find a node by numerical index
   if negative, then scan backward, from the list tail
   for negative scans, "node -1" is the first
   for forward scans "node 0" is the first
*/
struct vt_listnode *vt_list_index(struct vt_list *l, int index)
{
  struct vt_listnode *wn, *nn;

  if (index<0) {
    wn = l->tailpred;
    nn = wn->prev;
    index++;
    while (nn && (index<0)) {
      wn=nn;
      nn=nn->prev;
      index++;
    }
  } else {
    wn = l->head;
    nn = wn->next;
    while (nn && index) {
      wn=nn;
      nn=nn->next;
      index--;
    }
  }
  if (index==0) {
    return wn;
  } else {
    return 0;
  }
}

Generated by  Doxygen 1.6.0   Back to index