/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
   Contributed by Andy Vaught

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 <string.h>
#include <strings.h>
#include <ctype.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

int caf_num_images = -1;

/* Implementation of secure_getenv() for targets where it is not
   provided. */

#ifdef FALLBACK_SECURE_GETENV

#if SUPPORTS_WEAKREF && defined(HAVE___SECURE_GETENV)
static char* weak_secure_getenv (const char*)
  __attribute__((__weakref__("__secure_getenv")));
#endif

char *
secure_getenv (const char *name)
{
#if SUPPORTS_WEAKREF && defined(HAVE___SECURE_GETENV)
  if (weak_secure_getenv)
    return weak_secure_getenv (name);
#endif

  if ((getuid () == geteuid ()) && (getgid () == getegid ()))
    return getenv (name);
  else
    return NULL;
}
#endif



/* Examine the environment for controlling aspects of the program's
   execution.  Our philosophy here that the environment should not prevent
   the program from running, so any invalid value will be ignored.  */


options_t options;

typedef struct variable
{
  const char *name;
  int default_value;
  int *var;           
  void (*init) (struct variable *);
}
variable;

static void init_unformatted (variable *);


/* Initialize an integer environment variable.  */

static void
init_integer (variable * v)
{
  char *p, *q;

  p = getenv (v->name);
  if (p == NULL)
    return;

  for (q = p; *q; q++)
    if (!isdigit (*q) && (p != q || *q != '-'))
      return;

  *v->var = atoi (p);
}


/* Initialize an integer environment variable which has to be positive.  */

static void
init_unsigned_integer (variable * v)
{
  char *p, *q;

  p = getenv (v->name);
  if (p == NULL)
    return;

  for (q = p; *q; q++)
    if (!isdigit (*q))
      return;

  *v->var = atoi (p);
}


/* Initialize a boolean environment variable. We only look at the first
   letter of the value. */

static void
init_boolean (variable * v)
{
  char *p;

  p = getenv (v->name);
  if (p == NULL)
    return;

  if (*p == '1' || *p == 'Y' || *p == 'y')
    *v->var = 1;
  else if (*p == '0' || *p == 'N' || *p == 'n')
    *v->var = 0;
}


/* Initialize a list output separator.  It may contain any number of spaces
   and at most one comma.  */

static void
init_sep (variable * v)
{
  int seen_comma;
  char *p;

  p = getenv (v->name);
  if (p == NULL)
    goto set_default;

  options.separator = p;
  options.separator_len = strlen (p);

  /* Make sure the separator is valid */

  if (options.separator_len == 0)
    goto set_default;
  seen_comma = 0;

  while (*p)
    {
      if (*p == ',')
	{
	  if (seen_comma)
	    goto set_default;
	  seen_comma = 1;
	  p++;
	  continue;
	}

      if (*p++ != ' ')
	goto set_default;
    }

  return;

set_default:
  options.separator = " ";
  options.separator_len = 1;
}


static variable variable_table[] = {

  /* Unit number that will be preconnected to standard input */
  { "GFORTRAN_STDIN_UNIT", GFC_STDIN_UNIT_NUMBER, &options.stdin_unit,
    init_integer },

  /* Unit number that will be preconnected to standard output */
  { "GFORTRAN_STDOUT_UNIT", GFC_STDOUT_UNIT_NUMBER, &options.stdout_unit,
    init_integer },

  /* Unit number that will be preconnected to standard error */
  { "GFORTRAN_STDERR_UNIT", GFC_STDERR_UNIT_NUMBER, &options.stderr_unit,
    init_integer },

  /* If TRUE, all output will be unbuffered */
  { "GFORTRAN_UNBUFFERED_ALL", 0, &options.all_unbuffered, init_boolean },

  /* If TRUE, output to preconnected units will be unbuffered */
  { "GFORTRAN_UNBUFFERED_PRECONNECTED", 0, &options.unbuffered_preconnected,
    init_boolean },

  /* Whether to print filename and line number on runtime error */
  { "GFORTRAN_SHOW_LOCUS", 1, &options.locus, init_boolean },

  /* Print optional plus signs in numbers where permitted */
  { "GFORTRAN_OPTIONAL_PLUS", 0, &options.optional_plus, init_boolean },

  /* Separator to use when writing list output */
  { "GFORTRAN_LIST_SEPARATOR", 0, NULL, init_sep },

  /* Set the default data conversion for unformatted I/O */
  { "GFORTRAN_CONVERT_UNIT", 0, 0, init_unformatted },

  /* Print out a backtrace if possible on runtime error */
  { "GFORTRAN_ERROR_BACKTRACE", -1, &options.backtrace, init_boolean },

  /* Number of images to start with -fcoarray=pthread.  */
  { "GFORTRAN_CAF_IMAGES", 4, &caf_num_images, init_integer },

  { NULL, 0, NULL, NULL }
};


/* Initialize most runtime variables from
 * environment variables. */

void
init_variables (void)
{
  variable *v;

  for (v = variable_table; v->name; v++)
    {
      if (v->var)
	*v->var = v->default_value;
      v->init (v);
    }
}


/* This is the handling of the GFORTRAN_CONVERT_UNITS environment variable.
   It is called from environ.c to parse this variable, and from
   open.c to determine if the user specified a default for an
   unformatted file.
   The syntax of the environment variable is, in bison grammar:

   GFORTRAN_CONVERT_UNITS: mode | mode ';' exception ;
   mode: 'native' | 'swap' | 'big_endian' | 'little_endian' ;
   exception: mode ':' unit_list | unit_list ;
   unit_list: unit_spec | unit_list unit_spec ;
   unit_spec: INTEGER | INTEGER '-' INTEGER ;
*/

/* Defines for the tokens.  Other valid tokens are ',', ':', '-'.  */


#define NATIVE   257
#define SWAP     258
#define BIG      259
#define LITTLE   260
/* Some space for additional tokens later.  */
#define INTEGER  273
#define END      (-1)
#define ILLEGAL  (-2)

typedef struct
{
  int unit;
  unit_convert conv;
} exception_t;


static char *p;            /* Main character pointer for parsing.  */
static char *lastpos;      /* Auxiliary pointer, for backing up.  */
static int unit_num;       /* The last unit number read.  */
static int unit_count;     /* The number of units found. */
static int do_count;       /* Parsing is done twice - first to count the number
			      of units, then to fill in the table.  This
			      variable controls what to do.  */
static exception_t *elist; /* The list of exceptions to the default. This is
			      sorted according to unit number.  */
static int n_elist;        /* Number of exceptions to the default.  */

static unit_convert endian; /* Current endianness.  */

static unit_convert def; /* Default as specified (if any).  */

/* Search for a unit number, using a binary search.  The
   first argument is the unit number to search for.  The second argument
   is a pointer to an index.
   If the unit number is found, the function returns 1, and the index
   is that of the element.
   If the unit number is not found, the function returns 0, and the
   index is the one where the element would be inserted.  */

static int
search_unit (int unit, int *ip)
{
  int low, high, mid;

  if (n_elist == 0)
    {
      *ip = 0;
      return 0;
    }

  low = 0;
  high = n_elist - 1;

  do 
    {
      mid = (low + high) / 2;
      if (unit == elist[mid].unit)
	{
	  *ip = mid;
	  return 1;
	}
      else if (unit > elist[mid].unit)
	low = mid + 1;
      else
	high = mid - 1;
    } while (low <= high);

  if (unit > elist[mid].unit)
    *ip = mid + 1;
  else
    *ip = mid;

  return 0;
}

/* This matches a keyword.  If it is found, return the token supplied,
   otherwise return ILLEGAL.  */

static int
match_word (const char *word, int tok)
{
  int res;

  if (strncasecmp (p, word, strlen (word)) == 0)
    {
      p += strlen (word);
      res = tok;
    }
  else
    res = ILLEGAL;
  return res;
}

/* Match an integer and store its value in unit_num.  This only works
   if p actually points to the start of an integer.  The caller has
   to ensure this.  */

static int
match_integer (void)
{
  unit_num = 0;
  while (isdigit (*p))
    unit_num = unit_num * 10 + (*p++ - '0');
  return INTEGER;
}

/* This reads the next token from the GFORTRAN_CONVERT_UNITS variable.
   Returned values are the different tokens.  */

static int
next_token (void)
{
  int result;

  lastpos = p;
  switch (*p)
    {
    case '\0':
      result = END;
      break;
      
    case ':':
    case ',': 
    case '-':
    case ';':
      result = *p;
      p++;
      break;

    case 'b':
    case 'B':
      result = match_word ("big_endian", BIG);
      break;

    case 'l':
    case 'L':
      result = match_word ("little_endian", LITTLE);
      break;

    case 'n':
    case 'N':
      result = match_word ("native", NATIVE);
      break;

    case 's':
    case 'S':
      result = match_word ("swap", SWAP);
      break;

    case '1': case '2': case '3': case '4': case '5':
    case '6': case '7': case '8': case '9':
      result = match_integer ();
      break;

    default:
      result = ILLEGAL;
      break;
    }
  return result;
}

/* Back up the last token by setting back the character pointer.  */

static void
push_token (void)
{
  p = lastpos;
}

/* This is called when a unit is identified.  If do_count is nonzero,
   increment the number of units by one.  If do_count is zero,
   put the unit into the table.  */

static void
mark_single (int unit)
{
  int i,j;

  if (do_count)
    {
      unit_count++;
      return;
    }
  if (search_unit (unit, &i))
    {
      elist[i].conv = endian;
    }
  else
    {
      for (j=n_elist-1; j>=i; j--)
	elist[j+1] = elist[j];

      n_elist += 1;
      elist[i].unit = unit;
      elist[i].conv = endian;
    }
}

/* This is called when a unit range is identified.  If do_count is
   nonzero, increase the number of units.  If do_count is zero,
   put the unit into the table.  */

static void
mark_range (int unit1, int unit2)
{
  int i;
  if (do_count)
    unit_count += abs (unit2 - unit1) + 1;
  else
    {
      if (unit2 < unit1)
	for (i=unit2; i<=unit1; i++)
	  mark_single (i);
      else
	for (i=unit1; i<=unit2; i++)
	  mark_single (i);
    }
}

/* Parse the GFORTRAN_CONVERT_UNITS variable.  This is called
   twice, once to count the units and once to actually mark them in
   the table.  When counting, we don't check for double occurrences
   of units.  */

static int
do_parse (void)
{
  int tok;
  int unit1;
  int continue_ulist;
  char *start;

  unit_count = 0;

  start = p;

  /* Parse the string.  First, let's look for a default.  */
  tok = next_token ();
  switch (tok)
    {
    case NATIVE:
      endian = GFC_CONVERT_NATIVE;
      break;

    case SWAP:
      endian = GFC_CONVERT_SWAP;
      break;

    case BIG:
      endian = GFC_CONVERT_BIG;
      break;

    case LITTLE:
      endian = GFC_CONVERT_LITTLE;
      break;

    case INTEGER:
      /* A leading digit means that we are looking at an exception.
	 Reset the position to the beginning, and continue processing
	 at the exception list.  */
      p = start;
      goto exceptions;
      break;

    case END:
      goto end;
      break;

    default:
      goto error;
      break;
    }

  tok = next_token ();
  switch (tok)
    {
    case ';':
      def = endian;
      break;

    case ':':
      /* This isn't a default after all.  Reset the position to the
	 beginning, and continue processing at the exception list.  */
      p = start;
      goto exceptions;
      break;

    case END:
      def = endian;
      goto end;
      break;

    default:
      goto error;
      break;
    }

 exceptions:

  /* Loop over all exceptions.  */
  while(1)
    {
      tok = next_token ();
      switch (tok)
	{
	case NATIVE:
	  if (next_token () != ':')
	    goto error;
	  endian = GFC_CONVERT_NATIVE;
	  break;

	case SWAP:
	  if (next_token () != ':')
	    goto error;
	  endian = GFC_CONVERT_SWAP;
	  break;

	case LITTLE:
	  if (next_token () != ':')
	    goto error;
	  endian = GFC_CONVERT_LITTLE;
	  break;

	case BIG:
	  if (next_token () != ':')
	    goto error;
	  endian = GFC_CONVERT_BIG;
	  break;

	case INTEGER:
	  push_token ();
	  break;

	case END:
	  goto end;
	  break;

	default:
	  goto error;
	  break;
	}
      /* We arrive here when we want to parse a list of
	 numbers.  */
      continue_ulist = 1;
      do
	{
	  tok = next_token ();
	  if (tok != INTEGER)
	    goto error;

	  unit1 = unit_num;
	  tok = next_token ();
	  /* The number can be followed by a - and another number,
	     which means that this is a unit range, a comma
	     or a semicolon.  */
	  if (tok == '-')
	    {
	      if (next_token () != INTEGER)
		goto error;

	      mark_range (unit1, unit_num);
	      tok = next_token ();
	      if (tok == END)
		goto end;
	      else if (tok == ';')
		continue_ulist = 0;
	      else if (tok != ',')
		goto error;
	    }
	  else
	    {
	      mark_single (unit1);
	      switch (tok)
		{
		case ';':
		  continue_ulist = 0;
		  break;

		case ',':
		  break;

		case END:
		  goto end;
		  break;

		default:
		  goto error;
		}
	    }
	} while (continue_ulist);
    }
 end:
  return 0;
 error:
  def = GFC_CONVERT_NONE;
  return -1;
}

void init_unformatted (variable * v)
{
  char *val;
  val = getenv (v->name);
  def = GFC_CONVERT_NONE;
  n_elist = 0;

  if (val == NULL)
    return;
  do_count = 1;
  p = val;
  do_parse ();
  if (do_count <= 0)
    {
      n_elist = 0;
      elist = NULL;
    }
  else
    {
      elist = xmallocarray (unit_count, sizeof (exception_t));
      do_count = 0;
      p = val;
      do_parse ();
    }
}

/* Get the default conversion for for an unformatted unit.  */

unit_convert
get_unformatted_convert (int unit)
{
  int i;

  if (elist == NULL)
    return def;
  else if (search_unit (unit, &i))
    return elist[i].conv;
  else
    return def;
}
