/* Handling of compile-time options that influence the library.
   Copyright (C) 2005-2014 Free Software Foundation, Inc.

This file is part of the GNU Fortran runtime library (libgfortran).

Libgfortran 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 3, or (at your option)
any later version.

Libgfortran 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.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "libgfortran.h"
#include <signal.h>


/* Useful compile-time options will be stored in here.  */
compile_options_t compile_options;


volatile sig_atomic_t fatal_error_in_progress = 0;


/* Helper function for backtrace_handler to write information about the
   received signal to stderr before actually giving the backtrace.  */
static void
show_signal (int signum)
{
  const char * name = NULL, * desc = NULL;

  switch (signum)
    {
#if defined(SIGQUIT)
      case SIGQUIT:
	name = "SIGQUIT";
	desc = "Terminal quit signal";
	break;
#endif

      /* The following 4 signals are defined by C89.  */
      case SIGILL:
	name = "SIGILL";
	desc = "Illegal instruction";
	break;

      case SIGABRT:
	name = "SIGABRT";
	desc = "Process abort signal";
	break;

      case SIGFPE:
	name = "SIGFPE";
	desc = "Floating-point exception - erroneous arithmetic operation";
	break;

      case SIGSEGV:
	name = "SIGSEGV";
	desc = "Segmentation fault - invalid memory reference";
	break;

#if defined(SIGBUS)
      case SIGBUS:
	name = "SIGBUS";
	desc = "Access to an undefined portion of a memory object";
	break;
#endif

#if defined(SIGSYS)
      case SIGSYS:
	name = "SIGSYS";
	desc = "Bad system call";
	break;
#endif

#if defined(SIGTRAP)
      case SIGTRAP:
	name = "SIGTRAP";
	desc = "Trace/breakpoint trap";
	break;
#endif

#if defined(SIGXCPU)
      case SIGXCPU:
	name = "SIGXCPU";
	desc = "CPU time limit exceeded";
	break;
#endif

#if defined(SIGXFSZ)
      case SIGXFSZ:
	name = "SIGXFSZ";
	desc = "File size limit exceeded";
	break;
#endif
    }

  if (name)
    st_printf ("\nProgram received signal %s: %s.\n", name, desc);
  else
    st_printf ("\nProgram received signal %d.\n", signum);
}


/* A signal handler to allow us to output a backtrace.  */
void
backtrace_handler (int signum)
{
  /* Since this handler is established for more than one kind of signal, 
     it might still get invoked recursively by delivery of some other kind
     of signal.  Use a static variable to keep track of that. */
  if (fatal_error_in_progress)
    raise (signum);
  fatal_error_in_progress = 1;

  show_signal (signum);
  estr_write ("\nBacktrace for this error:\n");
  backtrace ();

  /* Now reraise the signal.  We reactivate the signal's
     default handling, which is to terminate the process.
     We could just call exit or abort,
     but reraising the signal sets the return status
     from the process correctly. */
  signal (signum, SIG_DFL);
  raise (signum);
}


/* Helper function for set_options because we need to access the
   global variable options which is not seen in set_options.  */
static void
maybe_find_addr2line (void)
{
  if (options.backtrace == -1)
    find_addr2line ();
}

/* Set the usual compile-time options.  */
extern void set_options (int , int []);
export_proto(set_options);

void
set_options (int num, int options[])
{
  if (num >= 1)
    compile_options.warn_std = options[0];
  if (num >= 2)
    compile_options.allow_std = options[1];
  if (num >= 3)
    compile_options.pedantic = options[2];
  /* options[3] is the removed -fdump-core option. It's place in the
     options array is retained due to ABI compatibility. Remove when
     bumping the library ABI.  */
  if (num >= 5)
    compile_options.backtrace = options[4];
  if (num >= 6)
    compile_options.sign_zero = options[5];
  if (num >= 7)
    compile_options.bounds_check = options[6];
  /* options[7] is the -frange-check option, which no longer affects
     the library behavior; range checking is now always done when
     parsing integers. It's place in the options array is retained due
     to ABI compatibility. Remove when bumping the library ABI.  */
  if (num >= 9)
    compile_options.fpe_summary = options[8];

  /* If backtrace is required, we set signal handlers on the POSIX
     2001 signals with core action.  */
  if (compile_options.backtrace)
    {
#if defined(SIGQUIT)
      signal (SIGQUIT, backtrace_handler);
#endif

      /* The following 4 signals are defined by C89.  */
      signal (SIGILL, backtrace_handler);
      signal (SIGABRT, backtrace_handler);
      signal (SIGFPE, backtrace_handler);
      signal (SIGSEGV, backtrace_handler);

#if defined(SIGBUS)
      signal (SIGBUS, backtrace_handler);
#endif

#if defined(SIGSYS)
      signal (SIGSYS, backtrace_handler);
#endif

#if defined(SIGTRAP)
      signal (SIGTRAP, backtrace_handler);
#endif

#if defined(SIGXCPU)
      signal (SIGXCPU, backtrace_handler);
#endif

#if defined(SIGXFSZ)
      signal (SIGXFSZ, backtrace_handler);
#endif

      maybe_find_addr2line ();
    }
}


/* Default values for the compile-time options.  Keep in sync with
   gcc/fortran/options.c (gfc_init_options).  */
void
init_compile_options (void)
{
  compile_options.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY;
  compile_options.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
    | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77
    | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY;
  compile_options.pedantic = 0;
  compile_options.backtrace = 0;
  compile_options.sign_zero = 1;
  compile_options.fpe_summary = 0;
}

/* Function called by the front-end to tell us the
   default for unformatted data conversion.  */

extern void set_convert (int);
export_proto (set_convert);

void
set_convert (int conv)
{
  compile_options.convert = conv;
}

extern void set_record_marker (int);
export_proto (set_record_marker);


void
set_record_marker (int val)
{

  switch(val)
    {
    case 4:
      compile_options.record_marker = sizeof (GFC_INTEGER_4);
      break;

    case 8:
      compile_options.record_marker = sizeof (GFC_INTEGER_8);
      break;

    default:
      runtime_error ("Invalid value for record marker");
      break;
    }
}

extern void set_max_subrecord_length (int);
export_proto (set_max_subrecord_length);

void set_max_subrecord_length(int val)
{
  if (val > GFC_MAX_SUBRECORD_LENGTH || val < 1)
    {
      runtime_error ("Invalid value for maximum subrecord length");
      return;
    }

  compile_options.max_subrecord_length = val;
}
