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

/*============================================================================
 * Parsing of program arguments and associated initializations
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Standard C library headers
 *----------------------------------------------------------------------------*/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#if defined(_CS_HAVE_MPI)
#include <mpi.h>
#endif

/*----------------------------------------------------------------------------
 * BFT library headers
 *----------------------------------------------------------------------------*/

#include <bft_config.h>
#include <bft_mem.h>
#include <bft_printf.h>

/*----------------------------------------------------------------------------
 * Local headers
 *----------------------------------------------------------------------------*/

#include "cs_base.h"
#include "cs_comm.h"

#include "cs_couplage.h"
#include "cs_syr_coupling.h"

#if defined(_CS_HAVE_XML)
#include "cs_gui.h"
#include "cs_gui_util.h"
#endif

/*----------------------------------------------------------------------------
 *  Header for the current file
 *----------------------------------------------------------------------------*/

#include "cs_opts.h"

/*----------------------------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#if 0
} /* Fake brace to force back Emacs auto-indentation back to column 0 */
#endif
#endif /* __cplusplus */

/*=============================================================================
 * Local Macro Definitions
 *============================================================================*/

/*=============================================================================
 * Local Structure Definitions
 *============================================================================*/

/*============================================================================
 * Static global variables
 *============================================================================*/

/*============================================================================
 * Private function definitions
 *============================================================================*/

/*============================================================================
 * Public function definitions for Fortran API
 *============================================================================*/

/*============================================================================
 * Public function definitions
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Print command line help
 *
 * parameters:
 *   name  --> name of executable program
 *----------------------------------------------------------------------------*/

static void
_arg_env_help(const char  *name)
{
  FILE *e = stderr;

  if (cs_glob_base_rang >= 1)
    return;

  fprintf (e, _("Utilisation : %s [options]\n"), name);

  fprintf (e, "\nOptions de la ligne de commandes :\n\n");
  fprintf
    (e, _(" -ec, --echo-comm  echo de la communication avec l'enveloppe ;\n"
          "                   -1 : erreur seulement (défaut)\n"
          "                    0 : impression des entêtes des messages\n"
          "                    n : impression des entêtes des messages ainsi\n"
          "                        que des n premiers et derniers éléments\n"));

  fprintf
    (e, _(" -ifoenv           utilisation de l'Enveloppe ;\n"
          "                    0 : solveur autonome\n"
          "                    1 : pré-traitement par l'Enveloppe (défaut)\n"));

  fprintf
    (e, _(" -longia           taille du tableau de travail entier IA ;\n"
          "                    n : nombre d'entiers (défaut : automatique)\n"
          " -longra           taille du tableau de travail réel RA ;\n"
          "                    n : nombre de réels (defaut : automatique)\n"));

  fprintf
    (e, _(" -mc, --mode-comm  mode de communication avec l'Enveloppe ;\n"
          "                    txt     : fichiers texte\n"
          "                    bin     : fichiers binaires (défaut)\n"));
#if defined(_CS_HAVE_MPI)
  fprintf
    (e, _(" -p, --parallel    activation du parallélisme ;\n"
          "                    [i] n : rang MPI global du 1er processus\n"
          "                            noyau (défaut : 0) et nombre\n"
          "                            de processus noyau\n"));
  fprintf
    (e, _(" --coupl-cs        couplage avec une autre instance du code\n"
          "                     i : rang MPI global du 1er processus\n"
          "                         couplé\n"));
#endif
  fprintf
    (e, _(" -syrthes          couplage Syrthes aux faces sélectionnées\n"
          "                   -2d : le maillage Syrthes associé est 2D\n"
          "                   -X : axe préférentiel de projection\n"
          "                        pour un maillage Syrthes 2D \n"
          "                   -Y : axe préférentiel de projection\n"
          "                        pour un maillage Syrthes 2D \n"
          "                   -Z : axe préférentiel de projection\n"
          "                        pour un maillage Syrthes 2D (défaut)\n"));
#if defined(_CS_HAVE_MPI)
  fprintf
    (e, _("                   -proc <numéro> : rang MPI du processus Syrthes"
          "\n"));
#endif
#if defined(_CS_HAVE_SOCKET)
  fprintf
    (e, _("                   -socket : communication par socket IP\n"
          "                             (tubes nommés par défaut)\n"));
#endif
  fprintf
    (e, _("                   -couleur <numéro(s)> : couleurs des faces\n"
          "                                          à sélectionner\n"
          "                   -groupe <nom(s)>     : groupes des faces\n"
          "                                          à sélectionner\n"
          "                   -invsel : inversion de la sélection\n"));
  fprintf
    (e, _(" -v, --verif       vérifications\n"
          "                   -1 : pas de tests activés (défaut)\n"
          "                    0 : verification de l'initialisation seule\n"
          "                    1 à 5 : activation de tests élémentaires\n"));
  fprintf
    (e, _(" --log             redirection des sorties de rang -1 ou 0 :\n"
          "                     0 : sortie standard\n"
          "                     1 : sorties dans \"listing\" (défaut)\n"));
  fprintf
    (e, _(" --logp            redirection des sorties de rang > 0 :\n"
          "                    -1 : sorties supprimees (défaut)\n"
          "                     0 : aucune redirection (si terminaux\n"
          "                         indépendants, type deboggeur)\n"
          "                     1 : sorties dans \"listing_n<rang>\"\n"));

#if defined(_CS_HAVE_XML)
  fprintf
    (e, _(" -param            [nom_du_fichier] fichier de paramètres\n"));
#endif

  fprintf
    (e, _(" -h, --help        appel de l'aide (cet affichage)\n\n"));
}

/*----------------------------------------------------------------------------
 * Convert an argument to an integer and check its validity
 *
 * parameters:
 *   arg_id  --> index of argument in argv
 *   argc    --> number of command line arguments
 *   argv    --> array of command line arguments
 *   argerr  <-- error indicator
 *
 * returns:
 *   integer value
 *----------------------------------------------------------------------------*/

static int
_arg_to_int(int    arg_id,
            int    argc,
            char  *argv[],
            int   *argerr)
{
  char *start;
  char *end;
  int   retval = 0;

  *argerr = 0;

  if (arg_id < argc) {
    start = argv[arg_id];
    end = start + strlen(start);
    retval = strtol(start, &end, 0);
    if (end != start + strlen(start)) *argerr = 1;
  }
  else {
    *argerr = 1;
  }

  return retval;
}

#if defined(_CS_HAVE_MPI)

/*----------------------------------------------------------------------------
 * First analysis of the command line to determine if Syrthes coupling
 * requires MPI
 *
 * parameters:
 *   arg_id  <-> index of argument in argv
 *   argc    --> number of command line arguments
 *   argv    --> array of command line arguments
 *
 * returns:
 *   -1 if MPI is not needed, or rank of Syrthes process in MPI_COMM_WORLD
 *----------------------------------------------------------------------------*/

static int
_syr_mpi_rank(int   *arg_id,
              int    argc,
              char  *argv[])
{
  /* local variables */

  int  ii;

  const char  *s = NULL;
  cs_bool_t    is_end = CS_FALSE;
  int          syr_rank = -1;
  int          tmperr = -1;

  for (ii = *arg_id; ii < argc && is_end == CS_FALSE; ii++) {
    s = argv[ii];

    if (strcmp(s, "-2d") == 0 || strcmp(s, "-invsel") == 0)
      continue;
    else if (strcmp(s, "-socket") == 0)
      continue;
    else if (strcmp(s, "-proc") == 0) {
      is_end = CS_TRUE;
      syr_rank = _arg_to_int(ii + 1, argc, argv, &tmperr);
      if (tmperr == 0) {
        ii++;
      }
    }
    else {
      /* Check if the current args define face selection options;
         otherwise, we have reached the end of the Syrthes options */

      if (strcmp(s,"-couleur") == 0 || strcmp(s,"-groupe") == 0) {
        while (ii + 1 < argc && strncmp(argv[ii + 1], "-", 1))
          ii++;
      }
      else {
        is_end = CS_TRUE;
      }
    }

  } /* End of loop on Syrthes related arguments */

  if (is_end == CS_TRUE)
    *arg_id = ii - 2;

  return syr_rank;
}

#endif /* defined(_CS_HAVE_MPI) */

/*----------------------------------------------------------------------------
 * First analysis of a Syrthes sub-command line before calling
 * cs_coupl_syr_lit_cmd() to process
 *
 * parameters:
 *   arg_id  <-> index of argument in argv
 *   argc    --> number of command line arguments
 *   argv    --> array of command line arguments
 *   argerr  <-- error indicator
 *----------------------------------------------------------------------------*/

static void
_syr_read_args(int   *arg_id,
               int    argc,
               char  *argv[],
               int   *argerr)
{
  cs_int_t ii, ii_save, arg_id_first;

  const char  *s = NULL;
  cs_bool_t is_end = CS_FALSE;

  /* Parameters with defaults */

  cs_bool_t invsel = CS_FALSE;
  cs_int_t  dim = 3;
  cs_int_t  axis_id = 2;
  cs_int_t  n_colors = 0;
  cs_int_t *colors = NULL;
  cs_int_t  n_groups = 0;
  char    **groups = NULL;
  cs_comm_type_t  comm_type = CS_COMM_TYPE_BINAIRE;
#if defined (_CS_HAVE_MPI)
  cs_int_t  syr_proc_rank = -1;
#endif

  const char missing_arg_fmt[]
    = N_("Erreur dans la spécification de la ligne de commande.\n\n"
         "L'option \"%s\" nécessite un argument au moins.");

  arg_id_first = *arg_id;

  /* Loop on options associated to a Syrthes coupling */

  for (ii = *arg_id; ii < argc && is_end == CS_FALSE; ii++) {

    s = argv[ii];

    if (strcmp(s, "-2d") == 0)
      dim = 2;
    else if (strcmp(s, "-X") == 0)
      axis_id = 0;
    else if (strcmp(s, "-Y") == 0)
      axis_id = 1;
    else if (strcmp(s, "-Z") == 0)
      axis_id = 2;
    else if (strcmp(s, "-invsel") == 0)
      invsel = CS_TRUE;
#if defined(_CS_HAVE_SOCKET)
    else if (strcmp(s, "-socket") == 0) {
      comm_type = CS_COMM_TYPE_SOCKET;
      cs_comm_init_socket();
    }
#endif
#if defined (_CS_HAVE_MPI)
    else if (strcmp(s, "-proc") == 0) {
      comm_type = CS_COMM_TYPE_MPI;
      if (ii < argc - 1 && strncmp(argv[ii + 1], "-", 1))
        syr_proc_rank = atoi(argv[++ii]);
    }
#endif
    else if (strcmp(s, "-couleur") == 0) {
      ii_save = ii;

      while (ii + 1 < argc && strncmp(argv[ii + 1], "-", 1)) {
        ii++;
        BFT_REALLOC(colors, n_colors + 1, cs_int_t);
        colors[n_colors] = atoi(argv[ii]);
        n_colors++;
      }

      /* Check that at least one color has been defined */
      if (ii_save == ii) {
        _arg_env_help(argv[0]);
        bft_error(__FILE__, __LINE__, 0, missing_arg_fmt, s);
      }
    }
    else if (strcmp(s, "-groupe") == 0) {

      ii_save = ii;

      while (ii + 1 < argc && strncmp(argv[ii + 1], "-", 1)) {
        ii++;
        BFT_REALLOC(groups, n_groups + 1, char*);
        BFT_MALLOC(groups[n_groups], strlen(argv[ii]) + 1, char);
        strcpy(groups[n_groups],argv[ii]);
        n_groups++;
      }

      /* Check that at least one group has been defined */
      if (ii_save == ii) {
        _arg_env_help(argv[0]);
        bft_error(__FILE__, __LINE__, 0, missing_arg_fmt, s);
      }
    }
    else
      is_end = CS_TRUE;

  } /* End of loop on options associated to a Syrthes coupling */

  if (is_end == CS_TRUE)
    *arg_id = ii - 2;
  else
    *arg_id = --ii;

  if (*arg_id <= arg_id_first)
    *argerr = 1;

  if (*argerr == 0)
    cs_syr_coupling_add(dim,
                        axis_id,
                        invsel,
                        n_colors,
                        colors,
                        n_groups,
                        groups,
#if defined (_CS_HAVE_MPI)
                        syr_proc_rank,
#endif
                        comm_type);

  /* Free temporary memory */

  BFT_FREE(colors);
  for (ii = 0; ii < n_groups; ii++)
    BFT_FREE(groups[ii]);
  BFT_FREE(groups);
}

/*============================================================================
 * Public function definitions for Fortran API
 *============================================================================*/

/*============================================================================
 * Public function definitions
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Print logfile header
 *
 * parameters:
 *   argc  --> number of command line arguments
 *   argv  --> array of command line arguments
 *----------------------------------------------------------------------------*/

void
cs_opts_logfile_head(int    argc,
                     char  *argv[])
{
  char str[81];
  int ii;
  char date_str[] = __DATE__;
  char time_str[] = __TIME__;
  const char mon_name[12][4]
    = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  struct tm time_cnv;

  /* Define MPI Information */

#if defined(MPI_VERSION) && defined(MPI_SUBVERSION)
#if defined(OPEN_MPI)
  const char mpi_lib[] = "Open MPI";
#elif defined(MPICH2)
  const char mpi_lib[] = "MPICH2";
#elif defined(LAM_MPI)
  const char mpi_lib[] = "LAM/MPI";
#elif defined(MPICH_NAME)
  const char mpi_lib[] = "MPICH";
#elif defined(HP_MPI)
  const char mpi_lib[] = "HP-MPI";
#elif defined(MPI_VERSION) && defined(MPI_SUBVERSION)
  const char *mpi_lib = NULL;
#endif
#endif /* defined(MPI_VERSION) && defined(MPI_SUBVERSION) */

  /* Determine compilation date */

  for (ii = 0; ii < 12; ii++) {
    if (strncmp(date_str, mon_name[ii], 3) == 0) {
      time_cnv.tm_mon = ii ;
      break;
    }
  }

  sscanf(date_str + 3, "%d", &(time_cnv.tm_mday)) ;
  sscanf(date_str + 6, "%d", &(time_cnv.tm_year)) ;

  time_cnv.tm_year -= 1900 ;

  sscanf(time_str    , "%d", &(time_cnv.tm_hour)) ;
  sscanf(time_str + 3, "%d", &(time_cnv.tm_min)) ;
  sscanf(time_str + 6, "%d", &(time_cnv.tm_sec)) ;

  time_cnv.tm_isdst = -1 ;

  /* Re-compute and internationalize build date */

  mktime(&time_cnv) ;
  strftime(str, 80, "%c", &time_cnv) ;

  /* Now print info */

  bft_printf(_("commande : \n"));

  for (ii = 0 ; ii < argc ; ii++)
    bft_printf(" %s", argv[ii]);

  bft_printf(_("\n"));
  bft_printf(_("\n************************************"
		   "***************************\n\n"));
  bft_printf(_("                                  (R)\n"
		   "                      Code_Saturne\n\n"
		   "                      Version 1.3.f\n\n"));

  bft_printf(_("\n  Copyright (C) 1998-2007 EDF S.A., France\n\n"));


  bft_printf(_("  build %s\n"), str);

#if defined(MPI_VERSION) && defined(MPI_SUBVERSION)
  if (mpi_lib != NULL)
    bft_printf(_("  MPI version %d.%d (%s)\n\n"),
               MPI_VERSION, MPI_SUBVERSION, mpi_lib);
  else
    bft_printf(_("  MPI version %d.%d\n\n"),
               MPI_VERSION, MPI_SUBVERSION);
#endif

  bft_printf(_("\n"));
  bft_printf(_("  The Code_Saturne CFD tool  is free software;\n"
		   "  you can redistribute it and/or modify it under the terms\n"
		   "  of the GNU General Public License as published by the\n"
		   "  Free Software Foundation; either version 2 of the License,\n"
		   "  or (at your option) any later version.\n\n"));

  bft_printf(_("  The Code_Saturne CFD tool is distributed in the hope that\n"
		   "  it will be useful, but WITHOUT ANY WARRANTY; without even\n"
		   "  the implied warranty of MERCHANTABILITY or FITNESS FOR A\n"
		   "  PARTICULAR PURPOSE.  See the GNU General Public License\n"
		   "  for more details.\n"));

  bft_printf(_("\n************************************"
		   "***************************\n\n"));
}

/*----------------------------------------------------------------------------
 * First analysis of the command line to determine if we require MPI
 *
 * parameters:
 *   argc  <-> number of command line arguments
 *   argv  <-> array of command line arguments
 *
 * returns:
 *   -1 if MPI is not needed, or rank in MPI_COMM_WORLD of the first
 *   process associated with this instance of Code_Saturne
 *----------------------------------------------------------------------------*/

int
cs_opts_mpi_rank(int    * argc,
                 char  **argv[])
{
  char    *s;
  int     arg_id, argerr;

  int  n_ranks = 1;
  int  root_rank = -1;
  int  syr_rank = -1;
  int  syr_rank_max = -1;

  cs_bool_t  use_mpi = CS_FALSE;

  arg_id = 0, argerr = 0;

#if defined(MPICH_NAME)

  /*
    Using standard MPICH1 1.2.x with the p4 (default) mechanism,
    the information required by MPI_Init() are transferred through
    the commande line, which is then modified by MPI_Init();
    in this case, only rank 0 knows the "user" command line arguments
    at program startup, the other processes obtaining them only upon
    calling  MPI_Init(). In this case, it is thus necessary to initialize
    MPI before parsing the the command line.
  */

  for (arg_id = 0 ; arg_id < *argc ; arg_id++) {

    if (   !strcmp((*argv)[arg_id], "-p4pg")         /* For process 0 */
        || !strcmp((*argv)[arg_id], "-p4rmrank")) {  /* For other processes */

      MPI_Init(argc, argv);
      break;
    }
  }

#endif

  /* Loop on command line arguments */

  arg_id = 0;

  while (++arg_id < *argc) {

    s = (*argv)[arg_id];

    /* Parallel run */

    if (strcmp(s, "-p") == 0 || strcmp(s, "--parallel") == 0) {
      cs_int_t n1 = 0, n2 = 0;
      cs_int_t tmperr = 0;
      n1 = (cs_int_t) _arg_to_int(++arg_id, *argc, *argv, &argerr);
      n_ranks = n1;
      if (argerr == 0)
        n2 = (cs_int_t) _arg_to_int(arg_id + 1, *argc, *argv, &tmperr);
      if (tmperr == 0) {
        arg_id++;
        if (n2 > 0) {
          root_rank = n1;
          n_ranks = n2;
        }
      }
      else
        n_ranks = n1;
      if (n_ranks > 1)
        use_mpi = CS_TRUE;
    }

    /* Coupling */

    else if (strcmp (s, "--coupl-cs") == 0) {
      cs_int_t n1 = 0;
      n1 = (cs_int_t) _arg_to_int(++arg_id, *argc, *argv, &argerr);
      if (argerr == 0)
        use_mpi = CS_TRUE;
    }

    /* Syrthes coupling */

    else if (strcmp(s, "-syrthes") == 0) {
      arg_id++;
#if defined(_CS_HAVE_MPI)
      syr_rank = _syr_mpi_rank(&arg_id,
                               *argc,
                               *argv);
#endif


      if (syr_rank > -1) {
        use_mpi = CS_TRUE;
        syr_rank_max = CS_MAX(syr_rank_max, syr_rank);
      }
    }

  } /* End of loop on command line arguments */

  /*
    Return -1 if MPI is not needed, or rank in MPI_COMM_WORLD of
    the first process associated with this instance of Code_Saturne
    if MPI is needed
  */

  if (use_mpi == CS_TRUE) {

    if (syr_rank_max > -1) {
      if (root_rank == -1)
        root_rank = syr_rank_max + 1;
    }
    if (root_rank == -1)
      root_rank = 0;

  }

  return root_rank;
}

/*----------------------------------------------------------------------------
 * Define options and call some associated initializations
 * based on command line arguments
 *
 * parameters:
 *   argc  --> number of command line arguments
 *   argv  --> array of command line arguments
 *   opts  <-- options structure
 *----------------------------------------------------------------------------*/

void
cs_opts_define(int         argc,
               char       *argv[],
               cs_opts_t  *opts)
{
  /* Local variables */

  char  *s;
  int    arg_id = 0, argerr = 0;

  /* Default initialization */

  opts->ifoenv = 1;
  opts->echo_comm = -1;
  opts->comm_type = CS_COMM_TYPE_BINAIRE_FORTRAN;

  opts->longia =  0;
  opts->longra =  0;

  opts->ilisr0 = 1;
  opts->ilisrp = 2;

  opts->iverif = -1;

  /* Parse command line arguments */

  while (++arg_id < argc) {

    s = argv[arg_id];

    if (strcmp(s, "-ifoenv") == 0)
      opts->ifoenv = (cs_int_t) _arg_to_int(++arg_id, argc, argv, &argerr);
    else if (strcmp(s, "-mc") == 0 || strcmp(s, "--mode-comm") == 0) {
      s = argv[++arg_id];
      if (strcmp (s, "txt") == 0)
        opts->comm_type = CS_COMM_TYPE_ASCII;
      else if (strcmp(s, "bin") == 0)
        opts->comm_type = CS_COMM_TYPE_BINAIRE_FORTRAN;
      else
        argerr = 1;
    }

    else if (strcmp(s, "-ec") == 0 || strcmp(s, "--echo-comm") == 0)
      opts->echo_comm = (cs_int_t) _arg_to_int(++arg_id, argc, argv, &argerr);

    else if (strcmp(s, "-longia") == 0)
      opts->longia = (cs_int_t) _arg_to_int(++arg_id, argc, argv, &argerr);
    else if (strcmp(s, "-longra") == 0)
      opts->longra = (cs_int_t) _arg_to_int(++arg_id, argc, argv, &argerr);

#if defined(_CS_HAVE_MPI)

    else if (strcmp(s, "-p") == 0 || strcmp(s, "--parallel") == 0) {
      cs_int_t n1 = 0, n2 = 0;
      cs_int_t tmperr = 0;
      n1 = (cs_int_t) _arg_to_int(++arg_id, argc, argv, &argerr);
      if (argerr == 0)
        n2 = (cs_int_t) _arg_to_int(arg_id + 1, argc, argv, &tmperr);
      if (tmperr == 0) {
        arg_id++;
      }
    }

    else if (strcmp(s, "--coupl-cs") == 0) {
      cs_int_t n1 = 0;
      n1 = (cs_int_t) _arg_to_int(++arg_id, argc, argv, &argerr);
      if (argerr == 0)
        cs_couplage_ajoute(n1);
    }

#endif /* defined(_CS_HAVE_MPI) */
    else if (strcmp(s, "-syrthes") == 0) {
      arg_id++;
      _syr_read_args(&arg_id, argc, argv, &argerr);
    }

    else if (strcmp(s, "-v") == 0 || strcmp(s, "--verif") == 0) {
      cs_int_t tmperr = 0;
      opts->iverif = (cs_int_t) _arg_to_int(arg_id + 1, argc, argv, &tmperr);
      if (tmperr == 0)
        arg_id++;
    }

    else if (strcmp(s, "--log") == 0) {
      cs_int_t n1 = 0;
      n1 = (cs_int_t) _arg_to_int(++arg_id, argc, argv, &argerr);
      if (n1 == 0)
        opts->ilisr0 = 0;
      else if (n1 == 1)
        opts->ilisr0 = 1;
      else
        argerr = 1;
    }

    else if (strcmp(s, "--logp") == 0) {
      cs_int_t n1 = 0;
      n1 = (cs_int_t) _arg_to_int(++arg_id, argc, argv, &argerr);
      if (n1 == -1)
        opts->ilisrp = 2;
      else if (n1 == 0)
        opts->ilisrp = 0;
      else if (n1 == 1)
        opts->ilisrp = 1;
      else
        argerr = 1;
    }

#if defined(_CS_HAVE_XML)
    else if (strcmp(s, "-param") == 0) {
      s = argv[++arg_id];
      argerr = cs_gui_file_loading(s);
    }
#endif

    else if (strcmp(s, "-h") == 0 || strcmp(s, "--help") == 0)
      argerr = 2;
    else
      argerr = 1;

  } /* End parsing command line */

  /* End initialization (sanity check) */
  if (opts->ifoenv <  0 || opts->ifoenv > 1) argerr = 1;
  if (opts->echo_comm < -1) argerr = 1;
  if (opts->longia <  0 || opts->longra < 0) argerr = 1;

  /* Print help and exit if required of in case of command line error */
  if (argerr != 0) {
    cs_opts_logfile_head(argc, argv);
    _arg_env_help(argv[0]) ;
    if (argerr == 2)
      cs_exit(EXIT_SUCCESS);
    else
      cs_exit(EXIT_FAILURE);
  }
}


syntax highlighted by Code2HTML, v. 0.9.1