/* Copyright (C) 2002-2014 Free Software Foundation, Inc.
   Contributed by Andy Vaught
   F2003 I/O support contributed by Jerry DeLisle

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 "io.h"
#include "fbuf.h"
#include "unix.h"

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

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


static const st_option access_opt[] = {
  {"sequential", ACCESS_SEQUENTIAL},
  {"direct", ACCESS_DIRECT},
  {"append", ACCESS_APPEND},
  {"stream", ACCESS_STREAM},
  {NULL, 0}
};

static const st_option action_opt[] =
{
  { "read", ACTION_READ},
  { "write", ACTION_WRITE},
  { "readwrite", ACTION_READWRITE},
  { NULL, 0}
};

static const st_option blank_opt[] =
{
  { "null", BLANK_NULL},
  { "zero", BLANK_ZERO},
  { NULL, 0}
};

static const st_option delim_opt[] =
{
  { "none", DELIM_NONE},
  { "apostrophe", DELIM_APOSTROPHE},
  { "quote", DELIM_QUOTE},
  { NULL, 0}
};

static const st_option form_opt[] =
{
  { "formatted", FORM_FORMATTED},
  { "unformatted", FORM_UNFORMATTED},
  { NULL, 0}
};

static const st_option position_opt[] =
{
  { "asis", POSITION_ASIS},
  { "rewind", POSITION_REWIND},
  { "append", POSITION_APPEND},
  { NULL, 0}
};

static const st_option status_opt[] =
{
  { "unknown", STATUS_UNKNOWN},
  { "old", STATUS_OLD},
  { "new", STATUS_NEW},
  { "replace", STATUS_REPLACE},
  { "scratch", STATUS_SCRATCH},
  { NULL, 0}
};

static const st_option pad_opt[] =
{
  { "yes", PAD_YES},
  { "no", PAD_NO},
  { NULL, 0}
};

static const st_option decimal_opt[] =
{
  { "point", DECIMAL_POINT},
  { "comma", DECIMAL_COMMA},
  { NULL, 0}
};

static const st_option encoding_opt[] =
{
  { "utf-8", ENCODING_UTF8},
  { "default", ENCODING_DEFAULT},
  { NULL, 0}
};

static const st_option round_opt[] =
{
  { "up", ROUND_UP},
  { "down", ROUND_DOWN},
  { "zero", ROUND_ZERO},
  { "nearest", ROUND_NEAREST},
  { "compatible", ROUND_COMPATIBLE},
  { "processor_defined", ROUND_PROCDEFINED},
  { NULL, 0}
};

static const st_option sign_opt[] =
{
  { "plus", SIGN_PLUS},
  { "suppress", SIGN_SUPPRESS},
  { "processor_defined", SIGN_PROCDEFINED},
  { NULL, 0}
};

static const st_option convert_opt[] =
{
  { "native", GFC_CONVERT_NATIVE},
  { "swap", GFC_CONVERT_SWAP},
  { "big_endian", GFC_CONVERT_BIG},
  { "little_endian", GFC_CONVERT_LITTLE},
  { NULL, 0}
};

static const st_option async_opt[] =
{
  { "yes", ASYNC_YES},
  { "no", ASYNC_NO},
  { NULL, 0}
};

/* Given a unit, test to see if the file is positioned at the terminal
   point, and if so, change state from NO_ENDFILE flag to AT_ENDFILE.
   This prevents us from changing the state from AFTER_ENDFILE to
   AT_ENDFILE.  */

static void
test_endfile (gfc_unit * u)
{
  if (u->endfile == NO_ENDFILE)
    { 
      gfc_offset sz = ssize (u->s);
      if (sz == 0 || sz == stell (u->s))
	u->endfile = AT_ENDFILE;
    }
}


/* Change the modes of a file, those that are allowed * to be
   changed.  */

static void
edit_modes (st_parameter_open *opp, gfc_unit * u, unit_flags * flags)
{
  /* Complain about attempts to change the unchangeable.  */

  if (flags->status != STATUS_UNSPECIFIED && flags->status != STATUS_OLD && 
      u->flags.status != flags->status)
    generate_error (&opp->common, LIBERROR_BAD_OPTION,
		    "Cannot change STATUS parameter in OPEN statement");

  if (flags->access != ACCESS_UNSPECIFIED && u->flags.access != flags->access)
    generate_error (&opp->common, LIBERROR_BAD_OPTION,
		    "Cannot change ACCESS parameter in OPEN statement");

  if (flags->form != FORM_UNSPECIFIED && u->flags.form != flags->form)
    generate_error (&opp->common, LIBERROR_BAD_OPTION,
		    "Cannot change FORM parameter in OPEN statement");

  if ((opp->common.flags & IOPARM_OPEN_HAS_RECL_IN)
      && opp->recl_in != u->recl)
    generate_error (&opp->common, LIBERROR_BAD_OPTION,
		    "Cannot change RECL parameter in OPEN statement");

  if (flags->action != ACTION_UNSPECIFIED && u->flags.action != flags->action)
    generate_error (&opp->common, LIBERROR_BAD_OPTION,
		    "Cannot change ACTION parameter in OPEN statement");

  /* Status must be OLD if present.  */

  if (flags->status != STATUS_UNSPECIFIED && flags->status != STATUS_OLD &&
      flags->status != STATUS_UNKNOWN)
    {
      if (flags->status == STATUS_SCRATCH)
	notify_std (&opp->common, GFC_STD_GNU,
		    "OPEN statement must have a STATUS of OLD or UNKNOWN");
      else
	generate_error (&opp->common, LIBERROR_BAD_OPTION,
		    "OPEN statement must have a STATUS of OLD or UNKNOWN");
    }

  if (u->flags.form == FORM_UNFORMATTED)
    {
      if (flags->delim != DELIM_UNSPECIFIED)
	generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			"DELIM parameter conflicts with UNFORMATTED form in "
			"OPEN statement");

      if (flags->blank != BLANK_UNSPECIFIED)
	generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			"BLANK parameter conflicts with UNFORMATTED form in "
			"OPEN statement");

      if (flags->pad != PAD_UNSPECIFIED)
	generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			"PAD parameter conflicts with UNFORMATTED form in "
			"OPEN statement");

      if (flags->decimal != DECIMAL_UNSPECIFIED)
	generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			"DECIMAL parameter conflicts with UNFORMATTED form in "
			"OPEN statement");

      if (flags->encoding != ENCODING_UNSPECIFIED)
	generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			"ENCODING parameter conflicts with UNFORMATTED form in "
			"OPEN statement");

      if (flags->round != ROUND_UNSPECIFIED)
	generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			"ROUND parameter conflicts with UNFORMATTED form in "
			"OPEN statement");

      if (flags->sign != SIGN_UNSPECIFIED)
	generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			"SIGN parameter conflicts with UNFORMATTED form in "
			"OPEN statement");
    }

  if ((opp->common.flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_OK)
    {
      /* Change the changeable:  */
      if (flags->blank != BLANK_UNSPECIFIED)
	u->flags.blank = flags->blank;
      if (flags->delim != DELIM_UNSPECIFIED)
	u->flags.delim = flags->delim;
      if (flags->pad != PAD_UNSPECIFIED)
	u->flags.pad = flags->pad;
      if (flags->decimal != DECIMAL_UNSPECIFIED)
	u->flags.decimal = flags->decimal;
      if (flags->encoding != ENCODING_UNSPECIFIED)
	u->flags.encoding = flags->encoding;
      if (flags->async != ASYNC_UNSPECIFIED)
	u->flags.async = flags->async;
      if (flags->round != ROUND_UNSPECIFIED)
	u->flags.round = flags->round;
      if (flags->sign != SIGN_UNSPECIFIED)
	u->flags.sign = flags->sign;

      /* Reposition the file if necessary.  */
    
      switch (flags->position)
	{
	case POSITION_UNSPECIFIED:
	case POSITION_ASIS:
	  break;
    
	case POSITION_REWIND:
	  if (sseek (u->s, 0, SEEK_SET) != 0)
	    goto seek_error;
    
	  u->current_record = 0;
	  u->last_record = 0;
    
	  test_endfile (u);
	  break;
    
	case POSITION_APPEND:
	  if (sseek (u->s, 0, SEEK_END) < 0)
	    goto seek_error;
    
	  if (flags->access != ACCESS_STREAM)
	    u->current_record = 0;
    
	  u->endfile = AT_ENDFILE;	/* We are at the end.  */
	  break;
    
	seek_error:
	  generate_error (&opp->common, LIBERROR_OS, NULL);
	  break;
	}
    }

  unlock_unit (u);
}


/* Open an unused unit.  */

gfc_unit *
new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
{
  gfc_unit *u2;
  stream *s;
  char tmpname[5 /* fort. */ + 10 /* digits of unit number */ + 1 /* 0 */];

  /* Change unspecifieds to defaults.  Leave (flags->action ==
     ACTION_UNSPECIFIED) alone so open_external() can set it based on
     what type of open actually works.  */

  if (flags->access == ACCESS_UNSPECIFIED)
    flags->access = ACCESS_SEQUENTIAL;

  if (flags->form == FORM_UNSPECIFIED)
    flags->form = (flags->access == ACCESS_SEQUENTIAL)
      ? FORM_FORMATTED : FORM_UNFORMATTED;

  if (flags->async == ASYNC_UNSPECIFIED)
    flags->async = ASYNC_NO;

  if (flags->status == STATUS_UNSPECIFIED)
    flags->status = STATUS_UNKNOWN;

  /* Checks.  */

  if (flags->delim != DELIM_UNSPECIFIED
      && flags->form == FORM_UNFORMATTED)
    {
      generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
		      "DELIM parameter conflicts with UNFORMATTED form in "
		      "OPEN statement");
      goto fail;
    }

  if (flags->blank == BLANK_UNSPECIFIED)
    flags->blank = BLANK_NULL;
  else
    {
      if (flags->form == FORM_UNFORMATTED)
	{
	  generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			  "BLANK parameter conflicts with UNFORMATTED form in "
			  "OPEN statement");
	  goto fail;
	}
    }

  if (flags->pad == PAD_UNSPECIFIED)
    flags->pad = PAD_YES;
  else
    {
      if (flags->form == FORM_UNFORMATTED)
	{
	  generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			  "PAD parameter conflicts with UNFORMATTED form in "
			  "OPEN statement");
	  goto fail;
	}
    }

  if (flags->decimal == DECIMAL_UNSPECIFIED)
    flags->decimal = DECIMAL_POINT;
  else
    {
      if (flags->form == FORM_UNFORMATTED)
	{
	  generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			  "DECIMAL parameter conflicts with UNFORMATTED form "
			  "in OPEN statement");
	  goto fail;
	}
    }

  if (flags->encoding == ENCODING_UNSPECIFIED)
    flags->encoding = ENCODING_DEFAULT;
  else
    {
      if (flags->form == FORM_UNFORMATTED)
	{
	  generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			  "ENCODING parameter conflicts with UNFORMATTED form in "
			  "OPEN statement");
	  goto fail;
	}
    }

  /* NB: the value for ROUND when it's not specified by the user does not
         have to be PROCESSOR_DEFINED; the standard says that it is
	 processor dependent, and requires that it is one of the
	 possible value (see F2003, 9.4.5.13).  */
  if (flags->round == ROUND_UNSPECIFIED)
    flags->round = ROUND_PROCDEFINED;
  else
    {
      if (flags->form == FORM_UNFORMATTED)
	{
	  generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			  "ROUND parameter conflicts with UNFORMATTED form in "
			  "OPEN statement");
	  goto fail;
	}
    }

  if (flags->sign == SIGN_UNSPECIFIED)
    flags->sign = SIGN_PROCDEFINED;
  else
    {
      if (flags->form == FORM_UNFORMATTED)
	{
	  generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
			  "SIGN parameter conflicts with UNFORMATTED form in "
			  "OPEN statement");
	  goto fail;
	}
    }

  if (flags->position != POSITION_ASIS && flags->access == ACCESS_DIRECT)
   {
     generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
                     "ACCESS parameter conflicts with SEQUENTIAL access in "
                     "OPEN statement");
     goto fail;
   }
  else
   if (flags->position == POSITION_UNSPECIFIED)
     flags->position = POSITION_ASIS;

  if (flags->access == ACCESS_DIRECT
      && (opp->common.flags & IOPARM_OPEN_HAS_RECL_IN) == 0)
    {
      generate_error (&opp->common, LIBERROR_MISSING_OPTION,
		      "Missing RECL parameter in OPEN statement");
      goto fail;
    }

  if ((opp->common.flags & IOPARM_OPEN_HAS_RECL_IN) && opp->recl_in <= 0)
    {
      generate_error (&opp->common, LIBERROR_BAD_OPTION,
		      "RECL parameter is non-positive in OPEN statement");
      goto fail;
    }

  switch (flags->status)
    {
    case STATUS_SCRATCH:
      if ((opp->common.flags & IOPARM_OPEN_HAS_FILE) == 0)
	{
	  opp->file = NULL;
	  break;
	}

      generate_error (&opp->common, LIBERROR_BAD_OPTION,
		      "FILE parameter must not be present in OPEN statement");
      goto fail;

    case STATUS_OLD:
    case STATUS_NEW:
    case STATUS_REPLACE:
    case STATUS_UNKNOWN:
      if ((opp->common.flags & IOPARM_OPEN_HAS_FILE))
	break;

      opp->file = tmpname;
      opp->file_len = snprintf(opp->file, sizeof (tmpname), "fort.%d", 
			       (int) opp->common.unit);
      break;

    default:
      internal_error (&opp->common, "new_unit(): Bad status");
    }

  /* Make sure the file isn't already open someplace else.
     Do not error if opening file preconnected to stdin, stdout, stderr.  */

  u2 = NULL;
  if ((opp->common.flags & IOPARM_OPEN_HAS_FILE) != 0)
    u2 = find_file (opp->file, opp->file_len);
  if (u2 != NULL
      && (options.stdin_unit < 0 || u2->unit_number != options.stdin_unit)
      && (options.stdout_unit < 0 || u2->unit_number != options.stdout_unit)
      && (options.stderr_unit < 0 || u2->unit_number != options.stderr_unit))
    {
      unlock_unit (u2);
      generate_error (&opp->common, LIBERROR_ALREADY_OPEN, NULL);
      goto cleanup;
    }

  if (u2 != NULL)
    unlock_unit (u2);

  /* Open file.  */

  s = open_external (opp, flags);
  if (s == NULL)
    {
      char *path, *msg;
      size_t msglen;
      path = (char *) gfc_alloca (opp->file_len + 1);
      msglen = opp->file_len + 51;
      msg = (char *) gfc_alloca (msglen);
      unpack_filename (path, opp->file, opp->file_len);

      switch (errno)
	{
	case ENOENT: 
	  snprintf (msg, msglen, "File '%s' does not exist", path);
	  break;

	case EEXIST:
	  snprintf (msg, msglen, "File '%s' already exists", path);
	  break;

	case EACCES:
	  snprintf (msg, msglen, 
		    "Permission denied trying to open file '%s'", path);
	  break;

	case EISDIR:
	  snprintf (msg, msglen, "'%s' is a directory", path);
	  break;

	default:
	  msg = NULL;
	}

      generate_error (&opp->common, LIBERROR_OS, msg);
      goto cleanup;
    }

  if (flags->status == STATUS_NEW || flags->status == STATUS_REPLACE)
    flags->status = STATUS_OLD;

  /* Create the unit structure.  */

  u->file = xmalloc (opp->file_len);
  if (u->unit_number != opp->common.unit)
    internal_error (&opp->common, "Unit number changed");
  u->s = s;
  u->flags = *flags;
  u->read_bad = 0;
  u->endfile = NO_ENDFILE;
  u->last_record = 0;
  u->current_record = 0;
  u->mode = READING;
  u->maxrec = 0;
  u->bytes_left = 0;
  u->saved_pos = 0;

  if (flags->position == POSITION_APPEND)
    {
      if (sseek (u->s, 0, SEEK_END) < 0)
	{
	  generate_error (&opp->common, LIBERROR_OS, NULL);
	  goto cleanup;
	}
      u->endfile = AT_ENDFILE;
    }

  /* Unspecified recl ends up with a processor dependent value.  */

  if ((opp->common.flags & IOPARM_OPEN_HAS_RECL_IN))
    {
      u->flags.has_recl = 1;
      u->recl = opp->recl_in;
      u->recl_subrecord = u->recl;
      u->bytes_left = u->recl;
    }
  else
    {
      u->flags.has_recl = 0;
      u->recl = max_offset;
      if (compile_options.max_subrecord_length)
	{
	  u->recl_subrecord = compile_options.max_subrecord_length;
	}
      else
	{
	  switch (compile_options.record_marker)
	    {
	    case 0:
	      /* Fall through */
	    case sizeof (GFC_INTEGER_4):
	      u->recl_subrecord = GFC_MAX_SUBRECORD_LENGTH;
	      break;

	    case sizeof (GFC_INTEGER_8):
	      u->recl_subrecord = max_offset - 16;
	      break;

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

  /* If the file is direct access, calculate the maximum record number
     via a division now instead of letting the multiplication overflow
     later.  */

  if (flags->access == ACCESS_DIRECT)
    u->maxrec = max_offset / u->recl;
  
  if (flags->access == ACCESS_STREAM)
    {
      u->maxrec = max_offset;
      u->recl = 1;
      u->bytes_left = 1;
      u->strm_pos = stell (u->s) + 1;
    }

  memmove (u->file, opp->file, opp->file_len);
  u->file_len = opp->file_len;

  /* Curiously, the standard requires that the
     position specifier be ignored for new files so a newly connected
     file starts out at the initial point.  We still need to figure
     out if the file is at the end or not.  */

  test_endfile (u);

  if (flags->status == STATUS_SCRATCH && opp->file != NULL)
    free (opp->file);
    
  if (flags->form == FORM_FORMATTED)
    {
      if ((opp->common.flags & IOPARM_OPEN_HAS_RECL_IN))
        fbuf_init (u, u->recl);
      else
        fbuf_init (u, 0);
    }
  else
    u->fbuf = NULL;

    
    
  return u;

 cleanup:

  /* Free memory associated with a temporary filename.  */

  if (flags->status == STATUS_SCRATCH && opp->file != NULL)
    free (opp->file);

 fail:

  close_unit (u);
  return NULL;
}


/* Open a unit which is already open.  This involves changing the
   modes or closing what is there now and opening the new file.  */

static void
already_open (st_parameter_open *opp, gfc_unit * u, unit_flags * flags)
{
  if ((opp->common.flags & IOPARM_OPEN_HAS_FILE) == 0)
    {
      edit_modes (opp, u, flags);
      return;
    }

  /* If the file is connected to something else, close it and open a
     new unit.  */

  if (!compare_file_filename (u, opp->file, opp->file_len))
    {
#if !HAVE_UNLINK_OPEN_FILE
      char *path = NULL;
      if (u->file && u->flags.status == STATUS_SCRATCH)
	{
	  path = (char *) gfc_alloca (u->file_len + 1);
	  unpack_filename (path, u->file, u->file_len);
	}
#endif

      if (sclose (u->s) == -1)
	{
	  unlock_unit (u);
	  generate_error (&opp->common, LIBERROR_OS,
			  "Error closing file in OPEN statement");
	  return;
	}

      u->s = NULL;
      free (u->file);
      u->file = NULL;
      u->file_len = 0;

#if !HAVE_UNLINK_OPEN_FILE
      if (path != NULL)
	unlink (path);
#endif

      u = new_unit (opp, u, flags);
      if (u != NULL)
	unlock_unit (u);
      return;
    }

  edit_modes (opp, u, flags);
}


/* Open file.  */

extern void st_open (st_parameter_open *opp);
export_proto(st_open);

void
st_open (st_parameter_open *opp)
{
  unit_flags flags;
  gfc_unit *u = NULL;
  GFC_INTEGER_4 cf = opp->common.flags;
  unit_convert conv;
 
  library_start (&opp->common);

  /* Decode options.  */

  flags.access = !(cf & IOPARM_OPEN_HAS_ACCESS) ? ACCESS_UNSPECIFIED :
    find_option (&opp->common, opp->access, opp->access_len,
		 access_opt, "Bad ACCESS parameter in OPEN statement");

  flags.action = !(cf & IOPARM_OPEN_HAS_ACTION) ? ACTION_UNSPECIFIED :
    find_option (&opp->common, opp->action, opp->action_len,
		 action_opt, "Bad ACTION parameter in OPEN statement");

  flags.blank = !(cf & IOPARM_OPEN_HAS_BLANK) ? BLANK_UNSPECIFIED :
    find_option (&opp->common, opp->blank, opp->blank_len,
		 blank_opt, "Bad BLANK parameter in OPEN statement");

  flags.delim = !(cf & IOPARM_OPEN_HAS_DELIM) ? DELIM_UNSPECIFIED :
    find_option (&opp->common, opp->delim, opp->delim_len,
		 delim_opt, "Bad DELIM parameter in OPEN statement");

  flags.pad = !(cf & IOPARM_OPEN_HAS_PAD) ? PAD_UNSPECIFIED :
    find_option (&opp->common, opp->pad, opp->pad_len,
		 pad_opt, "Bad PAD parameter in OPEN statement");

  flags.decimal = !(cf & IOPARM_OPEN_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
    find_option (&opp->common, opp->decimal, opp->decimal_len,
		 decimal_opt, "Bad DECIMAL parameter in OPEN statement");

  flags.encoding = !(cf & IOPARM_OPEN_HAS_ENCODING) ? ENCODING_UNSPECIFIED :
    find_option (&opp->common, opp->encoding, opp->encoding_len,
		 encoding_opt, "Bad ENCODING parameter in OPEN statement");

  flags.async = !(cf & IOPARM_OPEN_HAS_ASYNCHRONOUS) ? ASYNC_UNSPECIFIED :
    find_option (&opp->common, opp->asynchronous, opp->asynchronous_len,
		 async_opt, "Bad ASYNCHRONOUS parameter in OPEN statement");

  flags.round = !(cf & IOPARM_OPEN_HAS_ROUND) ? ROUND_UNSPECIFIED :
    find_option (&opp->common, opp->round, opp->round_len,
		 round_opt, "Bad ROUND parameter in OPEN statement");

  flags.sign = !(cf & IOPARM_OPEN_HAS_SIGN) ? SIGN_UNSPECIFIED :
    find_option (&opp->common, opp->sign, opp->sign_len,
		 sign_opt, "Bad SIGN parameter in OPEN statement");

  flags.form = !(cf & IOPARM_OPEN_HAS_FORM) ? FORM_UNSPECIFIED :
    find_option (&opp->common, opp->form, opp->form_len,
		 form_opt, "Bad FORM parameter in OPEN statement");

  flags.position = !(cf & IOPARM_OPEN_HAS_POSITION) ? POSITION_UNSPECIFIED :
    find_option (&opp->common, opp->position, opp->position_len,
		 position_opt, "Bad POSITION parameter in OPEN statement");

  flags.status = !(cf & IOPARM_OPEN_HAS_STATUS) ? STATUS_UNSPECIFIED :
    find_option (&opp->common, opp->status, opp->status_len,
		 status_opt, "Bad STATUS parameter in OPEN statement");

  /* First, we check wether the convert flag has been set via environment
     variable.  This overrides the convert tag in the open statement.  */

  conv = get_unformatted_convert (opp->common.unit);

  if (conv == GFC_CONVERT_NONE)
    {
      /* Nothing has been set by environment variable, check the convert tag.  */
      if (cf & IOPARM_OPEN_HAS_CONVERT)
	conv = find_option (&opp->common, opp->convert, opp->convert_len,
			    convert_opt,
			    "Bad CONVERT parameter in OPEN statement");
      else
	conv = compile_options.convert;
    }
  
  /* We use big_endian, which is 0 on little-endian machines
     and 1 on big-endian machines.  */
  switch (conv)
    {
    case GFC_CONVERT_NATIVE:
    case GFC_CONVERT_SWAP:
      break;
      
    case GFC_CONVERT_BIG:
      conv = big_endian ? GFC_CONVERT_NATIVE : GFC_CONVERT_SWAP;
      break;
      
    case GFC_CONVERT_LITTLE:
      conv = big_endian ? GFC_CONVERT_SWAP : GFC_CONVERT_NATIVE;
      break;
      
    default:
      internal_error (&opp->common, "Illegal value for CONVERT");
      break;
    }

  flags.convert = conv;

  if (flags.position != POSITION_UNSPECIFIED
      && flags.access == ACCESS_DIRECT)
    generate_error (&opp->common, LIBERROR_BAD_OPTION,
		    "Cannot use POSITION with direct access files");

  if (flags.access == ACCESS_APPEND)
    {
      if (flags.position != POSITION_UNSPECIFIED
	  && flags.position != POSITION_APPEND)
	generate_error (&opp->common, LIBERROR_BAD_OPTION,
			"Conflicting ACCESS and POSITION flags in"
			" OPEN statement");

      notify_std (&opp->common, GFC_STD_GNU,
		  "Extension: APPEND as a value for ACCESS in OPEN statement");
      flags.access = ACCESS_SEQUENTIAL;
      flags.position = POSITION_APPEND;
    }

  if (flags.position == POSITION_UNSPECIFIED)
    flags.position = POSITION_ASIS;

  if ((opp->common.flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_OK)
    {
      if ((opp->common.flags & IOPARM_OPEN_HAS_NEWUNIT))
	opp->common.unit = get_unique_unit_number(opp);
      else if (opp->common.unit < 0)
	{
	  u = find_unit (opp->common.unit);
	  if (u == NULL) /* Negative unit and no NEWUNIT-created unit found.  */
	    {
	      generate_error (&opp->common, LIBERROR_BAD_OPTION,
			      "Bad unit number in OPEN statement");
	      library_end ();
	      return;
	    }
	}

      if (u == NULL)
	u = find_or_create_unit (opp->common.unit);
      if (u->s == NULL)
	{
	  u = new_unit (opp, u, &flags);
	  if (u != NULL)
	    unlock_unit (u);
	}
      else
	already_open (opp, u, &flags);
    }
    
  if ((opp->common.flags & IOPARM_OPEN_HAS_NEWUNIT)
      && (opp->common.flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_OK)
    *opp->newunit = opp->common.unit;
  
  library_end ();
}
