/* Deal with I/O statements & related stuff.
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 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 2, 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 COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "flags.h"
#include "gfortran.h"
#include "match.h"
#include "parse.h"

gfc_st_label format_asterisk =
  { -1, ST_LABEL_FORMAT, ST_LABEL_FORMAT, NULL, 0,
    {NULL, NULL}, NULL, NULL};

typedef struct
{
  const char *name, *spec;
  bt type;
}
io_tag;

static const io_tag
	tag_file	= { "FILE", " file = %e", BT_CHARACTER },
	tag_status	= { "STATUS", " status = %e", BT_CHARACTER},
	tag_e_access	= {"ACCESS", " access = %e", BT_CHARACTER},
	tag_e_form	= {"FORM", " form = %e", BT_CHARACTER},
	tag_e_recl	= {"RECL", " recl = %e", BT_INTEGER},
	tag_e_blank	= {"BLANK", " blank = %e", BT_CHARACTER},
	tag_e_position	= {"POSITION", " position = %e", BT_CHARACTER},
	tag_e_action	= {"ACTION", " action = %e", BT_CHARACTER},
	tag_e_delim	= {"DELIM", " delim = %e", BT_CHARACTER},
	tag_e_pad	= {"PAD", " pad = %e", BT_CHARACTER},
	tag_unit	= {"UNIT", " unit = %e", BT_INTEGER},
	tag_advance	= {"ADVANCE", " advance = %e", BT_CHARACTER},
	tag_rec		= {"REC", " rec = %e", BT_INTEGER},
	tag_format	= {"FORMAT", NULL, BT_CHARACTER},
	tag_iostat	= {"IOSTAT", " iostat = %v", BT_INTEGER},
	tag_size	= {"SIZE", " size = %v", BT_INTEGER},
	tag_exist	= {"EXIST", " exist = %v", BT_LOGICAL},
	tag_opened	= {"OPENED", " opened = %v", BT_LOGICAL},
	tag_named	= {"NAMED", " named = %v", BT_LOGICAL},
	tag_name	= {"NAME", " name = %v", BT_CHARACTER},
	tag_number	= {"NUMBER", " number = %v", BT_INTEGER},
	tag_s_access	= {"ACCESS", " access = %v", BT_CHARACTER},
	tag_sequential	= {"SEQUENTIAL", " sequential = %v", BT_CHARACTER},
	tag_direct	= {"DIRECT", " direct = %v", BT_CHARACTER},
	tag_s_form	= {"FORM", " form = %v", BT_CHARACTER},
	tag_formatted	= {"FORMATTED", " formatted = %v", BT_CHARACTER},
	tag_unformatted	= {"UNFORMATTED", " unformatted = %v", BT_CHARACTER},
	tag_s_recl	= {"RECL", " recl = %v", BT_INTEGER},
	tag_nextrec	= {"NEXTREC", " nextrec = %v", BT_INTEGER},
	tag_s_blank	= {"BLANK", " blank = %v", BT_CHARACTER},
	tag_s_position	= {"POSITION", " position = %v", BT_CHARACTER},
	tag_s_action	= {"ACTION", " action = %v", BT_CHARACTER},
	tag_read	= {"READ", " read = %v", BT_CHARACTER},
	tag_write	= {"WRITE", " write = %v", BT_CHARACTER},
	tag_readwrite	= {"READWRITE", " readwrite = %v", BT_CHARACTER},
	tag_s_delim	= {"DELIM", " delim = %v", BT_CHARACTER},
	tag_s_pad	= {"PAD", " pad = %v", BT_CHARACTER},
	tag_iolength	= {"IOLENGTH", " iolength = %v", BT_INTEGER},
	tag_err		= {"ERR", " err = %l", BT_UNKNOWN},
	tag_end		= {"END", " end = %l", BT_UNKNOWN},
	tag_eor		= {"EOR", " eor = %l", BT_UNKNOWN};

static gfc_dt *current_dt;

#define RESOLVE_TAG(x, y) if (resolve_tag(x, y) == FAILURE) return FAILURE;


/**************** Fortran 95 FORMAT parser  *****************/

/* FORMAT tokens returned by format_lex().  */
typedef enum
{
  FMT_NONE, FMT_UNKNOWN, FMT_SIGNED_INT, FMT_ZERO, FMT_POSINT, FMT_PERIOD,
  FMT_COMMA, FMT_COLON, FMT_SLASH, FMT_DOLLAR, FMT_POS, FMT_LPAREN,
  FMT_RPAREN, FMT_X, FMT_SIGN, FMT_BLANK, FMT_CHAR, FMT_P, FMT_IBOZ, FMT_F,
  FMT_E, FMT_EXT, FMT_G, FMT_L, FMT_A, FMT_D, FMT_H, FMT_END
}
format_token;

/* Local variables for checking format strings.  The saved_token is
   used to back up by a single format token during the parsing
   process.  */
static char *format_string;
static int format_length, use_last_char;

static format_token saved_token;

static enum
{ MODE_STRING, MODE_FORMAT, MODE_COPY }
mode;


/* Return the next character in the format string.  */

static char
next_char (int in_string)
{
  static char c;

  if (use_last_char)
    {
      use_last_char = 0;
      return c;
    }

  format_length++;

  if (mode == MODE_STRING)
    c = *format_string++;
  else
    {
      c = gfc_next_char_literal (in_string);
      if (c == '\n')
	c = '\0';

      if (mode == MODE_COPY)
	*format_string++ = c;
    }

  c = TOUPPER (c);
  return c;
}


/* Back up one character position.  Only works once.  */

static void
unget_char (void)
{

  use_last_char = 1;
}

static int value = 0;

/* Simple lexical analyzer for getting the next token in a FORMAT
   statement.  */

static format_token
format_lex (void)
{
  format_token token;
  char c, delim;
  int zflag;
  int negative_flag;

  if (saved_token != FMT_NONE)
    {
      token = saved_token;
      saved_token = FMT_NONE;
      return token;
    }

  do
    {
      c = next_char (0);
    }
  while (gfc_is_whitespace (c));

  negative_flag = 0;
  switch (c)
    {
    case '-':
      negative_flag = 1;
    case '+':
      c = next_char (0);
      if (!ISDIGIT (c))
	{
	  token = FMT_UNKNOWN;
	  break;
	}

      value = c - '0';

      do
	{
	  c = next_char (0);
          if(ISDIGIT (c))
            value = 10 * value + c - '0';
	}
      while (ISDIGIT (c));

      unget_char ();

      if (negative_flag)
        value = -value;

      token = FMT_SIGNED_INT;
      break;

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      zflag = (c == '0');

      value = c - '0';

      do
	{
	  c = next_char (0);
	  if (c != '0')
	    zflag = 0;
          if (ISDIGIT (c))
            value = 10 * value + c - '0';
	}
      while (ISDIGIT (c));

      unget_char ();
      token = zflag ? FMT_ZERO : FMT_POSINT;
      break;

    case '.':
      token = FMT_PERIOD;
      break;

    case ',':
      token = FMT_COMMA;
      break;

    case ':':
      token = FMT_COLON;
      break;

    case '/':
      token = FMT_SLASH;
      break;

    case '$':
      token = FMT_DOLLAR;
      break;

    case 'T':
      c = next_char (0);
      if (c != 'L' && c != 'R')
	unget_char ();

      token = FMT_POS;
      break;

    case '(':
      token = FMT_LPAREN;
      break;

    case ')':
      token = FMT_RPAREN;
      break;

    case 'X':
      token = FMT_X;
      break;

    case 'S':
      c = next_char (0);
      if (c != 'P' && c != 'S')
	unget_char ();

      token = FMT_SIGN;
      break;

    case 'B':
      c = next_char (0);
      if (c == 'N' || c == 'Z')
	token = FMT_BLANK;
      else
	{
	  unget_char ();
	  token = FMT_IBOZ;
	}

      break;

    case '\'':
    case '"':
      delim = c;

      value = 0;

      for (;;)
	{
	  c = next_char (1);
	  if (c == '\0')
	    {
	      token = FMT_END;
	      break;
	    }

	  if (c == delim)
	    {
	      c = next_char (1);

	      if (c == '\0')
		{
		  token = FMT_END;
		  break;
		}

	      if (c != delim)
		{
		  unget_char ();
		  token = FMT_CHAR;
		  break;
		}
	    }
          value++;
	}
      break;

    case 'P':
      token = FMT_P;
      break;

    case 'I':
    case 'O':
    case 'Z':
      token = FMT_IBOZ;
      break;

    case 'F':
      token = FMT_F;
      break;

    case 'E':
      c = next_char (0);
      if (c == 'N' || c == 'S')
	token = FMT_EXT;
      else
	{
	  token = FMT_E;
	  unget_char ();
	}

      break;

    case 'G':
      token = FMT_G;
      break;

    case 'H':
      token = FMT_H;
      break;

    case 'L':
      token = FMT_L;
      break;

    case 'A':
      token = FMT_A;
      break;

    case 'D':
      token = FMT_D;
      break;

    case '\0':
      token = FMT_END;
      break;

    default:
      token = FMT_UNKNOWN;
      break;
    }

  return token;
}


/* Check a format statement.  The format string, either from a FORMAT
   statement or a constant in an I/O statement has already been parsed
   by itself, and we are checking it for validity.  The dual origin
   means that the warning message is a little less than great.  */

static try
check_format (void)
{
  const char *posint_required	  = "Positive width required";
  const char *period_required	  = "Period required";
  const char *nonneg_required	  = "Nonnegative width required";
  const char *unexpected_element  = "Unexpected element";
  const char *unexpected_end	  = "Unexpected end of format string";

  const char *error;
  format_token t, u;
  int level;
  int repeat;
  try rv;

  use_last_char = 0;
  saved_token = FMT_NONE;
  level = 0;
  repeat = 0;
  rv = SUCCESS;

  t = format_lex ();
  if (t != FMT_LPAREN)
    {
      error = "Missing leading left parenthesis";
      goto syntax;
    }

  t = format_lex ();
  if (t == FMT_RPAREN)
    goto finished;		/* Empty format is legal */
  saved_token = t;

format_item:
  /* In this state, the next thing has to be a format item.  */
  t = format_lex ();
  switch (t)
    {
    case FMT_POSINT:
      repeat = value;
      t = format_lex ();
      if (t == FMT_LPAREN)
	{
	  level++;
	  goto format_item;
	}

      if (t == FMT_SLASH)
	goto optional_comma;

      goto data_desc;

    case FMT_LPAREN:
      level++;
      goto format_item;

    case FMT_SIGNED_INT:
      /* Signed integer can only precede a P format.  */
      t = format_lex ();
      if (t != FMT_P)
	{
	  error = "Expected P edit descriptor";
	  goto syntax;
	}

      goto data_desc;

    case FMT_P:
      /* P requires a prior number.  */
      error = "P descriptor requires leading scale factor";
      goto syntax;

    case FMT_X:
      /* X requires a prior number if we're being pedantic.  */
      if (gfc_notify_std (GFC_STD_GNU, "Extension: X descriptor "
			  "requires leading space count at %C")
	  == FAILURE)
	return FAILURE;
      goto between_desc;

    case FMT_SIGN:
    case FMT_BLANK:
      goto between_desc;

    case FMT_CHAR:
      goto extension_optional_comma;

    case FMT_COLON:
    case FMT_SLASH:
      goto optional_comma;

    case FMT_DOLLAR:
      t = format_lex ();

      if (gfc_notify_std (GFC_STD_GNU, "Extension: $ descriptor at %C")
          == FAILURE)
        return FAILURE;
      if (t != FMT_RPAREN || level > 0)
	{
	  error = "$ must the last specifier";
	  goto syntax;
	}

      goto finished;

    case FMT_POS:
    case FMT_IBOZ:
    case FMT_F:
    case FMT_E:
    case FMT_EXT:
    case FMT_G:
    case FMT_L:
    case FMT_A:
    case FMT_D:
      goto data_desc;

    case FMT_H:
      goto data_desc;

    case FMT_END:
      error = unexpected_end;
      goto syntax;

    default:
      error = unexpected_element;
      goto syntax;
    }

data_desc:
  /* In this state, t must currently be a data descriptor.
     Deal with things that can/must follow the descriptor.  */
  switch (t)
    {
    case FMT_SIGN:
    case FMT_BLANK:
    case FMT_X:
      break;

    case FMT_P:
      if (pedantic)
	{
	  t = format_lex ();
	  if (t == FMT_POSINT)
	    {
	      error = "Repeat count cannot follow P descriptor";
	      goto syntax;
	    }

	  saved_token = t;
	}

      goto optional_comma;

    case FMT_POS:
    case FMT_L:
      t = format_lex ();
      if (t == FMT_POSINT)
	break;

      error = posint_required;
      goto syntax;

    case FMT_A:
      t = format_lex ();
      if (t != FMT_POSINT)
	saved_token = t;
      break;

    case FMT_D:
    case FMT_E:
    case FMT_G:
    case FMT_EXT:
      u = format_lex ();
      if (u != FMT_POSINT)
	{
	  error = posint_required;
	  goto syntax;
	}

      u = format_lex ();
      if (u != FMT_PERIOD)
	{
	  error = period_required;
	  goto syntax;
	}

      u = format_lex ();
      if (u != FMT_ZERO && u != FMT_POSINT)
	{
	  error = nonneg_required;
	  goto syntax;
	}

      if (t == FMT_D)
	break;

      /* Look for optional exponent.  */
      u = format_lex ();
      if (u != FMT_E)
	{
	  saved_token = u;
	}
      else
	{
	  u = format_lex ();
	  if (u != FMT_POSINT)
	    {
	      error = "Positive exponent width required";
	      goto syntax;
	    }
	}

      break;

    case FMT_F:
      t = format_lex ();
      if (t != FMT_ZERO && t != FMT_POSINT)
	{
	  error = nonneg_required;
	  goto syntax;
	}

      t = format_lex ();
      if (t != FMT_PERIOD)
	{
	  error = period_required;
	  goto syntax;
	}

      t = format_lex ();
      if (t != FMT_ZERO && t != FMT_POSINT)
	{
	  error = nonneg_required;
	  goto syntax;
	}

      break;

    case FMT_H:
      if(mode == MODE_STRING)
      {
        format_string += value;
        format_length -= value;
      }
      else
      {
        while(repeat >0)
         {
          next_char(1);
          repeat -- ;
         }
      }
     break;

    case FMT_IBOZ:
      t = format_lex ();
      if (t != FMT_ZERO && t != FMT_POSINT)
	{
	  error = nonneg_required;
	  goto syntax;
	}

      t = format_lex ();
      if (t != FMT_PERIOD)
	{
	  saved_token = t;
	}
      else
	{
	  t = format_lex ();
	  if (t != FMT_ZERO && t != FMT_POSINT)
	    {
	      error = nonneg_required;
	      goto syntax;
	    }
	}

      break;

    default:
      error = unexpected_element;
      goto syntax;
    }

between_desc:
  /* Between a descriptor and what comes next.  */
  t = format_lex ();
  switch (t)
    {

    case FMT_COMMA:
      goto format_item;

    case FMT_RPAREN:
      level--;
      if (level < 0)
	goto finished;
      goto between_desc;

    case FMT_COLON:
    case FMT_SLASH:
      goto optional_comma;

    case FMT_END:
      error = unexpected_end;
      goto syntax;

    default:
      error = "Missing comma";
      goto syntax;
    }

optional_comma:
  /* Optional comma is a weird between state where we've just finished
     reading a colon, slash or P descriptor.  */
  t = format_lex ();
  switch (t)
    {
    case FMT_COMMA:
      break;

    case FMT_RPAREN:
      level--;
      if (level < 0)
	goto finished;
      goto between_desc;

    default:
      /* Assume that we have another format item.  */
      saved_token = t;
      break;
    }

  goto format_item;

extension_optional_comma:
  /* As a GNU extension, permit a missing comma after a string literal.  */
  t = format_lex ();
  switch (t)
    {
    case FMT_COMMA:
      break;

    case FMT_RPAREN:
      level--;
      if (level < 0)
	goto finished;
      goto between_desc;

    case FMT_COLON:
    case FMT_SLASH:
      goto optional_comma;

    case FMT_END:
      error = unexpected_end;
      goto syntax;

    default:
      if (gfc_notify_std (GFC_STD_GNU, "Extension: Missing comma at %C")
	  == FAILURE)
	return FAILURE;
      saved_token = t;
      break;
    }

  goto format_item;

syntax:
  /* Something went wrong.  If the format we're checking is a string,
     generate a warning, since the program is correct.  If the format
     is in a FORMAT statement, this messes up parsing, which is an
     error.  */
  if (mode != MODE_STRING)
    gfc_error ("%s in format string at %C", error);
  else
    {
      gfc_warning ("%s in format string at %C", error);

      /* TODO: More elaborate measures are needed to show where a problem
         is within a format string that has been calculated.  */
    }

  rv = FAILURE;

finished:
  return rv;
}


/* Given an expression node that is a constant string, see if it looks
   like a format string.  */

static void
check_format_string (gfc_expr * e)
{

  mode = MODE_STRING;
  format_string = e->value.character.string;
  check_format ();
}


/************ Fortran 95 I/O statement matchers *************/

/* Match a FORMAT statement.  This amounts to actually parsing the
   format descriptors in order to correctly locate the end of the
   format string.  */

match
gfc_match_format (void)
{
  gfc_expr *e;
  locus start;

  if (gfc_statement_label == NULL)
    {
      gfc_error ("Missing format label at %C");
      return MATCH_ERROR;
    }
  gfc_gobble_whitespace ();

  mode = MODE_FORMAT;
  format_length = 0;

  start = gfc_current_locus;

  if (check_format () == FAILURE)
    return MATCH_ERROR;

  if (gfc_match_eos () != MATCH_YES)
    {
      gfc_syntax_error (ST_FORMAT);
      return MATCH_ERROR;
    }

  /* The label doesn't get created until after the statement is done
     being matched, so we have to leave the string for later.  */

  gfc_current_locus = start;	/* Back to the beginning */

  new_st.loc = start;
  new_st.op = EXEC_NOP;

  e = gfc_get_expr();
  e->expr_type = EXPR_CONSTANT;
  e->ts.type = BT_CHARACTER;
  e->ts.kind = gfc_default_character_kind;
  e->where = start;
  e->value.character.string = format_string = gfc_getmem(format_length+1);
  e->value.character.length = format_length;
  gfc_statement_label->format = e;

  mode = MODE_COPY;
  check_format ();		/* Guaranteed to succeed */
  gfc_match_eos ();		/* Guaranteed to succeed */

  return MATCH_YES;
}


/* Match an expression I/O tag of some sort.  */

static match
match_etag (const io_tag * tag, gfc_expr ** v)
{
  gfc_expr *result;
  match m;

  m = gfc_match (tag->spec, &result);
  if (m != MATCH_YES)
    return m;

  if (*v != NULL)
    {
      gfc_error ("Duplicate %s specification at %C", tag->name);
      gfc_free_expr (result);
      return MATCH_ERROR;
    }

  *v = result;
  return MATCH_YES;
}


/* Match a variable I/O tag of some sort.  */

static match
match_vtag (const io_tag * tag, gfc_expr ** v)
{
  gfc_expr *result;
  match m;

  m = gfc_match (tag->spec, &result);
  if (m != MATCH_YES)
    return m;

  if (*v != NULL)
    {
      gfc_error ("Duplicate %s specification at %C", tag->name);
      gfc_free_expr (result);
      return MATCH_ERROR;
    }

  if (result->symtree->n.sym->attr.intent == INTENT_IN)
    {
      gfc_error ("Variable tag cannot be INTENT(IN) at %C");
      gfc_free_expr (result);
      return MATCH_ERROR;
    }

  if (gfc_pure (NULL) && gfc_impure_variable (result->symtree->n.sym))
    {
      gfc_error ("Variable tag cannot be assigned in PURE procedure at %C");
      gfc_free_expr (result);
      return MATCH_ERROR;
    }

  *v = result;
  return MATCH_YES;
}


/* Match I/O tags that cause variables to become redefined.  */

static match
match_out_tag(const io_tag *tag, gfc_expr **result)
{
  match m;

  m = match_vtag(tag, result);
  if (m == MATCH_YES)
    gfc_check_do_variable((*result)->symtree);

  return m;
}


/* Match a label I/O tag.  */

static match
match_ltag (const io_tag * tag, gfc_st_label ** label)
{
  match m;
  gfc_st_label *old;

  old = *label;
  m = gfc_match (tag->spec, label);
  if (m == MATCH_YES && old != 0)
    {
      gfc_error ("Duplicate %s label specification at %C", tag->name);
      return MATCH_ERROR;
    }

  return m;
}


/* Do expression resolution and type-checking on an expression tag.  */

static try
resolve_tag (const io_tag * tag, gfc_expr * e)
{

  if (e == NULL)
    return SUCCESS;

  if (gfc_resolve_expr (e) == FAILURE)
    return FAILURE;

  if (e->ts.type != tag->type)
    {
      /* Format label can be integer varibale.  */
      if (tag != &tag_format || e->ts.type != BT_INTEGER)
        {
          gfc_error ("%s tag at %L must be of type %s or %s", tag->name,
		&e->where, gfc_basic_typename (tag->type),
		gfc_basic_typename (BT_INTEGER));
          return FAILURE;
        }
    }

  if (tag == &tag_format)
    {
      if (e->rank != 1 && e->rank != 0)
	{
	  gfc_error ("FORMAT tag at %L cannot be array of strings",
		     &e->where);
	  return FAILURE;
	}
      /* Check assigned label.  */
      if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_INTEGER
		&& e->symtree->n.sym->attr.assign != 1)
	{
	  gfc_error ("Variable '%s' has not been assigned a format label at %L",
			e->symtree->n.sym->name, &e->where);
	  return FAILURE;
	}
    }
  else
    {
      if (e->rank != 0)
	{
	  gfc_error ("%s tag at %L must be scalar", tag->name, &e->where);
	  return FAILURE;
	}
    }

  return SUCCESS;
}


/* Match a single tag of an OPEN statement.  */

static match
match_open_element (gfc_open * open)
{
  match m;

  m = match_etag (&tag_unit, &open->unit);
  if (m != MATCH_NO)
    return m;
  m = match_out_tag (&tag_iostat, &open->iostat);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_file, &open->file);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_status, &open->status);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_e_access, &open->access);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_e_form, &open->form);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_e_recl, &open->recl);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_e_blank, &open->blank);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_e_position, &open->position);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_e_action, &open->action);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_e_delim, &open->delim);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_e_pad, &open->pad);
  if (m != MATCH_NO)
    return m;
  m = match_ltag (&tag_err, &open->err);
  if (m != MATCH_NO)
    return m;

  return MATCH_NO;
}


/* Free the gfc_open structure and all the expressions it contains.  */

void
gfc_free_open (gfc_open * open)
{

  if (open == NULL)
    return;

  gfc_free_expr (open->unit);
  gfc_free_expr (open->iostat);
  gfc_free_expr (open->file);
  gfc_free_expr (open->status);
  gfc_free_expr (open->access);
  gfc_free_expr (open->form);
  gfc_free_expr (open->recl);
  gfc_free_expr (open->blank);
  gfc_free_expr (open->position);
  gfc_free_expr (open->action);
  gfc_free_expr (open->delim);
  gfc_free_expr (open->pad);

  gfc_free (open);
}


/* Resolve everything in a gfc_open structure.  */

try
gfc_resolve_open (gfc_open * open)
{

  RESOLVE_TAG (&tag_unit, open->unit);
  RESOLVE_TAG (&tag_iostat, open->iostat);
  RESOLVE_TAG (&tag_file, open->file);
  RESOLVE_TAG (&tag_status, open->status);
  RESOLVE_TAG (&tag_e_form, open->form);
  RESOLVE_TAG (&tag_e_recl, open->recl);

  RESOLVE_TAG (&tag_e_blank, open->blank);
  RESOLVE_TAG (&tag_e_position, open->position);
  RESOLVE_TAG (&tag_e_action, open->action);
  RESOLVE_TAG (&tag_e_delim, open->delim);
  RESOLVE_TAG (&tag_e_pad, open->pad);

  if (gfc_reference_st_label (open->err, ST_LABEL_TARGET) == FAILURE)
    return FAILURE;

  return SUCCESS;
}


/* Match an OPEN statement.  */

match
gfc_match_open (void)
{
  gfc_open *open;
  match m;

  m = gfc_match_char ('(');
  if (m == MATCH_NO)
    return m;

  open = gfc_getmem (sizeof (gfc_open));

  m = match_open_element (open);

  if (m == MATCH_ERROR)
    goto cleanup;
  if (m == MATCH_NO)
    {
      m = gfc_match_expr (&open->unit);
      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	goto cleanup;
    }

  for (;;)
    {
      if (gfc_match_char (')') == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;

      m = match_open_element (open);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;
    }

  if (gfc_match_eos () == MATCH_NO)
    goto syntax;

  if (gfc_pure (NULL))
    {
      gfc_error ("OPEN statement not allowed in PURE procedure at %C");
      goto cleanup;
    }

  new_st.op = EXEC_OPEN;
  new_st.ext.open = open;
  return MATCH_YES;

syntax:
  gfc_syntax_error (ST_OPEN);

cleanup:
  gfc_free_open (open);
  return MATCH_ERROR;
}


/* Free a gfc_close structure an all its expressions.  */

void
gfc_free_close (gfc_close * close)
{

  if (close == NULL)
    return;

  gfc_free_expr (close->unit);
  gfc_free_expr (close->iostat);
  gfc_free_expr (close->status);

  gfc_free (close);
}


/* Match elements of a CLOSE statement.  */

static match
match_close_element (gfc_close * close)
{
  match m;

  m = match_etag (&tag_unit, &close->unit);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_status, &close->status);
  if (m != MATCH_NO)
    return m;
  m = match_out_tag (&tag_iostat, &close->iostat);
  if (m != MATCH_NO)
    return m;
  m = match_ltag (&tag_err, &close->err);
  if (m != MATCH_NO)
    return m;

  return MATCH_NO;
}


/* Match a CLOSE statement.  */

match
gfc_match_close (void)
{
  gfc_close *close;
  match m;

  m = gfc_match_char ('(');
  if (m == MATCH_NO)
    return m;

  close = gfc_getmem (sizeof (gfc_close));

  m = match_close_element (close);

  if (m == MATCH_ERROR)
    goto cleanup;
  if (m == MATCH_NO)
    {
      m = gfc_match_expr (&close->unit);
      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	goto cleanup;
    }

  for (;;)
    {
      if (gfc_match_char (')') == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;

      m = match_close_element (close);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;
    }

  if (gfc_match_eos () == MATCH_NO)
    goto syntax;

  if (gfc_pure (NULL))
    {
      gfc_error ("CLOSE statement not allowed in PURE procedure at %C");
      goto cleanup;
    }

  new_st.op = EXEC_CLOSE;
  new_st.ext.close = close;
  return MATCH_YES;

syntax:
  gfc_syntax_error (ST_CLOSE);

cleanup:
  gfc_free_close (close);
  return MATCH_ERROR;
}


/* Resolve everything in a gfc_close structure.  */

try
gfc_resolve_close (gfc_close * close)
{

  RESOLVE_TAG (&tag_unit, close->unit);
  RESOLVE_TAG (&tag_iostat, close->iostat);
  RESOLVE_TAG (&tag_status, close->status);

  if (gfc_reference_st_label (close->err, ST_LABEL_TARGET) == FAILURE)
    return FAILURE;

  return SUCCESS;
}


/* Free a gfc_filepos structure.  */

void
gfc_free_filepos (gfc_filepos * fp)
{

  gfc_free_expr (fp->unit);
  gfc_free_expr (fp->iostat);
  gfc_free (fp);
}


/* Match elements of a REWIND, BACKSPACE or ENDFILE statement.  */

static match
match_file_element (gfc_filepos * fp)
{
  match m;

  m = match_etag (&tag_unit, &fp->unit);
  if (m != MATCH_NO)
    return m;
  m = match_out_tag (&tag_iostat, &fp->iostat);
  if (m != MATCH_NO)
    return m;
  m = match_ltag (&tag_err, &fp->err);
  if (m != MATCH_NO)
    return m;

  return MATCH_NO;
}


/* Match the second half of the file-positioning statements, REWIND,
   BACKSPACE or ENDFILE.  */

static match
match_filepos (gfc_statement st, gfc_exec_op op)
{
  gfc_filepos *fp;
  match m;

  fp = gfc_getmem (sizeof (gfc_filepos));

  if (gfc_match_char ('(') == MATCH_NO)
    {
      m = gfc_match_expr (&fp->unit);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;

      goto done;
    }

  m = match_file_element (fp);
  if (m == MATCH_ERROR)
    goto done;
  if (m == MATCH_NO)
    {
      m = gfc_match_expr (&fp->unit);
      if (m == MATCH_ERROR)
	goto done;
      if (m == MATCH_NO)
	goto syntax;
    }

  for (;;)
    {
      if (gfc_match_char (')') == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;

      m = match_file_element (fp);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;
    }

done:
  if (gfc_match_eos () != MATCH_YES)
    goto syntax;

  if (gfc_pure (NULL))
    {
      gfc_error ("%s statement not allowed in PURE procedure at %C",
		 gfc_ascii_statement (st));

      goto cleanup;
    }

  new_st.op = op;
  new_st.ext.filepos = fp;
  return MATCH_YES;

syntax:
  gfc_syntax_error (st);

cleanup:
  gfc_free_filepos (fp);
  return MATCH_ERROR;
}


try
gfc_resolve_filepos (gfc_filepos * fp)
{

  RESOLVE_TAG (&tag_unit, fp->unit);
  if (gfc_reference_st_label (fp->err, ST_LABEL_TARGET) == FAILURE)
    return FAILURE;

  return SUCCESS;
}


/* Match the file positioning statements: ENDFILE, BACKSPACE or
   REWIND.  */

match
gfc_match_endfile (void)
{

  return match_filepos (ST_END_FILE, EXEC_ENDFILE);
}

match
gfc_match_backspace (void)
{

  return match_filepos (ST_BACKSPACE, EXEC_BACKSPACE);
}

match
gfc_match_rewind (void)
{

  return match_filepos (ST_REWIND, EXEC_REWIND);
}


/******************** Data Transfer Statements *********************/

typedef enum
{ M_READ, M_WRITE, M_PRINT, M_INQUIRE }
io_kind;


/* Return a default unit number.  */

static gfc_expr *
default_unit (io_kind k)
{
  int unit;

  if (k == M_READ)
    unit = 5;
  else
    unit = 6;

  return gfc_int_expr (unit);
}


/* Match a unit specification for a data transfer statement.  */

static match
match_dt_unit (io_kind k, gfc_dt * dt)
{
  gfc_expr *e;

  if (gfc_match_char ('*') == MATCH_YES)
    {
      if (dt->io_unit != NULL)
	goto conflict;

      dt->io_unit = default_unit (k);
      return MATCH_YES;
    }

  if (gfc_match_expr (&e) == MATCH_YES)
    {
      if (dt->io_unit != NULL)
	{
	  gfc_free_expr (e);
	  goto conflict;
	}

      dt->io_unit = e;
      return MATCH_YES;
    }

  return MATCH_NO;

conflict:
  gfc_error ("Duplicate UNIT specification at %C");
  return MATCH_ERROR;
}


/* Match a format specification.  */

static match
match_dt_format (gfc_dt * dt)
{
  locus where;
  gfc_expr *e;
  gfc_st_label *label;

  where = gfc_current_locus;

  if (gfc_match_char ('*') == MATCH_YES)
    {
      if (dt->format_expr != NULL || dt->format_label != NULL)
	goto conflict;

      dt->format_label = &format_asterisk;
      return MATCH_YES;
    }

  if (gfc_match_st_label (&label, 0) == MATCH_YES)
    {
      if (dt->format_expr != NULL || dt->format_label != NULL)
	{
	  gfc_free_st_label (label);
	  goto conflict;
	}

      if (gfc_reference_st_label (label, ST_LABEL_FORMAT) == FAILURE)
	return MATCH_ERROR;

      dt->format_label = label;
      return MATCH_YES;
    }

  if (gfc_match_expr (&e) == MATCH_YES)
    {
      if (dt->format_expr != NULL || dt->format_label != NULL)
	{
	  gfc_free_expr (e);
	  goto conflict;
	}
      dt->format_expr = e;
      return MATCH_YES;
    }

  gfc_current_locus = where;	/* The only case where we have to restore */

  return MATCH_NO;

conflict:
  gfc_error ("Duplicate format specification at %C");
  return MATCH_ERROR;
}


/* Traverse a namelist that is part of a READ statement to make sure
   that none of the variables in the namelist are INTENT(IN).  Returns
   nonzero if we find such a variable.  */

static int
check_namelist (gfc_symbol * sym)
{
  gfc_namelist *p;

  for (p = sym->namelist; p; p = p->next)
    if (p->sym->attr.intent == INTENT_IN)
      {
	gfc_error ("Symbol '%s' in namelist '%s' is INTENT(IN) at %C",
		   p->sym->name, sym->name);
	return 1;
      }

  return 0;
}


/* Match a single data transfer element.  */

static match
match_dt_element (io_kind k, gfc_dt * dt)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  match m;

  if (gfc_match (" unit =") == MATCH_YES)
    {
      m = match_dt_unit (k, dt);
      if (m != MATCH_NO)
	return m;
    }

  if (gfc_match (" fmt =") == MATCH_YES)
    {
      m = match_dt_format (dt);
      if (m != MATCH_NO)
	return m;
    }

  if (gfc_match (" nml = %n", name) == MATCH_YES)
    {
      if (dt->namelist != NULL)
	{
	  gfc_error ("Duplicate NML specification at %C");
	  return MATCH_ERROR;
	}

      if (gfc_find_symbol (name, NULL, 1, &sym))
	return MATCH_ERROR;

      if (sym == NULL || sym->attr.flavor != FL_NAMELIST)
	{
	  gfc_error ("Symbol '%s' at %C must be a NAMELIST group name",
		     sym != NULL ? sym->name : name);
	  return MATCH_ERROR;
	}

      dt->namelist = sym;
      if (k == M_READ && check_namelist (sym))
	return MATCH_ERROR;

      return MATCH_YES;
    }

  m = match_etag (&tag_rec, &dt->rec);
  if (m != MATCH_NO)
    return m;
  m = match_out_tag (&tag_iostat, &dt->iostat);
  if (m != MATCH_NO)
    return m;
  m = match_ltag (&tag_err, &dt->err);
  if (m != MATCH_NO)
    return m;
  m = match_etag (&tag_advance, &dt->advance);
  if (m != MATCH_NO)
    return m;
  m = match_out_tag (&tag_size, &dt->size);
  if (m != MATCH_NO)
    return m;

  m = match_ltag (&tag_end, &dt->end);
  if (m == MATCH_YES)
    dt->end_where = gfc_current_locus;
  if (m != MATCH_NO)
    return m;

  m = match_ltag (&tag_eor, &dt->eor);
  if (m == MATCH_YES)
    dt->eor_where = gfc_current_locus;
  if (m != MATCH_NO)
    return m;

  return MATCH_NO;
}


/* Free a data transfer structure and everything below it.  */

void
gfc_free_dt (gfc_dt * dt)
{

  if (dt == NULL)
    return;

  gfc_free_expr (dt->io_unit);
  gfc_free_expr (dt->format_expr);
  gfc_free_expr (dt->rec);
  gfc_free_expr (dt->advance);
  gfc_free_expr (dt->iostat);
  gfc_free_expr (dt->size);

  gfc_free (dt);
}


/* Resolve everything in a gfc_dt structure.  */

try
gfc_resolve_dt (gfc_dt * dt)
{
  gfc_expr *e;

  RESOLVE_TAG (&tag_format, dt->format_expr);
  RESOLVE_TAG (&tag_rec, dt->rec);
  RESOLVE_TAG (&tag_advance, dt->advance);
  RESOLVE_TAG (&tag_iostat, dt->iostat);
  RESOLVE_TAG (&tag_size, dt->size);

  e = dt->io_unit;
  if (gfc_resolve_expr (e) == SUCCESS
      && (e->ts.type != BT_INTEGER
	  && (e->ts.type != BT_CHARACTER
	      || e->expr_type != EXPR_VARIABLE)))
    {
      gfc_error
	("UNIT specification at %L must be an INTEGER expression or a "
	 "CHARACTER variable", &e->where);
      return FAILURE;
    }

  /* Sanity checks on data transfer statements.  */
  if (e->ts.type == BT_CHARACTER)
    {
      if (dt->rec != NULL)
	{
	  gfc_error ("REC tag at %L is incompatible with internal file",
		     &dt->rec->where);
	  return FAILURE;
	}

      if (dt->namelist != NULL)
	{
	  gfc_error ("Internal file at %L is incompatible with namelist",
		     &dt->io_unit->where);
	  return FAILURE;
	}

      if (dt->advance != NULL)
	{
	  gfc_error ("ADVANCE tag at %L is incompatible with internal file",
		     &dt->advance->where);
	  return FAILURE;
	}
    }

  if (dt->rec != NULL)
    {
      if (dt->end != NULL)
	{
	  gfc_error ("REC tag at %L is incompatible with END tag",
		     &dt->rec->where);
	  return FAILURE;
	}

      if (dt->format_label == &format_asterisk)
	{
	  gfc_error
	    ("END tag at %L is incompatible with list directed format (*)",
	     &dt->end_where);
	  return FAILURE;
	}

      if (dt->namelist != NULL)
	{
	  gfc_error ("REC tag at %L is incompatible with namelist",
		     &dt->rec->where);
	  return FAILURE;
	}
    }

  if (dt->advance != NULL && dt->format_label == &format_asterisk)
    {
      gfc_error ("ADVANCE tag at %L is incompatible with list directed "
		 "format (*)", &dt->advance->where);
      return FAILURE;
    }

  if (dt->eor != 0 && dt->advance == NULL)
    {
      gfc_error ("EOR tag at %L requires an ADVANCE tag", &dt->eor_where);
      return FAILURE;
    }

  if (dt->size != NULL && dt->advance == NULL)
    {
      gfc_error ("SIZE tag at %L requires an ADVANCE tag", &dt->size->where);
      return FAILURE;
    }

  /* TODO: Make sure the ADVANCE tag is 'yes' or 'no' if it is a string
     constant.  */

  if (gfc_reference_st_label (dt->err, ST_LABEL_TARGET) == FAILURE)
    return FAILURE;

  if (gfc_reference_st_label (dt->end, ST_LABEL_TARGET) == FAILURE)
    return FAILURE;

  if (gfc_reference_st_label (dt->eor, ST_LABEL_TARGET) == FAILURE)
    return FAILURE;

  /* Check the format label actually exists.  */
  if (dt->format_label && dt->format_label != &format_asterisk
      && dt->format_label->defined == ST_LABEL_UNKNOWN)
    {
      gfc_error ("FORMAT label %d at %L not defined", dt->format_label->value,
	         &dt->format_label->where);
      return FAILURE;
    }
  return SUCCESS;
}


/* Given an io_kind, return its name.  */

static const char *
io_kind_name (io_kind k)
{
  const char *name;

  switch (k)
    {
    case M_READ:
      name = "READ";
      break;
    case M_WRITE:
      name = "WRITE";
      break;
    case M_PRINT:
      name = "PRINT";
      break;
    case M_INQUIRE:
      name = "INQUIRE";
      break;
    default:
      gfc_internal_error ("io_kind_name(): bad I/O-kind");
    }

  return name;
}


/* Match an IO iteration statement of the form:

   ( [<IO element> ,] <IO element>, I = <expr>, <expr> [, <expr> ] )

   which is equivalent to a single IO element.  This function is
   mutually recursive with match_io_element().  */

static match match_io_element (io_kind k, gfc_code **);

static match
match_io_iterator (io_kind k, gfc_code ** result)
{
  gfc_code *head, *tail, *new;
  gfc_iterator *iter;
  locus old_loc;
  match m;
  int n;

  iter = NULL;
  head = NULL;
  old_loc = gfc_current_locus;

  if (gfc_match_char ('(') != MATCH_YES)
    return MATCH_NO;

  m = match_io_element (k, &head);
  tail = head;

  if (m != MATCH_YES || gfc_match_char (',') != MATCH_YES)
    {
      m = MATCH_NO;
      goto cleanup;
    }

  /* Can't be anything but an IO iterator.  Build a list.  */
  iter = gfc_get_iterator ();

  for (n = 1;; n++)
    {
      m = gfc_match_iterator (iter, 0);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_YES)
	{
	  gfc_check_do_variable (iter->var->symtree);
	  break;
	}

      m = match_io_element (k, &new);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	{
	  if (n > 2)
	    goto syntax;
	  goto cleanup;
	}

      tail = gfc_append_code (tail, new);

      if (gfc_match_char (',') != MATCH_YES)
	{
	  if (n > 2)
	    goto syntax;
	  m = MATCH_NO;
	  goto cleanup;
	}
    }

  if (gfc_match_char (')') != MATCH_YES)
    goto syntax;

  new = gfc_get_code ();
  new->op = EXEC_DO;
  new->ext.iterator = iter;

  new->block = gfc_get_code ();
  new->block->op = EXEC_DO;
  new->block->next = head;

  *result = new;
  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in I/O iterator at %C");
  m = MATCH_ERROR;

cleanup:
  gfc_free_iterator (iter, 1);
  gfc_free_statements (head);
  gfc_current_locus = old_loc;
  return m;
}


/* Match a single element of an IO list, which is either a single
   expression or an IO Iterator.  */

static match
match_io_element (io_kind k, gfc_code ** cpp)
{
  gfc_expr *expr;
  gfc_code *cp;
  match m;

  expr = NULL;

  m = match_io_iterator (k, cpp);
  if (m == MATCH_YES)
    return MATCH_YES;

  if (k == M_READ)
    {
      m = gfc_match_variable (&expr, 0);
      if (m == MATCH_NO)
	gfc_error ("Expected variable in READ statement at %C");
    }
  else
    {
      m = gfc_match_expr (&expr);
      if (m == MATCH_NO)
	gfc_error ("Expected expression in %s statement at %C",
		   io_kind_name (k));
    }

  if (m == MATCH_YES)
    switch (k)
      {
      case M_READ:
	if (expr->symtree->n.sym->attr.intent == INTENT_IN)
	  {
	    gfc_error
	      ("Variable '%s' in input list at %C cannot be INTENT(IN)",
	       expr->symtree->n.sym->name);
	    m = MATCH_ERROR;
	  }

	if (gfc_pure (NULL)
	    && gfc_impure_variable (expr->symtree->n.sym)
	    && current_dt->io_unit->ts.type == BT_CHARACTER)
	  {
	    gfc_error ("Cannot read to variable '%s' in PURE procedure at %C",
		       expr->symtree->n.sym->name);
	    m = MATCH_ERROR;
	  }

	if (gfc_check_do_variable (expr->symtree))
	  m = MATCH_ERROR;

	break;

      case M_WRITE:
	if (current_dt->io_unit->ts.type == BT_CHARACTER
	    && gfc_pure (NULL)
	    && current_dt->io_unit->expr_type == EXPR_VARIABLE
	    && gfc_impure_variable (current_dt->io_unit->symtree->n.sym))
	  {
	    gfc_error
	      ("Cannot write to internal file unit '%s' at %C inside a "
	       "PURE procedure", current_dt->io_unit->symtree->n.sym->name);
	    m = MATCH_ERROR;
	  }

	break;

      default:
	break;
      }

  if (m != MATCH_YES)
    {
      gfc_free_expr (expr);
      return MATCH_ERROR;
    }

  cp = gfc_get_code ();
  cp->op = EXEC_TRANSFER;
  cp->expr = expr;

  *cpp = cp;
  return MATCH_YES;
}


/* Match an I/O list, building gfc_code structures as we go.  */

static match
match_io_list (io_kind k, gfc_code ** head_p)
{
  gfc_code *head, *tail, *new;
  match m;

  *head_p = head = tail = NULL;
  if (gfc_match_eos () == MATCH_YES)
    return MATCH_YES;

  for (;;)
    {
      m = match_io_element (k, &new);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;

      tail = gfc_append_code (tail, new);
      if (head == NULL)
	head = new;

      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  *head_p = head;
  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in %s statement at %C", io_kind_name (k));

cleanup:
  gfc_free_statements (head);
  return MATCH_ERROR;
}


/* Attach the data transfer end node.  */

static void
terminate_io (gfc_code * io_code)
{
  gfc_code *c;

  if (io_code == NULL)
    io_code = &new_st;

  c = gfc_get_code ();
  c->op = EXEC_DT_END;

  /* Point to structure that is already there */
  c->ext.dt = new_st.ext.dt;
  gfc_append_code (io_code, c);
}


/* Match a READ, WRITE or PRINT statement.  */

static match
match_io (io_kind k)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_code *io_code;
  gfc_symbol *sym;
  gfc_expr *expr;
  int comma_flag, c;
  locus where;
  gfc_dt *dt;
  match m;

  comma_flag = 0;
  current_dt = dt = gfc_getmem (sizeof (gfc_dt));

  if (gfc_match_char ('(') == MATCH_NO)
    {
      if (k == M_WRITE)
	goto syntax;

      if (gfc_current_form == FORM_FREE)
       {
         c = gfc_peek_char();
         if (c != ' ' && c != '*' && c != '\'' && c != '"')
           {
             m = MATCH_NO;
             goto cleanup;
           }
       }

      m = match_dt_format (dt);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;

      comma_flag = 1;
      dt->io_unit = default_unit (k);
      goto get_io_list;
    }

  /* Match a control list */
  if (match_dt_element (k, dt) == MATCH_YES)
    goto next;
  if (match_dt_unit (k, dt) != MATCH_YES)
    goto loop;

  if (gfc_match_char (')') == MATCH_YES)
    goto get_io_list;
  if (gfc_match_char (',') != MATCH_YES)
    goto syntax;

  m = match_dt_element (k, dt);
  if (m == MATCH_YES)
    goto next;
  if (m == MATCH_ERROR)
    goto cleanup;

  m = match_dt_format (dt);
  if (m == MATCH_YES)
    goto next;
  if (m == MATCH_ERROR)
    goto cleanup;

  where = gfc_current_locus;

  if (gfc_match_name (name) == MATCH_YES
      && !gfc_find_symbol (name, NULL, 1, &sym)
      && sym->attr.flavor == FL_NAMELIST)
    {
      dt->namelist = sym;
      if (k == M_READ && check_namelist (sym))
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}
      goto next;
    }

  gfc_current_locus = where;

  goto loop;			/* No matches, try regular elements */

next:
  if (gfc_match_char (')') == MATCH_YES)
    goto get_io_list;
  if (gfc_match_char (',') != MATCH_YES)
    goto syntax;

loop:
  for (;;)
    {
      m = match_dt_element (k, dt);
      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	goto cleanup;

      if (gfc_match_char (')') == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

get_io_list:
  /* Optional leading comma (non-standard).  */
  if (!comma_flag
      && gfc_match_char (',') == MATCH_YES
      && k == M_WRITE
      && gfc_notify_std (GFC_STD_GNU, "Extension: Comma before output "
			 "item list at %C is an extension") == FAILURE)
    return MATCH_ERROR;

  io_code = NULL;
  if (gfc_match_eos () != MATCH_YES)
    {
      if (comma_flag && gfc_match_char (',') != MATCH_YES)
	{
	  gfc_error ("Expected comma in I/O list at %C");
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      m = match_io_list (k, &io_code);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;
    }

  /* A full IO statement has been matched.  */
  if (dt->io_unit->expr_type == EXPR_VARIABLE
      && k == M_WRITE
      && dt->io_unit->ts.type == BT_CHARACTER
      && dt->io_unit->symtree->n.sym->attr.intent == INTENT_IN)
    {
      gfc_error ("Internal file '%s' at %L is INTENT(IN)",
		 dt->io_unit->symtree->n.sym->name, &dt->io_unit->where);
      m = MATCH_ERROR;
      goto cleanup;
    }

  expr = dt->format_expr;

  if (expr != NULL && expr->expr_type == EXPR_CONSTANT)
    check_format_string (expr);

  if (gfc_pure (NULL)
      && (k == M_READ || k == M_WRITE)
      && dt->io_unit->ts.type != BT_CHARACTER)
    {
      gfc_error
	("io-unit in %s statement at %C must be an internal file in a "
	 "PURE procedure", io_kind_name (k));
      m = MATCH_ERROR;
      goto cleanup;
    }

  new_st.op = (k == M_READ) ? EXEC_READ : EXEC_WRITE;
  new_st.ext.dt = dt;
  new_st.next = io_code;

  terminate_io (io_code);

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in %s statement at %C", io_kind_name (k));
  m = MATCH_ERROR;

cleanup:
  gfc_free_dt (dt);
  return m;
}


match
gfc_match_read (void)
{
  return match_io (M_READ);
}

match
gfc_match_write (void)
{
  return match_io (M_WRITE);
}

match
gfc_match_print (void)
{
  match m;

  m = match_io (M_PRINT);
  if (m != MATCH_YES)
    return m;

  if (gfc_pure (NULL))
    {
      gfc_error ("PRINT statement at %C not allowed within PURE procedure");
      return MATCH_ERROR;
    }

  return MATCH_YES;
}


/* Free a gfc_inquire structure.  */

void
gfc_free_inquire (gfc_inquire * inquire)
{

  if (inquire == NULL)
    return;

  gfc_free_expr (inquire->unit);
  gfc_free_expr (inquire->file);
  gfc_free_expr (inquire->iostat);
  gfc_free_expr (inquire->exist);
  gfc_free_expr (inquire->opened);
  gfc_free_expr (inquire->number);
  gfc_free_expr (inquire->named);
  gfc_free_expr (inquire->name);
  gfc_free_expr (inquire->access);
  gfc_free_expr (inquire->sequential);
  gfc_free_expr (inquire->direct);
  gfc_free_expr (inquire->form);
  gfc_free_expr (inquire->formatted);
  gfc_free_expr (inquire->unformatted);
  gfc_free_expr (inquire->recl);
  gfc_free_expr (inquire->nextrec);
  gfc_free_expr (inquire->blank);
  gfc_free_expr (inquire->position);
  gfc_free_expr (inquire->action);
  gfc_free_expr (inquire->read);
  gfc_free_expr (inquire->write);
  gfc_free_expr (inquire->readwrite);
  gfc_free_expr (inquire->delim);
  gfc_free_expr (inquire->pad);
  gfc_free_expr (inquire->iolength);

  gfc_free (inquire);
}


/* Match an element of an INQUIRE statement.  */

#define RETM   if (m != MATCH_NO) return m;

static match
match_inquire_element (gfc_inquire * inquire)
{
  match m;

  m = match_etag (&tag_unit, &inquire->unit);
  RETM m = match_etag (&tag_file, &inquire->file);
  RETM m = match_ltag (&tag_err, &inquire->err);
  RETM m = match_out_tag (&tag_iostat, &inquire->iostat);
  RETM m = match_vtag (&tag_exist, &inquire->exist);
  RETM m = match_vtag (&tag_opened, &inquire->opened);
  RETM m = match_vtag (&tag_named, &inquire->named);
  RETM m = match_vtag (&tag_name, &inquire->name);
  RETM m = match_out_tag (&tag_number, &inquire->number);
  RETM m = match_vtag (&tag_s_access, &inquire->access);
  RETM m = match_vtag (&tag_sequential, &inquire->sequential);
  RETM m = match_vtag (&tag_direct, &inquire->direct);
  RETM m = match_vtag (&tag_s_form, &inquire->form);
  RETM m = match_vtag (&tag_formatted, &inquire->formatted);
  RETM m = match_vtag (&tag_unformatted, &inquire->unformatted);
  RETM m = match_out_tag (&tag_s_recl, &inquire->recl);
  RETM m = match_out_tag (&tag_nextrec, &inquire->nextrec);
  RETM m = match_vtag (&tag_s_blank, &inquire->blank);
  RETM m = match_vtag (&tag_s_position, &inquire->position);
  RETM m = match_vtag (&tag_s_action, &inquire->action);
  RETM m = match_vtag (&tag_read, &inquire->read);
  RETM m = match_vtag (&tag_write, &inquire->write);
  RETM m = match_vtag (&tag_readwrite, &inquire->readwrite);
  RETM m = match_vtag (&tag_s_delim, &inquire->delim);
  RETM m = match_vtag (&tag_s_pad, &inquire->pad);
  RETM m = match_vtag (&tag_iolength, &inquire->iolength);
  RETM return MATCH_NO;
}

#undef RETM


match
gfc_match_inquire (void)
{
  gfc_inquire *inquire;
  gfc_code *code;
  match m;
  locus loc;

  m = gfc_match_char ('(');
  if (m == MATCH_NO)
    return m;

  inquire = gfc_getmem (sizeof (gfc_inquire));

  loc = gfc_current_locus;

  m = match_inquire_element (inquire);
  if (m == MATCH_ERROR)
    goto cleanup;
  if (m == MATCH_NO)
    {
      m = gfc_match_expr (&inquire->unit);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;
    }

  /* See if we have the IOLENGTH form of the inquire statement.  */
  if (inquire->iolength != NULL)
    {
      if (gfc_match_char (')') != MATCH_YES)
	goto syntax;

      m = match_io_list (M_INQUIRE, &code);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;

      terminate_io (code);

      new_st.op = EXEC_IOLENGTH;
      new_st.expr = inquire->iolength;
      new_st.ext.inquire = inquire;

      if (gfc_pure (NULL))
	{
	  gfc_free_statements (code);
	  gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
	  return MATCH_ERROR;
	}

      new_st.next = code;
      return MATCH_YES;
    }

  /* At this point, we have the non-IOLENGTH inquire statement.  */
  for (;;)
    {
      if (gfc_match_char (')') == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;

      m = match_inquire_element (inquire);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	goto syntax;

      if (inquire->iolength != NULL)
	{
	  gfc_error ("IOLENGTH tag invalid in INQUIRE statement at %C");
	  goto cleanup;
	}
    }

  if (gfc_match_eos () != MATCH_YES)
    goto syntax;

  if (inquire->unit != NULL && inquire->file != NULL)
    {
      gfc_error ("INQUIRE statement at %L cannot contain both FILE and"
		 " UNIT specifiers", &loc);
      goto cleanup;
    }

  if (inquire->unit == NULL && inquire->file == NULL)
    {
      gfc_error ("INQUIRE statement at %L requires either FILE or"
		     " UNIT specifier", &loc);
      goto cleanup;
    }

  if (gfc_pure (NULL))
    {
      gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
      goto cleanup;
    }

  new_st.op = EXEC_INQUIRE;
  new_st.ext.inquire = inquire;
  return MATCH_YES;

syntax:
  gfc_syntax_error (ST_INQUIRE);

cleanup:
  gfc_free_inquire (inquire);
  return MATCH_ERROR;
}


/* Resolve everything in a gfc_inquire structure.  */

try
gfc_resolve_inquire (gfc_inquire * inquire)
{

  RESOLVE_TAG (&tag_unit, inquire->unit);
  RESOLVE_TAG (&tag_file, inquire->file);
  RESOLVE_TAG (&tag_iostat, inquire->iostat);
  RESOLVE_TAG (&tag_exist, inquire->exist);
  RESOLVE_TAG (&tag_opened, inquire->opened);
  RESOLVE_TAG (&tag_number, inquire->number);
  RESOLVE_TAG (&tag_named, inquire->named);
  RESOLVE_TAG (&tag_name, inquire->name);
  RESOLVE_TAG (&tag_s_access, inquire->access);
  RESOLVE_TAG (&tag_sequential, inquire->sequential);
  RESOLVE_TAG (&tag_direct, inquire->direct);
  RESOLVE_TAG (&tag_s_form, inquire->form);
  RESOLVE_TAG (&tag_formatted, inquire->formatted);
  RESOLVE_TAG (&tag_unformatted, inquire->unformatted);
  RESOLVE_TAG (&tag_s_recl, inquire->recl);
  RESOLVE_TAG (&tag_nextrec, inquire->nextrec);
  RESOLVE_TAG (&tag_s_blank, inquire->blank);
  RESOLVE_TAG (&tag_s_position, inquire->position);
  RESOLVE_TAG (&tag_s_action, inquire->action);
  RESOLVE_TAG (&tag_read, inquire->read);
  RESOLVE_TAG (&tag_write, inquire->write);
  RESOLVE_TAG (&tag_readwrite, inquire->readwrite);
  RESOLVE_TAG (&tag_s_delim, inquire->delim);
  RESOLVE_TAG (&tag_s_pad, inquire->pad);
  RESOLVE_TAG (&tag_iolength, inquire->iolength);

  if (gfc_reference_st_label (inquire->err, ST_LABEL_TARGET) == FAILURE)
    return FAILURE;

  return SUCCESS;
}
