Home | History | Annotate | Line # | Download | only in io
      1  1.1.1.4  mrg /* Copyright (C) 2002-2024 Free Software Foundation, Inc.
      2      1.1  mrg    Contributed by Andy Vaught
      3      1.1  mrg    F2003 I/O support contributed by Jerry DeLisle
      4      1.1  mrg 
      5      1.1  mrg This file is part of the GNU Fortran runtime library (libgfortran).
      6      1.1  mrg 
      7      1.1  mrg Libgfortran is free software; you can redistribute it and/or modify
      8      1.1  mrg it under the terms of the GNU General Public License as published by
      9      1.1  mrg the Free Software Foundation; either version 3, or (at your option)
     10      1.1  mrg any later version.
     11      1.1  mrg 
     12      1.1  mrg Libgfortran is distributed in the hope that it will be useful,
     13      1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  mrg GNU General Public License for more details.
     16      1.1  mrg 
     17      1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     18      1.1  mrg permissions described in the GCC Runtime Library Exception, version
     19      1.1  mrg 3.1, as published by the Free Software Foundation.
     20      1.1  mrg 
     21      1.1  mrg You should have received a copy of the GNU General Public License and
     22      1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     23      1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24      1.1  mrg <http://www.gnu.org/licenses/>.  */
     25      1.1  mrg 
     26      1.1  mrg 
     27      1.1  mrg /* format.c-- parse a FORMAT string into a binary format suitable for
     28      1.1  mrg    interpretation during I/O statements.  */
     29      1.1  mrg 
     30      1.1  mrg #include "io.h"
     31      1.1  mrg #include "format.h"
     32      1.1  mrg #include <string.h>
     33      1.1  mrg 
     34      1.1  mrg 
     35  1.1.1.4  mrg static const fnode colon_node = { FMT_COLON, FMT_NONE, 0, NULL, NULL, {{ 0, 0, 0 }}, 0,
     36      1.1  mrg 				  NULL };
     37      1.1  mrg 
     38      1.1  mrg /* Error messages. */
     39      1.1  mrg 
     40  1.1.1.2  mrg static const char posint_required[] = "Positive integer required in format",
     41      1.1  mrg   period_required[] = "Period required in format",
     42      1.1  mrg   nonneg_required[] = "Nonnegative width required in format",
     43      1.1  mrg   unexpected_element[] = "Unexpected element '%c' in format\n",
     44      1.1  mrg   unexpected_end[] = "Unexpected end of format string",
     45      1.1  mrg   bad_string[] = "Unterminated character constant in format",
     46      1.1  mrg   bad_hollerith[] = "Hollerith constant extends past the end of the format",
     47      1.1  mrg   reversion_error[] = "Exhausted data descriptors in format",
     48      1.1  mrg   zero_width[] = "Zero width in format descriptor";
     49      1.1  mrg 
     50      1.1  mrg /* The following routines support caching format data from parsed format strings
     51      1.1  mrg    into a hash table.  This avoids repeatedly parsing duplicate format strings
     52      1.1  mrg    or format strings in I/O statements that are repeated in loops.  */
     53      1.1  mrg 
     54      1.1  mrg 
     55      1.1  mrg /* Traverse the table and free all data.  */
     56      1.1  mrg 
     57      1.1  mrg void
     58      1.1  mrg free_format_hash_table (gfc_unit *u)
     59      1.1  mrg {
     60      1.1  mrg   size_t i;
     61      1.1  mrg 
     62      1.1  mrg   /* free_format_data handles any NULL pointers.  */
     63      1.1  mrg   for (i = 0; i < FORMAT_HASH_SIZE; i++)
     64      1.1  mrg     {
     65      1.1  mrg       if (u->format_hash_table[i].hashed_fmt != NULL)
     66      1.1  mrg 	{
     67      1.1  mrg 	  free_format_data (u->format_hash_table[i].hashed_fmt);
     68      1.1  mrg 	  free (u->format_hash_table[i].key);
     69      1.1  mrg 	}
     70      1.1  mrg       u->format_hash_table[i].key = NULL;
     71      1.1  mrg       u->format_hash_table[i].key_len = 0;
     72      1.1  mrg       u->format_hash_table[i].hashed_fmt = NULL;
     73      1.1  mrg     }
     74      1.1  mrg }
     75      1.1  mrg 
     76      1.1  mrg /* Traverse the format_data structure and reset the fnode counters.  */
     77      1.1  mrg 
     78      1.1  mrg static void
     79      1.1  mrg reset_node (fnode *fn)
     80      1.1  mrg {
     81      1.1  mrg   fnode *f;
     82      1.1  mrg 
     83      1.1  mrg   fn->count = 0;
     84      1.1  mrg   fn->current = NULL;
     85      1.1  mrg 
     86      1.1  mrg   if (fn->format != FMT_LPAREN)
     87      1.1  mrg     return;
     88      1.1  mrg 
     89      1.1  mrg   for (f = fn->u.child; f; f = f->next)
     90      1.1  mrg     {
     91      1.1  mrg       if (f->format == FMT_RPAREN)
     92      1.1  mrg 	break;
     93      1.1  mrg       reset_node (f);
     94      1.1  mrg     }
     95      1.1  mrg }
     96      1.1  mrg 
     97      1.1  mrg static void
     98      1.1  mrg reset_fnode_counters (st_parameter_dt *dtp)
     99      1.1  mrg {
    100      1.1  mrg   fnode *f;
    101      1.1  mrg   format_data *fmt;
    102      1.1  mrg 
    103      1.1  mrg   fmt = dtp->u.p.fmt;
    104      1.1  mrg 
    105      1.1  mrg   /* Clear this pointer at the head so things start at the right place.  */
    106      1.1  mrg   fmt->array.array[0].current = NULL;
    107      1.1  mrg 
    108      1.1  mrg   for (f = fmt->array.array[0].u.child; f; f = f->next)
    109      1.1  mrg     reset_node (f);
    110      1.1  mrg }
    111      1.1  mrg 
    112      1.1  mrg 
    113      1.1  mrg /* A simple hashing function to generate an index into the hash table.  */
    114      1.1  mrg 
    115      1.1  mrg static uint32_t
    116      1.1  mrg format_hash (st_parameter_dt *dtp)
    117      1.1  mrg {
    118      1.1  mrg   char *key;
    119      1.1  mrg   gfc_charlen_type key_len;
    120      1.1  mrg   uint32_t hash = 0;
    121      1.1  mrg   gfc_charlen_type i;
    122      1.1  mrg 
    123      1.1  mrg   /* Hash the format string. Super simple, but what the heck!  */
    124      1.1  mrg   key = dtp->format;
    125      1.1  mrg   key_len = dtp->format_len;
    126      1.1  mrg   for (i = 0; i < key_len; i++)
    127      1.1  mrg     hash ^= key[i];
    128      1.1  mrg   hash &= (FORMAT_HASH_SIZE - 1);
    129      1.1  mrg   return hash;
    130      1.1  mrg }
    131      1.1  mrg 
    132      1.1  mrg 
    133      1.1  mrg static void
    134      1.1  mrg save_parsed_format (st_parameter_dt *dtp)
    135      1.1  mrg {
    136      1.1  mrg   uint32_t hash;
    137      1.1  mrg   gfc_unit *u;
    138      1.1  mrg 
    139      1.1  mrg   hash = format_hash (dtp);
    140      1.1  mrg   u = dtp->u.p.current_unit;
    141      1.1  mrg 
    142      1.1  mrg   /* Index into the hash table.  We are simply replacing whatever is there
    143      1.1  mrg      relying on probability.  */
    144      1.1  mrg   if (u->format_hash_table[hash].hashed_fmt != NULL)
    145      1.1  mrg     free_format_data (u->format_hash_table[hash].hashed_fmt);
    146      1.1  mrg   u->format_hash_table[hash].hashed_fmt = NULL;
    147      1.1  mrg 
    148      1.1  mrg   free (u->format_hash_table[hash].key);
    149      1.1  mrg   u->format_hash_table[hash].key = dtp->format;
    150      1.1  mrg 
    151      1.1  mrg   u->format_hash_table[hash].key_len = dtp->format_len;
    152      1.1  mrg   u->format_hash_table[hash].hashed_fmt = dtp->u.p.fmt;
    153      1.1  mrg }
    154      1.1  mrg 
    155      1.1  mrg 
    156      1.1  mrg static format_data *
    157      1.1  mrg find_parsed_format (st_parameter_dt *dtp)
    158      1.1  mrg {
    159      1.1  mrg   uint32_t hash;
    160      1.1  mrg   gfc_unit *u;
    161      1.1  mrg 
    162      1.1  mrg   hash = format_hash (dtp);
    163      1.1  mrg   u = dtp->u.p.current_unit;
    164      1.1  mrg 
    165      1.1  mrg   if (u->format_hash_table[hash].key != NULL)
    166      1.1  mrg     {
    167      1.1  mrg       /* See if it matches.  */
    168      1.1  mrg       if (u->format_hash_table[hash].key_len == dtp->format_len)
    169      1.1  mrg 	{
    170      1.1  mrg 	  /* So far so good.  */
    171      1.1  mrg 	  if (strncmp (u->format_hash_table[hash].key,
    172      1.1  mrg 	      dtp->format, dtp->format_len) == 0)
    173      1.1  mrg 	    return u->format_hash_table[hash].hashed_fmt;
    174      1.1  mrg 	}
    175      1.1  mrg     }
    176      1.1  mrg   return NULL;
    177      1.1  mrg }
    178      1.1  mrg 
    179      1.1  mrg 
    180      1.1  mrg /* next_char()-- Return the next character in the format string.
    181      1.1  mrg    Returns -1 when the string is done.  If the literal flag is set,
    182      1.1  mrg    spaces are significant, otherwise they are not. */
    183      1.1  mrg 
    184      1.1  mrg static int
    185      1.1  mrg next_char (format_data *fmt, int literal)
    186      1.1  mrg {
    187      1.1  mrg   int c;
    188      1.1  mrg 
    189      1.1  mrg   do
    190      1.1  mrg     {
    191      1.1  mrg       if (fmt->format_string_len == 0)
    192      1.1  mrg 	return -1;
    193      1.1  mrg 
    194      1.1  mrg       fmt->format_string_len--;
    195  1.1.1.3  mrg       c = safe_toupper (*fmt->format_string++);
    196      1.1  mrg       fmt->error_element = c;
    197      1.1  mrg     }
    198      1.1  mrg   while ((c == ' ' || c == '\t') && !literal);
    199      1.1  mrg 
    200      1.1  mrg   return c;
    201      1.1  mrg }
    202      1.1  mrg 
    203      1.1  mrg 
    204      1.1  mrg /* unget_char()-- Back up one character position. */
    205      1.1  mrg 
    206      1.1  mrg #define unget_char(fmt) \
    207      1.1  mrg   { fmt->format_string--; fmt->format_string_len++; }
    208      1.1  mrg 
    209      1.1  mrg 
    210      1.1  mrg /* get_fnode()-- Allocate a new format node, inserting it into the
    211      1.1  mrg    current singly linked list.  These are initially allocated from the
    212      1.1  mrg    static buffer. */
    213      1.1  mrg 
    214      1.1  mrg static fnode *
    215      1.1  mrg get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t)
    216      1.1  mrg {
    217      1.1  mrg   fnode *f;
    218      1.1  mrg 
    219      1.1  mrg   if (fmt->avail == &fmt->last->array[FARRAY_SIZE])
    220      1.1  mrg     {
    221      1.1  mrg       fmt->last->next = xmalloc (sizeof (fnode_array));
    222      1.1  mrg       fmt->last = fmt->last->next;
    223      1.1  mrg       fmt->last->next = NULL;
    224      1.1  mrg       fmt->avail = &fmt->last->array[0];
    225      1.1  mrg     }
    226      1.1  mrg   f = fmt->avail++;
    227      1.1  mrg   memset (f, '\0', sizeof (fnode));
    228  1.1.1.4  mrg   f->pushed = FMT_NONE;
    229      1.1  mrg 
    230      1.1  mrg   if (*head == NULL)
    231      1.1  mrg     *head = *tail = f;
    232      1.1  mrg   else
    233      1.1  mrg     {
    234      1.1  mrg       (*tail)->next = f;
    235      1.1  mrg       *tail = f;
    236      1.1  mrg     }
    237      1.1  mrg 
    238      1.1  mrg   f->format = t;
    239      1.1  mrg   f->repeat = -1;
    240      1.1  mrg   f->source = fmt->format_string;
    241      1.1  mrg   return f;
    242      1.1  mrg }
    243      1.1  mrg 
    244      1.1  mrg 
    245      1.1  mrg /* free_format()-- Free allocated format string.  */
    246      1.1  mrg void
    247      1.1  mrg free_format (st_parameter_dt *dtp)
    248      1.1  mrg {
    249      1.1  mrg   if ((dtp->common.flags & IOPARM_DT_HAS_FORMAT) && dtp->format)
    250      1.1  mrg     {
    251      1.1  mrg       free (dtp->format);
    252      1.1  mrg       dtp->format = NULL;
    253      1.1  mrg     }
    254      1.1  mrg }
    255      1.1  mrg 
    256      1.1  mrg 
    257      1.1  mrg /* free_format_data()-- Free all allocated format data.  */
    258      1.1  mrg 
    259      1.1  mrg void
    260      1.1  mrg free_format_data (format_data *fmt)
    261      1.1  mrg {
    262      1.1  mrg   fnode_array *fa, *fa_next;
    263      1.1  mrg   fnode *fnp;
    264      1.1  mrg 
    265      1.1  mrg   if (fmt == NULL)
    266      1.1  mrg     return;
    267      1.1  mrg 
    268      1.1  mrg   /* Free vlist descriptors in the fnode_array if one was allocated.  */
    269      1.1  mrg   for (fnp = fmt->array.array; fnp < &fmt->array.array[FARRAY_SIZE] &&
    270      1.1  mrg        fnp->format != FMT_NONE; fnp++)
    271      1.1  mrg     if (fnp->format == FMT_DT)
    272      1.1  mrg 	{
    273  1.1.1.4  mrg 	  free (GFC_DESCRIPTOR_DATA(fnp->u.udf.vlist));
    274      1.1  mrg 	  free (fnp->u.udf.vlist);
    275      1.1  mrg 	}
    276      1.1  mrg 
    277      1.1  mrg   for (fa = fmt->array.next; fa; fa = fa_next)
    278      1.1  mrg     {
    279      1.1  mrg       fa_next = fa->next;
    280      1.1  mrg       free (fa);
    281      1.1  mrg     }
    282      1.1  mrg 
    283      1.1  mrg   free (fmt);
    284      1.1  mrg   fmt = NULL;
    285      1.1  mrg }
    286      1.1  mrg 
    287      1.1  mrg 
    288      1.1  mrg /* format_lex()-- Simple lexical analyzer for getting the next token
    289      1.1  mrg    in a FORMAT string.  We support a one-level token pushback in the
    290      1.1  mrg    fmt->saved_token variable. */
    291      1.1  mrg 
    292      1.1  mrg static format_token
    293      1.1  mrg format_lex (format_data *fmt)
    294      1.1  mrg {
    295      1.1  mrg   format_token token;
    296      1.1  mrg   int negative_flag;
    297      1.1  mrg   int c;
    298      1.1  mrg   char delim;
    299      1.1  mrg 
    300      1.1  mrg   if (fmt->saved_token != FMT_NONE)
    301      1.1  mrg     {
    302      1.1  mrg       token = fmt->saved_token;
    303      1.1  mrg       fmt->saved_token = FMT_NONE;
    304      1.1  mrg       return token;
    305      1.1  mrg     }
    306      1.1  mrg 
    307      1.1  mrg   negative_flag = 0;
    308      1.1  mrg   c = next_char (fmt, 0);
    309      1.1  mrg 
    310      1.1  mrg   switch (c)
    311      1.1  mrg     {
    312      1.1  mrg     case '*':
    313      1.1  mrg        token = FMT_STAR;
    314      1.1  mrg        break;
    315      1.1  mrg 
    316      1.1  mrg     case '(':
    317      1.1  mrg       token = FMT_LPAREN;
    318      1.1  mrg       break;
    319      1.1  mrg 
    320      1.1  mrg     case ')':
    321      1.1  mrg       token = FMT_RPAREN;
    322      1.1  mrg       break;
    323      1.1  mrg 
    324      1.1  mrg     case '-':
    325      1.1  mrg       negative_flag = 1;
    326      1.1  mrg       /* Fall Through */
    327      1.1  mrg 
    328      1.1  mrg     case '+':
    329      1.1  mrg       c = next_char (fmt, 0);
    330  1.1.1.3  mrg       if (!safe_isdigit (c))
    331      1.1  mrg 	{
    332      1.1  mrg 	  token = FMT_UNKNOWN;
    333      1.1  mrg 	  break;
    334      1.1  mrg 	}
    335      1.1  mrg 
    336      1.1  mrg       fmt->value = c - '0';
    337      1.1  mrg 
    338      1.1  mrg       for (;;)
    339      1.1  mrg 	{
    340      1.1  mrg 	  c = next_char (fmt, 0);
    341  1.1.1.3  mrg 	  if (!safe_isdigit (c))
    342      1.1  mrg 	    break;
    343      1.1  mrg 
    344      1.1  mrg 	  fmt->value = 10 * fmt->value + c - '0';
    345      1.1  mrg 	}
    346      1.1  mrg 
    347      1.1  mrg       unget_char (fmt);
    348      1.1  mrg 
    349      1.1  mrg       if (negative_flag)
    350      1.1  mrg 	fmt->value = -fmt->value;
    351      1.1  mrg       token = FMT_SIGNED_INT;
    352      1.1  mrg       break;
    353      1.1  mrg 
    354      1.1  mrg     case '0':
    355      1.1  mrg     case '1':
    356      1.1  mrg     case '2':
    357      1.1  mrg     case '3':
    358      1.1  mrg     case '4':
    359      1.1  mrg     case '5':
    360      1.1  mrg     case '6':
    361      1.1  mrg     case '7':
    362      1.1  mrg     case '8':
    363      1.1  mrg     case '9':
    364      1.1  mrg       fmt->value = c - '0';
    365      1.1  mrg 
    366      1.1  mrg       for (;;)
    367      1.1  mrg 	{
    368      1.1  mrg 	  c = next_char (fmt, 0);
    369  1.1.1.3  mrg 	  if (!safe_isdigit (c))
    370      1.1  mrg 	    break;
    371      1.1  mrg 
    372      1.1  mrg 	  fmt->value = 10 * fmt->value + c - '0';
    373      1.1  mrg 	}
    374      1.1  mrg 
    375      1.1  mrg       unget_char (fmt);
    376      1.1  mrg       token = (fmt->value == 0) ? FMT_ZERO : FMT_POSINT;
    377      1.1  mrg       break;
    378      1.1  mrg 
    379      1.1  mrg     case '.':
    380      1.1  mrg       token = FMT_PERIOD;
    381      1.1  mrg       break;
    382      1.1  mrg 
    383      1.1  mrg     case ',':
    384      1.1  mrg       token = FMT_COMMA;
    385      1.1  mrg       break;
    386      1.1  mrg 
    387      1.1  mrg     case ':':
    388      1.1  mrg       token = FMT_COLON;
    389      1.1  mrg       break;
    390      1.1  mrg 
    391      1.1  mrg     case '/':
    392      1.1  mrg       token = FMT_SLASH;
    393      1.1  mrg       break;
    394      1.1  mrg 
    395      1.1  mrg     case '$':
    396      1.1  mrg       token = FMT_DOLLAR;
    397      1.1  mrg       break;
    398      1.1  mrg 
    399      1.1  mrg     case 'T':
    400      1.1  mrg       switch (next_char (fmt, 0))
    401      1.1  mrg 	{
    402      1.1  mrg 	case 'L':
    403      1.1  mrg 	  token = FMT_TL;
    404      1.1  mrg 	  break;
    405      1.1  mrg 	case 'R':
    406      1.1  mrg 	  token = FMT_TR;
    407      1.1  mrg 	  break;
    408      1.1  mrg 	default:
    409      1.1  mrg 	  token = FMT_T;
    410      1.1  mrg 	  unget_char (fmt);
    411      1.1  mrg 	  break;
    412      1.1  mrg 	}
    413      1.1  mrg 
    414      1.1  mrg       break;
    415      1.1  mrg 
    416      1.1  mrg     case 'X':
    417      1.1  mrg       token = FMT_X;
    418      1.1  mrg       break;
    419      1.1  mrg 
    420      1.1  mrg     case 'S':
    421      1.1  mrg       switch (next_char (fmt, 0))
    422      1.1  mrg 	{
    423      1.1  mrg 	case 'S':
    424      1.1  mrg 	  token = FMT_SS;
    425      1.1  mrg 	  break;
    426      1.1  mrg 	case 'P':
    427      1.1  mrg 	  token = FMT_SP;
    428      1.1  mrg 	  break;
    429      1.1  mrg 	default:
    430      1.1  mrg 	  token = FMT_S;
    431      1.1  mrg 	  unget_char (fmt);
    432      1.1  mrg 	  break;
    433      1.1  mrg 	}
    434      1.1  mrg 
    435      1.1  mrg       break;
    436      1.1  mrg 
    437      1.1  mrg     case 'B':
    438      1.1  mrg       switch (next_char (fmt, 0))
    439      1.1  mrg 	{
    440      1.1  mrg 	case 'N':
    441      1.1  mrg 	  token = FMT_BN;
    442      1.1  mrg 	  break;
    443      1.1  mrg 	case 'Z':
    444      1.1  mrg 	  token = FMT_BZ;
    445      1.1  mrg 	  break;
    446      1.1  mrg 	default:
    447      1.1  mrg 	  token = FMT_B;
    448      1.1  mrg 	  unget_char (fmt);
    449      1.1  mrg 	  break;
    450      1.1  mrg 	}
    451      1.1  mrg 
    452      1.1  mrg       break;
    453      1.1  mrg 
    454      1.1  mrg     case '\'':
    455      1.1  mrg     case '"':
    456      1.1  mrg       delim = c;
    457      1.1  mrg 
    458      1.1  mrg       fmt->string = fmt->format_string;
    459      1.1  mrg       fmt->value = 0;		/* This is the length of the string */
    460      1.1  mrg 
    461      1.1  mrg       for (;;)
    462      1.1  mrg 	{
    463      1.1  mrg 	  c = next_char (fmt, 1);
    464      1.1  mrg 	  if (c == -1)
    465      1.1  mrg 	    {
    466      1.1  mrg 	      token = FMT_BADSTRING;
    467      1.1  mrg 	      fmt->error = bad_string;
    468      1.1  mrg 	      break;
    469      1.1  mrg 	    }
    470      1.1  mrg 
    471      1.1  mrg 	  if (c == delim)
    472      1.1  mrg 	    {
    473      1.1  mrg 	      c = next_char (fmt, 1);
    474      1.1  mrg 
    475      1.1  mrg 	      if (c == -1)
    476      1.1  mrg 		{
    477      1.1  mrg 		  token = FMT_BADSTRING;
    478      1.1  mrg 		  fmt->error = bad_string;
    479      1.1  mrg 		  break;
    480      1.1  mrg 		}
    481      1.1  mrg 
    482      1.1  mrg 	      if (c != delim)
    483      1.1  mrg 		{
    484      1.1  mrg 		  unget_char (fmt);
    485      1.1  mrg 		  token = FMT_STRING;
    486      1.1  mrg 		  break;
    487      1.1  mrg 		}
    488      1.1  mrg 	    }
    489      1.1  mrg 
    490      1.1  mrg 	  fmt->value++;
    491      1.1  mrg 	}
    492      1.1  mrg 
    493      1.1  mrg       break;
    494      1.1  mrg 
    495      1.1  mrg     case 'P':
    496      1.1  mrg       token = FMT_P;
    497      1.1  mrg       break;
    498      1.1  mrg 
    499      1.1  mrg     case 'I':
    500      1.1  mrg       token = FMT_I;
    501      1.1  mrg       break;
    502      1.1  mrg 
    503      1.1  mrg     case 'O':
    504      1.1  mrg       token = FMT_O;
    505      1.1  mrg       break;
    506      1.1  mrg 
    507      1.1  mrg     case 'Z':
    508      1.1  mrg       token = FMT_Z;
    509      1.1  mrg       break;
    510      1.1  mrg 
    511      1.1  mrg     case 'F':
    512      1.1  mrg       token = FMT_F;
    513      1.1  mrg       break;
    514      1.1  mrg 
    515      1.1  mrg     case 'E':
    516      1.1  mrg       switch (next_char (fmt, 0))
    517      1.1  mrg 	{
    518      1.1  mrg 	case 'N':
    519      1.1  mrg 	  token = FMT_EN;
    520      1.1  mrg 	  break;
    521      1.1  mrg 	case 'S':
    522      1.1  mrg 	  token = FMT_ES;
    523      1.1  mrg 	  break;
    524      1.1  mrg 	default:
    525      1.1  mrg 	  token = FMT_E;
    526      1.1  mrg 	  unget_char (fmt);
    527      1.1  mrg 	  break;
    528      1.1  mrg 	}
    529      1.1  mrg       break;
    530      1.1  mrg 
    531      1.1  mrg     case 'G':
    532      1.1  mrg       token = FMT_G;
    533      1.1  mrg       break;
    534      1.1  mrg 
    535      1.1  mrg     case 'H':
    536      1.1  mrg       token = FMT_H;
    537      1.1  mrg       break;
    538      1.1  mrg 
    539      1.1  mrg     case 'L':
    540      1.1  mrg       token = FMT_L;
    541      1.1  mrg       break;
    542      1.1  mrg 
    543      1.1  mrg     case 'A':
    544      1.1  mrg       token = FMT_A;
    545      1.1  mrg       break;
    546      1.1  mrg 
    547      1.1  mrg     case 'D':
    548      1.1  mrg       switch (next_char (fmt, 0))
    549      1.1  mrg 	{
    550      1.1  mrg 	case 'P':
    551      1.1  mrg 	  token = FMT_DP;
    552      1.1  mrg 	  break;
    553      1.1  mrg 	case 'C':
    554      1.1  mrg 	  token = FMT_DC;
    555      1.1  mrg 	  break;
    556      1.1  mrg 	case 'T':
    557      1.1  mrg 	  token = FMT_DT;
    558      1.1  mrg 	  break;
    559      1.1  mrg 	default:
    560      1.1  mrg 	  token = FMT_D;
    561      1.1  mrg 	  unget_char (fmt);
    562      1.1  mrg 	  break;
    563      1.1  mrg 	}
    564      1.1  mrg       break;
    565      1.1  mrg 
    566      1.1  mrg     case 'R':
    567      1.1  mrg       switch (next_char (fmt, 0))
    568      1.1  mrg 	{
    569      1.1  mrg 	case 'C':
    570      1.1  mrg 	  token = FMT_RC;
    571      1.1  mrg 	  break;
    572      1.1  mrg 	case 'D':
    573      1.1  mrg 	  token = FMT_RD;
    574      1.1  mrg 	  break;
    575      1.1  mrg 	case 'N':
    576      1.1  mrg 	  token = FMT_RN;
    577      1.1  mrg 	  break;
    578      1.1  mrg 	case 'P':
    579      1.1  mrg 	  token = FMT_RP;
    580      1.1  mrg 	  break;
    581      1.1  mrg 	case 'U':
    582      1.1  mrg 	  token = FMT_RU;
    583      1.1  mrg 	  break;
    584      1.1  mrg 	case 'Z':
    585      1.1  mrg 	  token = FMT_RZ;
    586      1.1  mrg 	  break;
    587      1.1  mrg 	default:
    588      1.1  mrg 	  unget_char (fmt);
    589      1.1  mrg 	  token = FMT_UNKNOWN;
    590      1.1  mrg 	  break;
    591      1.1  mrg 	}
    592      1.1  mrg       break;
    593      1.1  mrg 
    594      1.1  mrg     case -1:
    595      1.1  mrg       token = FMT_END;
    596      1.1  mrg       break;
    597      1.1  mrg 
    598      1.1  mrg     default:
    599      1.1  mrg       token = FMT_UNKNOWN;
    600      1.1  mrg       break;
    601      1.1  mrg     }
    602      1.1  mrg 
    603      1.1  mrg   return token;
    604      1.1  mrg }
    605      1.1  mrg 
    606      1.1  mrg 
    607      1.1  mrg /* parse_format_list()-- Parse a format list.  Assumes that a left
    608      1.1  mrg    paren has already been seen.  Returns a list representing the
    609      1.1  mrg    parenthesis node which contains the rest of the list. */
    610      1.1  mrg 
    611      1.1  mrg static fnode *
    612      1.1  mrg parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
    613      1.1  mrg {
    614      1.1  mrg   fnode *head, *tail;
    615      1.1  mrg   format_token t, u, t2;
    616      1.1  mrg   int repeat;
    617      1.1  mrg   format_data *fmt = dtp->u.p.fmt;
    618      1.1  mrg   bool seen_data_desc = false;
    619  1.1.1.3  mrg   int standard;
    620      1.1  mrg 
    621      1.1  mrg   head = tail = NULL;
    622      1.1  mrg 
    623      1.1  mrg   /* Get the next format item */
    624      1.1  mrg  format_item:
    625      1.1  mrg   t = format_lex (fmt);
    626      1.1  mrg  format_item_1:
    627      1.1  mrg   switch (t)
    628      1.1  mrg     {
    629      1.1  mrg     case FMT_STAR:
    630      1.1  mrg       t = format_lex (fmt);
    631      1.1  mrg       if (t != FMT_LPAREN)
    632      1.1  mrg 	{
    633      1.1  mrg 	  fmt->error = "Left parenthesis required after '*'";
    634      1.1  mrg 	  goto finished;
    635      1.1  mrg 	}
    636      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_LPAREN);
    637      1.1  mrg       tail->repeat = -2;  /* Signifies unlimited format.  */
    638      1.1  mrg       tail->u.child = parse_format_list (dtp, &seen_data_desc);
    639      1.1  mrg       *seen_dd = seen_data_desc;
    640      1.1  mrg       if (fmt->error != NULL)
    641      1.1  mrg 	goto finished;
    642      1.1  mrg       if (!seen_data_desc)
    643      1.1  mrg 	{
    644      1.1  mrg 	  fmt->error = "'*' requires at least one associated data descriptor";
    645      1.1  mrg 	  goto finished;
    646      1.1  mrg 	}
    647      1.1  mrg       goto between_desc;
    648      1.1  mrg 
    649      1.1  mrg     case FMT_POSINT:
    650      1.1  mrg       repeat = fmt->value;
    651      1.1  mrg 
    652      1.1  mrg       t = format_lex (fmt);
    653      1.1  mrg       switch (t)
    654      1.1  mrg 	{
    655      1.1  mrg 	case FMT_LPAREN:
    656      1.1  mrg 	  get_fnode (fmt, &head, &tail, FMT_LPAREN);
    657      1.1  mrg 	  tail->repeat = repeat;
    658      1.1  mrg 	  tail->u.child = parse_format_list (dtp, &seen_data_desc);
    659      1.1  mrg 	  *seen_dd = seen_data_desc;
    660      1.1  mrg 	  if (fmt->error != NULL)
    661      1.1  mrg 	    goto finished;
    662      1.1  mrg 
    663      1.1  mrg 	  goto between_desc;
    664      1.1  mrg 
    665      1.1  mrg 	case FMT_SLASH:
    666      1.1  mrg 	  get_fnode (fmt, &head, &tail, FMT_SLASH);
    667      1.1  mrg 	  tail->repeat = repeat;
    668      1.1  mrg 	  goto optional_comma;
    669      1.1  mrg 
    670      1.1  mrg 	case FMT_X:
    671      1.1  mrg 	  get_fnode (fmt, &head, &tail, FMT_X);
    672      1.1  mrg 	  tail->repeat = 1;
    673      1.1  mrg 	  tail->u.k = fmt->value;
    674      1.1  mrg 	  goto between_desc;
    675      1.1  mrg 
    676      1.1  mrg 	case FMT_P:
    677      1.1  mrg 	  goto p_descriptor;
    678      1.1  mrg 
    679      1.1  mrg 	default:
    680      1.1  mrg 	  goto data_desc;
    681      1.1  mrg 	}
    682      1.1  mrg 
    683      1.1  mrg     case FMT_LPAREN:
    684      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_LPAREN);
    685      1.1  mrg       tail->repeat = 1;
    686      1.1  mrg       tail->u.child = parse_format_list (dtp, &seen_data_desc);
    687      1.1  mrg       *seen_dd = seen_data_desc;
    688      1.1  mrg       if (fmt->error != NULL)
    689      1.1  mrg 	goto finished;
    690      1.1  mrg 
    691      1.1  mrg       goto between_desc;
    692      1.1  mrg 
    693      1.1  mrg     case FMT_SIGNED_INT:	/* Signed integer can only precede a P format.  */
    694      1.1  mrg     case FMT_ZERO:		/* Same for zero.  */
    695      1.1  mrg       t = format_lex (fmt);
    696      1.1  mrg       if (t != FMT_P)
    697      1.1  mrg 	{
    698      1.1  mrg 	  fmt->error = "Expected P edit descriptor in format";
    699      1.1  mrg 	  goto finished;
    700      1.1  mrg 	}
    701      1.1  mrg 
    702      1.1  mrg     p_descriptor:
    703      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_P);
    704      1.1  mrg       tail->u.k = fmt->value;
    705      1.1  mrg       tail->repeat = 1;
    706      1.1  mrg 
    707      1.1  mrg       t = format_lex (fmt);
    708      1.1  mrg       if (t == FMT_F || t == FMT_EN || t == FMT_ES || t == FMT_D
    709      1.1  mrg 	  || t == FMT_G || t == FMT_E)
    710      1.1  mrg 	{
    711      1.1  mrg 	  repeat = 1;
    712      1.1  mrg 	  goto data_desc;
    713      1.1  mrg 	}
    714      1.1  mrg 
    715      1.1  mrg       if (t != FMT_COMMA && t != FMT_RPAREN && t != FMT_SLASH
    716      1.1  mrg 	  && t != FMT_POSINT)
    717      1.1  mrg 	{
    718      1.1  mrg 	  fmt->error = "Comma required after P descriptor";
    719      1.1  mrg 	  goto finished;
    720      1.1  mrg 	}
    721      1.1  mrg 
    722      1.1  mrg       fmt->saved_token = t;
    723      1.1  mrg       goto optional_comma;
    724      1.1  mrg 
    725      1.1  mrg     case FMT_P:		/* P and X require a prior number */
    726      1.1  mrg       fmt->error = "P descriptor requires leading scale factor";
    727      1.1  mrg       goto finished;
    728      1.1  mrg 
    729      1.1  mrg     case FMT_X:
    730      1.1  mrg /*
    731      1.1  mrg    EXTENSION!
    732      1.1  mrg 
    733      1.1  mrg    If we would be pedantic in the library, we would have to reject
    734      1.1  mrg    an X descriptor without an integer prefix:
    735      1.1  mrg 
    736      1.1  mrg       fmt->error = "X descriptor requires leading space count";
    737      1.1  mrg       goto finished;
    738      1.1  mrg 
    739      1.1  mrg    However, this is an extension supported by many Fortran compilers,
    740      1.1  mrg    including Cray, HP, AIX, and IRIX.  Therefore, we allow it in the
    741      1.1  mrg    runtime library, and make the front end reject it if the compiler
    742      1.1  mrg    is in pedantic mode.  The interpretation of 'X' is '1X'.
    743      1.1  mrg */
    744      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_X);
    745      1.1  mrg       tail->repeat = 1;
    746      1.1  mrg       tail->u.k = 1;
    747      1.1  mrg       goto between_desc;
    748      1.1  mrg 
    749      1.1  mrg     case FMT_STRING:
    750      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_STRING);
    751      1.1  mrg       tail->u.string.p = fmt->string;
    752      1.1  mrg       tail->u.string.length = fmt->value;
    753      1.1  mrg       tail->repeat = 1;
    754      1.1  mrg       goto optional_comma;
    755      1.1  mrg 
    756      1.1  mrg     case FMT_RC:
    757      1.1  mrg     case FMT_RD:
    758      1.1  mrg     case FMT_RN:
    759      1.1  mrg     case FMT_RP:
    760      1.1  mrg     case FMT_RU:
    761      1.1  mrg     case FMT_RZ:
    762      1.1  mrg       notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: Round "
    763      1.1  mrg 		  "descriptor not allowed");
    764      1.1  mrg       get_fnode (fmt, &head, &tail, t);
    765      1.1  mrg       tail->repeat = 1;
    766      1.1  mrg       goto between_desc;
    767      1.1  mrg 
    768      1.1  mrg     case FMT_DC:
    769      1.1  mrg     case FMT_DP:
    770      1.1  mrg       notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: DC or DP "
    771      1.1  mrg 		  "descriptor not allowed");
    772      1.1  mrg     /* Fall through.  */
    773      1.1  mrg     case FMT_S:
    774      1.1  mrg     case FMT_SS:
    775      1.1  mrg     case FMT_SP:
    776      1.1  mrg     case FMT_BN:
    777      1.1  mrg     case FMT_BZ:
    778      1.1  mrg       get_fnode (fmt, &head, &tail, t);
    779      1.1  mrg       tail->repeat = 1;
    780      1.1  mrg       goto between_desc;
    781      1.1  mrg 
    782      1.1  mrg     case FMT_COLON:
    783      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_COLON);
    784      1.1  mrg       tail->repeat = 1;
    785      1.1  mrg       goto optional_comma;
    786      1.1  mrg 
    787      1.1  mrg     case FMT_SLASH:
    788      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_SLASH);
    789      1.1  mrg       tail->repeat = 1;
    790      1.1  mrg       tail->u.r = 1;
    791      1.1  mrg       goto optional_comma;
    792      1.1  mrg 
    793      1.1  mrg     case FMT_DOLLAR:
    794      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_DOLLAR);
    795      1.1  mrg       tail->repeat = 1;
    796      1.1  mrg       notify_std (&dtp->common, GFC_STD_GNU, "Extension: $ descriptor");
    797      1.1  mrg       goto between_desc;
    798      1.1  mrg 
    799      1.1  mrg     case FMT_T:
    800      1.1  mrg     case FMT_TL:
    801      1.1  mrg     case FMT_TR:
    802      1.1  mrg       t2 = format_lex (fmt);
    803      1.1  mrg       if (t2 != FMT_POSINT)
    804      1.1  mrg 	{
    805      1.1  mrg 	  fmt->error = posint_required;
    806      1.1  mrg 	  goto finished;
    807      1.1  mrg 	}
    808      1.1  mrg       get_fnode (fmt, &head, &tail, t);
    809      1.1  mrg       tail->u.n = fmt->value;
    810      1.1  mrg       tail->repeat = 1;
    811      1.1  mrg       goto between_desc;
    812      1.1  mrg 
    813      1.1  mrg     case FMT_I:
    814      1.1  mrg     case FMT_B:
    815      1.1  mrg     case FMT_O:
    816      1.1  mrg     case FMT_Z:
    817      1.1  mrg     case FMT_E:
    818      1.1  mrg     case FMT_EN:
    819      1.1  mrg     case FMT_ES:
    820      1.1  mrg     case FMT_D:
    821      1.1  mrg     case FMT_DT:
    822      1.1  mrg     case FMT_L:
    823      1.1  mrg     case FMT_A:
    824      1.1  mrg     case FMT_F:
    825      1.1  mrg     case FMT_G:
    826      1.1  mrg       repeat = 1;
    827      1.1  mrg       *seen_dd = true;
    828      1.1  mrg       goto data_desc;
    829      1.1  mrg 
    830      1.1  mrg     case FMT_H:
    831      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_STRING);
    832      1.1  mrg       if (fmt->format_string_len < 1)
    833      1.1  mrg 	{
    834      1.1  mrg 	  fmt->error = bad_hollerith;
    835      1.1  mrg 	  goto finished;
    836      1.1  mrg 	}
    837      1.1  mrg 
    838      1.1  mrg       tail->u.string.p = fmt->format_string;
    839      1.1  mrg       tail->u.string.length = 1;
    840      1.1  mrg       tail->repeat = 1;
    841      1.1  mrg 
    842      1.1  mrg       fmt->format_string++;
    843      1.1  mrg       fmt->format_string_len--;
    844      1.1  mrg 
    845      1.1  mrg       goto between_desc;
    846      1.1  mrg 
    847      1.1  mrg     case FMT_END:
    848      1.1  mrg       fmt->error = unexpected_end;
    849      1.1  mrg       goto finished;
    850      1.1  mrg 
    851      1.1  mrg     case FMT_BADSTRING:
    852      1.1  mrg       goto finished;
    853      1.1  mrg 
    854      1.1  mrg     case FMT_RPAREN:
    855      1.1  mrg       goto finished;
    856      1.1  mrg 
    857      1.1  mrg     default:
    858      1.1  mrg       fmt->error = unexpected_element;
    859      1.1  mrg       goto finished;
    860      1.1  mrg     }
    861      1.1  mrg 
    862      1.1  mrg   /* In this state, t must currently be a data descriptor.  Deal with
    863      1.1  mrg      things that can/must follow the descriptor */
    864      1.1  mrg  data_desc:
    865      1.1  mrg 
    866      1.1  mrg   switch (t)
    867      1.1  mrg     {
    868      1.1  mrg     case FMT_L:
    869      1.1  mrg       *seen_dd = true;
    870      1.1  mrg       t = format_lex (fmt);
    871      1.1  mrg       if (t != FMT_POSINT)
    872      1.1  mrg 	{
    873      1.1  mrg 	  if (t == FMT_ZERO)
    874      1.1  mrg 	    {
    875      1.1  mrg 	      if (notification_std(GFC_STD_GNU) == NOTIFICATION_ERROR)
    876      1.1  mrg 		{
    877      1.1  mrg 		  fmt->error = "Extension: Zero width after L descriptor";
    878      1.1  mrg 		  goto finished;
    879      1.1  mrg 		}
    880      1.1  mrg 	      else
    881      1.1  mrg 		notify_std (&dtp->common, GFC_STD_GNU,
    882      1.1  mrg 			    "Zero width after L descriptor");
    883      1.1  mrg 	    }
    884      1.1  mrg 	  else
    885      1.1  mrg 	    {
    886      1.1  mrg 	      fmt->saved_token = t;
    887      1.1  mrg 	      notify_std (&dtp->common, GFC_STD_GNU,
    888      1.1  mrg 			  "Positive width required with L descriptor");
    889      1.1  mrg 	    }
    890      1.1  mrg 	  fmt->value = 1;	/* Default width */
    891      1.1  mrg 	}
    892      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_L);
    893      1.1  mrg       tail->u.n = fmt->value;
    894      1.1  mrg       tail->repeat = repeat;
    895      1.1  mrg       break;
    896      1.1  mrg 
    897      1.1  mrg     case FMT_A:
    898      1.1  mrg       *seen_dd = true;
    899      1.1  mrg       t = format_lex (fmt);
    900      1.1  mrg       if (t == FMT_ZERO)
    901      1.1  mrg 	{
    902      1.1  mrg 	  fmt->error = zero_width;
    903      1.1  mrg 	  goto finished;
    904      1.1  mrg 	}
    905      1.1  mrg 
    906      1.1  mrg       if (t != FMT_POSINT)
    907      1.1  mrg 	{
    908      1.1  mrg 	  fmt->saved_token = t;
    909      1.1  mrg 	  fmt->value = -1;		/* Width not present */
    910      1.1  mrg 	}
    911      1.1  mrg 
    912      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_A);
    913      1.1  mrg       tail->repeat = repeat;
    914      1.1  mrg       tail->u.n = fmt->value;
    915      1.1  mrg       break;
    916      1.1  mrg 
    917      1.1  mrg     case FMT_D:
    918      1.1  mrg     case FMT_E:
    919      1.1  mrg     case FMT_F:
    920      1.1  mrg     case FMT_G:
    921      1.1  mrg     case FMT_EN:
    922      1.1  mrg     case FMT_ES:
    923      1.1  mrg       *seen_dd = true;
    924      1.1  mrg       get_fnode (fmt, &head, &tail, t);
    925      1.1  mrg       tail->repeat = repeat;
    926  1.1.1.4  mrg       tail->pushed = FMT_NONE;
    927      1.1  mrg 
    928      1.1  mrg       u = format_lex (fmt);
    929  1.1.1.2  mrg 
    930  1.1.1.2  mrg       /* Processing for zero width formats.  */
    931  1.1.1.2  mrg       if (u == FMT_ZERO)
    932      1.1  mrg 	{
    933  1.1.1.3  mrg           if (t == FMT_F)
    934  1.1.1.3  mrg 	    standard = GFC_STD_F95;
    935  1.1.1.3  mrg 	  else if (t == FMT_G)
    936  1.1.1.3  mrg 	    standard = GFC_STD_F2008;
    937  1.1.1.3  mrg 	  else
    938  1.1.1.3  mrg 	    standard = GFC_STD_F2018;
    939  1.1.1.3  mrg 
    940  1.1.1.3  mrg 	  if (notification_std (standard) == NOTIFICATION_ERROR
    941      1.1  mrg 	      || dtp->u.p.mode == READING)
    942      1.1  mrg 	    {
    943      1.1  mrg 	      fmt->error = zero_width;
    944      1.1  mrg 	      goto finished;
    945      1.1  mrg 	    }
    946      1.1  mrg 	  tail->u.real.w = 0;
    947  1.1.1.2  mrg 
    948  1.1.1.2  mrg 	  /* Look for the dot seperator.  */
    949      1.1  mrg 	  u = format_lex (fmt);
    950      1.1  mrg 	  if (u != FMT_PERIOD)
    951      1.1  mrg 	    {
    952      1.1  mrg 	      fmt->saved_token = u;
    953      1.1  mrg 	      break;
    954      1.1  mrg 	    }
    955      1.1  mrg 
    956  1.1.1.2  mrg 	  /* Look for the precision.  */
    957      1.1  mrg 	  u = format_lex (fmt);
    958  1.1.1.2  mrg 	  if (u != FMT_ZERO && u != FMT_POSINT)
    959      1.1  mrg 	    {
    960  1.1.1.2  mrg 	      fmt->error = nonneg_required;
    961      1.1  mrg 	      goto finished;
    962      1.1  mrg 	    }
    963      1.1  mrg 	  tail->u.real.d = fmt->value;
    964  1.1.1.2  mrg 
    965  1.1.1.2  mrg 	  /* Look for optional exponent, not allowed for FMT_D */
    966  1.1.1.2  mrg 	  if (t == FMT_D)
    967  1.1.1.2  mrg 	    break;
    968  1.1.1.2  mrg 	  u = format_lex (fmt);
    969  1.1.1.2  mrg 	  if (u != FMT_E)
    970  1.1.1.2  mrg 	    fmt->saved_token = u;
    971  1.1.1.2  mrg 	  else
    972  1.1.1.2  mrg 	    {
    973  1.1.1.2  mrg 	      u = format_lex (fmt);
    974  1.1.1.2  mrg 	      if (u != FMT_POSINT)
    975  1.1.1.2  mrg 		{
    976  1.1.1.2  mrg 		  if (u == FMT_ZERO)
    977  1.1.1.2  mrg 		    {
    978  1.1.1.2  mrg 		      notify_std (&dtp->common, GFC_STD_F2018,
    979  1.1.1.2  mrg 				  "Positive exponent width required");
    980  1.1.1.2  mrg 		    }
    981  1.1.1.2  mrg 		  else
    982  1.1.1.2  mrg 		    {
    983  1.1.1.2  mrg 		      fmt->error = "Positive exponent width required in "
    984  1.1.1.2  mrg 				   "format string at %L";
    985  1.1.1.2  mrg 		      goto finished;
    986  1.1.1.2  mrg 		    }
    987  1.1.1.2  mrg 		}
    988  1.1.1.2  mrg 	      tail->u.real.e = fmt->value;
    989  1.1.1.2  mrg 	    }
    990      1.1  mrg 	  break;
    991      1.1  mrg 	}
    992  1.1.1.2  mrg 
    993  1.1.1.2  mrg       /* Processing for positive width formats.  */
    994  1.1.1.2  mrg       if (u == FMT_POSINT)
    995      1.1  mrg 	{
    996  1.1.1.2  mrg 	  tail->u.real.w = fmt->value;
    997  1.1.1.2  mrg 
    998  1.1.1.2  mrg 	  /* Look for the dot separator. Because of legacy behaviors
    999  1.1.1.2  mrg 	     we do some look ahead for missing things.  */
   1000  1.1.1.2  mrg 	  t2 = t;
   1001  1.1.1.2  mrg 	  t = format_lex (fmt);
   1002  1.1.1.2  mrg 	  if (t != FMT_PERIOD)
   1003      1.1  mrg 	    {
   1004  1.1.1.2  mrg 	      /* We treat a missing decimal descriptor as 0.  Note: This is only
   1005  1.1.1.2  mrg 		 allowed if -std=legacy, otherwise an error occurs.  */
   1006  1.1.1.2  mrg 	      if (compile_options.warn_std != 0)
   1007  1.1.1.2  mrg 		{
   1008  1.1.1.2  mrg 		  fmt->error = period_required;
   1009  1.1.1.2  mrg 		  goto finished;
   1010  1.1.1.2  mrg 		}
   1011  1.1.1.2  mrg 	      fmt->saved_token = t;
   1012  1.1.1.2  mrg 	      tail->u.real.d = 0;
   1013  1.1.1.2  mrg 	      tail->u.real.e = -1;
   1014  1.1.1.2  mrg 	      break;
   1015      1.1  mrg 	    }
   1016      1.1  mrg 
   1017  1.1.1.2  mrg 	  /* If we made it here, we should have the dot so look for the
   1018  1.1.1.2  mrg 	     precision.  */
   1019  1.1.1.2  mrg 	  t = format_lex (fmt);
   1020  1.1.1.2  mrg 	  if (t != FMT_ZERO && t != FMT_POSINT)
   1021      1.1  mrg 	    {
   1022  1.1.1.2  mrg 	      fmt->error = nonneg_required;
   1023      1.1  mrg 	      goto finished;
   1024      1.1  mrg 	    }
   1025  1.1.1.2  mrg 	  tail->u.real.d = fmt->value;
   1026      1.1  mrg 	  tail->u.real.e = -1;
   1027      1.1  mrg 
   1028  1.1.1.2  mrg 	  /* Done with D and F formats.  */
   1029  1.1.1.2  mrg 	  if (t2 == FMT_D || t2 == FMT_F)
   1030  1.1.1.2  mrg 	    {
   1031  1.1.1.2  mrg 	      *seen_dd = true;
   1032  1.1.1.2  mrg 	      break;
   1033  1.1.1.2  mrg 	    }
   1034      1.1  mrg 
   1035  1.1.1.2  mrg 	  /* Look for optional exponent */
   1036  1.1.1.2  mrg 	  u = format_lex (fmt);
   1037  1.1.1.2  mrg 	  if (u != FMT_E)
   1038  1.1.1.2  mrg 	    fmt->saved_token = u;
   1039  1.1.1.2  mrg 	  else
   1040  1.1.1.2  mrg 	    {
   1041  1.1.1.2  mrg 	      u = format_lex (fmt);
   1042  1.1.1.2  mrg 	      if (u != FMT_POSINT)
   1043  1.1.1.2  mrg 		{
   1044  1.1.1.2  mrg 		  if (u == FMT_ZERO)
   1045  1.1.1.2  mrg 		    {
   1046  1.1.1.2  mrg 		      notify_std (&dtp->common, GFC_STD_F2018,
   1047  1.1.1.2  mrg 				  "Positive exponent width required");
   1048  1.1.1.2  mrg 		    }
   1049  1.1.1.2  mrg 		  else
   1050  1.1.1.2  mrg 		    {
   1051  1.1.1.2  mrg 		      fmt->error = "Positive exponent width required in "
   1052  1.1.1.2  mrg 				   "format string at %L";
   1053  1.1.1.2  mrg 		      goto finished;
   1054  1.1.1.2  mrg 		    }
   1055  1.1.1.2  mrg 		}
   1056  1.1.1.2  mrg 	      tail->u.real.e = fmt->value;
   1057  1.1.1.2  mrg 	    }
   1058      1.1  mrg 	  break;
   1059      1.1  mrg 	}
   1060      1.1  mrg 
   1061  1.1.1.2  mrg       /* Old DEC codes may not have width or precision specified.  */
   1062  1.1.1.2  mrg       if (dtp->u.p.mode == WRITING && (dtp->common.flags & IOPARM_DT_DEC_EXT))
   1063      1.1  mrg 	{
   1064  1.1.1.2  mrg 	  tail->u.real.w = DEFAULT_WIDTH;
   1065  1.1.1.2  mrg 	  tail->u.real.d = 0;
   1066  1.1.1.2  mrg 	  tail->u.real.e = -1;
   1067  1.1.1.2  mrg 	  fmt->saved_token = u;
   1068      1.1  mrg 	}
   1069      1.1  mrg       break;
   1070  1.1.1.2  mrg 
   1071      1.1  mrg     case FMT_DT:
   1072      1.1  mrg       *seen_dd = true;
   1073      1.1  mrg       get_fnode (fmt, &head, &tail, t);
   1074      1.1  mrg       tail->repeat = repeat;
   1075      1.1  mrg 
   1076      1.1  mrg       t = format_lex (fmt);
   1077      1.1  mrg 
   1078      1.1  mrg       /* Initialize the vlist to a zero size, rank-one array.  */
   1079      1.1  mrg       tail->u.udf.vlist= xmalloc (sizeof(gfc_array_i4)
   1080      1.1  mrg 				  + sizeof (descriptor_dimension));
   1081      1.1  mrg       GFC_DESCRIPTOR_DATA(tail->u.udf.vlist) = NULL;
   1082      1.1  mrg       GFC_DIMENSION_SET(tail->u.udf.vlist->dim[0],1, 0, 0);
   1083      1.1  mrg 
   1084      1.1  mrg       if (t == FMT_STRING)
   1085      1.1  mrg         {
   1086      1.1  mrg 	  /* Get pointer to the optional format string.  */
   1087      1.1  mrg 	  tail->u.udf.string = fmt->string;
   1088      1.1  mrg 	  tail->u.udf.string_len = fmt->value;
   1089      1.1  mrg 	  t = format_lex (fmt);
   1090      1.1  mrg 	}
   1091      1.1  mrg       if (t == FMT_LPAREN)
   1092      1.1  mrg         {
   1093      1.1  mrg 	  /* Temporary buffer to hold the vlist values.  */
   1094      1.1  mrg 	  GFC_INTEGER_4 temp[FARRAY_SIZE];
   1095      1.1  mrg 	  int i = 0;
   1096      1.1  mrg 	loop:
   1097      1.1  mrg 	  t = format_lex (fmt);
   1098      1.1  mrg 	  if (t != FMT_POSINT)
   1099      1.1  mrg 	    {
   1100      1.1  mrg 	      fmt->error = posint_required;
   1101      1.1  mrg 	      goto finished;
   1102      1.1  mrg 	    }
   1103      1.1  mrg 	  /* Save the positive integer value.  */
   1104      1.1  mrg 	  temp[i++] = fmt->value;
   1105      1.1  mrg 	  t = format_lex (fmt);
   1106      1.1  mrg 	  if (t == FMT_COMMA)
   1107      1.1  mrg 	    goto loop;
   1108      1.1  mrg 	  if (t == FMT_RPAREN)
   1109      1.1  mrg 	    {
   1110      1.1  mrg 	      /* We have parsed the complete vlist so initialize the
   1111      1.1  mrg 	         array descriptor and save it in the format node.  */
   1112      1.1  mrg 	      gfc_full_array_i4 *vp = tail->u.udf.vlist;
   1113      1.1  mrg 	      GFC_DESCRIPTOR_DATA(vp) = xmalloc (i * sizeof(GFC_INTEGER_4));
   1114      1.1  mrg 	      GFC_DIMENSION_SET(vp->dim[0],1, i, 1);
   1115      1.1  mrg 	      memcpy (GFC_DESCRIPTOR_DATA(vp), temp, i * sizeof(GFC_INTEGER_4));
   1116      1.1  mrg 	      break;
   1117      1.1  mrg 	    }
   1118      1.1  mrg 	  fmt->error = unexpected_element;
   1119      1.1  mrg 	  goto finished;
   1120      1.1  mrg 	}
   1121      1.1  mrg       fmt->saved_token = t;
   1122      1.1  mrg       break;
   1123      1.1  mrg     case FMT_H:
   1124      1.1  mrg       if (repeat > fmt->format_string_len)
   1125      1.1  mrg 	{
   1126      1.1  mrg 	  fmt->error = bad_hollerith;
   1127      1.1  mrg 	  goto finished;
   1128      1.1  mrg 	}
   1129      1.1  mrg 
   1130      1.1  mrg       get_fnode (fmt, &head, &tail, FMT_STRING);
   1131      1.1  mrg       tail->u.string.p = fmt->format_string;
   1132      1.1  mrg       tail->u.string.length = repeat;
   1133      1.1  mrg       tail->repeat = 1;
   1134      1.1  mrg 
   1135      1.1  mrg       fmt->format_string += fmt->value;
   1136      1.1  mrg       fmt->format_string_len -= repeat;
   1137      1.1  mrg 
   1138      1.1  mrg       break;
   1139      1.1  mrg 
   1140      1.1  mrg     case FMT_I:
   1141      1.1  mrg     case FMT_B:
   1142      1.1  mrg     case FMT_O:
   1143      1.1  mrg     case FMT_Z:
   1144      1.1  mrg       *seen_dd = true;
   1145      1.1  mrg       get_fnode (fmt, &head, &tail, t);
   1146      1.1  mrg       tail->repeat = repeat;
   1147      1.1  mrg 
   1148      1.1  mrg       t = format_lex (fmt);
   1149      1.1  mrg 
   1150      1.1  mrg       if (dtp->u.p.mode == READING)
   1151      1.1  mrg 	{
   1152      1.1  mrg 	  if (t != FMT_POSINT)
   1153      1.1  mrg 	    {
   1154  1.1.1.2  mrg 	      if (dtp->common.flags & IOPARM_DT_DEC_EXT)
   1155  1.1.1.2  mrg 		{
   1156  1.1.1.2  mrg 		  tail->u.integer.w = DEFAULT_WIDTH;
   1157  1.1.1.2  mrg 		  tail->u.integer.m = -1;
   1158  1.1.1.2  mrg 		  fmt->saved_token = t;
   1159  1.1.1.2  mrg 		  break;
   1160  1.1.1.2  mrg 		}
   1161      1.1  mrg 	      fmt->error = posint_required;
   1162      1.1  mrg 	      goto finished;
   1163      1.1  mrg 	    }
   1164      1.1  mrg 	}
   1165      1.1  mrg       else
   1166      1.1  mrg 	{
   1167      1.1  mrg 	  if (t != FMT_ZERO && t != FMT_POSINT)
   1168      1.1  mrg 	    {
   1169  1.1.1.2  mrg 	      if (dtp->common.flags & IOPARM_DT_DEC_EXT)
   1170  1.1.1.2  mrg 		{
   1171  1.1.1.2  mrg 		  tail->u.integer.w = DEFAULT_WIDTH;
   1172  1.1.1.2  mrg 		  tail->u.integer.m = -1;
   1173  1.1.1.2  mrg 		  fmt->saved_token = t;
   1174  1.1.1.2  mrg 		  break;
   1175  1.1.1.2  mrg 		}
   1176      1.1  mrg 	      fmt->error = nonneg_required;
   1177      1.1  mrg 	      goto finished;
   1178      1.1  mrg 	    }
   1179      1.1  mrg 	}
   1180      1.1  mrg 
   1181      1.1  mrg       tail->u.integer.w = fmt->value;
   1182      1.1  mrg       tail->u.integer.m = -1;
   1183      1.1  mrg 
   1184      1.1  mrg       t = format_lex (fmt);
   1185      1.1  mrg       if (t != FMT_PERIOD)
   1186      1.1  mrg 	{
   1187      1.1  mrg 	  fmt->saved_token = t;
   1188      1.1  mrg 	}
   1189      1.1  mrg       else
   1190      1.1  mrg 	{
   1191      1.1  mrg 	  t = format_lex (fmt);
   1192      1.1  mrg 	  if (t != FMT_ZERO && t != FMT_POSINT)
   1193      1.1  mrg 	    {
   1194      1.1  mrg 	      fmt->error = nonneg_required;
   1195      1.1  mrg 	      goto finished;
   1196      1.1  mrg 	    }
   1197      1.1  mrg 
   1198      1.1  mrg 	  tail->u.integer.m = fmt->value;
   1199      1.1  mrg 	}
   1200      1.1  mrg 
   1201      1.1  mrg       if (tail->u.integer.w != 0 && tail->u.integer.m > tail->u.integer.w)
   1202      1.1  mrg 	{
   1203      1.1  mrg 	  fmt->error = "Minimum digits exceeds field width";
   1204      1.1  mrg 	  goto finished;
   1205      1.1  mrg 	}
   1206      1.1  mrg 
   1207      1.1  mrg       break;
   1208      1.1  mrg 
   1209      1.1  mrg     default:
   1210      1.1  mrg       fmt->error = unexpected_element;
   1211      1.1  mrg       goto finished;
   1212      1.1  mrg     }
   1213      1.1  mrg 
   1214      1.1  mrg   /* Between a descriptor and what comes next */
   1215      1.1  mrg  between_desc:
   1216      1.1  mrg   t = format_lex (fmt);
   1217      1.1  mrg   switch (t)
   1218      1.1  mrg     {
   1219      1.1  mrg     case FMT_COMMA:
   1220      1.1  mrg       goto format_item;
   1221      1.1  mrg 
   1222      1.1  mrg     case FMT_RPAREN:
   1223      1.1  mrg       goto finished;
   1224      1.1  mrg 
   1225      1.1  mrg     case FMT_SLASH:
   1226      1.1  mrg     case FMT_COLON:
   1227      1.1  mrg       get_fnode (fmt, &head, &tail, t);
   1228      1.1  mrg       tail->repeat = 1;
   1229      1.1  mrg       goto optional_comma;
   1230      1.1  mrg 
   1231      1.1  mrg     case FMT_END:
   1232      1.1  mrg       fmt->error = unexpected_end;
   1233      1.1  mrg       goto finished;
   1234      1.1  mrg 
   1235      1.1  mrg     default:
   1236      1.1  mrg       /* Assume a missing comma, this is a GNU extension */
   1237      1.1  mrg       goto format_item_1;
   1238      1.1  mrg     }
   1239      1.1  mrg 
   1240      1.1  mrg   /* Optional comma is a weird between state where we've just finished
   1241      1.1  mrg      reading a colon, slash or P descriptor. */
   1242      1.1  mrg  optional_comma:
   1243      1.1  mrg   t = format_lex (fmt);
   1244      1.1  mrg   switch (t)
   1245      1.1  mrg     {
   1246      1.1  mrg     case FMT_COMMA:
   1247      1.1  mrg       break;
   1248      1.1  mrg 
   1249      1.1  mrg     case FMT_RPAREN:
   1250      1.1  mrg       goto finished;
   1251      1.1  mrg 
   1252      1.1  mrg     default:			/* Assume that we have another format item */
   1253      1.1  mrg       fmt->saved_token = t;
   1254      1.1  mrg       break;
   1255      1.1  mrg     }
   1256      1.1  mrg 
   1257      1.1  mrg   goto format_item;
   1258      1.1  mrg 
   1259      1.1  mrg  finished:
   1260      1.1  mrg 
   1261      1.1  mrg   return head;
   1262      1.1  mrg }
   1263      1.1  mrg 
   1264      1.1  mrg 
   1265      1.1  mrg /* format_error()-- Generate an error message for a format statement.
   1266      1.1  mrg    If the node that gives the location of the error is NULL, the error
   1267      1.1  mrg    is assumed to happen at parse time, and the current location of the
   1268      1.1  mrg    parser is shown.
   1269      1.1  mrg 
   1270      1.1  mrg    We generate a message showing where the problem is.  We take extra
   1271      1.1  mrg    care to print only the relevant part of the format if it is longer
   1272      1.1  mrg    than a standard 80 column display. */
   1273      1.1  mrg 
   1274      1.1  mrg void
   1275      1.1  mrg format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
   1276      1.1  mrg {
   1277      1.1  mrg   int width, i, offset;
   1278      1.1  mrg #define BUFLEN 300
   1279      1.1  mrg   char *p, buffer[BUFLEN];
   1280      1.1  mrg   format_data *fmt = dtp->u.p.fmt;
   1281      1.1  mrg 
   1282      1.1  mrg   if (f != NULL)
   1283      1.1  mrg     p = f->source;
   1284      1.1  mrg   else                /* This should not happen.  */
   1285      1.1  mrg     p = dtp->format;
   1286      1.1  mrg 
   1287      1.1  mrg   if (message == unexpected_element)
   1288      1.1  mrg     snprintf (buffer, BUFLEN, message, fmt->error_element);
   1289      1.1  mrg   else
   1290      1.1  mrg     snprintf (buffer, BUFLEN, "%s\n", message);
   1291      1.1  mrg 
   1292      1.1  mrg   /* Get the offset into the format string where the error occurred.  */
   1293      1.1  mrg   offset = dtp->format_len - (fmt->reversion_ok ?
   1294      1.1  mrg 			      (int) strlen(p) : fmt->format_string_len);
   1295      1.1  mrg 
   1296      1.1  mrg   width = dtp->format_len;
   1297      1.1  mrg 
   1298      1.1  mrg   if (width > 80)
   1299      1.1  mrg     width = 80;
   1300      1.1  mrg 
   1301      1.1  mrg   /* Show the format */
   1302      1.1  mrg 
   1303      1.1  mrg   p = strchr (buffer, '\0');
   1304      1.1  mrg 
   1305      1.1  mrg   if (dtp->format)
   1306      1.1  mrg     memcpy (p, dtp->format, width);
   1307      1.1  mrg 
   1308      1.1  mrg   p += width;
   1309      1.1  mrg   *p++ = '\n';
   1310      1.1  mrg 
   1311      1.1  mrg   /* Show where the problem is */
   1312      1.1  mrg 
   1313      1.1  mrg   for (i = 1; i < offset; i++)
   1314      1.1  mrg     *p++ = ' ';
   1315      1.1  mrg 
   1316      1.1  mrg   *p++ = '^';
   1317      1.1  mrg   *p = '\0';
   1318      1.1  mrg 
   1319      1.1  mrg   generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
   1320      1.1  mrg }
   1321      1.1  mrg 
   1322      1.1  mrg 
   1323      1.1  mrg /* revert()-- Do reversion of the format.  Control reverts to the left
   1324      1.1  mrg    parenthesis that matches the rightmost right parenthesis.  From our
   1325      1.1  mrg    tree structure, we are looking for the rightmost parenthesis node
   1326      1.1  mrg    at the second level, the first level always being a single
   1327      1.1  mrg    parenthesis node.  If this node doesn't exit, we use the top
   1328      1.1  mrg    level. */
   1329      1.1  mrg 
   1330      1.1  mrg static void
   1331      1.1  mrg revert (st_parameter_dt *dtp)
   1332      1.1  mrg {
   1333      1.1  mrg   fnode *f, *r;
   1334      1.1  mrg   format_data *fmt = dtp->u.p.fmt;
   1335      1.1  mrg 
   1336      1.1  mrg   dtp->u.p.reversion_flag = 1;
   1337      1.1  mrg 
   1338      1.1  mrg   r = NULL;
   1339      1.1  mrg 
   1340      1.1  mrg   for (f = fmt->array.array[0].u.child; f; f = f->next)
   1341      1.1  mrg     if (f->format == FMT_LPAREN)
   1342      1.1  mrg       r = f;
   1343      1.1  mrg 
   1344      1.1  mrg   /* If r is NULL because no node was found, the whole tree will be used */
   1345      1.1  mrg 
   1346      1.1  mrg   fmt->array.array[0].current = r;
   1347      1.1  mrg   fmt->array.array[0].count = 0;
   1348      1.1  mrg }
   1349      1.1  mrg 
   1350      1.1  mrg /* parse_format()-- Parse a format string.  */
   1351      1.1  mrg 
   1352      1.1  mrg void
   1353      1.1  mrg parse_format (st_parameter_dt *dtp)
   1354      1.1  mrg {
   1355      1.1  mrg   format_data *fmt;
   1356      1.1  mrg   bool format_cache_ok, seen_data_desc = false;
   1357      1.1  mrg 
   1358      1.1  mrg   /* Don't cache for internal units and set an arbitrary limit on the
   1359      1.1  mrg      size of format strings we will cache.  (Avoids memory issues.)
   1360      1.1  mrg      Also, the format_hash_table resides in the current_unit, so
   1361      1.1  mrg      child_dtio procedures would overwrite the parent table  */
   1362      1.1  mrg   format_cache_ok = !is_internal_unit (dtp)
   1363      1.1  mrg 		    && (dtp->u.p.current_unit->child_dtio == 0);
   1364      1.1  mrg 
   1365      1.1  mrg   /* Lookup format string to see if it has already been parsed.  */
   1366      1.1  mrg   if (format_cache_ok)
   1367      1.1  mrg     {
   1368      1.1  mrg       dtp->u.p.fmt = find_parsed_format (dtp);
   1369      1.1  mrg 
   1370      1.1  mrg       if (dtp->u.p.fmt != NULL)
   1371      1.1  mrg 	{
   1372      1.1  mrg 	  dtp->u.p.fmt->reversion_ok = 0;
   1373      1.1  mrg 	  dtp->u.p.fmt->saved_token = FMT_NONE;
   1374      1.1  mrg 	  dtp->u.p.fmt->saved_format = NULL;
   1375      1.1  mrg 	  reset_fnode_counters (dtp);
   1376      1.1  mrg 	  return;
   1377      1.1  mrg 	}
   1378      1.1  mrg     }
   1379      1.1  mrg 
   1380      1.1  mrg   /* Not found so proceed as follows.  */
   1381      1.1  mrg 
   1382      1.1  mrg   char *fmt_string = fc_strdup_notrim (dtp->format, dtp->format_len);
   1383      1.1  mrg   dtp->format = fmt_string;
   1384      1.1  mrg 
   1385      1.1  mrg   dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data));
   1386      1.1  mrg   fmt->format_string = dtp->format;
   1387      1.1  mrg   fmt->format_string_len = dtp->format_len;
   1388      1.1  mrg 
   1389      1.1  mrg   fmt->string = NULL;
   1390      1.1  mrg   fmt->saved_token = FMT_NONE;
   1391      1.1  mrg   fmt->error = NULL;
   1392      1.1  mrg   fmt->value = 0;
   1393      1.1  mrg 
   1394      1.1  mrg   /* Initialize variables used during traversal of the tree.  */
   1395      1.1  mrg 
   1396      1.1  mrg   fmt->reversion_ok = 0;
   1397      1.1  mrg   fmt->saved_format = NULL;
   1398      1.1  mrg 
   1399      1.1  mrg   /* Initialize the fnode_array.  */
   1400      1.1  mrg 
   1401      1.1  mrg   memset (&(fmt->array), 0, sizeof(fmt->array));
   1402      1.1  mrg 
   1403      1.1  mrg   /* Allocate the first format node as the root of the tree.  */
   1404      1.1  mrg 
   1405      1.1  mrg   fmt->last = &fmt->array;
   1406      1.1  mrg   fmt->last->next = NULL;
   1407      1.1  mrg   fmt->avail = &fmt->array.array[0];
   1408      1.1  mrg 
   1409      1.1  mrg   memset (fmt->avail, 0, sizeof (*fmt->avail));
   1410      1.1  mrg   fmt->avail->format = FMT_LPAREN;
   1411      1.1  mrg   fmt->avail->repeat = 1;
   1412      1.1  mrg   fmt->avail++;
   1413      1.1  mrg 
   1414      1.1  mrg   if (format_lex (fmt) == FMT_LPAREN)
   1415      1.1  mrg     fmt->array.array[0].u.child = parse_format_list (dtp, &seen_data_desc);
   1416      1.1  mrg   else
   1417      1.1  mrg     fmt->error = "Missing initial left parenthesis in format";
   1418      1.1  mrg 
   1419      1.1  mrg   if (format_cache_ok)
   1420      1.1  mrg     save_parsed_format (dtp);
   1421      1.1  mrg   else
   1422      1.1  mrg     dtp->u.p.format_not_saved = 1;
   1423      1.1  mrg 
   1424      1.1  mrg   if (fmt->error)
   1425      1.1  mrg     format_error (dtp, NULL, fmt->error);
   1426      1.1  mrg }
   1427      1.1  mrg 
   1428      1.1  mrg 
   1429      1.1  mrg /* next_format0()-- Get the next format node without worrying about
   1430      1.1  mrg    reversion.  Returns NULL when we hit the end of the list.
   1431      1.1  mrg    Parenthesis nodes are incremented after the list has been
   1432      1.1  mrg    exhausted, other nodes are incremented before they are returned. */
   1433      1.1  mrg 
   1434      1.1  mrg static const fnode *
   1435      1.1  mrg next_format0 (fnode *f)
   1436      1.1  mrg {
   1437      1.1  mrg   const fnode *r;
   1438      1.1  mrg 
   1439      1.1  mrg   if (f == NULL)
   1440      1.1  mrg     return NULL;
   1441      1.1  mrg 
   1442      1.1  mrg   if (f->format != FMT_LPAREN)
   1443      1.1  mrg     {
   1444      1.1  mrg       f->count++;
   1445      1.1  mrg       if (f->count <= f->repeat)
   1446      1.1  mrg 	return f;
   1447      1.1  mrg 
   1448      1.1  mrg       f->count = 0;
   1449      1.1  mrg       return NULL;
   1450      1.1  mrg     }
   1451      1.1  mrg 
   1452      1.1  mrg   /* Deal with a parenthesis node with unlimited format.  */
   1453      1.1  mrg 
   1454      1.1  mrg   if (f->repeat == -2)  /* -2 signifies unlimited.  */
   1455      1.1  mrg   for (;;)
   1456      1.1  mrg     {
   1457      1.1  mrg       if (f->current == NULL)
   1458      1.1  mrg 	f->current = f->u.child;
   1459      1.1  mrg 
   1460      1.1  mrg       for (; f->current != NULL; f->current = f->current->next)
   1461      1.1  mrg 	{
   1462      1.1  mrg 	  r = next_format0 (f->current);
   1463      1.1  mrg 	  if (r != NULL)
   1464      1.1  mrg 	    return r;
   1465      1.1  mrg 	}
   1466      1.1  mrg     }
   1467      1.1  mrg 
   1468      1.1  mrg   /* Deal with a parenthesis node with specific repeat count.  */
   1469      1.1  mrg   for (; f->count < f->repeat; f->count++)
   1470      1.1  mrg     {
   1471      1.1  mrg       if (f->current == NULL)
   1472      1.1  mrg 	f->current = f->u.child;
   1473      1.1  mrg 
   1474      1.1  mrg       for (; f->current != NULL; f->current = f->current->next)
   1475      1.1  mrg 	{
   1476      1.1  mrg 	  r = next_format0 (f->current);
   1477      1.1  mrg 	  if (r != NULL)
   1478      1.1  mrg 	    return r;
   1479      1.1  mrg 	}
   1480      1.1  mrg     }
   1481      1.1  mrg 
   1482      1.1  mrg   f->count = 0;
   1483      1.1  mrg   return NULL;
   1484      1.1  mrg }
   1485      1.1  mrg 
   1486      1.1  mrg 
   1487      1.1  mrg /* next_format()-- Return the next format node.  If the format list
   1488      1.1  mrg    ends up being exhausted, we do reversion.  Reversion is only
   1489      1.1  mrg    allowed if we've seen a data descriptor since the
   1490      1.1  mrg    initialization or the last reversion.  We return NULL if there
   1491      1.1  mrg    are no more data descriptors to return (which is an error
   1492      1.1  mrg    condition).  */
   1493      1.1  mrg 
   1494      1.1  mrg const fnode *
   1495      1.1  mrg next_format (st_parameter_dt *dtp)
   1496      1.1  mrg {
   1497      1.1  mrg   format_token t;
   1498      1.1  mrg   const fnode *f;
   1499      1.1  mrg   format_data *fmt = dtp->u.p.fmt;
   1500      1.1  mrg 
   1501      1.1  mrg   if (fmt->saved_format != NULL)
   1502      1.1  mrg     {				/* Deal with a pushed-back format node */
   1503      1.1  mrg       f = fmt->saved_format;
   1504      1.1  mrg       fmt->saved_format = NULL;
   1505      1.1  mrg       goto done;
   1506      1.1  mrg     }
   1507      1.1  mrg 
   1508      1.1  mrg   f = next_format0 (&fmt->array.array[0]);
   1509      1.1  mrg   if (f == NULL)
   1510      1.1  mrg     {
   1511      1.1  mrg       if (!fmt->reversion_ok)
   1512      1.1  mrg 	return NULL;
   1513      1.1  mrg 
   1514      1.1  mrg       fmt->reversion_ok = 0;
   1515      1.1  mrg       revert (dtp);
   1516      1.1  mrg 
   1517      1.1  mrg       f = next_format0 (&fmt->array.array[0]);
   1518      1.1  mrg       if (f == NULL)
   1519      1.1  mrg 	{
   1520      1.1  mrg 	  format_error (dtp, NULL, reversion_error);
   1521      1.1  mrg 	  return NULL;
   1522      1.1  mrg 	}
   1523      1.1  mrg 
   1524      1.1  mrg       /* Push the first reverted token and return a colon node in case
   1525      1.1  mrg 	 there are no more data items.  */
   1526      1.1  mrg 
   1527      1.1  mrg       fmt->saved_format = f;
   1528      1.1  mrg       return &colon_node;
   1529      1.1  mrg     }
   1530      1.1  mrg 
   1531      1.1  mrg   /* If this is a data edit descriptor, then reversion has become OK. */
   1532      1.1  mrg  done:
   1533      1.1  mrg   t = f->format;
   1534      1.1  mrg 
   1535      1.1  mrg   if (!fmt->reversion_ok &&
   1536      1.1  mrg       (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F ||
   1537      1.1  mrg        t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L ||
   1538      1.1  mrg        t == FMT_A || t == FMT_D || t == FMT_DT))
   1539      1.1  mrg     fmt->reversion_ok = 1;
   1540      1.1  mrg   return f;
   1541      1.1  mrg }
   1542      1.1  mrg 
   1543      1.1  mrg 
   1544      1.1  mrg /* unget_format()-- Push the given format back so that it will be
   1545      1.1  mrg    returned on the next call to next_format() without affecting
   1546      1.1  mrg    counts.  This is necessary when we've encountered a data
   1547      1.1  mrg    descriptor, but don't know what the data item is yet.  The format
   1548      1.1  mrg    node is pushed back, and we return control to the main program,
   1549      1.1  mrg    which calls the library back with the data item (or not). */
   1550      1.1  mrg 
   1551      1.1  mrg void
   1552      1.1  mrg unget_format (st_parameter_dt *dtp, const fnode *f)
   1553      1.1  mrg {
   1554      1.1  mrg   dtp->u.p.fmt->saved_format = f;
   1555      1.1  mrg }
   1556      1.1  mrg 
   1557