1 /* Copyright (C) 2002-2013 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 F2003 I/O support contributed by Jerry DeLisle
5 This file is part of the GNU Fortran runtime library (libgfortran).
7 Libgfortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
27 /* format.c-- parse a FORMAT string into a binary format suitable for
28 * interpretation during I/O statements */
38 static const fnode colon_node
= { FMT_COLON
, 0, NULL
, NULL
, {{ 0, 0, 0 }}, 0,
43 static const char posint_required
[] = "Positive width required in format",
44 period_required
[] = "Period required in format",
45 nonneg_required
[] = "Nonnegative width required in format",
46 unexpected_element
[] = "Unexpected element '%c' in format\n",
47 unexpected_end
[] = "Unexpected end of format string",
48 bad_string
[] = "Unterminated character constant in format",
49 bad_hollerith
[] = "Hollerith constant extends past the end of the format",
50 reversion_error
[] = "Exhausted data descriptors in format",
51 zero_width
[] = "Zero width in format descriptor";
53 /* The following routines support caching format data from parsed format strings
54 into a hash table. This avoids repeatedly parsing duplicate format strings
55 or format strings in I/O statements that are repeated in loops. */
58 /* Traverse the table and free all data. */
61 free_format_hash_table (gfc_unit
*u
)
65 /* free_format_data handles any NULL pointers. */
66 for (i
= 0; i
< FORMAT_HASH_SIZE
; i
++)
68 if (u
->format_hash_table
[i
].hashed_fmt
!= NULL
)
70 free_format_data (u
->format_hash_table
[i
].hashed_fmt
);
71 free (u
->format_hash_table
[i
].key
);
73 u
->format_hash_table
[i
].key
= NULL
;
74 u
->format_hash_table
[i
].key_len
= 0;
75 u
->format_hash_table
[i
].hashed_fmt
= NULL
;
79 /* Traverse the format_data structure and reset the fnode counters. */
82 reset_node (fnode
*fn
)
89 if (fn
->format
!= FMT_LPAREN
)
92 for (f
= fn
->u
.child
; f
; f
= f
->next
)
94 if (f
->format
== FMT_RPAREN
)
101 reset_fnode_counters (st_parameter_dt
*dtp
)
108 /* Clear this pointer at the head so things start at the right place. */
109 fmt
->array
.array
[0].current
= NULL
;
111 for (f
= fmt
->array
.array
[0].u
.child
; f
; f
= f
->next
)
116 /* A simple hashing function to generate an index into the hash table. */
119 format_hash (st_parameter_dt
*dtp
)
122 gfc_charlen_type key_len
;
126 /* Hash the format string. Super simple, but what the heck! */
128 key_len
= dtp
->format_len
;
129 for (i
= 0; i
< key_len
; i
++)
131 hash
&= (FORMAT_HASH_SIZE
- 1);
137 save_parsed_format (st_parameter_dt
*dtp
)
142 hash
= format_hash (dtp
);
143 u
= dtp
->u
.p
.current_unit
;
145 /* Index into the hash table. We are simply replacing whatever is there
146 relying on probability. */
147 if (u
->format_hash_table
[hash
].hashed_fmt
!= NULL
)
148 free_format_data (u
->format_hash_table
[hash
].hashed_fmt
);
149 u
->format_hash_table
[hash
].hashed_fmt
= NULL
;
151 free (u
->format_hash_table
[hash
].key
);
152 u
->format_hash_table
[hash
].key
= dtp
->format
;
154 u
->format_hash_table
[hash
].key_len
= dtp
->format_len
;
155 u
->format_hash_table
[hash
].hashed_fmt
= dtp
->u
.p
.fmt
;
160 find_parsed_format (st_parameter_dt
*dtp
)
165 hash
= format_hash (dtp
);
166 u
= dtp
->u
.p
.current_unit
;
168 if (u
->format_hash_table
[hash
].key
!= NULL
)
170 /* See if it matches. */
171 if (u
->format_hash_table
[hash
].key_len
== dtp
->format_len
)
173 /* So far so good. */
174 if (strncmp (u
->format_hash_table
[hash
].key
,
175 dtp
->format
, dtp
->format_len
) == 0)
176 return u
->format_hash_table
[hash
].hashed_fmt
;
183 /* next_char()-- Return the next character in the format string.
184 * Returns -1 when the string is done. If the literal flag is set,
185 * spaces are significant, otherwise they are not. */
188 next_char (format_data
*fmt
, int literal
)
194 if (fmt
->format_string_len
== 0)
197 fmt
->format_string_len
--;
198 c
= toupper (*fmt
->format_string
++);
199 fmt
->error_element
= c
;
201 while ((c
== ' ' || c
== '\t') && !literal
);
207 /* unget_char()-- Back up one character position. */
209 #define unget_char(fmt) \
210 { fmt->format_string--; fmt->format_string_len++; }
213 /* get_fnode()-- Allocate a new format node, inserting it into the
214 * current singly linked list. These are initially allocated from the
218 get_fnode (format_data
*fmt
, fnode
**head
, fnode
**tail
, format_token t
)
222 if (fmt
->avail
== &fmt
->last
->array
[FARRAY_SIZE
])
224 fmt
->last
->next
= xmalloc (sizeof (fnode_array
));
225 fmt
->last
= fmt
->last
->next
;
226 fmt
->last
->next
= NULL
;
227 fmt
->avail
= &fmt
->last
->array
[0];
230 memset (f
, '\0', sizeof (fnode
));
242 f
->source
= fmt
->format_string
;
247 /* free_format_data()-- Free all allocated format data. */
250 free_format_data (format_data
*fmt
)
252 fnode_array
*fa
, *fa_next
;
258 for (fa
= fmt
->array
.next
; fa
; fa
= fa_next
)
269 /* format_lex()-- Simple lexical analyzer for getting the next token
270 * in a FORMAT string. We support a one-level token pushback in the
271 * fmt->saved_token variable. */
274 format_lex (format_data
*fmt
)
281 if (fmt
->saved_token
!= FMT_NONE
)
283 token
= fmt
->saved_token
;
284 fmt
->saved_token
= FMT_NONE
;
289 c
= next_char (fmt
, 0);
310 c
= next_char (fmt
, 0);
317 fmt
->value
= c
- '0';
321 c
= next_char (fmt
, 0);
325 fmt
->value
= 10 * fmt
->value
+ c
- '0';
331 fmt
->value
= -fmt
->value
;
332 token
= FMT_SIGNED_INT
;
345 fmt
->value
= c
- '0';
349 c
= next_char (fmt
, 0);
353 fmt
->value
= 10 * fmt
->value
+ c
- '0';
357 token
= (fmt
->value
== 0) ? FMT_ZERO
: FMT_POSINT
;
381 switch (next_char (fmt
, 0))
402 switch (next_char (fmt
, 0))
419 switch (next_char (fmt
, 0))
439 fmt
->string
= fmt
->format_string
;
440 fmt
->value
= 0; /* This is the length of the string */
444 c
= next_char (fmt
, 1);
447 token
= FMT_BADSTRING
;
448 fmt
->error
= bad_string
;
454 c
= next_char (fmt
, 1);
458 token
= FMT_BADSTRING
;
459 fmt
->error
= bad_string
;
497 switch (next_char (fmt
, 0))
529 switch (next_char (fmt
, 0))
545 switch (next_char (fmt
, 0))
585 /* parse_format_list()-- Parse a format list. Assumes that a left
586 * paren has already been seen. Returns a list representing the
587 * parenthesis node which contains the rest of the list. */
590 parse_format_list (st_parameter_dt
*dtp
, bool *seen_dd
)
593 format_token t
, u
, t2
;
595 format_data
*fmt
= dtp
->u
.p
.fmt
;
596 bool seen_data_desc
= false;
600 /* Get the next format item */
602 t
= format_lex (fmt
);
607 t
= format_lex (fmt
);
610 fmt
->error
= "Left parenthesis required after '*'";
613 get_fnode (fmt
, &head
, &tail
, FMT_LPAREN
);
614 tail
->repeat
= -2; /* Signifies unlimited format. */
615 tail
->u
.child
= parse_format_list (dtp
, &seen_data_desc
);
616 if (fmt
->error
!= NULL
)
620 fmt
->error
= "'*' requires at least one associated data descriptor";
628 t
= format_lex (fmt
);
632 get_fnode (fmt
, &head
, &tail
, FMT_LPAREN
);
633 tail
->repeat
= repeat
;
634 tail
->u
.child
= parse_format_list (dtp
, &seen_data_desc
);
635 *seen_dd
= seen_data_desc
;
636 if (fmt
->error
!= NULL
)
642 get_fnode (fmt
, &head
, &tail
, FMT_SLASH
);
643 tail
->repeat
= repeat
;
647 get_fnode (fmt
, &head
, &tail
, FMT_X
);
649 tail
->u
.k
= fmt
->value
;
660 get_fnode (fmt
, &head
, &tail
, FMT_LPAREN
);
662 tail
->u
.child
= parse_format_list (dtp
, &seen_data_desc
);
663 *seen_dd
= seen_data_desc
;
664 if (fmt
->error
!= NULL
)
669 case FMT_SIGNED_INT
: /* Signed integer can only precede a P format. */
670 case FMT_ZERO
: /* Same for zero. */
671 t
= format_lex (fmt
);
674 fmt
->error
= "Expected P edit descriptor in format";
679 get_fnode (fmt
, &head
, &tail
, FMT_P
);
680 tail
->u
.k
= fmt
->value
;
683 t
= format_lex (fmt
);
684 if (t
== FMT_F
|| t
== FMT_EN
|| t
== FMT_ES
|| t
== FMT_D
685 || t
== FMT_G
|| t
== FMT_E
)
691 if (t
!= FMT_COMMA
&& t
!= FMT_RPAREN
&& t
!= FMT_SLASH
694 fmt
->error
= "Comma required after P descriptor";
698 fmt
->saved_token
= t
;
701 case FMT_P
: /* P and X require a prior number */
702 fmt
->error
= "P descriptor requires leading scale factor";
709 If we would be pedantic in the library, we would have to reject
710 an X descriptor without an integer prefix:
712 fmt->error = "X descriptor requires leading space count";
715 However, this is an extension supported by many Fortran compilers,
716 including Cray, HP, AIX, and IRIX. Therefore, we allow it in the
717 runtime library, and make the front end reject it if the compiler
718 is in pedantic mode. The interpretation of 'X' is '1X'.
720 get_fnode (fmt
, &head
, &tail
, FMT_X
);
726 get_fnode (fmt
, &head
, &tail
, FMT_STRING
);
727 tail
->u
.string
.p
= fmt
->string
;
728 tail
->u
.string
.length
= fmt
->value
;
738 notify_std (&dtp
->common
, GFC_STD_F2003
, "Fortran 2003: Round "
739 "descriptor not allowed");
740 get_fnode (fmt
, &head
, &tail
, t
);
746 notify_std (&dtp
->common
, GFC_STD_F2003
, "Fortran 2003: DC or DP "
747 "descriptor not allowed");
754 get_fnode (fmt
, &head
, &tail
, t
);
759 get_fnode (fmt
, &head
, &tail
, FMT_COLON
);
764 get_fnode (fmt
, &head
, &tail
, FMT_SLASH
);
770 get_fnode (fmt
, &head
, &tail
, FMT_DOLLAR
);
772 notify_std (&dtp
->common
, GFC_STD_GNU
, "Extension: $ descriptor");
778 t2
= format_lex (fmt
);
779 if (t2
!= FMT_POSINT
)
781 fmt
->error
= posint_required
;
784 get_fnode (fmt
, &head
, &tail
, t
);
785 tail
->u
.n
= fmt
->value
;
806 get_fnode (fmt
, &head
, &tail
, FMT_STRING
);
807 if (fmt
->format_string_len
< 1)
809 fmt
->error
= bad_hollerith
;
813 tail
->u
.string
.p
= fmt
->format_string
;
814 tail
->u
.string
.length
= 1;
817 fmt
->format_string
++;
818 fmt
->format_string_len
--;
823 fmt
->error
= unexpected_end
;
833 fmt
->error
= unexpected_element
;
837 /* In this state, t must currently be a data descriptor. Deal with
838 things that can/must follow the descriptor */
843 t
= format_lex (fmt
);
846 if (notification_std(GFC_STD_GNU
) == NOTIFICATION_ERROR
)
848 fmt
->error
= posint_required
;
853 fmt
->saved_token
= t
;
854 fmt
->value
= 1; /* Default width */
855 notify_std (&dtp
->common
, GFC_STD_GNU
, posint_required
);
859 get_fnode (fmt
, &head
, &tail
, FMT_L
);
860 tail
->u
.n
= fmt
->value
;
861 tail
->repeat
= repeat
;
865 t
= format_lex (fmt
);
868 fmt
->error
= zero_width
;
874 fmt
->saved_token
= t
;
875 fmt
->value
= -1; /* Width not present */
878 get_fnode (fmt
, &head
, &tail
, FMT_A
);
879 tail
->repeat
= repeat
;
880 tail
->u
.n
= fmt
->value
;
889 get_fnode (fmt
, &head
, &tail
, t
);
890 tail
->repeat
= repeat
;
892 u
= format_lex (fmt
);
893 if (t
== FMT_G
&& u
== FMT_ZERO
)
895 if (notification_std (GFC_STD_F2008
) == NOTIFICATION_ERROR
896 || dtp
->u
.p
.mode
== READING
)
898 fmt
->error
= zero_width
;
902 u
= format_lex (fmt
);
905 fmt
->saved_token
= u
;
909 u
= format_lex (fmt
);
912 fmt
->error
= posint_required
;
915 tail
->u
.real
.d
= fmt
->value
;
918 if (t
== FMT_F
&& dtp
->u
.p
.mode
== WRITING
)
920 if (u
!= FMT_POSINT
&& u
!= FMT_ZERO
)
922 fmt
->error
= nonneg_required
;
926 else if (u
!= FMT_POSINT
)
928 fmt
->error
= posint_required
;
932 tail
->u
.real
.w
= fmt
->value
;
934 t
= format_lex (fmt
);
937 /* We treat a missing decimal descriptor as 0. Note: This is only
938 allowed if -std=legacy, otherwise an error occurs. */
939 if (compile_options
.warn_std
!= 0)
941 fmt
->error
= period_required
;
944 fmt
->saved_token
= t
;
950 t
= format_lex (fmt
);
951 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
953 fmt
->error
= nonneg_required
;
957 tail
->u
.real
.d
= fmt
->value
;
960 if (t2
== FMT_D
|| t2
== FMT_F
)
964 /* Look for optional exponent */
965 t
= format_lex (fmt
);
967 fmt
->saved_token
= t
;
970 t
= format_lex (fmt
);
973 fmt
->error
= "Positive exponent width required in format";
977 tail
->u
.real
.e
= fmt
->value
;
983 if (repeat
> fmt
->format_string_len
)
985 fmt
->error
= bad_hollerith
;
989 get_fnode (fmt
, &head
, &tail
, FMT_STRING
);
990 tail
->u
.string
.p
= fmt
->format_string
;
991 tail
->u
.string
.length
= repeat
;
994 fmt
->format_string
+= fmt
->value
;
995 fmt
->format_string_len
-= repeat
;
1003 get_fnode (fmt
, &head
, &tail
, t
);
1004 tail
->repeat
= repeat
;
1006 t
= format_lex (fmt
);
1008 if (dtp
->u
.p
.mode
== READING
)
1010 if (t
!= FMT_POSINT
)
1012 fmt
->error
= posint_required
;
1018 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
1020 fmt
->error
= nonneg_required
;
1025 tail
->u
.integer
.w
= fmt
->value
;
1026 tail
->u
.integer
.m
= -1;
1028 t
= format_lex (fmt
);
1029 if (t
!= FMT_PERIOD
)
1031 fmt
->saved_token
= t
;
1035 t
= format_lex (fmt
);
1036 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
1038 fmt
->error
= nonneg_required
;
1042 tail
->u
.integer
.m
= fmt
->value
;
1045 if (tail
->u
.integer
.w
!= 0 && tail
->u
.integer
.m
> tail
->u
.integer
.w
)
1047 fmt
->error
= "Minimum digits exceeds field width";
1054 fmt
->error
= unexpected_element
;
1058 /* Between a descriptor and what comes next */
1060 t
= format_lex (fmt
);
1071 get_fnode (fmt
, &head
, &tail
, t
);
1073 goto optional_comma
;
1076 fmt
->error
= unexpected_end
;
1080 /* Assume a missing comma, this is a GNU extension */
1084 /* Optional comma is a weird between state where we've just finished
1085 reading a colon, slash or P descriptor. */
1087 t
= format_lex (fmt
);
1096 default: /* Assume that we have another format item */
1097 fmt
->saved_token
= t
;
1109 /* format_error()-- Generate an error message for a format statement.
1110 * If the node that gives the location of the error is NULL, the error
1111 * is assumed to happen at parse time, and the current location of the
1114 * We generate a message showing where the problem is. We take extra
1115 * care to print only the relevant part of the format if it is longer
1116 * than a standard 80 column display. */
1119 format_error (st_parameter_dt
*dtp
, const fnode
*f
, const char *message
)
1121 int width
, i
, j
, offset
;
1123 char *p
, buffer
[BUFLEN
];
1124 format_data
*fmt
= dtp
->u
.p
.fmt
;
1127 fmt
->format_string
= f
->source
;
1129 if (message
== unexpected_element
)
1130 snprintf (buffer
, BUFLEN
, message
, fmt
->error_element
);
1132 snprintf (buffer
, BUFLEN
, "%s\n", message
);
1134 j
= fmt
->format_string
- dtp
->format
;
1136 offset
= (j
> 60) ? j
- 40 : 0;
1139 width
= dtp
->format_len
- offset
;
1144 /* Show the format */
1146 p
= strchr (buffer
, '\0');
1148 memcpy (p
, dtp
->format
+ offset
, width
);
1153 /* Show where the problem is */
1155 for (i
= 1; i
< j
; i
++)
1161 generate_error (&dtp
->common
, LIBERROR_FORMAT
, buffer
);
1165 /* revert()-- Do reversion of the format. Control reverts to the left
1166 * parenthesis that matches the rightmost right parenthesis. From our
1167 * tree structure, we are looking for the rightmost parenthesis node
1168 * at the second level, the first level always being a single
1169 * parenthesis node. If this node doesn't exit, we use the top
1173 revert (st_parameter_dt
*dtp
)
1176 format_data
*fmt
= dtp
->u
.p
.fmt
;
1178 dtp
->u
.p
.reversion_flag
= 1;
1182 for (f
= fmt
->array
.array
[0].u
.child
; f
; f
= f
->next
)
1183 if (f
->format
== FMT_LPAREN
)
1186 /* If r is NULL because no node was found, the whole tree will be used */
1188 fmt
->array
.array
[0].current
= r
;
1189 fmt
->array
.array
[0].count
= 0;
1192 /* parse_format()-- Parse a format string. */
1195 parse_format (st_parameter_dt
*dtp
)
1198 bool format_cache_ok
, seen_data_desc
= false;
1200 /* Don't cache for internal units and set an arbitrary limit on the size of
1201 format strings we will cache. (Avoids memory issues.) */
1202 format_cache_ok
= !is_internal_unit (dtp
);
1204 /* Lookup format string to see if it has already been parsed. */
1205 if (format_cache_ok
)
1207 dtp
->u
.p
.fmt
= find_parsed_format (dtp
);
1209 if (dtp
->u
.p
.fmt
!= NULL
)
1211 dtp
->u
.p
.fmt
->reversion_ok
= 0;
1212 dtp
->u
.p
.fmt
->saved_token
= FMT_NONE
;
1213 dtp
->u
.p
.fmt
->saved_format
= NULL
;
1214 reset_fnode_counters (dtp
);
1219 /* Not found so proceed as follows. */
1221 if (format_cache_ok
)
1223 char *fmt_string
= xmalloc (dtp
->format_len
);
1224 memcpy (fmt_string
, dtp
->format
, dtp
->format_len
);
1225 dtp
->format
= fmt_string
;
1228 dtp
->u
.p
.fmt
= fmt
= xmalloc (sizeof (format_data
));
1229 fmt
->format_string
= dtp
->format
;
1230 fmt
->format_string_len
= dtp
->format_len
;
1233 fmt
->saved_token
= FMT_NONE
;
1237 /* Initialize variables used during traversal of the tree. */
1239 fmt
->reversion_ok
= 0;
1240 fmt
->saved_format
= NULL
;
1242 /* Allocate the first format node as the root of the tree. */
1244 fmt
->last
= &fmt
->array
;
1245 fmt
->last
->next
= NULL
;
1246 fmt
->avail
= &fmt
->array
.array
[0];
1248 memset (fmt
->avail
, 0, sizeof (*fmt
->avail
));
1249 fmt
->avail
->format
= FMT_LPAREN
;
1250 fmt
->avail
->repeat
= 1;
1253 if (format_lex (fmt
) == FMT_LPAREN
)
1254 fmt
->array
.array
[0].u
.child
= parse_format_list (dtp
, &seen_data_desc
);
1256 fmt
->error
= "Missing initial left parenthesis in format";
1260 format_error (dtp
, NULL
, fmt
->error
);
1261 if (format_cache_ok
)
1263 free_format_hash_table (dtp
->u
.p
.current_unit
);
1267 if (format_cache_ok
)
1268 save_parsed_format (dtp
);
1270 dtp
->u
.p
.format_not_saved
= 1;
1274 /* next_format0()-- Get the next format node without worrying about
1275 * reversion. Returns NULL when we hit the end of the list.
1276 * Parenthesis nodes are incremented after the list has been
1277 * exhausted, other nodes are incremented before they are returned. */
1279 static const fnode
*
1280 next_format0 (fnode
* f
)
1287 if (f
->format
!= FMT_LPAREN
)
1290 if (f
->count
<= f
->repeat
)
1297 /* Deal with a parenthesis node with unlimited format. */
1299 if (f
->repeat
== -2) /* -2 signifies unlimited. */
1302 if (f
->current
== NULL
)
1303 f
->current
= f
->u
.child
;
1305 for (; f
->current
!= NULL
; f
->current
= f
->current
->next
)
1307 r
= next_format0 (f
->current
);
1313 /* Deal with a parenthesis node with specific repeat count. */
1314 for (; f
->count
< f
->repeat
; f
->count
++)
1316 if (f
->current
== NULL
)
1317 f
->current
= f
->u
.child
;
1319 for (; f
->current
!= NULL
; f
->current
= f
->current
->next
)
1321 r
= next_format0 (f
->current
);
1332 /* next_format()-- Return the next format node. If the format list
1333 * ends up being exhausted, we do reversion. Reversion is only
1334 * allowed if we've seen a data descriptor since the
1335 * initialization or the last reversion. We return NULL if there
1336 * are no more data descriptors to return (which is an error
1340 next_format (st_parameter_dt
*dtp
)
1344 format_data
*fmt
= dtp
->u
.p
.fmt
;
1346 if (fmt
->saved_format
!= NULL
)
1347 { /* Deal with a pushed-back format node */
1348 f
= fmt
->saved_format
;
1349 fmt
->saved_format
= NULL
;
1353 f
= next_format0 (&fmt
->array
.array
[0]);
1356 if (!fmt
->reversion_ok
)
1359 fmt
->reversion_ok
= 0;
1362 f
= next_format0 (&fmt
->array
.array
[0]);
1365 format_error (dtp
, NULL
, reversion_error
);
1369 /* Push the first reverted token and return a colon node in case
1370 * there are no more data items. */
1372 fmt
->saved_format
= f
;
1376 /* If this is a data edit descriptor, then reversion has become OK. */
1380 if (!fmt
->reversion_ok
&&
1381 (t
== FMT_I
|| t
== FMT_B
|| t
== FMT_O
|| t
== FMT_Z
|| t
== FMT_F
||
1382 t
== FMT_E
|| t
== FMT_EN
|| t
== FMT_ES
|| t
== FMT_G
|| t
== FMT_L
||
1383 t
== FMT_A
|| t
== FMT_D
))
1384 fmt
->reversion_ok
= 1;
1389 /* unget_format()-- Push the given format back so that it will be
1390 * returned on the next call to next_format() without affecting
1391 * counts. This is necessary when we've encountered a data
1392 * descriptor, but don't know what the data item is yet. The format
1393 * node is pushed back, and we return control to the main program,
1394 * which calls the library back with the data item (or not). */
1397 unget_format (st_parameter_dt
*dtp
, const fnode
*f
)
1399 dtp
->u
.p
.fmt
->saved_format
= f
;