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

ecs_descr_chaine.c

/*============================================================================
 *  Définitions des fonctions de base
 *   associées à une liste chaînée de structures `ecs_descr_t' décrivant
 *   un descripteur de champ
 *============================================================================*/

/*
  This file is part of the Code_Saturne Preprocessor, element of the
  Code_Saturne CFD tool.

  Copyright (C) 1999-2007 EDF S.A., France

  contact: saturne-support@edf.fr

  The Code_Saturne Preprocessor 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 2 of
  the License, or (at your option) any later version.

  The Code_Saturne Preprocessor 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 the Code_Saturne Preprocessor; if not, write to the
  Free Software Foundation, Inc.,
  51 Franklin St, Fifth Floor,
  Boston, MA  02110-1301  USA
*/


/*============================================================================
 *                                 Visibilité
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Fichiers `include' librairie standard C ou BFT
 *----------------------------------------------------------------------------*/

#include <assert.h>
#include <string.h>

#include <bft_file.h>
#include <bft_mem.h>


/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles du  paquetage global "Utilitaire"
 *----------------------------------------------------------------------------*/

#include "ecs_def.h"
#include "ecs_fic.h"
#include "ecs_tab.h"


/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles des paquetages visibles
 *----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles du  paquetage courant
 *----------------------------------------------------------------------------*/

#include "ecs_descr.h"


/*----------------------------------------------------------------------------
 *  Fichier  `include' du  paquetage courant associe au fichier courant
 *----------------------------------------------------------------------------*/

#include "ecs_descr_chaine.h"


/*----------------------------------------------------------------------------
 *  Fichiers `include' prives   du  paquetage courant
 *----------------------------------------------------------------------------*/

#include "ecs_descr_priv.h"


/*============================================================================
 *                       Prototypes de fonctions privées
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Fonction qui supprime un noeud donné
 *   dans une liste chaînée de descripteurs dont la tête est donnée
 *
 *  La tête de la liste qui n'est pas modifiée
 *   sauf si le noeud à supprimer est aussi la tête de la liste !
 *----------------------------------------------------------------------------*/

static void ecs_loc_descr_chaine__supprime
(
 ecs_descr_t * * this_descr_noeud ,       /* --> Adresse du descr à supprimer */
 ecs_descr_t * * descr_tete               /* --> tête de la liste contenant   */
                                          /*      le noeud à supprimer        */
) ;


/*============================================================================
 *                             Fonctions publiques
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Fonction libérant la portion d'une liste chaînée de descripteurs
 *   à partir d'un noeud dont le pointeur est donné en argument.
 *  Le noeud est à NULL au retour de la fonction
 *----------------------------------------------------------------------------*/

void ecs_descr_chaine__detruit
(
 ecs_descr_t * * this_descr_noeud
)
{


  if (*this_descr_noeud != NULL) {

    ecs_descr_chaine__detruit(&(*this_descr_noeud)->l_descr_sui) ;

    *this_descr_noeud = ecs_descr__detruit(*this_descr_noeud) ;

  }


}


/*----------------------------------------------------------------------------
 *  Fonction imprimant à partir d'un noeud `ecs_descr_t' donné
 *   une liste chaînée de champs
 *   sur le flux décrit par la structure `bft_file_t'
 *----------------------------------------------------------------------------*/

void ecs_descr_chaine__imprime
(
 const ecs_descr_t *const this_descr_noeud ,
       ecs_int_t          imp_col          ,
       bft_file_t  *const fic_imp
)
{


#define ECS_FCT_IMP_DESCR_NOEUD       "descr"


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  if (this_descr_noeud != NULL) {

    ecs_descr_chaine__imprime(this_descr_noeud->l_descr_sui,
                              imp_col,
                              fic_imp) ;

    ecs_fic__imprime_ptr(fic_imp, imp_col, ECS_FCT_IMP_DESCR_NOEUD,
                         (const void *)this_descr_noeud) ;

    ecs_descr__imprime(this_descr_noeud,
                       imp_col,
                       fic_imp) ;

  }


}


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie la taille en octets
 *   d'une chaîné de structures `ecs_descr_t'
 *----------------------------------------------------------------------------*/

float ecs_descr_chaine__ret_taille
(
 const ecs_descr_t *const this_descr_noeud
)
{

  float         taille ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  taille = 0. ;


  if (this_descr_noeud != NULL) {

    taille +=
      ecs_descr_chaine__ret_taille(this_descr_noeud->l_descr_sui) ;

    taille += ecs_descr__ret_taille(this_descr_noeud) ;

  }


  return taille ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui ajoute à la fin d'une liste chaînée de descripteurs de champ
 *   réceptrice dont la tête est donnée,
 *   une liste chaînée de descripteurs de champ à concaténer
 *    dont la tête est donnée
 *
 *  Les numéros des descripteurs de la liste à concaténer sont incrementés
 *   à partir du nombre de descripteur de la liste réceptrice
 *
 *  Remarque: cette fonction se contente d'ajouter des descripteurs sans
 *            vérifier si le descripteur ajoute a le même contenu qu'un autre
 *            descripteur déjà présent dans la liste.
 *            Pour une vérification, utiliser `ecs_descr_chaine__concatene()'
 *----------------------------------------------------------------------------*/

void ecs_descr_chaine__ajoute
(
 ecs_descr_t *      * this_descr_tete   ,
 ecs_descr_t *const   descr_concat_tete
)
{

  ecs_int_t   inum ;

  ecs_descr_t * loc_descr_prec ;
  ecs_descr_t * ptr_descr      ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_descr_tete   != NULL) ;


  if (*this_descr_tete != NULL) {


    /* On va à la fin de la chaîne réceptrice */

    for (ptr_descr = *this_descr_tete       ;
         ptr_descr != NULL                  ;
         ptr_descr = ptr_descr->l_descr_sui  )
      loc_descr_prec = ptr_descr ;


    /* On ajoute le lien avec le début de la chaîne à concaténer */

    loc_descr_prec->l_descr_sui = descr_concat_tete ;


    /* Les numéros des descripteurs de la liste à concaténer sont incrémentés */
    /*  à partir du nombre de descripteur de la liste réceptrice              */

    for (ptr_descr = descr_concat_tete     , inum = 1 ;
         ptr_descr != NULL                            ;
         ptr_descr = ptr_descr->l_descr_sui, inum++    )
      ptr_descr->num = loc_descr_prec->num + inum ;


  }
  else {


    *this_descr_tete = descr_concat_tete ;

  }


}


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie le nombre de descripteurs
 *   de la liste chaînée des descripteurs dont la tête est donnée
 *----------------------------------------------------------------------------*/

ecs_int_t ecs_descr_chaine__ret_nbr
(
 const ecs_descr_t *const this_descr_tete
)
{

  const ecs_descr_t  * ptr_descr ; /* Pointeur de boucle sur les descripteurs */
  ecs_int_t            nbr_descr ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_descr_tete != NULL) ;


  nbr_descr = 0 ;


  for (ptr_descr = this_descr_tete ;
       ptr_descr != NULL ;
       ptr_descr = ptr_descr->l_descr_sui) {

    nbr_descr++ ;

  }


  return nbr_descr ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui copie une liste chaînée de descripteurs
 *   dont la tête est donnée
 *----------------------------------------------------------------------------*/

ecs_descr_t * ecs_descr_chaine__copie
(
 ecs_descr_t * descr_tete
)
{

  ecs_descr_t * descr_copie ;
  ecs_descr_t * descr_tete_copie ;
  ecs_descr_t * ptr_descr ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  descr_tete_copie = NULL ;

  for (ptr_descr  = descr_tete             ;
       ptr_descr != NULL                   ;
       ptr_descr  = ptr_descr->l_descr_sui  ) {

    descr_copie = ecs_descr__copie(ptr_descr) ;

    ecs_descr_chaine__ajoute(&descr_tete_copie,
                             descr_copie) ;

  }


  return descr_tete_copie ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui concatène,
 *   à la fin d'une liste chaînée de descripteurs dont la tête est donnée,
 *   une autre liste chaînée de descripteurs dont la tête est donnée,
 *   en supprimant les descripteurs déjà présents dans la 1ère liste
 *   et en décalant la renumérotation des descripteurs de la 2nde liste
 *
 *  La fonction renvoie la renumérotation des descripteurs de la 2nde liste
 *----------------------------------------------------------------------------*/

ecs_tab_int_t ecs_descr_chaine__concatene
(
 ecs_descr_t * *const descr_recept_tete ,
 ecs_descr_t * *const descr_concat_tete
)
{

  ecs_int_t     cpt_descr              ;

  ecs_descr_t   * ptr_descr_concat       ;
  ecs_descr_t   * ptr_descr_recept       ;

  ecs_tab_int_t   tab_renum_descr_concat ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(*descr_concat_tete != NULL) ;


  /* On repère le plus grand numéro de descripteur de la chaîne à concaténer */

  for (ptr_descr_concat = *descr_concat_tete           , cpt_descr = 0 ;
       ptr_descr_concat != NULL                                        ;
       ptr_descr_concat = ptr_descr_concat->l_descr_sui, cpt_descr++    )
    ;

  BFT_MALLOC(tab_renum_descr_concat.val, cpt_descr, ecs_int_t) ;
  tab_renum_descr_concat.nbr = cpt_descr ;


  /* On repère le plus grand numéro de descripteur de la chaîne réceptrice */

  for (ptr_descr_recept = *descr_recept_tete           , cpt_descr = 0 ;
       ptr_descr_recept != NULL                                        ;
       ptr_descr_recept = ptr_descr_recept->l_descr_sui, cpt_descr++    )
    ;


  /* On parcourt les descripteurs de la chaîne réceptrice   :               */
  /* on parcourt les descripteurs de la chaîne à concaténer :               */
  /*  - si un descripteur n'a pas un descripteur identique                  */
  /*     dans la chaîne à concaténer                                        */
  /*     -> le descripteur de la liste à concaténer prend un nouveau numéro */
  /*  - sinon                                                               */
  /*     -> il est supprime de la chaîne à concaténer                       */

  for (ptr_descr_recept = *descr_recept_tete            ;
       ptr_descr_recept != NULL                         ;
       ptr_descr_recept = ptr_descr_recept->l_descr_sui  ) {


    ptr_descr_concat = *descr_concat_tete ;
    while (ptr_descr_concat != NULL                          &&
           ecs_descr__compare(ptr_descr_recept,
                              ptr_descr_concat) == ECS_FALSE    )
      ptr_descr_concat = ptr_descr_concat->l_descr_sui ;


    if (ptr_descr_concat != NULL) {

      /* Il y a un descripteur identique dans la chaîne à concaténer */

      tab_renum_descr_concat.val[ptr_descr_concat->num - 1]
        = ptr_descr_recept->num - 1 ;

      ecs_loc_descr_chaine__supprime(&ptr_descr_concat,
                                 descr_concat_tete) ;

    }


  }


  if (*descr_concat_tete != NULL) {


    /* Les numéros des descripteurs restants de la chaîne à concaténer */
    /*  sont modifies                                                  */

    for (ptr_descr_concat = *descr_concat_tete            ;
         ptr_descr_concat != NULL                         ;
         ptr_descr_concat = ptr_descr_concat->l_descr_sui  ) {

      tab_renum_descr_concat.val[ptr_descr_concat->num - 1] = cpt_descr ;
      cpt_descr++ ;

    }


    /* On ajoute à la fin de la chaîne réceptrice,          */
    /*  les descripteurs restants de la chaîne à concaténer */

    ecs_descr_chaine__ajoute(descr_recept_tete,
                             *descr_concat_tete) ;

  }


  return tab_renum_descr_concat ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui affiche les contenus des descripteurs
 *   de la liste chaînée des descripteurs dont la tête est donnée
 *----------------------------------------------------------------------------*/

void ecs_descr_chaine__affiche
(
       ecs_descr_t  *const descr_tete ,
 const int                 decal
)
{

  ecs_descr_t * ptr_descr ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  for (ptr_descr  = descr_tete ;
       ptr_descr != NULL ;
       ptr_descr  = ptr_descr->l_descr_sui) {

    ecs_descr__affiche(ptr_descr,
                       decal) ;

  }


}


/*----------------------------------------------------------------------------
 *  Fonction qui recherche dans une liste chaînée de descripteurs
 *   dont la tête est donnée,
 *   un numéro de descripteur donné
 *
 *  La fonction renvoie :
 *  -    le pointeur du descripteur si le numéro de descripteur a été trouve
 *  - ou NULL                       sinon
 *----------------------------------------------------------------------------*/

ecs_descr_t * ecs_descr_chaine__cherche_num
(
       ecs_descr_t *const descr_tete ,
 const ecs_int_t          num
)
{

  ecs_descr_t * ptr_descr ;  /* Pointeur de boucle sur les descripteurs       */


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(descr_tete != NULL) ;


  ptr_descr = descr_tete ;

  while (ptr_descr      != NULL &&
         ptr_descr->num != num    )
    ptr_descr = ptr_descr->l_descr_sui ;


    return ptr_descr ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui recherche dans une liste chaînée de descripteurs
 *   dont la tête est donnée,
 *   un descripteur ayant les mêmes type, identificateur et nom
 *   que le descripteur donné
 *
 *  La fonction renvoie :
 *  -    le numéro du descripteur si le descripteur   a     été trouve
 *  - ou ECS_DESCR_NUM_NUL        si le descripteur n'a pas été trouve
 *----------------------------------------------------------------------------*/

ecs_int_t ecs_descr_chaine__trouve_num
(
       ecs_descr_t *const descr_tete ,
 const ecs_descr_t *const descr_rech
)
{

  ecs_descr_t * ptr_descr ;  /* Pointeur de boucle sur les descripteurs       */


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(descr_tete != NULL && descr_rech != NULL) ;


  ptr_descr = descr_tete ;

  while (ptr_descr != NULL                                      &&
         ecs_descr__compare_selection(ptr_descr ,
                                      descr_rech ) == ECS_FALSE    )
    ptr_descr = ptr_descr->l_descr_sui ;


  if (ptr_descr != NULL) {

    return ptr_descr->num ;

  }
  else {

    return ECS_DESCR_NUM_NUL ;

  }


}


/*----------------------------------------------------------------------------
 *  Fonction qui crée une nouvelle chaîne de descripteurs
 *   à partir d'une chaîne de descripteurs dont la tête est donnée
 *  Un descripteur est copié dans la nouvelle chaîne si son numéro
 *   ne se transforme pas par le vecteur de transformation donné
 *   en `ECS_DESCR_NUM_NUL'
 *  Les membres du descripteur sont copies dans le nouveau sans modification
 *   sauf le numéro qui devient celui transformé par le vecteur
 *----------------------------------------------------------------------------*/

ecs_descr_t * ecs_descr_chaine__renumerote
(
       ecs_descr_t   *const this_descr_tete ,
 const ecs_tab_int_t        vect_transf
)
{

  size_t        inum ;

  ecs_descr_t * descr_new ;
  ecs_descr_t * descr_tete_new ;
  ecs_descr_t * ptr_descr ;       /* Pointeur de boucle sur les descripteurs */


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  descr_tete_new = NULL ;


  for (inum = 0 ; inum < vect_transf.nbr ; inum++) {

    ptr_descr = this_descr_tete ;
    while (ptr_descr != NULL && vect_transf.val[inum] != (ptr_descr->num - 1))
      ptr_descr = ptr_descr->l_descr_sui ;

    assert(ptr_descr != NULL) ;

    descr_new = ecs_descr__cree(ptr_descr->typ_e,
                                ptr_descr->ide,
                                ptr_descr->nom) ;

    ecs_descr_chaine__ajoute(&descr_tete_new,
                             descr_new) ;

  }


  return descr_tete_new ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie le nombre et la liste des identificateurs
 *   des descripteurs de type couleur d'une liste chaînée de descripteurs
 *   dont la tête est donnée en argument
 *----------------------------------------------------------------------------*/

ecs_tab_int_t ecs_descr_chaine__ret_ide
(
 ecs_descr_t  *const descr_tete
)
{

  ecs_int_t     cpt_descr ;

  ecs_descr_t   * ptr_descr ;

  ecs_tab_int_t   tab_ide_descr_chaine ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(descr_tete != NULL) ;


  /* Comptage des descripteurs de type couleur */

  cpt_descr = 0 ;

  for (ptr_descr  = descr_tete ;
       ptr_descr != NULL ;
       ptr_descr  = ptr_descr->l_descr_sui) {

    if (ptr_descr->typ_e == ECS_DESCR_TYP_COULEUR) {

      assert(ptr_descr->ide != ECS_DESCR_IDE_NUL) ;

      cpt_descr += 1 ;

    }

  }

  BFT_MALLOC(tab_ide_descr_chaine.val, cpt_descr, ecs_int_t) ;
  tab_ide_descr_chaine.nbr = cpt_descr;


  /* Construction de la liste des descripteurs de type couleur */

  cpt_descr = 0 ;

  for (ptr_descr  = descr_tete ;
       ptr_descr != NULL ;
       ptr_descr  = ptr_descr->l_descr_sui) {

    if (ptr_descr->typ_e == ECS_DESCR_TYP_COULEUR) {

      tab_ide_descr_chaine.val[cpt_descr] = ptr_descr->ide ;

      cpt_descr += 1 ;

    }

  }


  return tab_ide_descr_chaine ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie le nombre et la liste des pointeurs sur les noms
 *   des descripteurs de type groupe d'une liste chaînée dont la tête est
 *   donnée en argument
 *----------------------------------------------------------------------------*/

ecs_tab_char_t ecs_descr_chaine__ret_nom
(
 ecs_descr_t   *const descr_tete
)
{

  ecs_int_t       cpt_descr ;

  ecs_descr_t   * ptr_descr ;

  ecs_tab_char_t  tab_nom_descr_chaine ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(descr_tete != NULL) ;


  /* Comptage des descripteurs de type groupe */

  cpt_descr = 0 ;

  for (ptr_descr  = descr_tete ;
       ptr_descr != NULL ;
       ptr_descr  = ptr_descr->l_descr_sui) {

    if (ptr_descr->typ_e == ECS_DESCR_TYP_GROUPE) {

      assert(ptr_descr->nom != NULL) ;

      cpt_descr += 1 ;

    }

  }

  BFT_MALLOC(tab_nom_descr_chaine.val, cpt_descr, char *) ;
  tab_nom_descr_chaine.nbr = cpt_descr;


  /* Construction de la liste des descripteurs de type groupe */

  cpt_descr = 0 ;

  for (ptr_descr  = descr_tete ;
       ptr_descr != NULL ;
       ptr_descr  = ptr_descr->l_descr_sui) {

    if (ptr_descr->typ_e == ECS_DESCR_TYP_GROUPE) {

      tab_nom_descr_chaine.val[cpt_descr] = ptr_descr->nom ;

      cpt_descr += 1 ;

    }

  }

  return tab_nom_descr_chaine ;

}


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie la liste des références des descripteurs
 *   de la liste chaînée des descripteurs dont la tête est donnée
 *----------------------------------------------------------------------------*/

ecs_descr_t * * ecs_descr_chaine__ret_ref
(
 ecs_descr_t  *const descr_tete ,
 ecs_int_t    *const nbr_descr
)
{

  ecs_int_t     idescr ;

  ecs_descr_t * * liste_ref_descr ;
  ecs_descr_t   * ptr_descr ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Détermination du nombre de descripteurs de la liste chaînée */
  /*-------------------------------------------------------------*/

  *nbr_descr = ecs_descr_chaine__ret_nbr(descr_tete) ;


  BFT_MALLOC(liste_ref_descr, *nbr_descr, ecs_descr_t *) ;


  idescr = 0 ;

  for (ptr_descr  = descr_tete             ;
       ptr_descr != NULL                   ;
       ptr_descr  = ptr_descr->l_descr_sui   ) {

    liste_ref_descr[idescr++] = ptr_descr ;

  }


  return liste_ref_descr ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui retourne la tête de la liste chaînée des descripteurs
 *   de type donné `descr_typ_e'
 *   contenus dans la liste chaînée des descripteurs dont la tête est donnée
 *----------------------------------------------------------------------------*/

ecs_descr_t * ecs_descr_chaine__ret_descr_typ
(
 ecs_descr_t      *const this_descr_tete ,
 ECS_DESCR_TYP_E         descr_typ_e
)
{

  ecs_descr_t * descr_copie ;
  ecs_descr_t * descr_tete_typ ;
  ecs_descr_t * ptr_descr ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  descr_tete_typ  = NULL ;


  for (ptr_descr  = this_descr_tete ;
       ptr_descr != NULL ;
       ptr_descr  = ptr_descr->l_descr_sui) {

    if (ptr_descr->typ_e == descr_typ_e) {

      descr_copie = ecs_descr__copie(ptr_descr) ;

      ecs_descr_chaine__ajoute(&descr_tete_typ,
                               descr_copie) ;

    }

  }


  return descr_tete_typ ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui indique si une chaîne de descripteurs contient l'un des
 *   attributs (couleur ou groupe) fournis en argument.
 *----------------------------------------------------------------------------*/

ecs_bool_t ecs_descr_chaine__select
(
 const ecs_descr_t     *const descr_tete    ,
 const ecs_tab_int_t          liste_couleur ,
 const ecs_tab_char_t         liste_groupe
)
{
  size_t ind ;

  const ecs_descr_t * ptr_descr ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  for (ptr_descr = descr_tete ;
       ptr_descr != NULL ;
       ptr_descr = ptr_descr->l_descr_sui) {

    if (ptr_descr->typ_e == ECS_DESCR_TYP_COULEUR) {

      for (ind = 0 ; ind < liste_couleur.nbr ; ind++) {
        if (liste_couleur.val[ind] == ptr_descr->ide)
          return ECS_TRUE ;
      }

    }

    else if (ptr_descr->typ_e == ECS_DESCR_TYP_GROUPE) {

      assert(ptr_descr->nom != NULL) ;

      for (ind = 0 ; ind < liste_groupe.nbr ; ind++) {
        if (!strcmp(liste_groupe.val[ind], ptr_descr->nom))
          return ECS_TRUE ;
      }

    }

  }

  return ECS_FALSE ;

}


/*============================================================================
 *                              Fonctions privées
 *============================================================================*/


/*----------------------------------------------------------------------------
 *  Fonction qui supprime un noeud donné
 *   dans une liste chaînée de descripteurs dont la tête est donnée
 *
 *  La tête de la liste qui n'est pas modifiée
 *   sauf si le noeud à supprimer est aussi la tête de la liste !
 *----------------------------------------------------------------------------*/

static void ecs_loc_descr_chaine__supprime
(
 ecs_descr_t * * this_descr_noeud ,       /* --> Adresse du descr à supprimer */
 ecs_descr_t * * descr_tete               /* --> tête de la liste contenant   */
                                          /*      le noeud à supprimer        */
)
{

  ecs_descr_t *loc_descr_sui  ;
  ecs_descr_t *ptr_descr      ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(*descr_tete != NULL) ;
  assert(*this_descr_noeud != NULL) ;


  if ((*this_descr_noeud) == *descr_tete) {

    /* Le descripteur noeud à supprimer est la tête de liste des descripteurs */
    /* Le descripteur suivant est la nouvelle tête                            */

    *descr_tete = (*descr_tete)->l_descr_sui ;

  }
  else {

    /* On recherche le noeud qui précède le noeud à supprimer */

    loc_descr_sui = (*this_descr_noeud)->l_descr_sui ;


    for (ptr_descr = *descr_tete ;
         ptr_descr != NULL && ptr_descr->l_descr_sui != (*this_descr_noeud) ;
         ptr_descr = ptr_descr->l_descr_sui)
      ;


    /* Le noeud à supprimer doit être contenu dans la liste */
    /* `*descr_tete' est la tête                            */
    assert(ptr_descr != NULL);

    ptr_descr->l_descr_sui = loc_descr_sui ;


  } /* Fin else : le descripteur à supprimer n'est pas le descripteur de tête */


  /* Libération du descripteur correspondant au noeud à supprimer */

  *this_descr_noeud = ecs_descr__detruit(*this_descr_noeud) ;


}


Generated by  Doxygen 1.6.0   Back to index