/* Parse and display command line options.
   Copyright (C) 2000-2017 Free Software Foundation, Inc.
   Contributed by Andy Vaught

This file is part of GCC.

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

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "tree.h"
#include "gfortran.h"
#include "diagnostic.h"	/* For global_dc.  */
#include "opts.h"
#include "toplev.h"  /* For save_decoded_options.  */
#include "cpp.h"
#include "langhooks.h"

gfc_option_t gfc_option;


/* Set flags that control warnings and errors for different
   Fortran standards to their default values.  Keep in sync with
   libgfortran/runtime/compile_options.c (init_compile_options).  */

static void
set_default_std_flags (void)
{
  gfc_option.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_F2008_TS | GFC_STD_GNU | GFC_STD_LEGACY;
  gfc_option.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY;
}


/* Set all the DEC extension flags.  */

static void
set_dec_flags (int value)
{
  /* Allow legacy code without warnings.  */
  gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
    | GFC_STD_GNU | GFC_STD_LEGACY;
  gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);

  /* Set -fd-lines-as-comments by default.  */
  if (value && gfc_current_form != FORM_FREE && gfc_option.flag_d_lines == -1)
    gfc_option.flag_d_lines = 0;

  /* Set other DEC compatibility extensions.  */
  flag_dollar_ok |= value;
  flag_cray_pointer |= value;
  flag_dec_structure |= value;
  flag_dec_intrinsic_ints |= value;
  flag_dec_static |= value;
  flag_dec_math |= value;
}


/* Return language mask for Fortran options.  */

unsigned int
gfc_option_lang_mask (void)
{
  return CL_Fortran;
}

/* Initialize options structure OPTS.  */

void
gfc_init_options_struct (struct gcc_options *opts)
{
  opts->x_flag_errno_math = 0;
  opts->frontend_set_flag_errno_math = true;
  opts->x_flag_associative_math = -1;
  opts->frontend_set_flag_associative_math = true;
}

/* Get ready for options handling. Keep in sync with
   libgfortran/runtime/compile_options.c (init_compile_options).  */

void
gfc_init_options (unsigned int decoded_options_count,
		  struct cl_decoded_option *decoded_options)
{
  gfc_source_file = NULL;
  gfc_option.module_dir = NULL;
  gfc_option.source_form = FORM_UNKNOWN;
  gfc_option.max_continue_fixed = 255;
  gfc_option.max_continue_free = 255;
  gfc_option.max_identifier_length = GFC_MAX_SYMBOL_LEN;
  gfc_option.max_errors = 25;

  gfc_option.flag_preprocessed = 0;
  gfc_option.flag_d_lines = -1;
  gfc_option.flag_init_integer = GFC_INIT_INTEGER_OFF;
  gfc_option.flag_init_integer_value = 0;
  gfc_option.flag_init_logical = GFC_INIT_LOGICAL_OFF;
  gfc_option.flag_init_character = GFC_INIT_CHARACTER_OFF;
  gfc_option.flag_init_character_value = (char)0;
  
  gfc_option.fpe = 0;
  /* All except GFC_FPE_INEXACT.  */
  gfc_option.fpe_summary = GFC_FPE_INVALID | GFC_FPE_DENORMAL
			   | GFC_FPE_ZERO | GFC_FPE_OVERFLOW
			   | GFC_FPE_UNDERFLOW;
  gfc_option.rtcheck = 0;

  /* ??? Wmissing-include-dirs is disabled by default in C/C++ but
     enabled by default in Fortran.  Ideally, we should express this
     in .opt, but that is not supported yet.  */
  if (!global_options_set.x_cpp_warn_missing_include_dirs)
    global_options.x_cpp_warn_missing_include_dirs = 1;

  set_dec_flags (0);

  set_default_std_flags ();

  /* Initialize cpp-related options.  */
  gfc_cpp_init_options (decoded_options_count, decoded_options);
  gfc_diagnostics_init ();
}


/* Determine the source form from the filename extension.  We assume
   case insensitivity.  */

static gfc_source_form
form_from_filename (const char *filename)
{
  static const struct
  {
    const char *extension;
    gfc_source_form form;
  }
  exttype[] =
  {
    {
    ".f90", FORM_FREE}
    ,
    {
    ".f95", FORM_FREE}
    ,
    {
    ".f03", FORM_FREE}
    ,
    {
    ".f08", FORM_FREE}
    ,
    {
    ".f", FORM_FIXED}
    ,
    {
    ".for", FORM_FIXED}
    ,
    {
    ".ftn", FORM_FIXED}
    ,
    {
    "", FORM_UNKNOWN}
  };		/* sentinel value */

  gfc_source_form f_form;
  const char *fileext;
  int i;

  /* Find end of file name.  Note, filename is either a NULL pointer or
     a NUL terminated string.  */
  i = 0;
  while (filename[i] != '\0')
    i++;

  /* Find last period.  */
  while (i >= 0 && (filename[i] != '.'))
    i--;

  /* Did we see a file extension?  */
  if (i < 0)
    return FORM_UNKNOWN; /* Nope  */

  /* Get file extension and compare it to others.  */
  fileext = &(filename[i]);

  i = -1;
  f_form = FORM_UNKNOWN;
  do
    {
      i++;
      if (strcasecmp (fileext, exttype[i].extension) == 0)
	{
	  f_form = exttype[i].form;
	  break;
	}
    }
  while (exttype[i].form != FORM_UNKNOWN);

  return f_form;
}


/* Finalize commandline options.  */

bool
gfc_post_options (const char **pfilename)
{
  const char *filename = *pfilename, *canon_source_file = NULL;
  char *source_path;
  int i;

  /* Excess precision other than "fast" requires front-end
     support.  */
  if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD)
    sorry ("-fexcess-precision=standard for Fortran");
  flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;

  /* Fortran allows associative math - but we cannot reassociate if
     we want traps or signed zeros. Cf. also flag_protect_parens.  */
  if (flag_associative_math == -1)
    flag_associative_math = (!flag_trapping_math && !flag_signed_zeros);

  if (flag_protect_parens == -1)
    flag_protect_parens = !optimize_fast;

  if (flag_stack_arrays == -1)
    flag_stack_arrays = optimize_fast;

  /* By default, disable (re)allocation during assignment for -std=f95,
     and enable it for F2003/F2008/GNU/Legacy.  */
  if (flag_realloc_lhs == -1)
    {
      if (gfc_option.allow_std & GFC_STD_F2003)
	flag_realloc_lhs = 1;
      else
	flag_realloc_lhs = 0;
    }

  /* -fbounds-check is equivalent to -fcheck=bounds */
  if (flag_bounds_check)
    gfc_option.rtcheck |= GFC_RTCHECK_BOUNDS;

  if (flag_compare_debug)
    flag_dump_fortran_original = 0;

  /* Make -fmax-errors visible to gfortran's diagnostic machinery.  */
  if (global_options_set.x_flag_max_errors)
    gfc_option.max_errors = flag_max_errors;

  /* Verify the input file name.  */
  if (!filename || strcmp (filename, "-") == 0)
    {
      filename = "";
    }

  if (gfc_option.flag_preprocessed)
    {
      /* For preprocessed files, if the first tokens are of the form # NUM.
	 handle the directives so we know the original file name.  */
      gfc_source_file = gfc_read_orig_filename (filename, &canon_source_file);
      if (gfc_source_file == NULL)
	gfc_source_file = filename;
      else
	*pfilename = gfc_source_file;
    }
  else
    gfc_source_file = filename;

  if (canon_source_file == NULL)
    canon_source_file = gfc_source_file;

  /* Adds the path where the source file is to the list of include files.  */

  i = strlen (canon_source_file);
  while (i > 0 && !IS_DIR_SEPARATOR (canon_source_file[i]))
    i--;

  if (i != 0)
    {
      source_path = (char *) alloca (i + 1);
      memcpy (source_path, canon_source_file, i);
      source_path[i] = 0;
      gfc_add_include_path (source_path, true, true, true);
    }
  else
    gfc_add_include_path (".", true, true, true);

  if (canon_source_file != gfc_source_file)
    free (CONST_CAST (char *, canon_source_file));

  /* Decide which form the file will be read in as.  */

  if (gfc_option.source_form != FORM_UNKNOWN)
    gfc_current_form = gfc_option.source_form;
  else
    {
      gfc_current_form = form_from_filename (filename);

      if (gfc_current_form == FORM_UNKNOWN)
	{
	  gfc_current_form = FORM_FREE;
	  gfc_warning_now (0, "Reading file %qs as free form", 
			   (filename[0] == '\0') ? "<stdin>" : filename);
	}
    }

  /* If the user specified -fd-lines-as-{code|comments} verify that we're
     in fixed form.  */
  if (gfc_current_form == FORM_FREE)
    {
      if (gfc_option.flag_d_lines == 0)
	gfc_warning_now (0, "%<-fd-lines-as-comments%> has no effect "
			   "in free form");
      else if (gfc_option.flag_d_lines == 1)
	gfc_warning_now (0, "%<-fd-lines-as-code%> has no effect in free form");

      if (warn_line_truncation == -1)
	  warn_line_truncation = 1;

      /* Enable -Werror=line-truncation when -Werror and -Wno-error have
	 not been set.  */
      if (warn_line_truncation && !global_options_set.x_warnings_are_errors
	  && (global_dc->classify_diagnostic[OPT_Wline_truncation] ==
	      DK_UNSPECIFIED))
	diagnostic_classify_diagnostic (global_dc, OPT_Wline_truncation,
					DK_ERROR, UNKNOWN_LOCATION);
    }
  else if (warn_line_truncation == -1)
    warn_line_truncation = 0;

  /* If -pedantic, warn about the use of GNU extensions.  */
  if (pedantic && (gfc_option.allow_std & GFC_STD_GNU) != 0)
    gfc_option.warn_std |= GFC_STD_GNU;
  /* -std=legacy -pedantic is effectively -std=gnu.  */
  if (pedantic && (gfc_option.allow_std & GFC_STD_LEGACY) != 0)
    gfc_option.warn_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_LEGACY;

  /* If the user didn't explicitly specify -f(no)-second-underscore we
     use it if we're trying to be compatible with f2c, and not
     otherwise.  */
  if (flag_second_underscore == -1)
    flag_second_underscore = flag_f2c;

  if (!flag_automatic && flag_max_stack_var_size != -2
      && flag_max_stack_var_size != 0)
    gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-fmax-stack-var-size=%d%>",
		     flag_max_stack_var_size);
  else if (!flag_automatic && flag_recursive)
    gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-frecursive%>");
  else if (!flag_automatic && flag_openmp)
    gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-frecursive%> implied by "
		     "%<-fopenmp%>");
  else if (flag_max_stack_var_size != -2 && flag_recursive)
    gfc_warning_now (0, "Flag %<-frecursive%> overwrites %<-fmax-stack-var-size=%d%>",
		     flag_max_stack_var_size);
  else if (flag_max_stack_var_size != -2 && flag_openmp)
    gfc_warning_now (0, "Flag %<-fmax-stack-var-size=%d%> overwrites %<-frecursive%> "
		     "implied by %<-fopenmp%>", flag_max_stack_var_size);

  /* Implement -frecursive as -fmax-stack-var-size=-1.  */
  if (flag_recursive)
    flag_max_stack_var_size = -1;

  /* Implied -frecursive; implemented as -fmax-stack-var-size=-1.  */
  if (flag_max_stack_var_size == -2 && flag_openmp && flag_automatic)
    {
      flag_recursive = 1;
      flag_max_stack_var_size = -1;
    }

  /* Set default.  */
  if (flag_max_stack_var_size == -2)
    flag_max_stack_var_size = 32768;

  /* Implement -fno-automatic as -fmax-stack-var-size=0.  */
  if (!flag_automatic)
    flag_max_stack_var_size = 0;
  
  /* If the user did not specify an inline matmul limit, inline up to the BLAS
     limit or up to 30 if no external BLAS is specified.  */

  if (flag_inline_matmul_limit < 0)
    {
      if (flag_external_blas)
	flag_inline_matmul_limit = flag_blas_matmul_limit;
      else
	flag_inline_matmul_limit = 30;
    }

  /* Optimization implies front end optimization, unless the user
     specified it directly.  */

  if (flag_frontend_optimize == -1)
    flag_frontend_optimize = optimize;

  if (flag_max_array_constructor < 65535)
    flag_max_array_constructor = 65535;

  if (flag_fixed_line_length != 0 && flag_fixed_line_length < 7)
    gfc_fatal_error ("Fixed line length must be at least seven");

  if (flag_free_line_length != 0 && flag_free_line_length < 4)
    gfc_fatal_error ("Free line length must be at least three");

  if (flag_max_subrecord_length > MAX_SUBRECORD_LENGTH)
    gfc_fatal_error ("Maximum subrecord length cannot exceed %d",
		     MAX_SUBRECORD_LENGTH);

  gfc_cpp_post_options ();

  if (gfc_option.allow_std & GFC_STD_F2008)
    lang_hooks.name = "GNU Fortran2008";
  else if (gfc_option.allow_std & GFC_STD_F2003)
    lang_hooks.name = "GNU Fortran2003";

  return gfc_cpp_preprocess_only ();
}


static void
gfc_handle_module_path_options (const char *arg)
{

  if (gfc_option.module_dir != NULL)
    gfc_fatal_error ("gfortran: Only one %<-J%> option allowed");

  gfc_option.module_dir = XCNEWVEC (char, strlen (arg) + 2);
  strcpy (gfc_option.module_dir, arg);

  gfc_add_include_path (gfc_option.module_dir, true, false, true);

  strcat (gfc_option.module_dir, "/");
}


/* Handle options -ffpe-trap= and -ffpe-summary=.  */

static void
gfc_handle_fpe_option (const char *arg, bool trap)
{
  int result, pos = 0, n;
  /* precision is a backwards compatibility alias for inexact.  */
  static const char * const exception[] = { "invalid", "denormal", "zero",
					    "overflow", "underflow",
					    "inexact", "precision", NULL };
  static const int opt_exception[] = { GFC_FPE_INVALID, GFC_FPE_DENORMAL,
				       GFC_FPE_ZERO, GFC_FPE_OVERFLOW,
				       GFC_FPE_UNDERFLOW, GFC_FPE_INEXACT,
				       GFC_FPE_INEXACT,
				       0 };

  /* As the default for -ffpe-summary= is nonzero, set it to 0.  */
  if (!trap)
    gfc_option.fpe_summary = 0;

  while (*arg)
    {
      while (*arg == ',')
	arg++;

      while (arg[pos] && arg[pos] != ',')
	pos++;

      result = 0;
      if (!trap && strncmp ("none", arg, pos) == 0)
	{
	  gfc_option.fpe_summary = 0;
	  arg += pos;
	  pos = 0;
	  continue;
	}
      else if (!trap && strncmp ("all", arg, pos) == 0)
	{
	  gfc_option.fpe_summary = GFC_FPE_INVALID | GFC_FPE_DENORMAL
				   | GFC_FPE_ZERO | GFC_FPE_OVERFLOW
				   | GFC_FPE_UNDERFLOW | GFC_FPE_INEXACT;
	  arg += pos;
	  pos = 0;
	  continue;
	}
      else
	for (n = 0; exception[n] != NULL; n++)
	  {
	  if (exception[n] && strncmp (exception[n], arg, pos) == 0)
	    {
	      if (trap)
		gfc_option.fpe |= opt_exception[n];
	      else
		gfc_option.fpe_summary |= opt_exception[n];
	      arg += pos;
	      pos = 0;
	      result = 1;
	      break;
	    }
	  }
      if (!result && !trap)
	gfc_fatal_error ("Argument to %<-ffpe-trap%> is not valid: %s", arg);
      else if (!result)
	gfc_fatal_error ("Argument to %<-ffpe-summary%> is not valid: %s", arg);

    }
}


static void
gfc_handle_runtime_check_option (const char *arg)
{
  int result, pos = 0, n;
  static const char * const optname[] = { "all", "bounds", "array-temps",
					  "recursion", "do", "pointer",
					  "mem", NULL };
  static const int optmask[] = { GFC_RTCHECK_ALL, GFC_RTCHECK_BOUNDS,
				 GFC_RTCHECK_ARRAY_TEMPS,
				 GFC_RTCHECK_RECURSION, GFC_RTCHECK_DO,
				 GFC_RTCHECK_POINTER, GFC_RTCHECK_MEM,
				 0 };
 
  while (*arg)
    {
      while (*arg == ',')
	arg++;

      while (arg[pos] && arg[pos] != ',')
	pos++;

      result = 0;
      for (n = 0; optname[n] != NULL; n++)
	{
	  if (optname[n] && strncmp (optname[n], arg, pos) == 0)
	    {
	      gfc_option.rtcheck |= optmask[n];
	      arg += pos;
	      pos = 0;
	      result = 1;
	      break;
	    }
	  else if (optname[n] && pos > 3 && strncmp ("no-", arg, 3) == 0
		   && strncmp (optname[n], arg+3, pos-3) == 0)
	    {
	      gfc_option.rtcheck &= ~optmask[n];
	      arg += pos;
	      pos = 0;
	      result = 1;
	      break;
	    }
	}
      if (!result)
	gfc_fatal_error ("Argument to %<-fcheck%> is not valid: %s", arg);
    }
}


/* Handle command-line options.  Returns 0 if unrecognized, 1 if
   recognized and handled.  */

bool
gfc_handle_option (size_t scode, const char *arg, int value,
		   int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
		   const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
{
  bool result = true;
  enum opt_code code = (enum opt_code) scode;

  if (gfc_cpp_handle_option (scode, arg, value) == 1)
    return true;

  switch (code)
    {
    default:
      if (cl_options[code].flags & gfc_option_lang_mask ())
	break;
      result = false;
      break;

    case OPT_fcheck_array_temporaries:
      gfc_option.rtcheck |= GFC_RTCHECK_ARRAY_TEMPS;
      break;
      
    case OPT_fd_lines_as_code:
      gfc_option.flag_d_lines = 1;
      break;

    case OPT_fd_lines_as_comments:
      gfc_option.flag_d_lines = 0;
      break;

    case OPT_ffixed_form:
      gfc_option.source_form = FORM_FIXED;
      break;

    case OPT_ffree_form:
      gfc_option.source_form = FORM_FREE;
      break;

    case OPT_static_libgfortran:
#ifndef HAVE_LD_STATIC_DYNAMIC
      gfc_fatal_error ("%<-static-libgfortran%> is not supported in this "
		       "configuration");
#endif
      break;

    case OPT_fintrinsic_modules_path:
    case OPT_fintrinsic_modules_path_:

      /* This is needed because omp_lib.h is in a directory together
	 with intrinsic modules.  Do no warn because during testing
	 without an installed compiler, we would get lots of bogus
	 warnings for a missing include directory.  */
      gfc_add_include_path (arg, false, false, false);

      gfc_add_intrinsic_modules_path (arg);
      break;

    case OPT_fpreprocessed:
      gfc_option.flag_preprocessed = value;
      break;

    case OPT_fmax_identifier_length_:
      if (value > GFC_MAX_SYMBOL_LEN)
	gfc_fatal_error ("Maximum supported identifier length is %d",
			 GFC_MAX_SYMBOL_LEN);
      gfc_option.max_identifier_length = value;
      break;

    case OPT_finit_local_zero:
      gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON;
      gfc_option.flag_init_integer_value = 0;
      flag_init_real = GFC_INIT_REAL_ZERO;
      gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE;
      gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON;
      gfc_option.flag_init_character_value = (char)0;
      break;

    case OPT_finit_logical_:
      if (!strcasecmp (arg, "false"))
	gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE;
      else if (!strcasecmp (arg, "true"))
	gfc_option.flag_init_logical = GFC_INIT_LOGICAL_TRUE;
      else
	gfc_fatal_error ("Unrecognized option to %<-finit-logical%>: %s",
			 arg);
      break;

    case OPT_finit_integer_:
      gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON;
      gfc_option.flag_init_integer_value = atoi (arg);
      break;

    case OPT_finit_character_:
      if (value >= 0 && value <= 127)
	{
	  gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON;
	  gfc_option.flag_init_character_value = (char)value;
	}
      else
	gfc_fatal_error ("The value of n in %<-finit-character=n%> must be "
			 "between 0 and 127");
      break;

    case OPT_I:
      gfc_add_include_path (arg, true, false, true);
      break;

    case OPT_J:
      gfc_handle_module_path_options (arg);
      break;

    case OPT_ffpe_trap_:
      gfc_handle_fpe_option (arg, true);
      break;

    case OPT_ffpe_summary_:
      gfc_handle_fpe_option (arg, false);
      break;

    case OPT_std_f95:
      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95 | GFC_STD_F77
			     | GFC_STD_F2008_OBS;
      gfc_option.warn_std = GFC_STD_F95_OBS;
      gfc_option.max_continue_fixed = 19;
      gfc_option.max_continue_free = 39;
      gfc_option.max_identifier_length = 31;
      warn_ampersand = 1;
      warn_tabs = 1;
      break;

    case OPT_std_f2003:
      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 
	| GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008_OBS;
      gfc_option.warn_std = GFC_STD_F95_OBS;
      gfc_option.max_identifier_length = 63;
      warn_ampersand = 1;
      warn_tabs = 1;
      break;

    case OPT_std_f2008:
      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 
	| GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008 | GFC_STD_F2008_OBS;
      gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS;
      gfc_option.max_identifier_length = 63;
      warn_ampersand = 1;
      warn_tabs = 1;
      break;

    case OPT_std_f2008ts:
      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 
	| GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008 | GFC_STD_F2008_OBS
	| GFC_STD_F2008_TS;
      gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS;
      gfc_option.max_identifier_length = 63;
      warn_ampersand = 1;
      warn_tabs = 1;
      break;

    case OPT_std_gnu:
      set_default_std_flags ();
      break;

    case OPT_std_legacy:
      set_default_std_flags ();
      gfc_option.warn_std = 0;
      break;

    case OPT_fshort_enums:
      /* Handled in language-independent code.  */
      break;

    case OPT_fcheck_:
      gfc_handle_runtime_check_option (arg);
      break;

    case OPT_fdec:
      /* Enable all DEC extensions.  */
      set_dec_flags (1);
      break;

    case OPT_fdec_structure:
      flag_dec_structure = 1;
      break;
    }

  Fortran_handle_option_auto (&global_options, &global_options_set, 
                              scode, arg, value, 
                              gfc_option_lang_mask (), kind,
                              loc, handlers, global_dc);
  return result;
}


/* Return a string with the options passed to the compiler; used for
   Fortran's compiler_options() intrinsic.  */

char *
gfc_get_option_string (void)
{
  unsigned j;
  size_t len, pos;
  char *result;

  /* Allocate and return a one-character string with '\0'.  */
  if (!save_decoded_options_count)
    return XCNEWVEC (char, 1);

  /* Determine required string length.  */

  len = 0;
  for (j = 1; j < save_decoded_options_count; j++)
    {
      switch (save_decoded_options[j].opt_index)
        {
        case OPT_o:
        case OPT_d:
        case OPT_dumpbase:
        case OPT_dumpdir:
        case OPT_auxbase:
        case OPT_quiet:
        case OPT_version:
        case OPT_fintrinsic_modules_path:
        case OPT_fintrinsic_modules_path_:
          /* Ignore these.  */
          break;
	default:
	  /* Ignore file names.  */
	  if (save_decoded_options[j].orig_option_with_args_text[0] == '-')
	    len += 1
		 + strlen (save_decoded_options[j].orig_option_with_args_text);
        }
    }

  result = XCNEWVEC (char, len);

  pos = 0; 
  for (j = 1; j < save_decoded_options_count; j++)
    {
      switch (save_decoded_options[j].opt_index)
        {
        case OPT_o:
        case OPT_d:
        case OPT_dumpbase:
        case OPT_dumpdir:
        case OPT_auxbase:
        case OPT_quiet:
        case OPT_version:
        case OPT_fintrinsic_modules_path:
        case OPT_fintrinsic_modules_path_:
          /* Ignore these.  */
	  continue;

        case OPT_cpp_:
	  /* Use "-cpp" rather than "-cpp=<temporary file>".  */
	  len = 4;
	  break;

        default:
	  /* Ignore file names.  */
	  if (save_decoded_options[j].orig_option_with_args_text[0] != '-')
	    continue;

	  len = strlen (save_decoded_options[j].orig_option_with_args_text);
        }

      memcpy (&result[pos], save_decoded_options[j].orig_option_with_args_text, len);
      pos += len;
      result[pos++] = ' ';
    }

  result[--pos] = '\0';
  return result;
}
