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

ecs_champ.c

/*============================================================================
 *  Définitions des fonctions de base
 *   associées à la structure `ecs_champ_t' décrivant un 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> /* strcpy() */

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


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

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


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

#include "ecs_descr_chaine.h"
#include "ecs_descr.h"


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

#include "ecs_champ_vec_int.h"


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

#include "ecs_champ.h"


/*----------------------------------------------------------------------------
 *  Fichiers `include' privés   du  paquetage courant
 *----------------------------------------------------------------------------*/

#include "ecs_champ_priv.h"


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

/*----------------------------------------------------------------------------
 *  Fonction d'impression d'un champ avec position réglée en ASCII
 *----------------------------------------------------------------------------*/

static void ecs_loc_champ__imprime_pos_pas
(
       bft_file_t     *const fic_imp   ,
       size_t                nbr_ent   ,
       size_t                pos_pas   ,
 const void           *const val       ,
       size_t                nbr_imp   ,
 ecs_type_t                  typ_val_e
) ;


/*----------------------------------------------------------------------------
 *  Fonction d'impression d'un champ avec position non réglée en ASCII
 *  (Champ entier uniquement)
 *----------------------------------------------------------------------------*/

static void ecs_loc_champ__imprime_pos_tab
(
       bft_file_t     *const fic_imp ,
       size_t                nbr_ent ,
       ecs_size_t     *const pos_tab ,
 const ecs_int_t      *const val_tab ,
       size_t                nbr_imp
) ;


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

/*----------------------------------------------------------------------------
 *  Fonction qui crée une structure `ecs_champ_t'
 *
 *  La structure devient propriétaire des tableaux tab_pos et tab_val
 *   fournis en argument.
 *
 *   nbr_elt   : Nombre d'éléments à remplir
 *   pas_pos   : Pas des positions  si REGLE
 *   tab_pos   : Positions du champ si non REGLE
 *   tab_val   : Valeurs du champ
 *   typ_val_e : Type des valeurs du champ
 *   nom       : Nom du champ
 *   descr     : Pointeur sur le descripteur
 *   statut_e  : Statut dans une transformation
 *----------------------------------------------------------------------------*/

ecs_champ_t * ecs_champ__cree
(
       size_t                      nbr_elt   ,
       size_t                      pas_pos   ,
       ecs_size_t           *const tab_pos   ,
       void                 *const tab_val   ,
       ecs_type_t                  typ_val_e ,
 const char                 *const nom       ,
       ecs_descr_t          *const descr     ,
       ECS_CHAMP_STATUT_E          statut_e
)
{

  ecs_champ_t     * this_champ ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(nom != NULL) ;


  /* Allocation de la structure `ecs_champ_t' */
  /*------------------------------------------*/

  BFT_MALLOC(this_champ, 1, ecs_champ_t);


  this_champ->nbr_elt = nbr_elt ;
  this_champ->typ_val = typ_val_e ;


  /* Définition des positions des valeurs (itérateur) */
  /*--------------------------------------------------*/

  this_champ->pos_pas = pas_pos ;
  this_champ->pos_tab = tab_pos ;

  ecs_champ__pos_en_regle(this_champ) ;


  /* Définition de la table des valeurs (conteneur) */
  /*------------------------------------------------*/

  this_champ->val_tab = tab_val ;


  /* Copie du nom */
  /*--------------*/

  BFT_MALLOC(this_champ->nom, strlen(nom) + 1, char) ;
  strcpy(this_champ->nom, nom) ;


  /* Affectation du descripteur de champ */
  /*-------------------------------------*/

  this_champ->descr = descr ;


  /* Initialisation du lien pour les listes chaînées */
  /* des champs auxiliaires                          */
  /*-------------------------------------------------*/

  this_champ->l_champ_sui = NULL ;


  /* Statut du champ dans une transformation */
  /*  de type découpage ou recollement       */
  /*-----------------------------------------*/

  this_champ->statut_e      = statut_e ;


  return this_champ ;

}


/*----------------------------------------------------------------------------
 *  Fonction libérant une structure `ecs_champ_t' donnée en argument.
 *  Elle renvoie un pointeur NULL
 *----------------------------------------------------------------------------*/

ecs_champ_t * ecs_champ__detruit
(
 ecs_champ_t * this_champ
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  if (this_champ == NULL)
    return (this_champ) ;


  /* Libération du contenu de la structure `ecs_champ_t' */
  /*=================================================*/


  /* Libération de la structure des positions */
  /*------------------------------------------*/

  if (this_champ->pos_tab != NULL)
    BFT_FREE(this_champ->pos_tab) ;


  /* Libération de la structure des valeurs */
  /*----------------------------------------*/

  if (this_champ->val_tab != NULL)
    BFT_FREE(this_champ->val_tab) ;


  /* Libération du nom */
  /*-------------------*/

  if (this_champ->nom != NULL)
    BFT_FREE(this_champ->nom) ;


  /* Libération du descripteur de champ */
  /*------------------------------------*/

  /* Appel à la fonction de libération d'un descripteur de champ */

  if (this_champ->descr != NULL)
    ecs_descr_chaine__detruit(&this_champ->descr) ;


  /* Libération de la structure `ecs_champ_t' */
  /*==========================================*/

  BFT_FREE(this_champ) ;


  return this_champ ;


}


/*----------------------------------------------------------------------------
 *  Fonction imprimant le contenu d'une structure `ecs_champ_t' donnée
 *   sur le flux décrit par la structure `bft_file_t'
 *----------------------------------------------------------------------------*/

void ecs_champ__imprime
(
 const ecs_champ_t  *const this_champ, /* --> Structure à imprimer           */
       size_t              imp_col,
       size_t              nbr_imp,
       bft_file_t   *const fic_imp      /* --> Descripteur fic. d'impression  */
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_champ   != NULL) ;
  assert(fic_imp      != NULL) ;


  imp_col++ ;


  /* Impression des champs d'information du champ */
  /*----------------------------------------------*/

  ecs_fic__imprime_val(fic_imp, imp_col, "nom", ECS_TYPE_char,
                       this_champ->nom) ;

  ecs_fic__imprime_val(fic_imp, imp_col, "typ_val", ECS_TYPE_ecs_int_t,
                       &this_champ->typ_val) ;

  ecs_fic__imprime_val(fic_imp, imp_col, "nbr_elt", ECS_TYPE_size_t,
                       &this_champ->nbr_elt) ;

  ecs_fic__imprime_val(fic_imp, imp_col, "pos_pas", ECS_TYPE_size_t,
                       &this_champ->pos_pas) ;

  ecs_fic__imprime_ptr(fic_imp, imp_col, "pos_tab", this_champ->pos_tab) ;
  ecs_fic__imprime_ptr(fic_imp, imp_col, "val_tab", this_champ->val_tab) ;


  /* Impression des positions et des valeurs */
  /*-----------------------------------------*/

  if (this_champ->pos_tab == NULL && this_champ->val_tab != NULL) {

    ecs_loc_champ__imprime_pos_pas(fic_imp,
                                   this_champ->nbr_elt,
                                   this_champ->pos_pas,
                                   this_champ->val_tab,
                                   nbr_imp,
                                   this_champ->typ_val) ;

  }
  else if (this_champ->pos_tab != NULL) {

    ecs_loc_champ__imprime_pos_tab(fic_imp ,
                                   this_champ->nbr_elt,
                                   this_champ->pos_tab,
                                   this_champ->val_tab,
                                   nbr_imp) ;

  }


  /* Impression de la liste chaînée des descripteurs */
  /*-------------------------------------------------*/

  /* Impression du pointeur sur le descripteur de tête */

  ecs_fic__imprime_val(fic_imp, imp_col, "descr_tete", ECS_TYPE_void,
                       this_champ->descr);


  if (this_champ->descr != NULL) {

    /* Appel à la fonction d'impression d'une chaîne de descripteurs de champ */

    ecs_descr_chaine__imprime(this_champ->descr,
                              imp_col + 1,
                              fic_imp) ;

  }


  /* Impression du lien sur un éventuel champ suivant */
  /*--------------------------------------------------*/

  ecs_fic__imprime_val(fic_imp, imp_col, "l_champ_sui", ECS_TYPE_void,
                       this_champ->l_champ_sui);


  /* Statut du champ dans une transformation */
  /*  de type découpage ou recollement       */
  /*-----------------------------------------*/

  ecs_fic__imprime_val(fic_imp, imp_col, "statut_e", ECS_TYPE_ecs_int_t,
                       &this_champ->statut_e) ;

}


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie la taille en octets d'une structure `ecs_champ_t'
 *----------------------------------------------------------------------------*/

size_t ecs_champ__ret_taille
(
 const ecs_champ_t *const this_champ
)
{

  size_t        nbr_val ;
  size_t        taille ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_champ != NULL) ;


  taille = sizeof(*this_champ) ;


  if (this_champ->pos_tab != NULL)
    taille += (sizeof(ecs_int_t) * (this_champ->nbr_elt + 1)) ;

  if (this_champ->val_tab != NULL) {
    nbr_val = ecs_champ__ret_val_nbr(this_champ) ;
    switch (this_champ->typ_val) {
    case ECS_TYPE_ecs_int_t:
      taille += (sizeof(ecs_int_t) * nbr_val) ;
      break ;
    case ECS_TYPE_ecs_real_t:
      taille += (sizeof(ecs_real_t) * nbr_val) ;
      break ;
    default:
      assert(0) ;
    }
  }

  taille += sizeof(*(this_champ->nom)) ;

  if (this_champ->nom != NULL)
    taille += (sizeof(char) * (strlen(this_champ->nom) + 1)) ;

  if (this_champ->descr != NULL)
    taille += ecs_descr_chaine__ret_taille(this_champ->descr) ;

  return taille ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie un champ entièrement réalloué
 *   dont le contenu est copié à partir du champ donné
 *
 *  Le membre donnant le lien sur un champ suivant `l_champ_sui'
 *   n'est pas copié et est mis à `NULL'
 *----------------------------------------------------------------------------*/

ecs_champ_t * ecs_champ__copie
(
 ecs_champ_t *const champ_init
)
{
  size_t        nbr_val ;
  ecs_champ_t * this_champ ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(champ_init != NULL) ;

  BFT_MALLOC(this_champ, 1, ecs_champ_t) ;

  this_champ->nbr_elt = champ_init->nbr_elt ;
  this_champ->typ_val = champ_init->typ_val ;

  this_champ->pos_pas = champ_init->pos_pas ;


  if (champ_init->pos_tab != NULL) {
    BFT_MALLOC(this_champ->pos_tab, champ_init->nbr_elt + 1, ecs_size_t) ;
    memcpy(this_champ->pos_tab,
           champ_init->pos_tab,
           (champ_init->nbr_elt + 1) * sizeof(ecs_int_t)) ;
  }
  else
    this_champ->pos_tab = NULL ;

  if (champ_init->val_tab != NULL) {
    nbr_val = ecs_champ__ret_val_nbr(champ_init) ;
    BFT_MALLOC(this_champ->val_tab, nbr_val, ecs_int_t) ;
    switch (this_champ->typ_val) {
    case ECS_TYPE_ecs_int_t:
      memcpy(this_champ->val_tab,
             champ_init->val_tab,
             sizeof(ecs_int_t) * nbr_val) ;
      break ;
    case ECS_TYPE_ecs_real_t:
      memcpy(this_champ->val_tab,
             champ_init->val_tab,
             sizeof(ecs_real_t) * nbr_val) ;
      break ;
    default:
      assert(0) ;
    }
  }
  else
    this_champ->val_tab = NULL ;

  if (champ_init->nom != NULL) {
    BFT_MALLOC(this_champ->nom, strlen(champ_init->nom) + 1, char) ;
    strcpy(this_champ->nom, champ_init->nom) ;
  }
  else {
    this_champ->nom = NULL ;
  }

  this_champ->descr         = ecs_descr_chaine__copie(champ_init->descr) ;

  this_champ->l_champ_sui   = NULL ;

  this_champ->statut_e      = champ_init->statut_e ;


  return this_champ ;

}


/*----------------------------------------------------------------------------
 *  Fonction qui créé une structure `ecs_champ_t'
 *   à partir d'un tableau `tab_elt' contenant les valeurs du champ.
 *
 *  Les valeurs du champ doivent être des valeurs entières.
 *  Si un élément n'a pas de valeur associée, la valeur correspondante
 *   dans `tab_elt' est `0'
 *----------------------------------------------------------------------------*/

ecs_champ_t * ecs_champ__transforme_tableau
(                                              /* <-- Pointeur créé           */
       size_t                      nbr_elt   , /* --> Nbr.éléments à remplir  */
 const ecs_int_t            *const tab_elt   , /* --> Valeurs du champ        */
 const char                 *const nom       , /* --> Nom du champ            */
       ecs_descr_t          *const descr     , /* --> Ptr. sur descripteur    */
       ECS_CHAMP_STATUT_E          statut_e    /* --> Statut pour transform.  */
)
{

  ecs_size_t *pos_tab ;
  ecs_int_t *val_tab ;
  size_t cpt_val ;
  size_t ielt ;

  ecs_champ_t * this_champ ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(nbr_elt != 0) ;
  assert(tab_elt != NULL) ;
  assert(nom != NULL) ;

  /* Allocation de la structure `ecs_champ_t' */
  /*--------------------------------------*/

  BFT_MALLOC(this_champ, 1, ecs_champ_t);


  this_champ->nbr_elt = nbr_elt ;
  this_champ->typ_val = ECS_TYPE_ecs_int_t ;


  /* Construction des tableaux de positions et de valeurs */
  /*------------------------------------------------------*/

  BFT_MALLOC(pos_tab, nbr_elt + 1, ecs_size_t);
  BFT_MALLOC(val_tab, nbr_elt    , ecs_int_t);

  pos_tab[0] = 1 ;
  cpt_val    = 0 ;

  for (ielt = 0 ; ielt < nbr_elt ; ielt++) {

    if (tab_elt[ielt] != 0) {

      pos_tab[ielt + 1]  = pos_tab[ielt] + 1 ;
      val_tab[cpt_val++] = tab_elt[ielt]     ;

    }
    else {

      pos_tab[ielt + 1]  = pos_tab[ielt] ;

    }

  }

  BFT_REALLOC(val_tab, cpt_val, ecs_int_t) ;


  /* Création de la table des positions des valeurs (itérateur) */
  /*------------------------------------------------------------*/

  this_champ->pos_pas = 0 ;
  this_champ->pos_tab = pos_tab ;

  ecs_champ__pos_en_regle(this_champ) ;


  /* Création de la table des valeurs (conteneur) */
  /*----------------------------------------------*/

  this_champ->val_tab = val_tab ;


  /* Copie du nom */
  /*--------------*/

  BFT_MALLOC(this_champ->nom, strlen(nom) + 1, char) ;
  strcpy(this_champ->nom, nom) ;


  /* Affectation du descripteur de champ */
  /*-------------------------------------*/

  this_champ->descr = descr ;


  /* Initialisation du lien pour les listes chaînées */
  /* des champs auxiliaires                          */
  /*-------------------------------------------------*/

  this_champ->l_champ_sui = NULL ;


  /* Statut du champ dans une transformation */
  /*  de type découpage ou recollement       */
  /*-----------------------------------------*/

  this_champ->statut_e    = statut_e ;


  return this_champ ;


}


/*----------------------------------------------------------------------------
 *  Fonction retournant le nombre de positions d'un champ donné
 *----------------------------------------------------------------------------*/

size_t ecs_champ__ret_pos_nbr
(
 const ecs_champ_t *const this_champ
)
{

  assert(this_champ != NULL) ;


  return (this_champ->nbr_elt + 1) ;

}


/*----------------------------------------------------------------------------
 *  Fonction renvoyant le nombre de valeurs associées à un champ donné
 *----------------------------------------------------------------------------*/

size_t ecs_champ__ret_val_nbr
(
 const ecs_champ_t  *const this_champ
)
{

  size_t  nbr_val ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_champ   != NULL) ;


  if (this_champ->pos_tab != NULL)
    nbr_val = this_champ->pos_tab[this_champ->nbr_elt] - 1;
  else
    nbr_val = (this_champ->pos_pas * this_champ->nbr_elt) ;


  return nbr_val ;

}


/*----------------------------------------------------------------------------
 *  Fonction retournant le nombre de descripteurs d'un champ donné
 *----------------------------------------------------------------------------*/

size_t ecs_champ__ret_descr_nbr
(
 const ecs_champ_t *const this_champ
)
{

  assert(this_champ != NULL) ;


  return ecs_descr_chaine__ret_nbr(this_champ->descr) ;

}


/*----------------------------------------------------------------------------
 *  Fonction retournant le type des valeurs d'un champ donné
 *----------------------------------------------------------------------------*/

ecs_type_t ecs_champ__ret_val_typ
(
 const ecs_champ_t *const this_champ
)
{

  assert(this_champ != NULL) ;


  return this_champ->typ_val ;

}


/*----------------------------------------------------------------------------
 *  Fonction renvoyant un pointeur sur le tableau des positions d'une
 *   structure `ecs_champ_t' donnée.
 *
 *  Si les positions correspondent à une REGLE, le tableau est alloué et
 *   construit. S'il est déjà défini, on renvoie simplement son pointeur.
 *   Pour libérer le tableau lorsqu'il correspond à une REGLE (sans le
 *   libérer si ce n'est pas le cas), on appelle ecs_champ__libere_pos_tab().
 *----------------------------------------------------------------------------*/

ecs_size_t * ecs_champ__ret_pos_tab
(
 ecs_champ_t  *const this_champ
)
{

  size_t ipos ;
  ecs_size_t *tab_pos ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_champ != NULL) ;


  if (this_champ->pos_tab != NULL)
    tab_pos =  this_champ->pos_tab ;

  else {

    BFT_MALLOC(tab_pos, this_champ->nbr_elt + 1, ecs_size_t) ;

    for (ipos = 0 ; ipos <= this_champ->nbr_elt ; ipos++)
      tab_pos[ipos] = (ipos * this_champ->pos_pas) + 1 ;

  }

  return tab_pos ;

}


/*----------------------------------------------------------------------------
 *  Fonction libérant un pointeur sur le tableau des positions d'une
 *   structure `ecs_champ_t' donnée.
 *
 *  Si les positions correspondent à une REGLE, le tableau est libéré.
 *   Sinon, il est conservé par la structure ecs_champ_t.
 *----------------------------------------------------------------------------*/

void ecs_champ__libere_pos_tab
(
 const ecs_champ_t  *const this_champ ,
       ecs_size_t   *      pos_tab
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_champ != NULL) ;

  assert(this_champ->pos_tab == NULL || this_champ->pos_tab == pos_tab) ;

  if (this_champ->pos_tab == NULL)
    BFT_FREE(pos_tab) ;

}


/*----------------------------------------------------------------------------
 *  Fonction qui concatène dans un champ récepteur donné,
 *   un champ à concaténer donné
 *
 *  Les 2 champs à concaténer sont supposés avoir le même nom
 *
 *  La concaténation de 2 champs consiste à concaténer :
 *  - les tables des positions des 2 champs ;
 *  - les tables des valeurs   des 2 champs ;
 *  - les listes chaînées des descripteurs des 2 champs
 *    (nécessaire uniquement pour des champs de type "attribut")
 *
 *  Les autres membres de la structure du champ récepteur ne sont pas modifiés
 *----------------------------------------------------------------------------*/

void ecs_champ__concatene
(
 ecs_champ_t *const champ_recept ,
 ecs_champ_t *const champ_concat
)
{

  size_t    ipos ;
  size_t    ival ;
  size_t    nbr_elt_recept ;
  size_t    nbr_val_recept ;
  size_t    nbr_val_concat ;
  size_t    pos_recept_fin ;

  ecs_descr_t  *descr_concat_copie ;
  ecs_tab_int_t tab_renum_descr ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(champ_recept != NULL) ;
  assert(champ_concat != NULL) ;
  assert(champ_recept->typ_val == champ_concat->typ_val) ;
  assert(strcmp(champ_recept->nom, champ_concat->nom) == 0) ;


  /* Dimensions avant concaténation */

  nbr_elt_recept = champ_recept->nbr_elt ;
  nbr_val_recept = ecs_champ__ret_val_nbr(champ_recept) ;
  nbr_val_concat = ecs_champ__ret_val_nbr(champ_concat) ;


  /* Pour les attributs,                                 */
  /*  il faut renuméroter les descripteurs               */
  /*  et propager ces nouvelles valeurs sur les éléments */

  tab_renum_descr.nbr = 0;
  tab_renum_descr.val = NULL;

  if (champ_concat->descr != NULL) {

    /* Unification des descripteurs d'attributs */

    descr_concat_copie = ecs_descr_chaine__copie(champ_concat->descr) ;


    tab_renum_descr = ecs_descr_chaine__concatene(&champ_recept->descr,
                                                  &descr_concat_copie) ;

  }


  /* Membres restant à modifier pour le champ recepteur : */
  /* - `nbr_elt'                                          */
  /* - `pos*'                                             */
  /* - `val*'                                             */

  champ_recept->nbr_elt += champ_concat->nbr_elt ;


  /* Traitement de la table des positions ; si l'on n'a pas
     une REGLE identique de part et d'autre, on doit la reconstruire */

  /* Si l'on a un pas identique de part et d'autre, on n'a rien à faire */

  if (   champ_recept->pos_tab != NULL
      || champ_concat->pos_tab != NULL
      || champ_recept->pos_pas != champ_concat->pos_pas) {

    /* 1ère étape : construire ou agrandir le tableau des positions,
       et le remplir des valeurs du champ initial */

    if (champ_recept->pos_tab == NULL) {

      BFT_MALLOC(champ_recept->pos_tab, champ_recept->nbr_elt + 1, ecs_size_t) ;
      champ_recept->pos_tab[0] = 1;
      for (ipos = 0 ; ipos <= nbr_elt_recept ; ipos++)
        champ_recept->pos_tab[ipos] = (champ_recept->pos_pas * ipos) + 1 ;

    }
    else {

      BFT_REALLOC(champ_recept->pos_tab, champ_recept->nbr_elt + 1, ecs_size_t) ;

    }

    /* 2ème étape : ajouter les positions à concaténer */

    pos_recept_fin = champ_recept->pos_tab[nbr_elt_recept] ;

    if (champ_concat->pos_tab == NULL) {

      for (ipos = 1 ; ipos <= champ_concat->nbr_elt ; ipos++)
        champ_recept->pos_tab[nbr_elt_recept + ipos]
          = pos_recept_fin + (ipos * champ_concat->pos_pas) ;

    }
    else { /* if (champ_concat->pos_tab != NULL) */

      for (ipos = 1 ; ipos <= champ_concat->nbr_elt ; ipos++)
        champ_recept->pos_tab[nbr_elt_recept + ipos]
          = pos_recept_fin - 1 + champ_concat->pos_tab[ipos] ;

    }

  }

  if (champ_recept->pos_tab != NULL)
    champ_recept->pos_pas = 0 ;


  /* Traitement de la table des valeurs */
  /*------------------------------------*/

  /* On concatène les tables de valeurs,
     en renumérotant éventuellement des attributs */

  if (champ_recept->nbr_elt > 0) {

    switch(champ_recept->typ_val) {

    case ECS_TYPE_ecs_int_t:

      /* 1ère étape : construire ou agrandir le tableau des valeurs,
         et le remplir des valeurs du champ initial */

      if (nbr_elt_recept == 0) {
        assert(champ_recept->val_tab == NULL) ;
        BFT_MALLOC(champ_recept->val_tab,
                   nbr_val_recept + nbr_val_concat,
                   ecs_int_t) ;
      }
      else {
        assert(champ_recept->val_tab != NULL) ;
        BFT_REALLOC(champ_recept->val_tab,
                    nbr_val_recept + nbr_val_concat,
                    ecs_int_t) ;
      }

      /* 2ème étape : ajouter les valeurs à concaténer, en les renumérotant,
         si nécessaire */

      if (tab_renum_descr.nbr == 0 && nbr_val_concat > 0)

        memcpy(((ecs_int_t *)champ_recept->val_tab) + nbr_val_recept,
               champ_concat->val_tab,
               nbr_val_concat * sizeof(ecs_int_t)) ;

      else {

        ecs_int_t *tab_val_recept = champ_recept->val_tab ;
        ecs_int_t *tab_val_concat = champ_concat->val_tab ;

        for (ival = 0 ; ival < nbr_val_concat ; ival++)
          tab_val_recept[nbr_val_recept + ival]
            = tab_renum_descr.val[ECS_ABS(tab_val_concat[ival]) - 1] + 1 ;

      }

      break ;

    case ECS_TYPE_ecs_real_t:

      assert(champ_recept->val_tab != NULL) ;

      /* 1ère étape : construire ou agrandir le tableau des valeurs,
         et le remplir des valeurs du champ initial */

      if (nbr_elt_recept == 0) {
        assert(champ_recept->val_tab == NULL) ;
        BFT_MALLOC(champ_recept->val_tab,
                   nbr_val_recept + nbr_val_concat,
                   ecs_real_t) ;
      }
      else {
        assert(champ_recept->val_tab != NULL) ;
        BFT_REALLOC(champ_recept->val_tab,
                    nbr_val_recept + nbr_val_concat,
                    ecs_real_t) ;
      }

      /* 2ème étape : ajouter les valeurs à concaténer (pas de valeurs
         constantes ou de renumérations pour les réels) */

      if (nbr_val_concat > 0)
        memcpy(((ecs_real_t *)champ_recept->val_tab) + nbr_val_recept,
               champ_concat->val_tab,
               nbr_val_concat * sizeof(ecs_real_t)) ;

      break ;

    default:
      assert(0) ;
    }

  } /* Fin de la concaténation des tables de valeurs */


  /* Suppression du tableau de renumérotation des descripteurs */

  if (tab_renum_descr.nbr > 0)
    BFT_FREE(tab_renum_descr.val) ;

}


/*----------------------------------------------------------------------------
 *  Fonction qui prolonge un champ récepteur donné
 *
 *  Il s'agit en fait de concaténer le champ avec un champ vide. Seule la
 *  table des positions est modifiée. Les autres membres de la structure du
 *  champ récepteur ne sont pas modifiés.
 *----------------------------------------------------------------------------*/

void ecs_champ__prolonge
(
 ecs_champ_t *const champ_recept ,
 size_t             nbr_elt_prec ,
 size_t             nbr_elt_suiv
)
{

  size_t      ipos ;
  size_t      nbr_elt_ini ;
  ecs_int_t   pos_fin ;
  ecs_bool_t  bool_pos_ini ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(champ_recept != NULL) ;
  assert(champ_recept->typ_val == ECS_TYPE_ecs_int_t) ;

  nbr_elt_ini = champ_recept->nbr_elt ;
  bool_pos_ini = (champ_recept->pos_tab != NULL) ? ECS_TRUE : ECS_FALSE ;


  /* Mise à jour du nombre d'éléments */

  champ_recept->nbr_elt += nbr_elt_prec + nbr_elt_suiv ;


  /* Si le champ n'est pas déjà vide, la table des positions ne
     correspondra pas à une REGLE, et devra être construite */

  if (champ_recept->pos_tab != NULL || champ_recept->pos_pas != 0) {

    BFT_REALLOC(champ_recept->pos_tab, champ_recept->nbr_elt + 1, ecs_size_t) ;

    if (bool_pos_ini == ECS_TRUE) {
      memmove(champ_recept->pos_tab + (nbr_elt_prec * sizeof(ecs_int_t)),
              champ_recept->pos_tab,
              (champ_recept->nbr_elt + 1) * sizeof(ecs_int_t)) ;
    }
    else {
      for (ipos = 0 ; ipos <= nbr_elt_ini ; ipos++)
        champ_recept->pos_tab[nbr_elt_prec + ipos]
          = (ipos * champ_recept->pos_pas) + 1 ;
    }

    champ_recept->pos_tab[0] = 1 ;

    for (ipos = 0 ; ipos < nbr_elt_prec ; ipos++)
      champ_recept->pos_tab[ipos + 1] = 1 ;

    pos_fin = champ_recept->pos_tab[nbr_elt_prec + nbr_elt_ini] ;
    for (ipos = 0 ; ipos < nbr_elt_suiv ; ipos++)
      champ_recept->pos_tab[nbr_elt_prec + nbr_elt_ini + ipos + 1] = pos_fin ;

  }

}


/*----------------------------------------------------------------------------
 *  Fonction qui convertit, si possible,
 *   le tableau des positions d'un champ en REGLE
 *----------------------------------------------------------------------------*/

void ecs_champ__pos_en_regle
(
 ecs_champ_t  *this_champ    /* --> Structure contenant le champ             */
)
{

  size_t      ipos ;
  size_t      pos_pas ;
  ecs_bool_t  bool_regle ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_champ != NULL) ;

  bool_regle = ECS_TRUE ;
  pos_pas = 0 ;

  if (this_champ->pos_tab != NULL && this_champ->nbr_elt > 0) {

    pos_pas = this_champ->pos_tab[1] - this_champ->pos_tab[0] ;

    for (ipos = 1 ; ipos < this_champ->nbr_elt ; ipos++) {

      if (this_champ->pos_tab[ipos + 1] - this_champ->pos_tab[ipos] != pos_pas) {
        bool_regle = ECS_FALSE ;
        break ;
      }

    }

  }


  if (bool_regle == ECS_TRUE && this_champ->pos_tab != NULL) {

    this_champ->pos_pas = pos_pas ;

    BFT_FREE(this_champ->pos_tab) ;

  }

}


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

/*----------------------------------------------------------------------------
 *  Fonction d'impression d'un champ avec position réglée en ASCII
 *----------------------------------------------------------------------------*/

static void ecs_loc_champ__imprime_pos_pas
(
       bft_file_t     *const fic_imp   ,
       size_t                nbr_ent   ,
       size_t                pos_pas   ,
 const void           *const val_tab   ,
       size_t                nbr_imp   ,
 ecs_type_t                  typ_val_e
)
{
  /* Variables locales */

  size_t  ient ;
  size_t  iloc ;

  size_t  ind_ent_1 = 0 ;
  size_t  ind_ent_2 ;

  char pos_str[32] ; /* Largement surdimensionné pour contenir une
                        chaîne de type [%10d], un entier "long" pouvant
                        nécessiter un format plus large */


  /* Instructions */

  assert(val_tab != NULL) ;

  ind_ent_2 = ECS_MIN(nbr_ent, nbr_imp) ;


  /* Impression des valeurs */
  /*========================*/

  while (1) {

    switch (typ_val_e) {

    case ECS_TYPE_ecs_int_t:

      {
        const int *const val_int = (const int *)val_tab ;

        for (ient = ind_ent_1 ; ient < ind_ent_2 ; ient++) {

          if (pos_pas == 1) {

            bft_file_printf(fic_imp, "%50s %12lu %12ld" "\n",
                            " ", (unsigned long)(ient+1),
                            (long)val_int[ient]) ;

          }
          else if (pos_pas > 1) {

            sprintf(pos_str, "[%d]", (int)(pos_pas*ient + 1)) ;

            bft_file_printf(fic_imp, "%37s %12lu %12s %12ld" "\n",
                            " ", (unsigned long)(ient+1), pos_str,
                            (long)val_int[pos_pas*ient]) ;

            for (iloc = 1 ; iloc < pos_pas ; iloc++)
              bft_file_printf(fic_imp, "%63s %12ld" "\n",
                              " ", (long)val_int[pos_pas*ient + iloc]) ;

          }

        }

      }

      break ;

    case ECS_TYPE_ecs_real_t:

      {
        const ecs_real_t *const val_real = (const ecs_real_t *)val_tab ;

        for (ient = ind_ent_1 ; ient < ind_ent_2 ; ient++) {

          if (pos_pas == 1) {

            bft_file_printf(fic_imp, "%50s %12lu %#12.5E\n",
                            " ", (unsigned long)(ient+1),
                            (double)val_real[ient]) ;

          }
          else if (pos_pas > 1) {

            sprintf(pos_str, "[%d]", (int)(pos_pas*ient + 1)) ;

            bft_file_printf(fic_imp, "%37s %12lu %12s %#12.5E\n",
                            " ", (unsigned long)(ient+1), pos_str,
                            (double)val_real[pos_pas*ient]) ;

            for (iloc = 1 ; iloc < pos_pas ; iloc++)
              bft_file_printf(fic_imp, "%63s %#12.5E\n",
                              " ", (double)val_real[pos_pas*ient + iloc]) ;

          }

        }

      }

      break ;

    default:

      assert(typ_val_e != ECS_TYPE_ecs_int_t  &&
             typ_val_e != ECS_TYPE_ecs_real_t   ) ;


    } /* Fin : switch(typ_val_e) */

    if (ind_ent_2 == nbr_ent)
      break ;

    ind_ent_1 = ECS_MAX(nbr_ent - nbr_imp, nbr_imp) ;

    if (ind_ent_1 > ind_ent_2)

      bft_file_printf(fic_imp,
                      "%77s", "............\n") ;

    ind_ent_2 = nbr_ent ;

  }

}


/*----------------------------------------------------------------------------
 *  Fonction d'impression d'un champ avec position non réglée en ASCII
 *  (Champ entier uniquement)
 *----------------------------------------------------------------------------*/

static void ecs_loc_champ__imprime_pos_tab
(
       bft_file_t     *const fic_imp ,
       size_t                nbr_ent ,
       ecs_size_t     *const pos_tab ,
 const ecs_int_t      *const val_tab ,
       size_t                nbr_imp
)
{
  /* Variables locales */

  size_t  ient ;
  size_t  iloc ;

  size_t  ind_ent_1 = 0 ;
  size_t  ind_ent_2 ;

  size_t  nbr_loc ;


  /* Instructions */

  assert(pos_tab != NULL) ;

  ind_ent_2 = ECS_MIN(nbr_ent, nbr_imp) ;



  /* Impression des valeurs */
  /*========================*/

  while (1) {

    for (ient = ind_ent_1 ; ient < ind_ent_2 ; ient++) {

      nbr_loc = pos_tab[ient + 1] - pos_tab[ient] ;

      if (nbr_loc > 0)
        bft_file_printf(fic_imp, "%37s %12lu %12lu %12ld\n",
                        " ", (unsigned long)(ient+1),
                        (unsigned long)pos_tab[ient],
                        (long)val_tab[pos_tab[ient] - 1]) ;
      else
        bft_file_printf(fic_imp, "%37s %12lu %12lu\n",
                        " ", (unsigned long)(ient+1),
                        (unsigned long)pos_tab[ient]) ;

      for (iloc = 1 ; iloc < nbr_loc ; iloc++)
        bft_file_printf(fic_imp, "%63s %12ld\n",
                        " ", (long)val_tab[pos_tab[ient] + iloc - 1]) ;

    }

    if (ind_ent_2 == nbr_ent)
      break ;

    ind_ent_1 = ECS_MAX(nbr_ent - nbr_imp, nbr_imp) ;

    if (ind_ent_1 > ind_ent_2)

      bft_file_printf(fic_imp,
                      "%77s", "............\n") ;

    ind_ent_2 = nbr_ent ;

  }

  bft_file_printf(fic_imp, "%50s %12lu\n",
                  " ", (unsigned long)pos_tab[nbr_ent]) ;

}


Generated by  Doxygen 1.6.0   Back to index