/* Handling of compile-time options that influence the library.
   Copyright (C) 2005-2015 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;

#ifndef LIBGFOR_MINIMAL
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 ();
}
#endif

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

#ifndef LIBGFOR_MINIMAL
  /* 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 ();
    }
#endif
}


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