/* OpenIDA - Outil d'analyse de fichiers binaires
* dllist.c - implantation simple des listes doublement chaînées
*
* Copyright (C) 2008 Cyrille Bagard
*
* This file is part of OpenIDA.
*
* OpenIDA is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* OpenIDA 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see .
*/
#include "dllist.h"
#include
/******************************************************************************
* *
* Paramètres : new = nouvel élément à ajouter. *
* head = adresse d'enregistrement de la tête de la liste. *
* prev = élément précédent dans la liste. *
* next = élément suivant dans la liste. *
* *
* Description : Ajoute un élément dans une liste doublement chaînée. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void __dl_list_add(dl_list_item *new, dl_list_head *head, dl_list_item *prev, dl_list_item *next)
{
prev->next = new;
new->prev = prev;
new->next = next;
next->prev = new;
if (*head == NULL)
*head = new;
}
/******************************************************************************
* *
* Paramètres : prev = élément précédent dans la liste. *
* next = élément suivant dans la liste. *
* *
* Description : Supprime un élément d'une liste doublement chaînée. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void __dl_list_del(dl_list_item *prev, dl_list_item *next)
{
next->prev = prev;
prev->next = next;
}
/******************************************************************************
* *
* Paramètres : head = début de la liste, à mettre éventuellement à jour. *
* a = premier élément à traiter. *
* b = second élément à traiter. *
* *
* Description : Intervertit deux éléments dans une liste doublement chaînée. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void swap_dl_list_items(dl_list_head *head, dl_list_item *a, dl_list_item *b)
{
bool a_is_head; /* Indique si a est le début */
bool b_is_head; /* Indique si b est le début */
dl_list_item tmp; /* Stockage temporaire */
a_is_head = (*head == a);
b_is_head = (*head == b);
/* Liens vers l'extérieur et l'intérieur */
if (a->prev != b) a->prev->next = b;
if (a->next != b) a->next->prev = b;
if (b->prev != a) b->prev->next = a;
if (b->next != a) b->next->prev = a;
/* Liens propres aux éléments */
tmp = *a;
a->prev = (b->prev == a ? b : b->prev);
a->next = (b->next == a ? b : b->next);
b->prev = (tmp.prev == b ? a : tmp.prev);
b->next = (tmp.next == b ? a : tmp.next);
/* Mise à jour éventuelle de la tête */
if (a_is_head) *head = b;
else if (b_is_head) *head = a;
}
/******************************************************************************
* *
* Paramètres : list = liste à parcourir. *
* *
* Description : Compte le nombre d'éléments présents dans une liste. *
* *
* Retour : Nombre d'éléments comptabilisés. *
* *
* Remarques : - *
* *
******************************************************************************/
unsigned int count_dl_list_items(dl_list_head list)
{
unsigned int result; /* Résultat à renvoyer */
dl_list_item *iter; /* Boucle de parcours */
result = 0;
dl_list_for_each(iter, list, dl_list_item *)
result++;
return result;
}