/* Copyright (C) 2002-2025 Free Software Foundation, Inc.
   Contributed by Andy Vaught
   Namelist input contributed by Paul Thomas
   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"
#include <string.h>

typedef unsigned char uchar;


/* List directed input.  Several parsing subroutines are practically
   reimplemented from formatted input, the reason being that there are
   all kinds of small differences between formatted and list directed
   parsing.  */


/* Subroutines for reading characters from the input.  Because a
   repeat count is ambiguous with an integer, we have to read the
   whole digit string before seeing if there is a '*' which signals
   the repeat count.  Since we can have a lot of potential leading
   zeros, we have to be able to back up by arbitrary amount.  Because
   the input might not be seekable, we have to buffer the data
   ourselves.  */

#define CASE_DIGITS   case '0': case '1': case '2': case '3': case '4': \
                      case '5': case '6': case '7': case '8': case '9'

#define CASE_SEPARATORS /* Fall through. */ \
			case ' ': case ',': case '/': case '\n': \
			case '\t': case '\r': case ';'

/* This macro assumes that we're operating on a variable.  */

#define is_separator(c) (c == '/' ||  c == ',' || c == '\n' || c == ' ' \
                         || c == '\t' || c == '\r' || c == ';' || \
			 (dtp->u.p.namelist_mode && c == '!'))

/* Maximum repeat count.  Less than ten times the maximum signed int32.  */

#define MAX_REPEAT 200000000

/* Wrappers for calling the current worker functions.  */

#define next_char(dtp) ((dtp)->u.p.current_unit->next_char_fn_ptr (dtp))
#define push_char(dtp, c) ((dtp)->u.p.current_unit->push_char_fn_ptr (dtp, c))

/* Worker function to save a default KIND=1 character to a string
   buffer, enlarging it as necessary.  */

static void
push_char_default (st_parameter_dt *dtp, int c)
{


  if (dtp->u.p.saved_string == NULL)
    {
      /* Plain malloc should suffice here, zeroing not needed?  */
      dtp->u.p.saved_string = xcalloc (SCRATCH_SIZE, 1);
      dtp->u.p.saved_length = SCRATCH_SIZE;
      dtp->u.p.saved_used = 0;
    }

  if (dtp->u.p.saved_used >= dtp->u.p.saved_length)
    {
      dtp->u.p.saved_length = 2 * dtp->u.p.saved_length;
      dtp->u.p.saved_string =
	xrealloc (dtp->u.p.saved_string, dtp->u.p.saved_length);
    }

  dtp->u.p.saved_string[dtp->u.p.saved_used++] = (char) c;
}


/* Worker function to save a KIND=4 character to a string buffer,
   enlarging the buffer as necessary.  */
static void
push_char4 (st_parameter_dt *dtp, int c)
{
  gfc_char4_t *p = (gfc_char4_t *) dtp->u.p.saved_string;

  if (p == NULL)
    {
      dtp->u.p.saved_string = xcalloc (SCRATCH_SIZE, sizeof (gfc_char4_t));
      dtp->u.p.saved_length = SCRATCH_SIZE;
      dtp->u.p.saved_used = 0;
      p = (gfc_char4_t *) dtp->u.p.saved_string;
    }

  if (dtp->u.p.saved_used >= dtp->u.p.saved_length)
    {
      dtp->u.p.saved_length = 2 * dtp->u.p.saved_length;
      dtp->u.p.saved_string =
	xrealloc (dtp->u.p.saved_string,
		  dtp->u.p.saved_length * sizeof (gfc_char4_t));
      p = (gfc_char4_t *) dtp->u.p.saved_string;
    }

  p[dtp->u.p.saved_used++] = c;
}


/* Free the input buffer if necessary.  */

static void
free_saved (st_parameter_dt *dtp)
{
  if (dtp->u.p.saved_string == NULL)
    return;

  free (dtp->u.p.saved_string);

  dtp->u.p.saved_string = NULL;
  dtp->u.p.saved_used = 0;
}


/* Free the line buffer if necessary.  */

static void
free_line (st_parameter_dt *dtp)
{
  dtp->u.p.line_buffer_pos = 0;
  dtp->u.p.line_buffer_enabled = 0;

  if (dtp->u.p.line_buffer == NULL)
    return;

  free (dtp->u.p.line_buffer);
  dtp->u.p.line_buffer = NULL;
}


/* Unget saves the last character so when reading the next character,
   we need to check to see if there is a character waiting.  Similar,
   if the line buffer is being used to read_logical, check it too.  */

static int
check_buffers (st_parameter_dt *dtp)
{
  int c;

  c = '\0';
  if (dtp->u.p.current_unit->last_char != EOF - 1)
    {
      dtp->u.p.at_eol = 0;
      c = dtp->u.p.current_unit->last_char;
      dtp->u.p.current_unit->last_char = EOF - 1;
      goto done;
    }

  /* Read from line_buffer if enabled.  */

  if (dtp->u.p.line_buffer_enabled)
    {
      dtp->u.p.at_eol = 0;

      c = dtp->u.p.line_buffer[dtp->u.p.line_buffer_pos];
      if (c != '\0' && dtp->u.p.line_buffer_pos < 64)
	{
	  dtp->u.p.line_buffer[dtp->u.p.line_buffer_pos] = '\0';
	  dtp->u.p.line_buffer_pos++;
	  goto done;
	}

      dtp->u.p.line_buffer_pos = 0;
      dtp->u.p.line_buffer_enabled = 0;
    }

done:
  dtp->u.p.at_eol = (c == '\n' || c == '\r' || c == EOF);
  return c;
}


/* Worker function for default character encoded file.  */
static int
next_char_default (st_parameter_dt *dtp)
{
  int c;

  /* Always check the unget and line buffer first.  */
  if ((c = check_buffers (dtp)))
    return c;

  c = fbuf_getc (dtp->u.p.current_unit);
  if (c != EOF && is_stream_io (dtp))
    dtp->u.p.current_unit->strm_pos++;

  dtp->u.p.at_eol = (c == '\n' || c == EOF);
  return c;
}


/* Worker function for internal and array I/O units.  */
static int
next_char_internal (st_parameter_dt *dtp)
{
  ssize_t length;
  gfc_offset record;
  int c;

  /* Always check the unget and line buffer first.  */
  if ((c = check_buffers (dtp)))
    return c;

  /* Handle the end-of-record and end-of-file conditions for
     internal array unit.  */
  if (is_array_io (dtp))
    {
      if (dtp->u.p.at_eof)
	return EOF;

      /* Check for "end-of-record" condition.  */
      if (dtp->u.p.current_unit->bytes_left == 0)
	{
	  int finished;

	  c = '\n';
	  record = next_array_record (dtp, dtp->u.p.current_unit->ls,
				      &finished);

	  /* Check for "end-of-file" condition.  */
	  if (finished)
	    {
	      dtp->u.p.at_eof = 1;
	      goto done;
	    }

	  record *= dtp->u.p.current_unit->recl;
	  if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
	    return EOF;

	  dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
	  goto done;
	}
    }

  /* Get the next character and handle end-of-record conditions.  */
  if (likely (dtp->u.p.current_unit->bytes_left > 0))
    {
      if (unlikely (is_char4_unit(dtp))) /* Check for kind=4 internal unit.  */
       length = sread (dtp->u.p.current_unit->s, &c, 1);
      else
       {
	 char cc;
	 length = sread (dtp->u.p.current_unit->s, &cc, 1);
	 c = cc;
       }
    }
  else
    length = 0;

  if (unlikely (length < 0))
    {
      generate_error (&dtp->common, LIBERROR_OS, NULL);
      return '\0';
    }

  if (is_array_io (dtp))
    {
      /* Check whether we hit EOF.  */
      if (unlikely (length == 0))
	{
	  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
	  return '\0';
	}
    }
  else
    {
      if (dtp->u.p.at_eof)
	return EOF;
      if (length == 0)
	{
	  c = '\n';
	  dtp->u.p.at_eof = 1;
	}
    }
  dtp->u.p.current_unit->bytes_left--;

done:
  dtp->u.p.at_eol = (c == '\n' || c == EOF);
  return c;
}


/* Worker function for UTF encoded files.  */
static int
next_char_utf8 (st_parameter_dt *dtp)
{
  static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x02, 0x01 };
  static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
  int i, nb;
  gfc_char4_t c;

  /* Always check the unget and line buffer first.  */
  if (!(c = check_buffers (dtp)))
    c = fbuf_getc (dtp->u.p.current_unit);

  if (c < 0x80)
    goto utf_done;

  /* The number of leading 1-bits in the first byte indicates how many
     bytes follow.  */
  for (nb = 2; nb < 7; nb++)
    if ((c & ~masks[nb-1]) == patns[nb-1])
      goto found;
  goto invalid;

 found:
  c = (c & masks[nb-1]);

  /* Decode the bytes read.  */
  for (i = 1; i < nb; i++)
    {
      gfc_char4_t n = fbuf_getc (dtp->u.p.current_unit);
      if ((n & 0xC0) != 0x80)
	goto invalid;
      c = ((c << 6) + (n & 0x3F));
    }

  /* Make sure the shortest possible encoding was used.  */
  if (c <=      0x7F && nb > 1) goto invalid;
  if (c <=     0x7FF && nb > 2) goto invalid;
  if (c <=    0xFFFF && nb > 3) goto invalid;
  if (c <=  0x1FFFFF && nb > 4) goto invalid;
  if (c <= 0x3FFFFFF && nb > 5) goto invalid;

  /* Make sure the character is valid.  */
  if (c > 0x7FFFFFFF || (c >= 0xD800 && c <= 0xDFFF))
    goto invalid;

utf_done:
  dtp->u.p.at_eol = (c == '\n' || c == (gfc_char4_t) EOF);
  return (int) c;

 invalid:
  generate_error (&dtp->common, LIBERROR_READ_VALUE, "Invalid UTF-8 encoding");
  return (gfc_char4_t) '?';
}

/* Push a character back onto the input.  */

static void
unget_char (st_parameter_dt *dtp, int c)
{
  dtp->u.p.current_unit->last_char = c;
}


/* Skip over spaces in the input.  Returns the nonspace character that
   terminated the eating and also places it back on the input.  */

static int
eat_spaces (st_parameter_dt *dtp)
{
  int c;

  /* If internal character array IO, peak ahead and seek past spaces.
     This is an optimization unique to character arrays with large
     character lengths (PR38199).  This code eliminates numerous calls
     to next_character.  */
  if (is_array_io (dtp) && (dtp->u.p.current_unit->last_char == EOF - 1))
    {
      gfc_offset offset = stell (dtp->u.p.current_unit->s);
      gfc_offset i;

      if (is_char4_unit(dtp)) /* kind=4 */
	{
	  for (i = 0; i < dtp->u.p.current_unit->bytes_left; i++)
	    {
	      if (dtp->internal_unit[(offset + i) * sizeof (gfc_char4_t)]
		  != (gfc_char4_t)' ')
	        break;
	    }
	}
      else
	{
	  for (i = 0; i < dtp->u.p.current_unit->bytes_left; i++)
	    {
	      if (dtp->internal_unit[offset + i] != ' ')
	        break;
	    }
	}

      if (i != 0)
	{
	  sseek (dtp->u.p.current_unit->s, offset + i, SEEK_SET);
	  dtp->u.p.current_unit->bytes_left -= i;
	}
    }

  /* Now skip spaces, EOF and EOL are handled in next_char.  */
  do
    c = next_char (dtp);
  while (c != EOF && (c == ' ' || c == '\r' || c == '\t'));

  unget_char (dtp, c);
  return c;
}


/* This function reads characters through to the end of the current
   line and just ignores them.  Returns 0 for success and LIBERROR_END
   if it hit EOF.  */

static int
eat_line (st_parameter_dt *dtp)
{
  int c;

  do
    c = next_char (dtp);
  while (c != EOF && c != '\n');
  if (c == EOF)
    return LIBERROR_END;
  return 0;
}


/* Skip over a separator.  Technically, we don't always eat the whole
   separator.  This is because if we've processed the last input item,
   then a separator is unnecessary.  Plus the fact that operating
   systems usually deliver console input on a line basis.

   The upshot is that if we see a newline as part of reading a
   separator, we stop reading.  If there are more input items, we
   continue reading the separator with finish_separator() which takes
   care of the fact that we may or may not have seen a comma as part
   of the separator.

   Returns 0 for success, and non-zero error code otherwise.  */

static int
eat_separator (st_parameter_dt *dtp)
{
  int c, n;
  int err = 0;

  dtp->u.p.comma_flag = 0;
  c = next_char (dtp);
  if (c == ' ' || c == '\t')
    {
      eat_spaces (dtp);
      c = next_char (dtp);
      if (c == ',')
	{
	  if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
	    unget_char (dtp, ';');
	  dtp->u.p.comma_flag = 1;
	  eat_spaces (dtp);
	  return err;
	}
      if (c == ';')
	{
	  if (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT)
	    unget_char (dtp, ',');
	  dtp->u.p.comma_flag = 1;
	  eat_spaces (dtp);
	  return err;
	}
    }

  switch (c)
    {
    case ',':
      if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
	{
	  generate_error (&dtp->common, LIBERROR_READ_VALUE,
	   "Comma not allowed as separator with DECIMAL='comma'");
	  unget_char (dtp, c);
	  break;
	}
      dtp->u.p.comma_flag = 1;
      eat_spaces (dtp);
      break;

    case ';':
      if (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT)
	{
	  generate_error (&dtp->common, LIBERROR_READ_VALUE,
	   "Semicolon not allowed as separator with DECIMAL='point'");
	  unget_char (dtp, c);
	  break;
	}
      dtp->u.p.comma_flag = 1;
      eat_spaces (dtp);
      break;

    case '/':
      dtp->u.p.input_complete = 1;
      break;

    case '\r':
      if ((n = next_char(dtp)) == EOF)
	return LIBERROR_END;
      if (n != '\n')
	{
	  unget_char (dtp, n);
	  break;
	}
    /* Fall through.  */
    case '\n':
      dtp->u.p.at_eol = 1;
      if (dtp->u.p.namelist_mode)
	{
	  do
	    {
	      if ((c = next_char (dtp)) == EOF)
		  return LIBERROR_END;
	      if (c == '!')
		{
		  err = eat_line (dtp);
		  if (err)
		    return err;
		  c = '\n';
		}
	    }
	  while (c == '\n' || c == '\r' || c == ' ' || c == '\t');
	  unget_char (dtp, c);
	}
      break;

    case '!':
      /* Eat a namelist comment.  */
      if (dtp->u.p.namelist_mode)
	{
	  err = eat_line (dtp);
	  if (err)
	    return err;

	  break;
	}

      /* Fall Through...  */

    default:
      unget_char (dtp, c);
      break;
    }
  return err;
}


/* Finish processing a separator that was interrupted by a newline.
   If we're here, then another data item is present, so we finish what
   we started on the previous line.  Return 0 on success, error code
   on failure.  */

static int
finish_separator (st_parameter_dt *dtp)
{
  int c;
  int err = LIBERROR_OK;

 restart:
  eat_spaces (dtp);

  if ((c = next_char (dtp)) == EOF)
    return LIBERROR_END;
  switch (c)
    {
    case ',':
      if (dtp->u.p.comma_flag)
	unget_char (dtp, c);
      else
	{
	  if ((c = eat_spaces (dtp)) == EOF)
	    return LIBERROR_END;
	  if (c == '\n' || c == '\r')
	    goto restart;
	}

      break;

    case '/':
      dtp->u.p.input_complete = 1;
      if (!dtp->u.p.namelist_mode)
	return err;
      break;

    case '\n':
    case '\r':
      goto restart;

    case '!':
      if (dtp->u.p.namelist_mode)
	{
	  err = eat_line (dtp);
	  if (err)
	    return err;
	  goto restart;
	}
      /* Fall through.  */
    default:
      unget_char (dtp, c);
      break;
    }
  return err;
}


/* This function is needed to catch bad conversions so that namelist can
   attempt to see if dtp->u.p.saved_string contains a new object name rather
   than a bad value.  */

static int
nml_bad_return (st_parameter_dt *dtp, char c)
{
  if (dtp->u.p.namelist_mode)
    {
      dtp->u.p.nml_read_error = 1;
      unget_char (dtp, c);
      return 1;
    }
  return 0;
}

/* Convert an unsigned string to an integer.  The length value is -1
   if we are working on a repeat count.  Returns nonzero if we have a
   range problem.  As a side effect, frees the dtp->u.p.saved_string.  */

static int
convert_integer (st_parameter_dt *dtp, int length, int negative)
{
  char c, *buffer, message[IOMSG_LEN];
  int m;
  GFC_UINTEGER_LARGEST v, max, max10;
  GFC_INTEGER_LARGEST value;

  buffer = dtp->u.p.saved_string;
  v = 0;

  if (length == -1)
    max = MAX_REPEAT;
  else
    {
      max = si_max (length);
      if (negative)
	max++;
    }
  max10 = max / 10;

  for (;;)
    {
      c = *buffer++;
      if (c == '\0')
	break;
      c -= '0';

      if (v > max10)
	goto overflow;
      v = 10 * v;

      if (v > max - c)
	goto overflow;
      v += c;
    }

  m = 0;

  if (length != -1)
    {
      if (negative)
	value = -v;
      else
	value = v;
      set_integer (dtp->u.p.value, value, length);
    }
  else
    {
      dtp->u.p.repeat_count = v;

      if (dtp->u.p.repeat_count == 0)
	{
	  snprintf (message, IOMSG_LEN, "Zero repeat count in item %d of list "
		    "input", dtp->u.p.item_count);

	  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
	  m = 1;
	}
    }

  free_saved (dtp);
  return m;

 overflow:
  if (length == -1)
    snprintf (message, IOMSG_LEN, "Repeat count overflow in item %d of list "
	      "input", dtp->u.p.item_count);
  else
    snprintf (message, IOMSG_LEN, "Integer overflow while reading item %d",
	     dtp->u.p.item_count);

  free_saved (dtp);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);

  return 1;
}

/* Same as above, but for unsigneds, where overflow checks are only
   preformed with -pedantic, except on the repeat count.  */

static int
convert_unsigned (st_parameter_dt *dtp, int length, int negative)
{
  char c, *buffer, message[IOMSG_LEN];
  GFC_UINTEGER_LARGEST v, value, max, v_old;
  int m;

  if (compile_options.pedantic && negative)
    goto overflow;

  buffer = dtp->u.p.saved_string;
  max = length == -1 ? MAX_REPEAT : us_max (length);

  v = 0;
  for (;;)
    {
      c = *buffer++;
      if (c == '\0')
	break;
      c -= '0';
      v_old = v;
      v = v * 10 + c;

      if (length == -1 && v > max)
	goto overflow;
      else if (compile_options.pedantic && v < v_old)
	goto overflow;
    }

  m = 0;

  if (length != -1)
    {
      if (negative)
	value = -v;
      else
	value = v;

      if (compile_options.pedantic && value > max)
	goto overflow;
      else
	value = value & max;

      set_unsigned (dtp->u.p.value, value, length);
    }
  else
    {
      dtp->u.p.repeat_count = v;

      if (dtp->u.p.repeat_count == 0)
	{
	  snprintf (message, IOMSG_LEN, "Zero repeat count in item %d of list input",
		   dtp->u.p.item_count);

	  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
	  m = 1;
	}
    }
  free_saved (dtp);
  return m;

 overflow:
  if (length== -1)
    snprintf (message, IOMSG_LEN, "Repeat count overflow in item %d of list input",
	      dtp->u.p.item_count);
  else if (negative)
    snprintf (message, IOMSG_LEN, "Negative sign for unsigned integer "
	      "in item %d of list input", dtp->u.p.item_count);
  else
    snprintf (message, IOMSG_LEN, "Unsigned integer overflow while reading "
	      "item %d of list input", dtp->u.p.item_count);

  free_saved (dtp);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);

  return 1;
}

/* Parse a repeat count for logical and complex values which cannot
   begin with a digit.  Returns nonzero if we are done, zero if we
   should continue on.  */

static int
parse_repeat (st_parameter_dt *dtp)
{
  char message[IOMSG_LEN];
  int c, repeat;

  if ((c = next_char (dtp)) == EOF)
    goto bad_repeat;
  switch (c)
    {
    CASE_DIGITS:
      repeat = c - '0';
      break;

    CASE_SEPARATORS:
      unget_char (dtp, c);
      eat_separator (dtp);
      return 1;

    default:
      unget_char (dtp, c);
      return 0;
    }

  for (;;)
    {
      c = next_char (dtp);
      switch (c)
	{
	CASE_DIGITS:
	  repeat = 10 * repeat + c - '0';

	  if (repeat > MAX_REPEAT)
	    {
	      snprintf (message, IOMSG_LEN,
		       "Repeat count overflow in item %d of list input",
		       dtp->u.p.item_count);

	      generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
	      return 1;
	    }

	  break;

	case '*':
	  if (repeat == 0)
	    {
	      snprintf (message, IOMSG_LEN,
		       "Zero repeat count in item %d of list input",
		       dtp->u.p.item_count);

	      generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
	      return 1;
	    }

	  goto done;

	default:
	  goto bad_repeat;
	}
    }

 done:
  dtp->u.p.repeat_count = repeat;
  return 0;

 bad_repeat:

  free_saved (dtp);
  if (c == EOF)
    {
      free_line (dtp);
      hit_eof (dtp);
      return 1;
    }
  else
    eat_line (dtp);
  snprintf (message, IOMSG_LEN, "Bad repeat count in item %d of list input",
	   dtp->u.p.item_count);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
  return 1;
}


/* To read a logical we have to look ahead in the input stream to make sure
    there is not an equal sign indicating a variable name.  To do this we use
    line_buffer to point to a temporary buffer, pushing characters there for
    possible later reading. */

static void
l_push_char (st_parameter_dt *dtp, char c)
{
  if (dtp->u.p.line_buffer == NULL)
    dtp->u.p.line_buffer = xcalloc (SCRATCH_SIZE, 1);

  dtp->u.p.line_buffer[dtp->u.p.line_buffer_pos++] = c;
}


/* Read a logical character on the input.  */

static void
read_logical (st_parameter_dt *dtp, int length)
{
  char message[IOMSG_LEN];
  int c, i, v;

  if (parse_repeat (dtp))
    return;

  c = safe_tolower (next_char (dtp));
  l_push_char (dtp, c);
  switch (c)
    {
    case 't':
      v = 1;
      c = next_char (dtp);
      l_push_char (dtp, c);

      if (!is_separator(c) && c != EOF)
	goto possible_name;

      unget_char (dtp, c);
      break;
    case 'f':
      v = 0;
      c = next_char (dtp);
      l_push_char (dtp, c);

      if (!is_separator(c) && c != EOF)
	goto possible_name;

      unget_char (dtp, c);
      break;

    case '.':
      c = safe_tolower (next_char (dtp));
      switch (c)
	{
	  case 't':
	    v = 1;
	    break;
	  case 'f':
	    v = 0;
	    break;
	  default:
	    goto bad_logical;
	}

      break;

    case '!':
      if (!dtp->u.p.namelist_mode)
        goto bad_logical;

    CASE_SEPARATORS:
    case EOF:
      unget_char (dtp, c);
      eat_separator (dtp);
      return;			/* Null value.  */

    default:
      /* Save the character in case it is the beginning
	 of the next object name. */
      unget_char (dtp, c);
      goto bad_logical;
    }

  dtp->u.p.saved_type = BT_LOGICAL;
  dtp->u.p.saved_length = length;

  /* Eat trailing garbage.  */
  do
    c = next_char (dtp);
  while (c != EOF && !is_separator (c));

  unget_char (dtp, c);
  eat_separator (dtp);
  set_integer ((int *) dtp->u.p.value, v, length);
  free_line (dtp);

  return;

 possible_name:

  for(i = 0; i < 63; i++)
    {
      c = next_char (dtp);
      if (c == '(')
	{
	  l_push_char (dtp, c);
	  dtp->u.p.nml_read_error = 1;
	  dtp->u.p.line_buffer_enabled = 1;
	  dtp->u.p.line_buffer_pos = 0;
	  return;
	}
      if (is_separator(c))
	{
	  /* All done if this is not a namelist read.  */
	  if (!dtp->u.p.namelist_mode)
	    goto logical_done;

	  unget_char (dtp, c);
	  eat_separator (dtp);
	  c = next_char (dtp);
	  if (c != '=')
	    {
	      unget_char (dtp, c);
	      goto logical_done;
	    }
	}

      l_push_char (dtp, c);
      if (c == '=')
	{
	  dtp->u.p.nml_read_error = 1;
	  dtp->u.p.line_buffer_enabled = 1;
	  dtp->u.p.line_buffer_pos = 0;
	  return;
	}

    }

 bad_logical:

  if (nml_bad_return (dtp, c))
    {
      free_line (dtp);
      return;
    }


  free_saved (dtp);
  if (c == EOF)
    {
      free_line (dtp);
      hit_eof (dtp);
      return;
    }
  else if (c != '\n')
    eat_line (dtp);
  snprintf (message, IOMSG_LEN, "Bad logical value while reading item %d",
	      dtp->u.p.item_count);
  free_line (dtp);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
  return;

 logical_done:

  dtp->u.p.saved_type = BT_LOGICAL;
  dtp->u.p.saved_length = length;
  set_integer ((int *) dtp->u.p.value, v, length);
  free_saved (dtp);
  free_line (dtp);
}


/* Reading integers is tricky because we can actually be reading a
   repeat count.  We have to store the characters in a buffer because
   we could be reading an integer that is larger than the default int
   used for repeat counts.  */

static void
read_integer (st_parameter_dt *dtp, int length, bt type)
{
  char message[IOMSG_LEN];
  int c, negative;
  negative = 0;

  c = next_char (dtp);
  switch (c)
    {
    case '-':
      negative = 1;
      /* Fall through...  */

    case '+':
      if ((c = next_char (dtp)) == EOF)
	goto bad_integer;
      goto get_integer;

    case '!':
      if (!dtp->u.p.namelist_mode)
        goto bad_integer;

    CASE_SEPARATORS:		/* Single null.  */
      unget_char (dtp, c);
      eat_separator (dtp);
      return;

    CASE_DIGITS:
      push_char (dtp, c);
      break;

    default:
      goto bad_integer;
    }

  /* Take care of what may be a repeat count.  */

  for (;;)
    {
      c = next_char (dtp);
      switch (c)
	{
	CASE_DIGITS:
	  push_char (dtp, c);
	  break;

	case '*':
	  push_char (dtp, '\0');
	  goto repeat;

	case '!':
	  if (!dtp->u.p.namelist_mode)
	    goto bad_integer;

	CASE_SEPARATORS:	/* Not a repeat count.  */
	case EOF:
	  goto done;

	default:
	  goto bad_integer;
	}
    }

 repeat:
  if (type == BT_INTEGER)
    {
      if (convert_integer (dtp, -1, 0))
	return;
    }

  /* Get the real integer.  */

  if ((c = next_char (dtp)) == EOF)
    goto bad_integer;
  switch (c)
    {
    CASE_DIGITS:
      break;

    case '!':
      if (!dtp->u.p.namelist_mode)
        goto bad_integer;

    CASE_SEPARATORS:
      unget_char (dtp, c);
      eat_separator (dtp);
      return;

    case '-':
      if (compile_options.pedantic && type == BT_UNSIGNED)
	goto bad_integer;

      negative = 1;
      /* Fall through...  */

    case '+':
      c = next_char (dtp);
      break;
    }

 get_integer:
  if (!safe_isdigit (c))
    goto bad_integer;
  push_char (dtp, c);

  for (;;)
    {
      c = next_char (dtp);
      switch (c)
	{
	CASE_DIGITS:
	  push_char (dtp, c);
	  break;

	case '!':
	  if (!dtp->u.p.namelist_mode)
	    goto bad_integer;

	CASE_SEPARATORS:
	case EOF:
	  goto done;

	default:
	  goto bad_integer;
	}
    }

 bad_integer:

  if (nml_bad_return (dtp, c))
    return;

  free_saved (dtp);
  if (c == EOF)
    {
      free_line (dtp);
      hit_eof (dtp);
      return;
    }
  else if (c != '\n')
    eat_line (dtp);

  if (type == BT_INTEGER)
    snprintf (message, IOMSG_LEN, "Bad integer for item %d in list input",
	      dtp->u.p.item_count);
  else
    snprintf (message, IOMSG_LEN, "Bad unsigned for item %d in list input",
	      dtp->u.p.item_count);

  free_line (dtp);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);

  return;

 done:
  unget_char (dtp, c);
  eat_separator (dtp);

  push_char (dtp, '\0');
  if (type == BT_INTEGER)
    {
      if (convert_integer (dtp, length, negative))
	{
	  free_saved (dtp);
	  return;
	}
    }
  else
    {
      if (convert_unsigned (dtp, length, negative))
	{
	  free_saved (dtp);
	  return;
	}
    }

  free_saved (dtp);
  dtp->u.p.saved_type = type;
}

/* Read a character variable.  */

static void
read_character (st_parameter_dt *dtp, int length __attribute__ ((unused)))
{
  char quote, message[IOMSG_LEN];
  int c;

  quote = ' ';			/* Space means no quote character.  */

  if ((c = next_char (dtp)) == EOF)
    goto eof;
  switch (c)
    {
    CASE_DIGITS:
      push_char (dtp, c);
      break;

    CASE_SEPARATORS:
    case EOF:
      unget_char (dtp, c);		/* NULL value.  */
      eat_separator (dtp);
      return;

    case '"':
    case '\'':
      quote = c;
      goto get_string;

    default:
      if (dtp->u.p.namelist_mode)
	{
	  unget_char (dtp, c);
	  return;
	}
      push_char (dtp, c);
      goto get_string;
    }

  /* Deal with a possible repeat count.  */

  for (;;)
    {
      c = next_char (dtp);
      switch (c)
	{
	CASE_DIGITS:
	  push_char (dtp, c);
	  break;

	CASE_SEPARATORS:
	case EOF:
	  unget_char (dtp, c);
	  goto done;		/* String was only digits!  */

	case '*':
	  push_char (dtp, '\0');
	  goto got_repeat;

	default:
	  push_char (dtp, c);
	  goto get_string;	/* Not a repeat count after all.  */
	}
    }

 got_repeat:
  if (convert_integer (dtp, -1, 0))
    return;

  /* Now get the real string.  */

  if ((c = next_char (dtp)) == EOF)
    goto eof;
  switch (c)
    {
    CASE_SEPARATORS:
      unget_char (dtp, c);		/* Repeated NULL values.  */
      eat_separator (dtp);
      return;

    case '"':
    case '\'':
      quote = c;
      break;

    default:
      push_char (dtp, c);
      break;
    }

 get_string:

  for (;;)
    {
      if ((c = next_char (dtp)) == EOF)
	goto done_eof;
      switch (c)
	{
	case '"':
	case '\'':
	  if (c != quote)
	    {
	      push_char (dtp, c);
	      break;
	    }

	  /* See if we have a doubled quote character or the end of
	     the string.  */

	  if ((c = next_char (dtp)) == EOF)
	    goto done_eof;
	  if (c == quote)
	    {
	      push_char (dtp, quote);
	      break;
	    }

	  unget_char (dtp, c);
	  goto done;

	CASE_SEPARATORS:
	  if (quote == ' ')
	    {
	      unget_char (dtp, c);
	      goto done;
	    }

	  if (c != '\n' && c != '\r')
	    push_char (dtp, c);
	  break;

	default:
	  push_char (dtp, c);
	  break;
	}
    }

  /* At this point, we have to have a separator, or else the string is
     invalid.  */
 done:
  c = next_char (dtp);
 done_eof:
  if (is_separator (c) || c == EOF)
    {
      unget_char (dtp, c);
      eat_separator (dtp);
      dtp->u.p.saved_type = BT_CHARACTER;
    }
  else
    {
      free_saved (dtp);
      snprintf (message, IOMSG_LEN, "Invalid string input in item %d",
		  dtp->u.p.item_count);
      generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
    }
  free_line (dtp);
  return;

 eof:
  free_saved (dtp);
  free_line (dtp);
  hit_eof (dtp);
}


/* Parse a component of a complex constant or a real number that we
   are sure is already there.  This is a straight real number parser.  */

static int
parse_real (st_parameter_dt *dtp, void *buffer, int length)
{
  char message[IOMSG_LEN];
  int c, m, seen_dp;

  if ((c = next_char (dtp)) == EOF)
    goto bad;

  if (c == '-' || c == '+')
    {
      push_char (dtp, c);
      if ((c = next_char (dtp)) == EOF)
	goto bad;
    }

  if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
    c = '.';

  if (!safe_isdigit (c) && c != '.')
    {
      if (c == 'i' || c == 'I' || c == 'n' || c == 'N')
	goto inf_nan;
      else
	goto bad;
    }

  push_char (dtp, c);

  seen_dp = (c == '.') ? 1 : 0;

  for (;;)
    {
      if ((c = next_char (dtp)) == EOF)
	goto bad;
      if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
	{
	  if (c == '.')
	    goto bad;
	  if (c == ',')
	    c = '.';
	}
      switch (c)
	{
	CASE_DIGITS:
	  push_char (dtp, c);
	  break;

	case '.':
	  if (seen_dp)
	    goto bad;

	  seen_dp = 1;
	  push_char (dtp, c);
	  break;

	case 'e':
	case 'E':
	case 'd':
	case 'D':
	case 'q':
	case 'Q':
	  push_char (dtp, 'e');
	  goto exp1;

	case '-':
	case '+':
	  push_char (dtp, 'e');
	  push_char (dtp, c);
	  if ((c = next_char (dtp)) == EOF)
	    goto bad;
	  goto exp2;

	case '!':
	  if (!dtp->u.p.namelist_mode)
	    goto bad;

	CASE_SEPARATORS:
	case EOF:
	  goto done;

	default:
	  goto done;
	}
    }

 exp1:
  if ((c = next_char (dtp)) == EOF)
    goto bad;
  if (c != '-' && c != '+')
    push_char (dtp, '+');
  else
    {
      push_char (dtp, c);
      c = next_char (dtp);
    }

 exp2:
  if (!safe_isdigit (c))
    {
      /* Extension: allow default exponent of 0 when omitted.  */
      if (dtp->common.flags & IOPARM_DT_DEC_EXT)
	{
	  push_char (dtp, '0');
	  goto done;
	}
      else
	goto bad_exponent;
    }

  push_char (dtp, c);

  for (;;)
    {
      if ((c = next_char (dtp)) == EOF)
	goto bad;
      switch (c)
	{
	CASE_DIGITS:
	  push_char (dtp, c);
	  break;

	case '!':
	  if (!dtp->u.p.namelist_mode)
	    goto bad;

	CASE_SEPARATORS:
	case EOF:
	  unget_char (dtp, c);
	  goto done;

	default:
	  goto done;
	}
    }

 done:
  unget_char (dtp, c);
  push_char (dtp, '\0');

  m = convert_real (dtp, buffer, dtp->u.p.saved_string, length);
  free_saved (dtp);

  return m;

 done_infnan:
  unget_char (dtp, c);
  push_char (dtp, '\0');

  m = convert_infnan (dtp, buffer, dtp->u.p.saved_string, length);
  free_saved (dtp);

  return m;

 inf_nan:
  /* Match INF and Infinity.  */
  if ((c == 'i' || c == 'I')
      && ((c = next_char (dtp)) == 'n' || c == 'N')
      && ((c = next_char (dtp)) == 'f' || c == 'F'))
    {
	c = next_char (dtp);
	if ((c != 'i' && c != 'I')
	    || ((c == 'i' || c == 'I')
		&& ((c = next_char (dtp)) == 'n' || c == 'N')
		&& ((c = next_char (dtp)) == 'i' || c == 'I')
		&& ((c = next_char (dtp)) == 't' || c == 'T')
		&& ((c = next_char (dtp)) == 'y' || c == 'Y')
		&& (c = next_char (dtp))))
	  {
	     if (is_separator (c) || (c == EOF))
	       unget_char (dtp, c);
	     push_char (dtp, 'i');
	     push_char (dtp, 'n');
	     push_char (dtp, 'f');
	     goto done_infnan;
	  }
    } /* Match NaN.  */
  else if (((c = next_char (dtp)) == 'a' || c == 'A')
	   && ((c = next_char (dtp)) == 'n' || c == 'N')
	   && (c = next_char (dtp)))
    {
      if (is_separator (c) || (c == EOF))
	unget_char (dtp, c);
      push_char (dtp, 'n');
      push_char (dtp, 'a');
      push_char (dtp, 'n');

      /* Match "NAN(alphanum)".  */
      if (c == '(')
	{
	  for ( ; c != ')'; c = next_char (dtp))
	    if (is_separator (c))
	      goto bad;

	  c = next_char (dtp);
	  if (is_separator (c) || (c == EOF))
	    unget_char (dtp, c);
	}
      goto done_infnan;
    }

 bad:

  if (nml_bad_return (dtp, c))
    return 0;

 bad_exponent:

  free_saved (dtp);
  if (c == EOF)
    {
      free_line (dtp);
      hit_eof (dtp);
      return 1;
    }
  else if (c != '\n')
    eat_line (dtp);

  snprintf (message, IOMSG_LEN, "Bad complex floating point "
	    "number for item %d", dtp->u.p.item_count);
  free_line (dtp);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);

  return 1;
}


/* Reading a complex number is straightforward because we can tell
   what it is right away.  */

static void
read_complex (st_parameter_dt *dtp, void *dest, int kind, size_t size)
{
  char message[IOMSG_LEN];
  int c;

  if (parse_repeat (dtp))
    return;

  c = next_char (dtp);
  switch (c)
    {
    case '(':
      break;

    case '!':
      if (!dtp->u.p.namelist_mode)
	goto bad_complex;

    CASE_SEPARATORS:
    case EOF:
      unget_char (dtp, c);
      eat_separator (dtp);
      return;

    default:
      goto bad_complex;
    }

eol_1:
  eat_spaces (dtp);
  c = next_char (dtp);
  if (c == '\n' || c== '\r')
    goto eol_1;
  else
    unget_char (dtp, c);

  if (parse_real (dtp, dest, kind))
    return;

eol_2:
  eat_spaces (dtp);
  c = next_char (dtp);
  if (c == '\n' || c== '\r')
    goto eol_2;
  else
    unget_char (dtp, c);

  if (next_char (dtp)
      !=  (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';'))
    goto bad_complex;

eol_3:
  eat_spaces (dtp);
  c = next_char (dtp);
  if (c == '\n' || c== '\r')
    goto eol_3;
  else
    unget_char (dtp, c);

  if (parse_real (dtp, dest + size / 2, kind))
    return;

eol_4:
  eat_spaces (dtp);
  c = next_char (dtp);
  if (c == '\n' || c== '\r')
    goto eol_4;
  else
    unget_char (dtp, c);

  if (next_char (dtp) != ')')
    goto bad_complex;

  c = next_char (dtp);
  if (!is_separator (c) && (c != EOF))
    goto bad_complex;

  unget_char (dtp, c);
  eat_separator (dtp);

  free_saved (dtp);
  dtp->u.p.saved_type = BT_COMPLEX;
  return;

 bad_complex:

  if (nml_bad_return (dtp, c))
    return;

  free_saved (dtp);
  if (c == EOF)
    {
      free_line (dtp);
      hit_eof (dtp);
      return;
    }
  else if (c != '\n')
    eat_line (dtp);

  snprintf (message, IOMSG_LEN, "Bad complex value in item %d of list input",
	      dtp->u.p.item_count);
  free_line (dtp);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
}


/* Parse a real number with a possible repeat count.  */

static void
read_real (st_parameter_dt *dtp, void *dest, int length)
{
  char message[IOMSG_LEN];
  int c;
  int seen_dp;
  int is_inf;

  seen_dp = 0;

  c = next_char (dtp);
  if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
    {
      if (c == '.')
	goto bad_real;
      if (c == ',')
	c = '.';
    }
  if (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT)
    {
      if (c == ';')
	goto bad_real;
    }
  switch (c)
    {
    CASE_DIGITS:
      push_char (dtp, c);
      break;

    case '.':
      push_char (dtp, c);
      seen_dp = 1;
      break;

    case '+':
    case '-':
      goto got_sign;

    case '!':
      if (!dtp->u.p.namelist_mode)
	goto bad_real;

    CASE_SEPARATORS:
      unget_char (dtp, c);		/* Single null.  */
      eat_separator (dtp);
      return;

    case 'i':
    case 'I':
    case 'n':
    case 'N':
      goto inf_nan;

    default:
      goto bad_real;
    }

  /* Get the digit string that might be a repeat count.  */

  for (;;)
    {
      c = next_char (dtp);
      if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
	{
	  if (c == '.')
	    goto bad_real;
	  if (c == ',')
	    c = '.';
	}
      switch (c)
	{
	CASE_DIGITS:
	  push_char (dtp, c);
	  break;

	case '.':
	  if (seen_dp)
	    goto bad_real;

	  seen_dp = 1;
	  push_char (dtp, c);
	  goto real_loop;

	case 'E':
	case 'e':
	case 'D':
	case 'd':
	case 'Q':
	case 'q':
	  goto exp1;

	case '+':
	case '-':
	  push_char (dtp, 'e');
	  push_char (dtp, c);
	  c = next_char (dtp);
	  goto exp2;

	case '*':
	  push_char (dtp, '\0');
	  goto got_repeat;

	case '!':
	  if (!dtp->u.p.namelist_mode)
	    goto bad_real;

	CASE_SEPARATORS:
	case EOF:
	  if (c != '\n' && c != ',' && c != ';' && c != '\r')
	    unget_char (dtp, c);
	  goto done;

	default:
	  goto bad_real;
	}
    }

 got_repeat:
  if (convert_integer (dtp, -1, 0))
    return;

  /* Now get the number itself.  */

  if ((c = next_char (dtp)) == EOF)
    goto bad_real;
  if (is_separator (c))
    {				/* Repeated null value.  */
      unget_char (dtp, c);
      eat_separator (dtp);
      return;
    }

  if (c != '-' && c != '+')
    push_char (dtp, '+');
  else
    {
    got_sign:
      push_char (dtp, c);
      if ((c = next_char (dtp)) == EOF)
	goto bad_real;
    }

  if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
    c = '.';

  if (!safe_isdigit (c) && c != '.')
    {
      if (c == 'i' || c == 'I' || c == 'n' || c == 'N')
	goto inf_nan;
      else
	goto bad_real;
    }

  if (c == '.')
    {
      if (seen_dp)
        goto bad_real;
      else
        seen_dp = 1;
    }

  push_char (dtp, c);

 real_loop:
  for (;;)
    {
      c = next_char (dtp);
      if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
	c = '.';
      switch (c)
	{
	CASE_DIGITS:
	  push_char (dtp, c);
	  break;

	case '!':
	  if (!dtp->u.p.namelist_mode)
	    goto bad_real;

	CASE_SEPARATORS:
	case EOF:
	  goto done;

	case '.':
	  if (seen_dp)
	    goto bad_real;

	  seen_dp = 1;
	  push_char (dtp, c);
	  break;

	case 'E':
	case 'e':
	case 'D':
	case 'd':
	case 'Q':
	case 'q':
	  goto exp1;

	case '+':
	case '-':
	  push_char (dtp, 'e');
	  push_char (dtp, c);
	  c = next_char (dtp);
	  goto exp2;

	default:
	  goto bad_real;
	}
    }

 exp1:
  push_char (dtp, 'e');

  if ((c = next_char (dtp)) == EOF)
    goto bad_real;
  if (c != '+' && c != '-')
    push_char (dtp, '+');
  else
    {
      push_char (dtp, c);
      c = next_char (dtp);
    }

 exp2:
  if (!safe_isdigit (c))
    {
      /* Extension: allow default exponent of 0 when omitted.  */
      if (dtp->common.flags & IOPARM_DT_DEC_EXT)
	{
	  push_char (dtp, '0');
	  goto done;
	}
      else
	goto bad_exponent;
    }

  push_char (dtp, c);

  for (;;)
    {
      c = next_char (dtp);

      switch (c)
	{
	CASE_DIGITS:
	  push_char (dtp, c);
	  break;

	case '!':
	  if (!dtp->u.p.namelist_mode)
	    goto bad_real;

	CASE_SEPARATORS:
	case EOF:
	  goto done;

	default:
	  goto bad_real;
	}
    }

 done:
  unget_char (dtp, c);
  eat_separator (dtp);
  push_char (dtp, '\0');
  if (convert_real (dtp, dest, dtp->u.p.saved_string, length))
    {
      free_saved (dtp);
      return;
    }

  free_saved (dtp);
  dtp->u.p.saved_type = BT_REAL;
  return;

 inf_nan:
  l_push_char (dtp, c);
  is_inf = 0;

  /* Match INF and Infinity.  */
  if (c == 'i' || c == 'I')
    {
      c = next_char (dtp);
      l_push_char (dtp, c);
      if (c != 'n' && c != 'N')
	goto unwind;
      c = next_char (dtp);
      l_push_char (dtp, c);
      if (c != 'f' && c != 'F')
	goto unwind;
      c = next_char (dtp);
      l_push_char (dtp, c);
      if (!is_separator (c) && (c != EOF))
	{
	  if (c != 'i' && c != 'I')
	    goto unwind;
	  c = next_char (dtp);
	  l_push_char (dtp, c);
	  if (c != 'n' && c != 'N')
	    goto unwind;
	  c = next_char (dtp);
	  l_push_char (dtp, c);
	  if (c != 'i' && c != 'I')
	    goto unwind;
	  c = next_char (dtp);
	  l_push_char (dtp, c);
	  if (c != 't' && c != 'T')
	    goto unwind;
	  c = next_char (dtp);
	  l_push_char (dtp, c);
	  if (c != 'y' && c != 'Y')
	    goto unwind;
	  c = next_char (dtp);
	  l_push_char (dtp, c);
	}
	is_inf = 1;
    } /* Match NaN.  */
  else
    {
      c = next_char (dtp);
      l_push_char (dtp, c);
      if (c != 'a' && c != 'A')
	goto unwind;
      c = next_char (dtp);
      l_push_char (dtp, c);
      if (c != 'n' && c != 'N')
	goto unwind;
      c = next_char (dtp);
      l_push_char (dtp, c);

      /* Match NAN(alphanum).  */
      if (c == '(')
	{
	  for (c = next_char (dtp); c != ')'; c = next_char (dtp))
	    if (is_separator (c))
	      goto unwind;
	    else
	      l_push_char (dtp, c);

	  l_push_char (dtp, ')');
	  c = next_char (dtp);
	  l_push_char (dtp, c);
	}
    }

  if (!is_separator (c) && (c != EOF))
    goto unwind;

  if (dtp->u.p.namelist_mode)
    {
      if (c == ' ' || c =='\n' || c == '\r')
	{
	  do
	    {
	      if ((c = next_char (dtp)) == EOF)
		goto bad_real;
	    }
	  while (c == ' ' || c =='\n' || c == '\r');

	  l_push_char (dtp, c);

	  if (c == '=')
	    goto unwind;
	}
    }

  if (is_inf)
    {
      push_char (dtp, 'i');
      push_char (dtp, 'n');
      push_char (dtp, 'f');
    }
  else
    {
      push_char (dtp, 'n');
      push_char (dtp, 'a');
      push_char (dtp, 'n');
    }

  free_line (dtp);
  unget_char (dtp, c);
  eat_separator (dtp);
  push_char (dtp, '\0');
  if (convert_infnan (dtp, dest, dtp->u.p.saved_string, length))
    return;

  free_saved (dtp);
  dtp->u.p.saved_type = BT_REAL;
  return;

 unwind:
  if (dtp->u.p.namelist_mode)
    {
      dtp->u.p.nml_read_error = 1;
      dtp->u.p.line_buffer_enabled = 1;
      dtp->u.p.line_buffer_pos = 0;
      return;
    }

 bad_real:

  if (nml_bad_return (dtp, c))
    return;

 bad_exponent:

  free_saved (dtp);
  if (c == EOF)
    {
      free_line (dtp);
      hit_eof (dtp);
      return;
    }
  else if (c != '\n')
    eat_line (dtp);

  snprintf (message, IOMSG_LEN, "Bad real number in item %d of list input",
	      dtp->u.p.item_count);
  free_line (dtp);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
}


/* Check the current type against the saved type to make sure they are
   compatible.  Returns nonzero if incompatible.  */

static int
check_type (st_parameter_dt *dtp, bt type, int kind)
{
  char message[IOMSG_LEN];

  if (dtp->u.p.saved_type != BT_UNKNOWN && dtp->u.p.saved_type != type)
    {
      snprintf (message, IOMSG_LEN, "Read type %s where %s was expected for item %d",
		  type_name (dtp->u.p.saved_type), type_name (type),
		  dtp->u.p.item_count);
      free_line (dtp);
      generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
      return 1;
    }

  if (dtp->u.p.saved_type == BT_UNKNOWN || dtp->u.p.saved_type == BT_CHARACTER)
    return 0;

  if ((type != BT_COMPLEX && dtp->u.p.saved_length != kind)
      || (type == BT_COMPLEX && dtp->u.p.saved_length != kind*2))
    {
      snprintf (message, IOMSG_LEN,
		  "Read kind %d %s where kind %d is required for item %d",
		  type == BT_COMPLEX ? dtp->u.p.saved_length / 2
				     : dtp->u.p.saved_length,
		  type_name (dtp->u.p.saved_type), kind,
		  dtp->u.p.item_count);
      free_line (dtp);
      generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
      return 1;
    }

  return 0;
}


/* Initialize the function pointers to select the correct versions of
   next_char and push_char depending on what we are doing.  */

static void
set_workers (st_parameter_dt *dtp)
{
  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
    {
      dtp->u.p.current_unit->next_char_fn_ptr = &next_char_utf8;
      dtp->u.p.current_unit->push_char_fn_ptr = &push_char4;
    }
  else if (is_internal_unit (dtp))
    {
      dtp->u.p.current_unit->next_char_fn_ptr = &next_char_internal;
      dtp->u.p.current_unit->push_char_fn_ptr = &push_char_default;
    }
  else
    {
      dtp->u.p.current_unit->next_char_fn_ptr = &next_char_default;
      dtp->u.p.current_unit->push_char_fn_ptr = &push_char_default;
    }

}

/* Top level data transfer subroutine for list reads.  Because we have
   to deal with repeat counts, the data item is always saved after
   reading, usually in the dtp->u.p.value[] array.  If a repeat count is
   greater than one, we copy the data item multiple times.  */

static int
list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p,
			    int kind, size_t size)
{
  gfc_char4_t *q, *r;
  size_t m;
  int c;
  int err = 0;

  /* Set the next_char and push_char worker functions.  */
  set_workers (dtp);

  if (dtp->u.p.first_item)
    {
      dtp->u.p.first_item = 0;
      dtp->u.p.input_complete = 0;
      dtp->u.p.repeat_count = 1;
      dtp->u.p.at_eol = 0;

      if ((c = eat_spaces (dtp)) == EOF)
	{
	  err = LIBERROR_END;
	  goto cleanup;
	}
      if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
	c = '.';
      else if (is_separator (c))
	{
	  /* Found a null value.  */
	  dtp->u.p.repeat_count = 0;
	  eat_separator (dtp);

	  /* Set end-of-line flag.  */
	  if (c == '\n' || c == '\r')
	    {
	      dtp->u.p.at_eol = 1;
	      if (finish_separator (dtp) == LIBERROR_END)
		{
		  err = LIBERROR_END;
		  goto cleanup;
		}
	    }
	  else
	    goto cleanup;
	}
    }
  else
    {
      if (dtp->u.p.repeat_count > 0)
	{
	  if (check_type (dtp, type, kind))
	    return err;
	  goto set_value;
	}

      if (dtp->u.p.input_complete)
	goto cleanup;

      if (dtp->u.p.at_eol)
	finish_separator (dtp);
      else
        {
	  eat_spaces (dtp);
          /* Trailing spaces prior to end of line.  */
	  if (dtp->u.p.at_eol)
	    finish_separator (dtp);
        }

      dtp->u.p.saved_type = BT_UNKNOWN;
      dtp->u.p.repeat_count = 1;
    }

  switch (type)
    {
    case BT_INTEGER:
    case BT_UNSIGNED:
      read_integer (dtp, kind, type);
      break;
    case BT_LOGICAL:
      read_logical (dtp, kind);
      break;
    case BT_CHARACTER:
      read_character (dtp, kind);
      break;
    case BT_REAL:
      read_real (dtp, p, kind);
      /* Copy value back to temporary if needed.  */
      if (dtp->u.p.repeat_count > 0)
	memcpy (dtp->u.p.value, p, size);
      break;
    case BT_COMPLEX:
      read_complex (dtp, p, kind, size);
      /* Copy value back to temporary if needed.  */
      if (dtp->u.p.repeat_count > 0)
	memcpy (dtp->u.p.value, p, size);
      break;
    case BT_CLASS:
      {
	  GFC_INTEGER_4 unit = dtp->u.p.current_unit->unit_number;
	  char iotype[] = "LISTDIRECTED";
          gfc_charlen_type iotype_len = 12;
	  char tmp_iomsg[IOMSG_LEN];
	  char *child_iomsg;
	  gfc_charlen_type child_iomsg_len;
	  GFC_INTEGER_4 noiostat;
	  GFC_INTEGER_4 *child_iostat = NULL;
	  gfc_full_array_i4 vlist;

	  GFC_DESCRIPTOR_DATA(&vlist) = NULL;
	  GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);

	  /* Set iostat, intent(out).  */
	  noiostat = 0;
	  child_iostat = ((dtp->common.flags & IOPARM_HAS_IOSTAT)
			  ? dtp->common.iostat : &noiostat);

	  /* Set iomsg, intent(inout).  */
	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
	    {
	      child_iomsg = dtp->common.iomsg;
	      child_iomsg_len = dtp->common.iomsg_len;
	    }
	  else
	    {
	      child_iomsg = tmp_iomsg;
	      child_iomsg_len = IOMSG_LEN;
	    }

	  /* Call the user defined formatted READ procedure.  */
	  dtp->u.p.current_unit->child_dtio++;
	  dtp->u.p.fdtio_ptr (p, &unit, iotype, &vlist,
			      child_iostat, child_iomsg,
			      iotype_len, child_iomsg_len);
	  dtp->u.p.child_saved_iostat = *child_iostat;
	  dtp->u.p.current_unit->child_dtio--;

	  if ((dtp->u.p.child_saved_iostat != 0) &&
	      !(dtp->common.flags & IOPARM_HAS_IOMSG) &&
	      !(dtp->common.flags & IOPARM_HAS_IOSTAT))
	    {
	      char message[IOMSG_LEN + 1];
	      child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg);
	      free_line (dtp);
	      fstrcpy (message, child_iomsg_len, child_iomsg, child_iomsg_len);
	      message[child_iomsg_len] = '\0';
	      generate_error (&dtp->common, dtp->u.p.child_saved_iostat,
			      message);
	    }
      }
      break;
    default:
      internal_error (&dtp->common, "Bad type for list read");
    }

  if (dtp->u.p.saved_type != BT_CHARACTER && dtp->u.p.saved_type != BT_UNKNOWN)
    dtp->u.p.saved_length = size;

  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    goto cleanup;

 set_value:
  switch (dtp->u.p.saved_type)
    {
    case BT_COMPLEX:
    case BT_REAL:
      if (dtp->u.p.repeat_count > 0)
	memcpy (p, dtp->u.p.value, size);
      break;

    case BT_INTEGER:
    case BT_UNSIGNED:
    case BT_LOGICAL:
      memcpy (p, dtp->u.p.value, size);
      break;

    case BT_CHARACTER:
      if (dtp->u.p.saved_string)
	{
	  m = (size < (size_t) dtp->u.p.saved_used)
	    ? size : (size_t) dtp->u.p.saved_used;

	  q = (gfc_char4_t *) p;
	  r = (gfc_char4_t *) dtp->u.p.saved_string;
	  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
	    for (size_t i = 0; i < m; i++)
	      *q++ = *r++;
	  else
	    {
	      if (kind == 1)
		memcpy (p, dtp->u.p.saved_string, m);
	      else
		for (size_t i = 0; i < m; i++)
		  *q++ = *r++;
	    }
	}
      else
	/* Just delimiters encountered, nothing to copy but SPACE.  */
        m = 0;

      if (m < size)
	{
	  if (kind == 1)
	    memset (((char *) p) + m, ' ', size - m);
	  else
	    {
	      q = (gfc_char4_t *) p;
	      for (size_t i = m; i < size; i++)
		q[i] = (unsigned char) ' ';
	    }
	}
      break;

    case BT_UNKNOWN:
      break;

    default:
      internal_error (&dtp->common, "Bad type for list read");
    }

  if (--dtp->u.p.repeat_count <= 0)
    free_saved (dtp);

cleanup:
  /* err may have been set above from finish_separator, so if it is set
     trigger the hit_eof. The hit_eof will set bits in common.flags.  */
  if (err == LIBERROR_END)
    {
      free_line (dtp);
      hit_eof (dtp);
    }
  /* Now we check common.flags for any errors that could have occurred in
     a READ elsewhere such as in read_integer.  */
  err = dtp->common.flags & IOPARM_LIBRETURN_MASK;
  fbuf_flush_list (dtp->u.p.current_unit, LIST_READING);
  return err;
}


void
list_formatted_read (st_parameter_dt *dtp, bt type, void *p, int kind,
		     size_t size, size_t nelems)
{
  size_t elem;
  char *tmp;
  size_t stride = type == BT_CHARACTER ?
		  size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
  int err;

  tmp = (char *) p;

  /* Big loop over all the elements.  */
  for (elem = 0; elem < nelems; elem++)
    {
      dtp->u.p.item_count++;
      err = list_formatted_read_scalar (dtp, type, tmp + stride*elem,
					kind, size);
      if (err)
	break;
    }
}


/* Finish a list read.  */

void
finish_list_read (st_parameter_dt *dtp)
{
  free_saved (dtp);

  fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);

  if (dtp->u.p.at_eol)
    {
      dtp->u.p.at_eol = 0;
      return;
    }

  if (!is_internal_unit (dtp))
    {
      int c;

      /* Set the next_char and push_char worker functions.  */
      set_workers (dtp);

      if (likely (dtp->u.p.child_saved_iostat == LIBERROR_OK)
	      && ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0))
	{
	  c = next_char (dtp);
	  if (c == EOF)
	    {
	      free_line (dtp);
	      hit_eof (dtp);
	      return;
	    }
	  if (c != '\n')
	    eat_line (dtp);
	}
    }

  free_line (dtp);

}

/*			NAMELIST INPUT

void namelist_read (st_parameter_dt *dtp)
calls:
   static void nml_match_name (char *name, int len)
   static int nml_query (st_parameter_dt *dtp)
   static int nml_get_obj_data (st_parameter_dt *dtp,
				namelist_info **prev_nl, char *, size_t)
calls:
      static void nml_untouch_nodes (st_parameter_dt *dtp)
      static namelist_info *find_nml_node (st_parameter_dt *dtp,
					   char *var_name)
      static int nml_parse_qualifier(descriptor_dimension *ad,
				     array_loop_spec *ls, int rank, char *)
      static void nml_touch_nodes (namelist_info *nl)
      static int nml_read_obj (namelist_info *nl, index_type offset,
			       namelist_info **prev_nl, char *, size_t,
			       index_type clow, index_type chigh)
calls:
      -itself-  */

/* Inputs a rank-dimensional qualifier, which can contain
   singlets, doublets, triplets or ':' with the standard meanings.  */

static bool
nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad,
		     array_loop_spec *ls, int rank, bt nml_elem_type,
		     char *parse_err_msg, size_t parse_err_msg_size,
		     int *parsed_rank)
{
  int dim;
  int indx;
  int neg;
  int null_flag;
  int is_array_section, is_char;
  int c;

  is_char = 0;
  is_array_section = 0;
  dtp->u.p.expanded_read = 0;

  /* See if this is a character substring qualifier we are looking for.  */
  if (rank == -1)
    {
      rank = 1;
      is_char = 1;
    }

  /* The next character in the stream should be the '('.  */

  if ((c = next_char (dtp)) == EOF)
    goto err_ret;

  /* Process the qualifier, by dimension and triplet.  */

  for (dim=0; dim < rank; dim++ )
    {
      for (indx=0; indx<3; indx++)
	{
	  free_saved (dtp);
	  eat_spaces (dtp);
	  neg = 0;

	  /* Process a potential sign.  */
	  if ((c = next_char (dtp)) == EOF)
	    goto err_ret;
	  switch (c)
	    {
	    case '-':
	      neg = 1;
	      break;

	    case '+':
	      break;

	    default:
	      unget_char (dtp, c);
	      break;
	    }

	  /* Process characters up to the next ':' , ',' or ')'.  */
	  for (;;)
	    {
	      c = next_char (dtp);
	      switch (c)
		{
		case EOF:
		  goto err_ret;

		case ':':
                  is_array_section = 1;
		  break;

		case ',': case ')':
		  if ((c==',' && dim == rank -1)
		      || (c==')' && dim < rank -1))
		    {
		      if (is_char)
		        snprintf (parse_err_msg, parse_err_msg_size,
				  "Bad substring qualifier");
		      else
			snprintf (parse_err_msg, parse_err_msg_size,
				 "Bad number of index fields");
		      goto err_ret;
		    }
		  break;

		CASE_DIGITS:
		  push_char (dtp, c);
		  continue;

		case ' ': case '\t': case '\r': case '\n':
		  eat_spaces (dtp);
		  break;

		default:
		  if (is_char)
		    snprintf (parse_err_msg, parse_err_msg_size,
			     "Bad character in substring qualifier");
		  else
		    snprintf (parse_err_msg, parse_err_msg_size,
			      "Bad character in index");
		  goto err_ret;
		}

	      if ((c == ',' || c == ')') && indx == 0
		  && dtp->u.p.saved_string == 0)
		{
		  if (is_char)
		    snprintf (parse_err_msg, parse_err_msg_size,
			      "Null substring qualifier");
		  else
		    snprintf (parse_err_msg, parse_err_msg_size,
			      "Null index field");
		  goto err_ret;
		}

	      if ((c == ':' && indx == 1 && dtp->u.p.saved_string == 0)
		  || (indx == 2 && dtp->u.p.saved_string == 0))
		{
		  if (is_char)
		    snprintf (parse_err_msg, parse_err_msg_size,
			      "Bad substring qualifier");
		  else
		    snprintf (parse_err_msg, parse_err_msg_size,
			      "Bad index triplet");
		  goto err_ret;
		}

	      if (is_char && !is_array_section)
		{
		  snprintf (parse_err_msg, parse_err_msg_size,
			   "Missing colon in substring qualifier");
		  goto err_ret;
		}

	      /* If '( : ? )' or '( ? : )' break and flag read failure.  */
	      null_flag = 0;
	      if ((c == ':' && indx == 0 && dtp->u.p.saved_string == 0)
		  || (indx==1 && dtp->u.p.saved_string == 0))
		{
		  null_flag = 1;
		  break;
		}

	      /* Now read the index.  */
	      if (convert_integer (dtp, sizeof(index_type), neg))
		{
		  if (is_char)
		    snprintf (parse_err_msg, parse_err_msg_size,
			      "Bad integer substring qualifier");
		  else
		    snprintf (parse_err_msg, parse_err_msg_size,
			      "Bad integer in index");
		  goto err_ret;
		}
	      break;
	    }

	  /* Feed the index values to the triplet arrays.  */
	  if (!null_flag)
	    {
	      if (indx == 0)
		memcpy (&ls[dim].start, dtp->u.p.value, sizeof(index_type));
	      if (indx == 1)
		memcpy (&ls[dim].end, dtp->u.p.value, sizeof(index_type));
	      if (indx == 2)
		memcpy (&ls[dim].step, dtp->u.p.value, sizeof(index_type));
	    }

	  /* Singlet or doublet indices.  */
	  if (c==',' || c==')')
	    {
	      if (indx == 0)
		{
		  memcpy (&ls[dim].start, dtp->u.p.value, sizeof(index_type));

		  /*  If -std=f95/2003 or an array section is specified,
		      do not allow excess data to be processed.  */
		  if (is_array_section == 1
		      || !(compile_options.allow_std & GFC_STD_GNU)
		      || nml_elem_type == BT_DERIVED)
		    ls[dim].end = ls[dim].start;
		  else
		    dtp->u.p.expanded_read = 1;
		}

	      /* Check for non-zero rank.  */
	      if (is_array_section == 1 && ls[dim].start != ls[dim].end)
		*parsed_rank = 1;

	      break;
	    }
	}

      if (is_array_section == 1 && dtp->u.p.expanded_read == 1)
	{
	  int i;
	  dtp->u.p.expanded_read = 0;
	  for (i = 0; i < dim; i++)
	    ls[i].end = ls[i].start;
	}

      /* Check the values of the triplet indices.  */
      if ((ls[dim].start > GFC_DIMENSION_UBOUND(ad[dim]))
	   || (ls[dim].start < GFC_DIMENSION_LBOUND(ad[dim]))
	   || (ls[dim].end > GFC_DIMENSION_UBOUND(ad[dim]))
	   || (ls[dim].end < GFC_DIMENSION_LBOUND(ad[dim])))
	{
	  if (is_char)
	    snprintf (parse_err_msg, parse_err_msg_size,
		      "Substring out of range");
	  else
	    snprintf (parse_err_msg, parse_err_msg_size,
		      "Index %d out of range", dim + 1);
	  goto err_ret;
	}

      if (((ls[dim].end - ls[dim].start ) * ls[dim].step < 0)
	  || (ls[dim].step == 0))
	{
	  snprintf (parse_err_msg, parse_err_msg_size,
		   "Bad range in index %d", dim + 1);
	  goto err_ret;
	}

      /* Initialise the loop index counter.  */
      ls[dim].idx = ls[dim].start;
    }
  eat_spaces (dtp);
  return true;

err_ret:

  /* The EOF error message is issued by hit_eof. Return true so that the
     caller does not use parse_err_msg and parse_err_msg_size to generate
     an unrelated error message.  */
  if (c == EOF)
    {
      hit_eof (dtp);
      dtp->u.p.input_complete = 1;
      return true;
    }
  return false;
}


static bool
extended_look_ahead (char *p, char *q)
{
  char *r, *s;

  /* Scan ahead to find a '%' in the p string.  */
  for(r = p, s = q; *r && *s; s++)
    if ((*s == '%' || *s == '+') && strcmp (r + 1, s + 1) == 0)
      return true;
  return false;
}


static bool
strcmp_extended_type (char *p, char *q)
{
  char *r, *s;

  for (r = p, s = q; *r && *s; r++, s++)
    {
      if (*r != *s)
	{
	  if (*r == '%' && *s == '+' && extended_look_ahead (r, s))
	    return true;
	  break;
	}
    }
  return false;
}


static namelist_info *
find_nml_node (st_parameter_dt *dtp, char *var_name)
{
  namelist_info *t = dtp->u.p.ionml;
  while (t != NULL)
    {
      if (strcmp (var_name, t->var_name) == 0)
	{
	  t->touched = 1;
	  return t;
	}
      if (strcmp_extended_type (var_name, t->var_name))
	{
	  t->touched = 1;
	  return t;
	}
      t = t->next;
    }
  return NULL;
}

/* Visits all the components of a derived type that have
   not explicitly been identified in the namelist input.
   touched is set and the loop specification initialised
   to default values  */

static void
nml_touch_nodes (namelist_info *nl)
{
  index_type len = strlen (nl->var_name) + 1;
  int dim;
  char *ext_name = xmalloc (len + 1);
  memcpy (ext_name, nl->var_name, len-1);
  memcpy (ext_name + len - 1, "%", 2);
  for (nl = nl->next; nl; nl = nl->next)
    {
      if (strncmp (nl->var_name, ext_name, len) == 0)
	{
	  nl->touched = 1;
	  for (dim=0; dim < nl->var_rank; dim++)
	    {
	      nl->ls[dim].step = 1;
	      nl->ls[dim].end = GFC_DESCRIPTOR_UBOUND(nl,dim);
	      nl->ls[dim].start = GFC_DESCRIPTOR_LBOUND(nl,dim);
	      nl->ls[dim].idx = nl->ls[dim].start;
	    }
	}
      else
	break;
    }
  free (ext_name);
  return;
}

/* Resets touched for the entire list of nml_nodes, ready for a
   new object.  */

static void
nml_untouch_nodes (st_parameter_dt *dtp)
{
  namelist_info *t;
  for (t = dtp->u.p.ionml; t; t = t->next)
    t->touched = 0;
  return;
}

/* Attempts to input name to namelist name.  Returns
   dtp->u.p.nml_read_error = 1 on no match.  */

static void
nml_match_name (st_parameter_dt *dtp, const char *name, index_type len)
{
  index_type i;
  int c;

  dtp->u.p.nml_read_error = 0;
  for (i = 0; i < len; i++)
    {
      c = next_char (dtp);
      if (c == EOF || (safe_tolower (c) != safe_tolower (name[i])))
	{
	  dtp->u.p.nml_read_error = 1;
	  break;
	}
    }
}

/* If the namelist read is from stdin, output the current state of the
   namelist to stdout.  This is used to implement the non-standard query
   features, ? and =?. If c == '=' the full namelist is printed. Otherwise
   the names alone are printed.  */

static void
nml_query (st_parameter_dt *dtp, char c)
{
  gfc_unit *temp_unit;
  namelist_info *nl;
  index_type len;
  char *p;
#ifdef HAVE_CRLF
  static const index_type endlen = 2;
  static const char endl[] = "\r\n";
  static const char nmlend[] = "&end\r\n";
#else
  static const index_type endlen = 1;
  static const char endl[] = "\n";
  static const char nmlend[] = "&end\n";
#endif

  if (dtp->u.p.current_unit->unit_number != options.stdin_unit)
    return;

  /* Store the current unit and transfer to stdout.  */

  temp_unit = dtp->u.p.current_unit;
  dtp->u.p.current_unit = find_unit (options.stdout_unit);

  if (dtp->u.p.current_unit)
    {
      dtp->u.p.mode = WRITING;
      next_record (dtp, 0);

      /* Write the namelist in its entirety.  */

      if (c == '=')
	namelist_write (dtp);

      /* Or write the list of names.  */

      else
	{
	  /* "&namelist_name\n"  */

	  len = dtp->namelist_name_len;
	  p = write_block (dtp, len - 1 + endlen);
          if (!p)
            goto query_return;
	  memcpy (p, "&", 1);
	  memcpy ((char*)(p + 1), dtp->namelist_name, len);
	  memcpy ((char*)(p + len + 1), &endl, endlen);
	  for (nl = dtp->u.p.ionml; nl; nl = nl->next)
	    {
	      /* " var_name\n"  */

	      len = strlen (nl->var_name);
              p = write_block (dtp, len + endlen);
	      if (!p)
		goto query_return;
	      memcpy (p, " ", 1);
	      memcpy ((char*)(p + 1), nl->var_name, len);
	      memcpy ((char*)(p + len + 1), &endl, endlen);
	    }

	  /* "&end\n"  */

          p = write_block (dtp, endlen + 4);
	  if (!p)
	    goto query_return;
          memcpy (p, &nmlend, endlen + 4);
	}

      /* Flush the stream to force immediate output.  */

      fbuf_flush (dtp->u.p.current_unit, WRITING);
      sflush (dtp->u.p.current_unit->s);
      unlock_unit (dtp->u.p.current_unit);
    }

query_return:

  /* Restore the current unit.  */

  dtp->u.p.current_unit = temp_unit;
  dtp->u.p.mode = READING;
  return;
}

/* Reads and stores the input for the namelist object nl.  For an array,
   the function loops over the ranges defined by the loop specification.
   This default to all the data or to the specification from a qualifier.
   nml_read_obj recursively calls itself to read derived types. It visits
   all its own components but only reads data for those that were touched
   when the name was parsed.  If a read error is encountered, an attempt is
   made to return to read a new object name because the standard allows too
   little data to be available.  On the other hand, too much data is an
   error.  */

static bool
nml_read_obj (st_parameter_dt *dtp, namelist_info *nl, index_type offset,
	      namelist_info **pprev_nl, char *nml_err_msg,
	      size_t nml_err_msg_size, index_type clow, index_type chigh)
{
  namelist_info *cmp;
  char *obj_name;
  int nml_carry;
  int len;
  int dim;
  index_type dlen;
  index_type m;
  size_t obj_name_len;
  void *pdata;
  gfc_class list_obj;

  /* If we have encountered a previous read error or this object has not been
     touched in name parsing, just return.  */
  if (dtp->u.p.nml_read_error || !nl->touched)
    return true;

  dtp->u.p.item_count++;  /* Used in error messages.  */
  dtp->u.p.repeat_count = 0;
  eat_spaces (dtp);

  len = nl->len;
  switch (nl->type)
  {
    case BT_INTEGER:
    case BT_LOGICAL:
      dlen = len;
      break;

    case BT_REAL:
      dlen = size_from_real_kind (len);
      break;

    case BT_COMPLEX:
      dlen = size_from_complex_kind (len);
      break;

    case BT_CHARACTER:
      dlen = chigh ? (chigh - clow + 1) : nl->string_length;
      break;

    default:
      dlen = 0;
    }

  do
    {
      /* Update the pointer to the data, using the current index vector  */

      if ((nl->type == BT_DERIVED || nl->type == BT_CLASS)
	  && nl->dtio_sub != NULL)
	{
	  pdata = NULL;  /* Not used under these conidtions.  */
	  if (nl->type == BT_CLASS)
	    list_obj.data = ((gfc_class*)nl->mem_pos)->data;
	  else
	    list_obj.data = (void *)nl->mem_pos;

	  for (dim = 0; dim < nl->var_rank; dim++)
	    list_obj.data = list_obj.data + (nl->ls[dim].idx
	      - GFC_DESCRIPTOR_LBOUND(nl,dim))
	      * GFC_DESCRIPTOR_STRIDE(nl,dim) * nl->size;
	}
      else
	{
	  pdata = (void*)(nl->mem_pos + offset);
	  for (dim = 0; dim < nl->var_rank; dim++)
	    pdata = (void*)(pdata + (nl->ls[dim].idx
	      - GFC_DESCRIPTOR_LBOUND(nl,dim))
	      * GFC_DESCRIPTOR_STRIDE(nl,dim) * nl->size);
	}

      /* If we are finished with the repeat count, try to read next value.  */

      nml_carry = 0;
      if (--dtp->u.p.repeat_count <= 0)
	{
	  if (dtp->u.p.input_complete)
	    return true;
	  if (dtp->u.p.at_eol)
	    finish_separator (dtp);
	  if (dtp->u.p.input_complete)
	    return true;

	  dtp->u.p.saved_type = BT_UNKNOWN;
	  free_saved (dtp);

          switch (nl->type)
	  {
	  case BT_INTEGER:
	  case BT_UNSIGNED:
	    read_integer (dtp, len, nl->type);
            break;

	  case BT_LOGICAL:
	    read_logical (dtp, len);
	    break;

	  case BT_CHARACTER:
	    read_character (dtp, len);
	    break;

	  case BT_REAL:
	    /* Need to copy data back from the real location to the temp in
	       order to handle nml reads into arrays.  */
	    read_real (dtp, pdata, len);
	    memcpy (dtp->u.p.value, pdata, dlen);
	    break;

	  case BT_COMPLEX:
	    /* Same as for REAL, copy back to temp.  */
	    read_complex (dtp, pdata, len, dlen);
	    memcpy (dtp->u.p.value, pdata, dlen);
	    break;

	  case BT_DERIVED:
	  case BT_CLASS:
	    /* If this object has a User Defined procedure, call it.  */
	    if (nl->dtio_sub != NULL)
	      {
		GFC_INTEGER_4 unit = dtp->u.p.current_unit->unit_number;
		char iotype[] = "NAMELIST";
		gfc_charlen_type iotype_len = 8;
		char tmp_iomsg[IOMSG_LEN] = "";
		char *child_iomsg;
		gfc_charlen_type child_iomsg_len;
		GFC_INTEGER_4 noiostat;
		GFC_INTEGER_4 *child_iostat = NULL;
		gfc_full_array_i4 vlist;
		formatted_dtio dtio_ptr = (formatted_dtio)nl->dtio_sub;

		GFC_DESCRIPTOR_DATA(&vlist) = NULL;
		GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);

		list_obj.vptr = nl->vtable;
		list_obj.len = 0;

		/* Set iostat, intent(out).  */
		noiostat = 0;
		child_iostat = ((dtp->common.flags & IOPARM_HAS_IOSTAT)
				? dtp->common.iostat : &noiostat);

		/* Set iomsg, intent(inout).  */
		if (dtp->common.flags & IOPARM_HAS_IOMSG)
		  {
		    child_iomsg = dtp->common.iomsg;
		    child_iomsg_len = dtp->common.iomsg_len;
		  }
		else
		  {
		    child_iomsg = tmp_iomsg;
		    child_iomsg_len = IOMSG_LEN;
		  }

		/* Call the user defined formatted READ procedure.  */
		dtp->u.p.current_unit->child_dtio++;
		dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
			  child_iostat, child_iomsg,
			  iotype_len, child_iomsg_len);
		dtp->u.p.child_saved_iostat = *child_iostat;
		dtp->u.p.current_unit->child_dtio--;

		if ((dtp->u.p.child_saved_iostat != 0) &&
		    !(dtp->common.flags & IOPARM_HAS_IOMSG) &&
		    !(dtp->common.flags & IOPARM_HAS_IOSTAT))
		  {
		    char message[IOMSG_LEN + 1];
		    child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg);
		    fstrcpy (message, child_iomsg_len, child_iomsg, child_iomsg_len);
		    message[child_iomsg_len] = '\0';
		    generate_error (&dtp->common, dtp->u.p.child_saved_iostat,
				    message);
		    goto nml_err_ret;
		  }

		goto incr_idx;
	      }

	    /* Must be default derived type namelist read.  */
	    obj_name_len = strlen (nl->var_name) + 1;
	    obj_name = xmalloc (obj_name_len+1);
	    memcpy (obj_name, nl->var_name, obj_name_len-1);
	    memcpy (obj_name + obj_name_len - 1, "%", 2);

	    /* If reading a derived type, disable the expanded read warning
	       since a single object can have multiple reads.  */
	    dtp->u.p.expanded_read = 0;

	    /* Now loop over the components.  */

	    for (cmp = nl->next;
		 cmp &&
		   !strncmp (cmp->var_name, obj_name, obj_name_len);
		 cmp = cmp->next)
	      {
		/* Jump over nested derived type by testing if the potential
		   component name contains '%'.  */
		if (strchr (cmp->var_name + obj_name_len, '%'))
		    continue;

		if (!nml_read_obj (dtp, cmp, (index_type)(pdata - nl->mem_pos),
				  pprev_nl, nml_err_msg, nml_err_msg_size,
				  clow, chigh))
		  {
		    free (obj_name);
		    return false;
		  }

		if (dtp->u.p.input_complete)
		  {
		    free (obj_name);
		    return true;
		  }
	      }

	    free (obj_name);
	    goto incr_idx;

          default:
	    snprintf (nml_err_msg, nml_err_msg_size,
		      "Bad type for namelist object %s", nl->var_name);
	    internal_error (&dtp->common, nml_err_msg);
	    goto nml_err_ret;
          }
        }

      /* The standard permits array data to stop short of the number of
	 elements specified in the loop specification.  In this case, we
	 should be here with dtp->u.p.nml_read_error != 0.  Control returns to
	 nml_get_obj_data and an attempt is made to read object name.  */

      *pprev_nl = nl;
      if (dtp->u.p.nml_read_error)
	{
	  dtp->u.p.expanded_read = 0;
	  return true;
	}

      if (dtp->u.p.saved_type == BT_UNKNOWN)
	{
	  dtp->u.p.expanded_read = 0;
	  goto incr_idx;
	}

      switch (dtp->u.p.saved_type)
      {

	case BT_COMPLEX:
	case BT_REAL:
	case BT_INTEGER:
	case BT_LOGICAL:
	  memcpy (pdata, dtp->u.p.value, dlen);
	  break;

	case BT_CHARACTER:
	  if (dlen < dtp->u.p.saved_used)
	    {
	      if (compile_options.bounds_check)
		{
		  snprintf (nml_err_msg, nml_err_msg_size,
			    "Namelist object '%s' truncated on read.",
			    nl->var_name);
		  generate_warning (&dtp->common, nml_err_msg);
		}
	      m = dlen;
	    }
	  else
	    m = dtp->u.p.saved_used;

	  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
	    {
	      gfc_char4_t *q4, *p4 = pdata;
	      int i;

	      q4 = (gfc_char4_t *) dtp->u.p.saved_string;
	      p4 += clow -1;
	      for (i = 0; i < m; i++)
		*p4++ = *q4++;
	      if (m < dlen)
		for (i = 0; i < dlen - m; i++)
		  *p4++ = (gfc_char4_t) ' ';
	    }
	  else
	    {
	      pdata = (void*)( pdata + clow - 1 );
	      memcpy (pdata, dtp->u.p.saved_string, m);
	      if (m < dlen)
		memset ((void*)( pdata + m ), ' ', dlen - m);
	    }
	  break;

	default:
	  break;
      }

      /* Warn if a non-standard expanded read occurs. A single read of a
	 single object is acceptable.  If a second read occurs, issue a warning
	 and set the flag to zero to prevent further warnings.  */
      if (dtp->u.p.expanded_read == 2)
	{
	  notify_std (&dtp->common, GFC_STD_GNU, "Non-standard expanded namelist read.");
	  dtp->u.p.expanded_read = 0;
	}

      /* If the expanded read warning flag is set, increment it,
	 indicating that a single read has occurred.  */
      if (dtp->u.p.expanded_read >= 1)
	dtp->u.p.expanded_read++;

      /* Break out of loop if scalar.  */
      if (!nl->var_rank)
	break;

      /* Now increment the index vector.  */

incr_idx:

      nml_carry = 1;
      for (dim = 0; dim < nl->var_rank; dim++)
	{
	  nl->ls[dim].idx += nml_carry * nl->ls[dim].step;
	  nml_carry = 0;
	  if (((nl->ls[dim].step > 0) && (nl->ls[dim].idx > nl->ls[dim].end))
	      ||
	      ((nl->ls[dim].step < 0) && (nl->ls[dim].idx < nl->ls[dim].end)))
	    {
	      nl->ls[dim].idx = nl->ls[dim].start;
	      nml_carry = 1;
	    }
        }
    } while (!nml_carry);

  if (dtp->u.p.repeat_count > 1)
    {
      snprintf (nml_err_msg, nml_err_msg_size,
		"Repeat count too large for namelist object %s", nl->var_name);
      goto nml_err_ret;
    }
  return true;

nml_err_ret:

  return false;
}

/* Parses the object name, including array and substring qualifiers.  It
   iterates over derived type components, touching those components and
   setting their loop specifications, if there is a qualifier.  If the
   object is itself a derived type, its components and subcomponents are
   touched.  nml_read_obj is called at the end and this reads the data in
   the manner specified by the object name.  */

static bool
nml_get_obj_data (st_parameter_dt *dtp, namelist_info **pprev_nl,
		  char *nml_err_msg, size_t nml_err_msg_size)
{
  int c;
  namelist_info *nl;
  namelist_info *first_nl = NULL;
  namelist_info *root_nl = NULL;
  int dim, parsed_rank;
  int component_flag, qualifier_flag;
  index_type clow, chigh;
  int non_zero_rank_count;

  /* Look for end of input or object name.  If '?' or '=?' are encountered
     in stdin, print the node names or the namelist to stdout.  */

  eat_separator (dtp);
  if (dtp->u.p.input_complete)
    return true;

  if (dtp->u.p.at_eol)
    finish_separator (dtp);
  if (dtp->u.p.input_complete)
    return true;

  if ((c = next_char (dtp)) == EOF)
    goto nml_err_ret;
  switch (c)
    {
    case '=':
      if ((c = next_char (dtp)) == EOF)
	goto nml_err_ret;
      if (c != '?')
	{
	  snprintf (nml_err_msg, nml_err_msg_size,
		    "namelist read: misplaced = sign");
	  goto nml_err_ret;
	}
      nml_query (dtp, '=');
      return true;

    case '?':
      nml_query (dtp, '?');
      return true;

    case '$':
    case '&':
      nml_match_name (dtp, "end", 3);
      if (dtp->u.p.nml_read_error)
	{
	  snprintf (nml_err_msg, nml_err_msg_size,
		    "namelist not terminated with / or &end");
	  goto nml_err_ret;
	}
      /* Fall through.  */
    case '/':
      dtp->u.p.input_complete = 1;
      return true;

    default :
      break;
    }

  /* Untouch all nodes of the namelist and reset the flags that are set for
     derived type components.  */

  nml_untouch_nodes (dtp);
  component_flag = 0;
  qualifier_flag = 0;
  non_zero_rank_count = 0;

  /* Get the object name - should '!' and '\n' be permitted separators?  */

get_name:

  free_saved (dtp);

  do
    {
      if (!is_separator (c))
	push_char_default (dtp, safe_tolower(c));
      if ((c = next_char (dtp)) == EOF)
	goto nml_err_ret;
    }
  while (!( c=='=' || c==' ' || c=='\t' || c =='(' || c =='%' ));

  unget_char (dtp, c);

  /* Check that the name is in the namelist and get pointer to object.
     Three error conditions exist: (i) An attempt is being made to
     identify a non-existent object, following a failed data read or
     (ii) The object name does not exist or (iii) Too many data items
     are present for an object.  (iii) gives the same error message
     as (i)  */

  push_char_default (dtp, '\0');

  if (component_flag)
    {
#define EXT_STACK_SZ 100
      char ext_stack[EXT_STACK_SZ];
      char *ext_name;
      size_t var_len = strlen (root_nl->var_name);
      size_t saved_len
	= dtp->u.p.saved_string ? strlen (dtp->u.p.saved_string) : 0;
      size_t ext_size = var_len + saved_len + 1;

      if (ext_size > EXT_STACK_SZ)
	ext_name = xmalloc (ext_size);
      else
	ext_name = ext_stack;

      memcpy (ext_name, root_nl->var_name, var_len);
      if (dtp->u.p.saved_string)
	memcpy (ext_name + var_len, dtp->u.p.saved_string, saved_len);
      ext_name[var_len + saved_len] = '\0';
      nl = find_nml_node (dtp, ext_name);

      if (ext_size > EXT_STACK_SZ)
	free (ext_name);
    }
  else
    nl = find_nml_node (dtp, dtp->u.p.saved_string);

  if (nl == NULL)
    {
      if (dtp->u.p.nml_read_error && *pprev_nl)
	snprintf (nml_err_msg, nml_err_msg_size,
		  "Bad data for namelist object %s", (*pprev_nl)->var_name);

      else
	snprintf (nml_err_msg, nml_err_msg_size,
		  "Cannot match namelist object name %s",
		  dtp->u.p.saved_string);

      goto nml_err_ret;
    }

  /* Get the length, data length, base pointer and rank of the variable.
     Set the default loop specification first.  */

  for (dim=0; dim < nl->var_rank; dim++)
    {
      nl->ls[dim].step = 1;
      nl->ls[dim].end = GFC_DESCRIPTOR_UBOUND(nl,dim);
      nl->ls[dim].start = GFC_DESCRIPTOR_LBOUND(nl,dim);
      nl->ls[dim].idx = nl->ls[dim].start;
    }

/* Check to see if there is a qualifier: if so, parse it.*/

  if (c == '(' && nl->var_rank)
    {
      parsed_rank = 0;
      if (!nml_parse_qualifier (dtp, nl->dim, nl->ls, nl->var_rank,
			       nl->type, nml_err_msg, nml_err_msg_size,
			       &parsed_rank))
	{
	  char *nml_err_msg_end = strchr (nml_err_msg, '\0');
	  snprintf (nml_err_msg_end,
		    nml_err_msg_size - (nml_err_msg_end - nml_err_msg),
		    " for namelist variable %s", nl->var_name);
	  goto nml_err_ret;
	}
      if (parsed_rank > 0)
	non_zero_rank_count++;

      qualifier_flag = 1;

      if ((c = next_char (dtp)) == EOF)
	goto nml_err_ret;
      unget_char (dtp, c);
    }
  else if (nl->var_rank > 0)
    non_zero_rank_count++;

  /* Now parse a derived type component. The root namelist_info address
     is backed up, as is the previous component level.  The  component flag
     is set and the iteration is made by jumping back to get_name.  */

  if (c == '%')
    {
      if (nl->type != BT_DERIVED)
	{
	  snprintf (nml_err_msg, nml_err_msg_size,
		    "Attempt to get derived component for %s", nl->var_name);
	  goto nml_err_ret;
	}

      /* Don't move first_nl further in the list if a qualifier was found.  */
      if ((*pprev_nl == NULL && !qualifier_flag) || !component_flag)
	first_nl = nl;

      root_nl = nl;

      component_flag = 1;
      if ((c = next_char (dtp)) == EOF)
	goto nml_err_ret;
      goto get_name;
    }

  /* Parse a character qualifier, if present.  chigh = 0 is a default
     that signals that the string length = string_length.  */

  clow = 1;
  chigh = 0;

  if (c == '(' && nl->type == BT_CHARACTER)
    {
      descriptor_dimension chd[1] = { {1, clow, nl->string_length} };
      array_loop_spec ind[1] = { {1, clow, nl->string_length, 1} };

      if (!nml_parse_qualifier (dtp, chd, ind, -1, nl->type,
				nml_err_msg, nml_err_msg_size, &parsed_rank))
	{
	  char *nml_err_msg_end = strchr (nml_err_msg, '\0');
	  snprintf (nml_err_msg_end,
		    nml_err_msg_size - (nml_err_msg_end - nml_err_msg),
		    " for namelist variable %s", nl->var_name);
	  goto nml_err_ret;
	}

      clow = ind[0].start;
      chigh = ind[0].end;

      if (ind[0].step != 1)
	{
	  snprintf (nml_err_msg, nml_err_msg_size,
		    "Step not allowed in substring qualifier"
		    " for namelist object %s", nl->var_name);
	  goto nml_err_ret;
	}

      if ((c = next_char (dtp)) == EOF)
	goto nml_err_ret;
      unget_char (dtp, c);
    }

  /* Make sure no extraneous qualifiers are there.  */

  if (c == '(')
    {
      snprintf (nml_err_msg, nml_err_msg_size,
		"Qualifier for a scalar or non-character namelist object %s",
		nl->var_name);
      goto nml_err_ret;
    }

  /* Make sure there is no more than one non-zero rank object.  */
  if (non_zero_rank_count > 1)
    {
      snprintf (nml_err_msg, nml_err_msg_size,
		"Multiple sub-objects with non-zero rank in namelist object %s",
		nl->var_name);
      non_zero_rank_count = 0;
      goto nml_err_ret;
    }

/* According to the standard, an equal sign MUST follow an object name. The
   following is possibly lax - it allows comments, blank lines and so on to
   intervene.  eat_spaces (dtp); c = next_char (dtp); would be compliant*/

  free_saved (dtp);

  eat_separator (dtp);
  if (dtp->u.p.input_complete)
    return true;

  if (dtp->u.p.at_eol)
    finish_separator (dtp);
  if (dtp->u.p.input_complete)
    return true;

  if ((c = next_char (dtp)) == EOF)
    goto nml_err_ret;

  if (c != '=')
    {
      snprintf (nml_err_msg, nml_err_msg_size,
		"Equal sign must follow namelist object name %s",
		nl->var_name);
      goto nml_err_ret;
    }

  /* If a derived type, touch its components and restore the root
     namelist_info if we have parsed a qualified derived type
     component.  */

  if (nl->type == BT_DERIVED && nl->dtio_sub == NULL)
    nml_touch_nodes (nl);

  if (first_nl)
    {
      if (first_nl->var_rank == 0)
	{
	  if (component_flag && qualifier_flag)
	    nl = first_nl;
	}
      else
	nl = first_nl;
    }

  dtp->u.p.nml_read_error = 0;
  if (!nml_read_obj (dtp, nl, 0, pprev_nl, nml_err_msg, nml_err_msg_size,
		    clow, chigh))
    goto nml_err_ret;

  return true;

nml_err_ret:

  /* The EOF error message is issued by hit_eof. Return true so that the
     caller does not use nml_err_msg and nml_err_msg_size to generate
     an unrelated error message.  */
  if (c == EOF)
    {
      dtp->u.p.input_complete = 1;
      unget_char (dtp, c);
      hit_eof (dtp);
      return true;
    }
  return false;
}

/* Entry point for namelist input.  Goes through input until namelist name
  is matched.  Then cycles through nml_get_obj_data until the input is
  completed or there is an error.  */

void
namelist_read (st_parameter_dt *dtp)
{
  int c;
  char nml_err_msg[200];

  /* Initialize the error string buffer just in case we get an unexpected fail
     somewhere and end up at nml_err_ret.  */
  strcpy (nml_err_msg, "Internal namelist read error");

  /* Pointer to the previously read object, in case attempt is made to read
     new object name.  Should this fail, error message can give previous
     name.  */
  namelist_info *prev_nl = NULL;

  dtp->u.p.input_complete = 0;
  dtp->u.p.expanded_read = 0;

  /* Set the next_char and push_char worker functions.  */
  set_workers (dtp);

  /* Look for &namelist_name .  Skip all characters, testing for $nmlname.
     Exit on success or EOF. If '?' or '=?' encountered in stdin, print
     node names or namelist on stdout.  */

find_nml_name:
  c = next_char (dtp);
  switch (c)
    {
    case '$':
    case '&':
          break;

    case '!':
      eat_line (dtp);
      goto find_nml_name;

    case '=':
      c = next_char (dtp);
      if (c == '?')
	nml_query (dtp, '=');
      else
	unget_char (dtp, c);
      goto find_nml_name;

    case '?':
      nml_query (dtp, '?');
      goto find_nml_name;

    case EOF:
      return;

    default:
      goto find_nml_name;
    }

  /* Match the name of the namelist.  */

  nml_match_name (dtp, dtp->namelist_name, dtp->namelist_name_len);

  if (dtp->u.p.nml_read_error)
    goto find_nml_name;

  /* A trailing space is required, we allow a comma with std=gnu.  */
  c = next_char (dtp);
  if ((c == ',' && !(compile_options.allow_std & GFC_STD_GNU)) || c == ';')
    generate_error (&dtp->common, LIBERROR_READ_VALUE,
		    "Non blank after namelist name not allowed");

  if (!is_separator(c) && c != '!')
    {
      unget_char (dtp, c);
      goto find_nml_name;
    }

  unget_char (dtp, c);
  eat_separator (dtp);

  /* Ready to read namelist objects.  If there is an error in input
     from stdin, output the error message and continue.  */

  while (!dtp->u.p.input_complete)
    {
      if (!nml_get_obj_data (dtp, &prev_nl, nml_err_msg, sizeof nml_err_msg))
	goto nml_err_ret;

      /* Reset the previous namelist pointer if we know we are not going
	 to be doing multiple reads within a single namelist object.  */
      if (prev_nl && prev_nl->var_rank == 0)
	prev_nl = NULL;
    }

  free_saved (dtp);
  free_line (dtp);
  return;


nml_err_ret:

  /* All namelist error calls return from here */
  free_saved (dtp);
  free_line (dtp);
  generate_error (&dtp->common, LIBERROR_READ_VALUE, nml_err_msg);
  return;
}
