/*============================================================================
*
*                    Code_Saturne version 1.3
*                    ------------------------
*
*
*     This file is part of the Code_Saturne Kernel, element of the
*     Code_Saturne CFD tool.
*
*     Copyright (C) 1998-2007 EDF S.A., France
*
*     contact: saturne-support@edf.fr
*
*     The Code_Saturne Kernel 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 Kernel 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 Kernel; if not, write to the
*     Free Software Foundation, Inc.,
*     51 Franklin St, Fifth Floor,
*     Boston, MA  02110-1301  USA
*
*============================================================================*/

/*============================================================================
 * Utilitaires pour le listing et les messages d'erreur
 *============================================================================*/

/* includes système */

#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/* Includes librairie BFT */

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


/* Includes librairie */

#include "cs_base.h"
#include "cs_msg.h"


/* Définitions locales */


/* Tampon pour impressions depuis du code C : on imprime dans un chaîne
   de caractères, qui sera imprimée vers un fichier par du code Fortran.
   Une fois les impressions Fortran totalement remplacées par des impressions
   C, on pourra supprimer cette étape, mais elle est nécessaire pour l'instant
   afin de pouvoir utiliser les mêmes fichiers de sortie */

#define CS_BUF_PRINT_F_SIZE 16384

static char cs_buf_print_f[CS_BUF_PRINT_F_SIZE];

/* Macro pour écriture dans un tampon */
#if defined(CS_HAVE_VSNPRINTF)
#define CS_VSNPRINTF(_buf, _max, _format, _arg_ptr) \
vsnprintf (_buf, _max, _format, _arg_ptr)
#else
#define CS_VSNPRINTF(_buf, _max, _format, _arg_ptr) \
vsprintf (_buf, _format, _arg_ptr)
#endif

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

/*----------------------------------------------------------------------------
 * Fonction Fortran d'impression d'un message sur la sortie standard
 *----------------------------------------------------------------------------*/

void CS_PROCF (csprnt, CSPRNT)
(
  char       *cs_buf_print,
  cs_int_t   *msgsize
);


/*----------------------------------------------------------------------------
 * Fonction Fortran de vidage du tampon du fichier d'impression
 *----------------------------------------------------------------------------*/

void CS_PROCF (csflsh, CSFLSH)
(
 void
);


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

/*----------------------------------------------------------------------------
 * Fonction d'impression d'un message d'erreur ou d'avertissement
 *----------------------------------------------------------------------------*/

void cs_msg_err
(
  const char          *file_name,
  const int            line_num,
  const cs_msg_type_t  msg_typ,
  const cs_int_t       error,           /* --> Numéro d'erreur système (pas
                                              une erreur système si 0)       */
  const char          *format,
  ...
)
{
  cs_int_t  line;
  cs_int_t  msgsize;
  va_list   arg_ptr;

  switch (msg_typ) {

  case CS_MSG_TYPE_ERR:
    fprintf (stderr, _("\n\n%s: %s:%d : Erreur fatale\n"),
             CS_MSG_NOM_PROGRAMME, file_name, line_num);
    break;

  case CS_MSG_TYPE_ERR_SYS:
    if (error != 0)
      fprintf (stderr, _("\n\nErreur système : %s\n"), strerror(error));
    fprintf (stderr, _("\n%s: %s:%d : Erreur fatale\n"),
             CS_MSG_NOM_PROGRAMME, file_name, line_num);
    break;

  case CS_MSG_TYPE_WARN:
    bft_printf (_("\n\n%s: %s:%d : Avertissement\n"),
                CS_MSG_NOM_PROGRAMME, file_name, line_num);
    break;

  }

  va_start (arg_ptr, format);

  msgsize = CS_VSNPRINTF (cs_buf_print_f, CS_BUF_PRINT_F_SIZE, format, arg_ptr);
  line = __LINE__ - 1;

  if (msgsize == -1 || msgsize > CS_BUF_PRINT_F_SIZE - 1) {
    fprintf (stderr, "\n%s: %s:%d\n", CS_MSG_NOM_PROGRAMME, __FILE__, line);
    fprintf (stderr, _("\nErreur système : %s\n"), strerror(errno));
    cs_exit (EXIT_FAILURE) ;
  }
  else if (msgsize < CS_BUF_PRINT_F_SIZE - 1) {
    cs_buf_print_f[msgsize] = '\n';
    msgsize += 1;
  }

  va_end (arg_ptr);

  CS_PROCF (csprnt, CSPRNT) (cs_buf_print_f, &msgsize);

  if (   msg_typ == CS_MSG_TYPE_ERR
      || msg_typ == CS_MSG_TYPE_ERR_SYS) {

    bft_backtrace_print(2);

    assert (CS_FALSE);

    cs_exit (EXIT_FAILURE);

  }

}


/*----------------------------------------------------------------------------
 * Fonction de vidage du tampon de fichier d'impression
 *----------------------------------------------------------------------------*/

void cs_msg_flush
(
 void
)
{
  CS_PROCF (csflsh, CSFLSH) ();
}


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

