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

ecs_def.c

/*============================================================================
 * Définitions, variables globales, et fonctions de base
 *============================================================================*/

/*
  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
*/

#include "ecs_config.h"


/* includes système ou BFT */

#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(HAVE_CGNS)
#include <cgnslib.h>
#endif

#include <bft_backtrace.h>
#include <bft_error.h>
#include <bft_printf.h>


/* Includes librairie */

#include "ecs_def.h"


/*============================================================================
 *  Constantes et Macros
 *============================================================================*/

/* Type pour la sauvegarde des signaux */

typedef void (*ecs_loc_def__sighandler_t) (int);


/*=============================================================================
 * Définitions de variables globales
 *============================================================================*/

/* Date de compilation */

char      ecs_glob_build_date[]   = __DATE__;

/* Support de la librairie d'échange de maillages et champs CGNS */

#if defined(HAVE_CGNS)
int       ecs_glob_have_cgns      = 1;
#if defined(CGNS_VERSION)
int       ecs_glob_cgns_ver_maj  = CGNS_VERSION/1000;
int       ecs_glob_cgns_ver_min  = (CGNS_VERSION % 1000) / 100;
int       ecs_glob_cgns_ver_rel  = (CGNS_VERSION % 100) / 10;
#elif defined(NofValidAreaTypes)
int       ecs_glob_cgns_ver_maj  = 2;
int       ecs_glob_cgns_ver_min  = 2;
int       ecs_glob_cgns_ver_rel  = -1;
#else
int       ecs_glob_cgns_ver_maj  = 2;
int       ecs_glob_cgns_ver_min  = 1;
int       ecs_glob_cgns_ver_rel  = -1;
#endif
#else
int       ecs_glob_have_cgns     = 0;
int       ecs_glob_cgns_ver_maj  = 0;
int       ecs_glob_cgns_ver_min  = 0;
int       ecs_glob_cgns_ver_rel  = 0;
#endif

/* Support de la librairie d'échange de maillages et champs MED */

#if defined(HAVE_MED)
int       ecs_glob_have_med     = 1;
#else
int       ecs_glob_have_med     = 0;
#endif

/* Variables globales associée à la gestion des signaux */

#if defined(SIGHUP)
static ecs_loc_def__sighandler_t ecs_loc_def__sighup_sauve  = SIG_DFL;
#endif

static ecs_loc_def__sighandler_t ecs_loc_def__sigint_sauve  = SIG_DFL;
static ecs_loc_def__sighandler_t ecs_loc_def__sigterm_sauve = SIG_DFL;
static ecs_loc_def__sighandler_t ecs_loc_def__sigfpe_sauve  = SIG_DFL;
static ecs_loc_def__sighandler_t ecs_loc_def__sigsegv_sauve = SIG_DFL;

#if defined(SIGXCPU)
static ecs_loc_def__sighandler_t ecs_loc_def__sigcpu_sauve  = SIG_DFL;
#endif

/* Détermination du type d'élément en connectivité nodale en fonction du
   nombre de ses sommets, pour des éléments de dimension 1 (arêtes),
   2 (faces), ou 3 (cellules) ;
   Au dessus de 8 sommets, on a toujours le type ECS_ELT_TYP_FAC_POLY pour
   les faces et ECS_ELT_TYP_FAC_POLY pour les cellules */

const ecs_elt_typ_t  ecs_glob_typ_elt[3][9] = {

  /* Arêtes */

  {ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_ARE,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL},

  /* Faces ; au dessus de 5 sommets, on a toujours des polygones */

  {ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_FAC_TRIA,
   ECS_ELT_TYP_FAC_QUAD,
   ECS_ELT_TYP_FAC_POLY,
   ECS_ELT_TYP_FAC_POLY,
   ECS_ELT_TYP_FAC_POLY,
   ECS_ELT_TYP_FAC_POLY},

  /* Cellules ; les polyèdres sont décrits en connectivité descendante,
     avec un sommet supplémentaire par face comme marqueur de fin de face,
     donc un tétraèdre nécessiterait 16 sommets sous cette forme ; tous
     les polyèdres ont donc plus de 8 sommets. */

  {ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_CEL_TETRA,
   ECS_ELT_TYP_CEL_PYRAM,
   ECS_ELT_TYP_CEL_PRISM,
   ECS_ELT_TYP_NUL,
   ECS_ELT_TYP_CEL_HEXA},

} ;


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

static void ecs_loc_def__error_handler
(
 const char     *const nom_fic,
 const int             num_ligne,
 const int             code_err_sys,
 const char     *const format,
       va_list         arg_ptr
);

/*----------------------------------------------------------------------------
 * Fonction d'impression d'un "backtrace"
 *----------------------------------------------------------------------------*/

static void ecs_loc_def__backtrace_print
(
 int niv_debut
);

/*----------------------------------------------------------------------------
 * Fonction de gestion d'un signal fatal (de type SIGFPE ou SIGSEGV)
 *----------------------------------------------------------------------------*/

static void ecs_loc_def__sig_fatal
(
 int  signum
);

/*----------------------------------------------------------------------------
 *  Fonction qui compte la largeur d'une chaîne de caractères, en tenant
 *  compte de la possibilité que cette chaîne soit de type UTF-8.
 *----------------------------------------------------------------------------*/

int  ecs_loc_def__strlen
(
 const char  * chaine
);


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

/*----------------------------------------------------------------------------
 * Fonction d'initialisation de la gestion des erreurs
 *----------------------------------------------------------------------------*/

void ecs_init_gestion_erreur
(
  void
)
{
  bft_error_handler_set(ecs_loc_def__error_handler);

  /* Gestion des signaux */

  bft_backtrace_print_set(ecs_loc_def__backtrace_print);

#if defined(SIGHUP)
  ecs_loc_def__sighup_sauve  = signal(SIGHUP, ecs_loc_def__sig_fatal);
#endif

  ecs_loc_def__sigint_sauve  = signal(SIGINT, ecs_loc_def__sig_fatal);
  ecs_loc_def__sigterm_sauve = signal(SIGTERM, ecs_loc_def__sig_fatal);
  ecs_loc_def__sigfpe_sauve  = signal(SIGFPE, ecs_loc_def__sig_fatal);
  ecs_loc_def__sigsegv_sauve = signal(SIGSEGV, ecs_loc_def__sig_fatal);

#if defined(SIGXCPU)
  ecs_loc_def__sigcpu_sauve  = signal(SIGXCPU, ecs_loc_def__sig_fatal);
#endif
}


/*----------------------------------------------------------------------------
 * Fonction d'arrêt
 *----------------------------------------------------------------------------*/

void ecs_exit
(
  const ecs_int_t  statut
)
{
  if (statut == EXIT_FAILURE) {

    fprintf (stdout, "\n\n %s\n\n", _("Abnormal end"));
    bft_backtrace_print(2);

#if defined(DEBUG) || !defined(NDEBUG)
    assert(0);
#endif

  }

  exit (statut);

}


/*----------------------------------------------------------------------------
 * Fonction d'impression d'un avertissement
 *----------------------------------------------------------------------------*/

void ecs_warn
(
  void
)
{
  bft_printf(_("\n"
               "Warning\n"
               "=======\n"));
}


/*----------------------------------------------------------------------------
 *  Fonction qui imprime une chaîne de caractères avec une largeur
 *  de colonne donnée.
 *----------------------------------------------------------------------------*/

void ecs_print_padded_str
(
 const char  *str,
       int    width
)
{

  int lng = ecs_loc_def__strlen(str);

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  if (str != NULL)
    bft_printf(str);

  if (width > lng)
    bft_printf("%-*s", width-lng, "" );

}


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

static void ecs_loc_def__error_handler
(
 const char     *const nom_fic,
 const int             num_ligne,
 const int             code_err_sys,
 const char     *const format,
       va_list         arg_ptr
)
{
  bft_printf_flush();

  fprintf(stderr, _("\n"
                    "Error in ECS execution\n"
                    "======================\n"));

  if (code_err_sys != 0)
    fprintf(stderr, _("\nSystem error: %s\n"), strerror(code_err_sys));

  fprintf(stderr, _("\n%s:%d: Fatal error.\n\n"), nom_fic, num_ligne);

  vfprintf(stderr, format, arg_ptr);

  fprintf(stderr, "\n\n");

  bft_backtrace_print(2);

  assert(0);   /* Utilisation de assert pour interception sous un debugger */

  exit(EXIT_FAILURE);
}


/*----------------------------------------------------------------------------
 * Fonction d'impression d'un "backtrace"
 *----------------------------------------------------------------------------*/

static void ecs_loc_def__backtrace_print
(
  int  niv_debut
)
{
  size_t  ind;
  bft_backtrace_t  *tr = NULL;

  tr = bft_backtrace_create();

  if (tr != NULL) {

    char s_func_buf[67];

    const char *s_file;
    const char *s_func;
    const char *s_addr;

    const char s_inconnu[] = "?";
    const char s_vide[] = "";
    const char *s_prefix = s_vide;

    size_t nbr = bft_backtrace_size(tr);

    if (nbr > 0)
      fprintf(stderr, _("\nCall stack \n"));

    for (ind = niv_debut ; ind < nbr ; ind++) {

      s_file = bft_backtrace_file(tr, ind);
      s_func = bft_backtrace_function(tr, ind);
      s_addr = bft_backtrace_address(tr, ind);

      if (s_file == NULL)
        s_file = s_inconnu;
      if (s_func == NULL)
        strcpy(s_func_buf, "?");
      else {
        s_func_buf[0] = '<';
        strncpy(s_func_buf + 1, s_func, 64);
        strcat(s_func_buf, ">");
      }
      if (s_addr == NULL)
        s_addr = s_inconnu;

      fprintf(stderr, "%s%4d: %-12s %-32s (%s)\n", s_prefix,
              (int)ind-niv_debut+1, s_addr, s_func_buf, s_file);

    }

    bft_backtrace_destroy(tr);

    if (nbr > 0)
      fprintf(stderr, _("End of stack\n\n"));
  }

}


/*----------------------------------------------------------------------------
 * Fonction de gestion d'un signal fatal (de type SIGFPE ou SIGSEGV)
 *----------------------------------------------------------------------------*/

static void ecs_loc_def__sig_fatal
(
 int  signum
)
{
  bft_printf_flush();

  switch (signum) {

#if defined(SIGHUP)
  case SIGHUP:
    fprintf(stderr, _("SIGHUP signal (hang-up) intercepted.\n"
                      "--> computation interrupted.\n"));
    break;
#endif

  case SIGINT:
    fprintf(stderr, _("SIGINT signal (Control+C or equivalent) received.\n"
                      "--> computation interrupted by user.\n"));
    break;

  case SIGTERM:
    fprintf(stderr, _("SIGTERM signal (termination) received.\n"
                      "--> computation interrupted by environment.\n"));
    break;

  case SIGFPE:
    fprintf(stderr, _("SIGFPE signal (floating-point exception) "
                      "intercepted !\n"));
    break;

  case SIGSEGV:
    fprintf(stderr, _("SIGSEGV signal (access to forbidden memory area) "
                      " intercepted !\n"));
    break;

#if defined(SIGXCPU)
  case SIGXCPU:
    fprintf(stderr, _("SIGXCPU signal (CPU time limit exceeded) "
                      "intercepted.\n"));
    break;
#endif

  default:
    fprintf(stderr, _("Signal %d intercepted !\n"), signum);
  }

  bft_backtrace_print(3);

  assert(0);   /* Use assert to avoit exiting under debugger */

  exit(EXIT_FAILURE);
}


/*----------------------------------------------------------------------------
 *  Fonction qui compte la largeur d'une chaîne de caractères, en tenant
 *  compte de la possibilité que cette chaîne soit de type UTF-8.
 *----------------------------------------------------------------------------*/

int  ecs_loc_def__strlen
(
 const char  * chaine
)
{
  static int mode_utf8 = -1;

  int lng = 0;
  int retval = 0;

  if (mode_utf8 == -1) {
    char *lang = getenv("LANG");
    mode_utf8 = 0;
    if (lang != NULL) {
      if (strcmp(lang + strlen(lang) - 5, "UTF-8") == 0)
        mode_utf8 = 1;
    }
  }

  if (chaine != NULL) {

    lng = strlen(chaine);

    if (mode_utf8 == 0)
      retval = lng;

    else if (mode_utf8 == 1) {

      int ind;
      ecs_bool_t multibyte = ECS_FALSE;

      for (ind = 0; ind < lng; ind++) {

        char c = chaine[ind];

        if (multibyte == ECS_FALSE || (c < 0x80 || c > 0xBF)) {

          multibyte = ECS_FALSE;

          if (c <= 0x7F) {
            retval++;
          }
          else if (c >= 0xC0 || c <= 0xFD) {
            multibyte = ECS_TRUE;
            retval++;
          }

        }

      }

    }

  }

  return retval;

}


Generated by  Doxygen 1.6.0   Back to index