1 /* Copyright (C) 2002-2015 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 */
37 static const fnode colon_node
= { FMT_COLON
, 0, NULL
, NULL
, {{ 0, 0, 0 }}, 0,
42 static const char posint_required
[] = "Positive width required in format",
43 period_required
[] = "Period required in format",
44 nonneg_required
[] = "Nonnegative width required in format",
45 unexpected_element
[] = "Unexpected element '%c' in format\n",
46 unexpected_end
[] = "Unexpected end of format string",
47 bad_string
[] = "Unterminated character constant in format",
48 bad_hollerith
[] = "Hollerith constant extends past the end of the format",
49 reversion_error
[] = "Exhausted data descriptors in format",
50 zero_width
[] = "Zero width in format descriptor";
52 /* The following routines support caching format data from parsed format strings
53 into a hash table. This avoids repeatedly parsing duplicate format strings
54 or format strings in I/O statements that are repeated in loops. */
57 /* Traverse the table and free all data. */
60 free_format_hash_table (gfc_unit
*u
)
64 /* free_format_data handles any NULL pointers. */
65 for (i
= 0; i
< FORMAT_HASH_SIZE
; i
++)
67 if (u
->format_hash_table
[i
].hashed_fmt
!= NULL
)
69 free_format_data (u
->format_hash_table
[i
].hashed_fmt
);
70 free (u
->format_hash_table
[i
].key
);
72 u
->format_hash_table
[i
].key
= NULL
;
73 u
->format_hash_table
[i
].key_len
= 0;
74 u
->format_hash_table
[i
].hashed_fmt
= NULL
;
78 /* Traverse the format_data structure and reset the fnode counters. */
81 reset_node (fnode
*fn
)
88 if (fn
->format
!= FMT_LPAREN
)
91 for (f
= fn
->u
.child
; f
; f
= f
->next
)
93 if (f
->format
== FMT_RPAREN
)
100 reset_fnode_counters (st_parameter_dt
*dtp
)
107 /* Clear this pointer at the head so things start at the right place. */
108 fmt
->array
.array
[0].current
= NULL
;
110 for (f
= fmt
->array
.array
[0].u
.child
; f
; f
= f
->next
)
115 /* A simple hashing function to generate an index into the hash table. */
118 format_hash (st_parameter_dt
*dtp
)
121 gfc_charlen_type key_len
;
125 /* Hash the format string. Super simple, but what the heck! */
127 key_len
= dtp
->format_len
;
128 for (i
= 0; i
< key_len
; i
++)
130 hash
&= (FORMAT_HASH_SIZE
- 1);
136 save_parsed_format (st_parameter_dt
*dtp
)
141 hash
= format_hash (dtp
);
142 u
= dtp
->u
.p
.current_unit
;
144 /* Index into the hash table. We are simply replacing whatever is there
145 relying on probability. */
146 if (u
->format_hash_table
[hash
].hashed_fmt
!= NULL
)
147 free_format_data (u
->format_hash_table
[hash
].hashed_fmt
);
148 u
->format_hash_table
[hash
].hashed_fmt
= NULL
;
150 free (u
->format_hash_table
[hash
].key
);
151 u
->format_hash_table
[hash
].key
= dtp
->format
;
153 u
->format_hash_table
[hash
].key_len
= dtp
->format_len
;
154 u
->format_hash_table
[hash
].hashed_fmt
= dtp
->u
.p
.fmt
;
159 find_parsed_format (st_parameter_dt
*dtp
)
164 hash
= format_hash (dtp
);
165 u
= dtp
->u
.p
.current_unit
;
167 if (u
->format_hash_table
[hash
].key
!= NULL
)
169 /* See if it matches. */
170 if (u
->format_hash_table
[hash
].key_len
== dtp
->format_len
)
172 /* So far so good. */
173 if (strncmp (u
->format_hash_table
[hash
].key
,
174 dtp
->format
, dtp
->format_len
) == 0)
175 return u
->format_hash_table
[hash
].hashed_fmt
;
182 /* next_char()-- Return the next character in the format string.
183 * Returns -1 when the string is done. If the literal flag is set,
184 * spaces are significant, otherwise they are not. */
187 next_char (format_data
*fmt
, int literal
)
193 if (fmt
->format_string_len
== 0)
196 fmt
->format_string_len
--;
197 c
= toupper (*fmt
->format_string
++);
198 fmt
->error_element
= c
;
200 while ((c
== ' ' || c
== '\t') && !literal
);
206 /* unget_char()-- Back up one character position. */
208 #define unget_char(fmt) \
209 { fmt->format_string--; fmt->format_string_len++; }
212 /* get_fnode()-- Allocate a new format node, inserting it into the
213 * current singly linked list. These are initially allocated from the
217 get_fnode (format_data
*fmt
, fnode
**head
, fnode
**tail
, format_token t
)
221 if (fmt
->avail
== &fmt
->last
->array
[FARRAY_SIZE
])
223 fmt
->last
->next
= xmalloc (sizeof (fnode_array
));
224 fmt
->last
= fmt
->last
->next
;
225 fmt
->last
->next
= NULL
;
226 fmt
->avail
= &fmt
->last
->array
[0];
229 memset (f
, '\0', sizeof (fnode
));
241 f
->source
= fmt
->format_string
;
246 /* free_format()-- Free allocated format string. */
248 free_format (st_parameter_dt
*dtp
)
250 if ((dtp
->common
.flags
& IOPARM_DT_HAS_FORMAT
) && dtp
->format
)
258 /* free_format_data()-- Free all allocated format data. */
261 free_format_data (format_data
*fmt
)
263 fnode_array
*fa
, *fa_next
;
269 for (fa
= fmt
->array
.next
; fa
; fa
= fa_next
)
280 /* format_lex()-- Simple lexical analyzer for getting the next token
281 * in a FORMAT string. We support a one-level token pushback in the
282 * fmt->saved_token variable. */
285 format_lex (format_data
*fmt
)
292 if (fmt
->saved_token
!= FMT_NONE
)
294 token
= fmt
->saved_token
;
295 fmt
->saved_token
= FMT_NONE
;
300 c
= next_char (fmt
, 0);
321 c
= next_char (fmt
, 0);
328 fmt
->value
= c
- '0';
332 c
= next_char (fmt
, 0);
336 fmt
->value
= 10 * fmt
->value
+ c
- '0';
342 fmt
->value
= -fmt
->value
;
343 token
= FMT_SIGNED_INT
;
356 fmt
->value
= c
- '0';
360 c
= next_char (fmt
, 0);
364 fmt
->value
= 10 * fmt
->value
+ c
- '0';
368 token
= (fmt
->value
== 0) ? FMT_ZERO
: FMT_POSINT
;
392 switch (next_char (fmt
, 0))
413 switch (next_char (fmt
, 0))
430 switch (next_char (fmt
, 0))
450 fmt
->string
= fmt
->format_string
;
451 fmt
->value
= 0; /* This is the length of the string */
455 c
= next_char (fmt
, 1);
458 token
= FMT_BADSTRING
;
459 fmt
->error
= bad_string
;
465 c
= next_char (fmt
, 1);
469 token
= FMT_BADSTRING
;
470 fmt
->error
= bad_string
;
508 switch (next_char (fmt
, 0))
540 switch (next_char (fmt
, 0))
556 switch (next_char (fmt
, 0))
596 /* parse_format_list()-- Parse a format list. Assumes that a left
597 * paren has already been seen. Returns a list representing the
598 * parenthesis node which contains the rest of the list. */
601 parse_format_list (st_parameter_dt
*dtp
, bool *seen_dd
)
604 format_token t
, u
, t2
;
606 format_data
*fmt
= dtp
->u
.p
.fmt
;
607 bool seen_data_desc
= false;
611 /* Get the next format item */
613 t
= format_lex (fmt
);
618 t
= format_lex (fmt
);
621 fmt
->error
= "Left parenthesis required after '*'";
624 get_fnode (fmt
, &head
, &tail
, FMT_LPAREN
);
625 tail
->repeat
= -2; /* Signifies unlimited format. */
626 tail
->u
.child
= parse_format_list (dtp
, &seen_data_desc
);
627 *seen_dd
= seen_data_desc
;
628 if (fmt
->error
!= NULL
)
632 fmt
->error
= "'*' requires at least one associated data descriptor";
640 t
= format_lex (fmt
);
644 get_fnode (fmt
, &head
, &tail
, FMT_LPAREN
);
645 tail
->repeat
= repeat
;
646 tail
->u
.child
= parse_format_list (dtp
, &seen_data_desc
);
647 *seen_dd
= seen_data_desc
;
648 if (fmt
->error
!= NULL
)
654 get_fnode (fmt
, &head
, &tail
, FMT_SLASH
);
655 tail
->repeat
= repeat
;
659 get_fnode (fmt
, &head
, &tail
, FMT_X
);
661 tail
->u
.k
= fmt
->value
;
672 get_fnode (fmt
, &head
, &tail
, FMT_LPAREN
);
674 tail
->u
.child
= parse_format_list (dtp
, &seen_data_desc
);
675 *seen_dd
= seen_data_desc
;
676 if (fmt
->error
!= NULL
)
681 case FMT_SIGNED_INT
: /* Signed integer can only precede a P format. */
682 case FMT_ZERO
: /* Same for zero. */
683 t
= format_lex (fmt
);
686 fmt
->error
= "Expected P edit descriptor in format";
691 get_fnode (fmt
, &head
, &tail
, FMT_P
);
692 tail
->u
.k
= fmt
->value
;
695 t
= format_lex (fmt
);
696 if (t
== FMT_F
|| t
== FMT_EN
|| t
== FMT_ES
|| t
== FMT_D
697 || t
== FMT_G
|| t
== FMT_E
)
703 if (t
!= FMT_COMMA
&& t
!= FMT_RPAREN
&& t
!= FMT_SLASH
706 fmt
->error
= "Comma required after P descriptor";
710 fmt
->saved_token
= t
;
713 case FMT_P
: /* P and X require a prior number */
714 fmt
->error
= "P descriptor requires leading scale factor";
721 If we would be pedantic in the library, we would have to reject
722 an X descriptor without an integer prefix:
724 fmt->error = "X descriptor requires leading space count";
727 However, this is an extension supported by many Fortran compilers,
728 including Cray, HP, AIX, and IRIX. Therefore, we allow it in the
729 runtime library, and make the front end reject it if the compiler
730 is in pedantic mode. The interpretation of 'X' is '1X'.
732 get_fnode (fmt
, &head
, &tail
, FMT_X
);
738 get_fnode (fmt
, &head
, &tail
, FMT_STRING
);
739 tail
->u
.string
.p
= fmt
->string
;
740 tail
->u
.string
.length
= fmt
->value
;
750 notify_std (&dtp
->common
, GFC_STD_F2003
, "Fortran 2003: Round "
751 "descriptor not allowed");
752 get_fnode (fmt
, &head
, &tail
, t
);
758 notify_std (&dtp
->common
, GFC_STD_F2003
, "Fortran 2003: DC or DP "
759 "descriptor not allowed");
766 get_fnode (fmt
, &head
, &tail
, t
);
771 get_fnode (fmt
, &head
, &tail
, FMT_COLON
);
776 get_fnode (fmt
, &head
, &tail
, FMT_SLASH
);
782 get_fnode (fmt
, &head
, &tail
, FMT_DOLLAR
);
784 notify_std (&dtp
->common
, GFC_STD_GNU
, "Extension: $ descriptor");
790 t2
= format_lex (fmt
);
791 if (t2
!= FMT_POSINT
)
793 fmt
->error
= posint_required
;
796 get_fnode (fmt
, &head
, &tail
, t
);
797 tail
->u
.n
= fmt
->value
;
818 get_fnode (fmt
, &head
, &tail
, FMT_STRING
);
819 if (fmt
->format_string_len
< 1)
821 fmt
->error
= bad_hollerith
;
825 tail
->u
.string
.p
= fmt
->format_string
;
826 tail
->u
.string
.length
= 1;
829 fmt
->format_string
++;
830 fmt
->format_string_len
--;
835 fmt
->error
= unexpected_end
;
845 fmt
->error
= unexpected_element
;
849 /* In this state, t must currently be a data descriptor. Deal with
850 things that can/must follow the descriptor */
856 t
= format_lex (fmt
);
859 if (notification_std(GFC_STD_GNU
) == NOTIFICATION_ERROR
)
861 fmt
->error
= posint_required
;
866 fmt
->saved_token
= t
;
867 fmt
->value
= 1; /* Default width */
868 notify_std (&dtp
->common
, GFC_STD_GNU
, posint_required
);
872 get_fnode (fmt
, &head
, &tail
, FMT_L
);
873 tail
->u
.n
= fmt
->value
;
874 tail
->repeat
= repeat
;
879 t
= format_lex (fmt
);
882 fmt
->error
= zero_width
;
888 fmt
->saved_token
= t
;
889 fmt
->value
= -1; /* Width not present */
892 get_fnode (fmt
, &head
, &tail
, FMT_A
);
893 tail
->repeat
= repeat
;
894 tail
->u
.n
= fmt
->value
;
904 get_fnode (fmt
, &head
, &tail
, t
);
905 tail
->repeat
= repeat
;
907 u
= format_lex (fmt
);
908 if (t
== FMT_G
&& u
== FMT_ZERO
)
911 if (notification_std (GFC_STD_F2008
) == NOTIFICATION_ERROR
912 || dtp
->u
.p
.mode
== READING
)
914 fmt
->error
= zero_width
;
918 u
= format_lex (fmt
);
921 fmt
->saved_token
= u
;
925 u
= format_lex (fmt
);
928 fmt
->error
= posint_required
;
931 tail
->u
.real
.d
= fmt
->value
;
934 if (t
== FMT_F
&& dtp
->u
.p
.mode
== WRITING
)
937 if (u
!= FMT_POSINT
&& u
!= FMT_ZERO
)
939 fmt
->error
= nonneg_required
;
943 else if (u
!= FMT_POSINT
)
945 fmt
->error
= posint_required
;
949 tail
->u
.real
.w
= fmt
->value
;
951 t
= format_lex (fmt
);
954 /* We treat a missing decimal descriptor as 0. Note: This is only
955 allowed if -std=legacy, otherwise an error occurs. */
956 if (compile_options
.warn_std
!= 0)
958 fmt
->error
= period_required
;
961 fmt
->saved_token
= t
;
967 t
= format_lex (fmt
);
968 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
970 fmt
->error
= nonneg_required
;
974 tail
->u
.real
.d
= fmt
->value
;
977 if (t2
== FMT_D
|| t2
== FMT_F
)
983 /* Look for optional exponent */
984 t
= format_lex (fmt
);
986 fmt
->saved_token
= t
;
989 t
= format_lex (fmt
);
992 fmt
->error
= "Positive exponent width required in format";
996 tail
->u
.real
.e
= fmt
->value
;
1002 if (repeat
> fmt
->format_string_len
)
1004 fmt
->error
= bad_hollerith
;
1008 get_fnode (fmt
, &head
, &tail
, FMT_STRING
);
1009 tail
->u
.string
.p
= fmt
->format_string
;
1010 tail
->u
.string
.length
= repeat
;
1013 fmt
->format_string
+= fmt
->value
;
1014 fmt
->format_string_len
-= repeat
;
1023 get_fnode (fmt
, &head
, &tail
, t
);
1024 tail
->repeat
= repeat
;
1026 t
= format_lex (fmt
);
1028 if (dtp
->u
.p
.mode
== READING
)
1030 if (t
!= FMT_POSINT
)
1032 fmt
->error
= posint_required
;
1038 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
1040 fmt
->error
= nonneg_required
;
1045 tail
->u
.integer
.w
= fmt
->value
;
1046 tail
->u
.integer
.m
= -1;
1048 t
= format_lex (fmt
);
1049 if (t
!= FMT_PERIOD
)
1051 fmt
->saved_token
= t
;
1055 t
= format_lex (fmt
);
1056 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
1058 fmt
->error
= nonneg_required
;
1062 tail
->u
.integer
.m
= fmt
->value
;
1065 if (tail
->u
.integer
.w
!= 0 && tail
->u
.integer
.m
> tail
->u
.integer
.w
)
1067 fmt
->error
= "Minimum digits exceeds field width";
1074 fmt
->error
= unexpected_element
;
1078 /* Between a descriptor and what comes next */
1080 t
= format_lex (fmt
);
1091 get_fnode (fmt
, &head
, &tail
, t
);
1093 goto optional_comma
;
1096 fmt
->error
= unexpected_end
;
1100 /* Assume a missing comma, this is a GNU extension */
1104 /* Optional comma is a weird between state where we've just finished
1105 reading a colon, slash or P descriptor. */
1107 t
= format_lex (fmt
);
1116 default: /* Assume that we have another format item */
1117 fmt
->saved_token
= t
;
1129 /* format_error()-- Generate an error message for a format statement.
1130 * If the node that gives the location of the error is NULL, the error
1131 * is assumed to happen at parse time, and the current location of the
1134 * We generate a message showing where the problem is. We take extra
1135 * care to print only the relevant part of the format if it is longer
1136 * than a standard 80 column display. */
1139 format_error (st_parameter_dt
*dtp
, const fnode
*f
, const char *message
)
1141 int width
, i
, offset
;
1143 char *p
, buffer
[BUFLEN
];
1144 format_data
*fmt
= dtp
->u
.p
.fmt
;
1148 else /* This should not happen. */
1151 if (message
== unexpected_element
)
1152 snprintf (buffer
, BUFLEN
, message
, fmt
->error_element
);
1154 snprintf (buffer
, BUFLEN
, "%s\n", message
);
1156 /* Get the offset into the format string where the error occurred. */
1157 offset
= dtp
->format_len
- (fmt
->reversion_ok
?
1158 (int) strlen(p
) : fmt
->format_string_len
);
1160 width
= dtp
->format_len
;
1165 /* Show the format */
1167 p
= strchr (buffer
, '\0');
1170 memcpy (p
, dtp
->format
, width
);
1175 /* Show where the problem is */
1177 for (i
= 1; i
< offset
; i
++)
1183 /* Cleanup any left over memory allocations before calling generate
1185 if (is_internal_unit (dtp
))
1187 if (dtp
->format
!= NULL
)
1193 /* Leave these alone if IOSTAT was given because execution will
1194 return from generate error in those cases. */
1195 if (!(dtp
->common
.flags
& IOPARM_HAS_IOSTAT
))
1197 free (dtp
->u
.p
.fmt
);
1198 free_format_hash_table (dtp
->u
.p
.current_unit
);
1199 free_internal_unit (dtp
);
1203 generate_error (&dtp
->common
, LIBERROR_FORMAT
, buffer
);
1207 /* revert()-- Do reversion of the format. Control reverts to the left
1208 * parenthesis that matches the rightmost right parenthesis. From our
1209 * tree structure, we are looking for the rightmost parenthesis node
1210 * at the second level, the first level always being a single
1211 * parenthesis node. If this node doesn't exit, we use the top
1215 revert (st_parameter_dt
*dtp
)
1218 format_data
*fmt
= dtp
->u
.p
.fmt
;
1220 dtp
->u
.p
.reversion_flag
= 1;
1224 for (f
= fmt
->array
.array
[0].u
.child
; f
; f
= f
->next
)
1225 if (f
->format
== FMT_LPAREN
)
1228 /* If r is NULL because no node was found, the whole tree will be used */
1230 fmt
->array
.array
[0].current
= r
;
1231 fmt
->array
.array
[0].count
= 0;
1234 /* parse_format()-- Parse a format string. */
1237 parse_format (st_parameter_dt
*dtp
)
1240 bool format_cache_ok
, seen_data_desc
= false;
1242 /* Don't cache for internal units and set an arbitrary limit on the size of
1243 format strings we will cache. (Avoids memory issues.) */
1244 format_cache_ok
= !is_internal_unit (dtp
);
1246 /* Lookup format string to see if it has already been parsed. */
1247 if (format_cache_ok
)
1249 dtp
->u
.p
.fmt
= find_parsed_format (dtp
);
1251 if (dtp
->u
.p
.fmt
!= NULL
)
1253 dtp
->u
.p
.fmt
->reversion_ok
= 0;
1254 dtp
->u
.p
.fmt
->saved_token
= FMT_NONE
;
1255 dtp
->u
.p
.fmt
->saved_format
= NULL
;
1256 reset_fnode_counters (dtp
);
1261 /* Not found so proceed as follows. */
1263 char *fmt_string
= fc_strdup_notrim (dtp
->format
, dtp
->format_len
);
1264 dtp
->format
= fmt_string
;
1266 dtp
->u
.p
.fmt
= fmt
= xmalloc (sizeof (format_data
));
1267 fmt
->format_string
= dtp
->format
;
1268 fmt
->format_string_len
= dtp
->format_len
;
1271 fmt
->saved_token
= FMT_NONE
;
1275 /* Initialize variables used during traversal of the tree. */
1277 fmt
->reversion_ok
= 0;
1278 fmt
->saved_format
= NULL
;
1280 /* Allocate the first format node as the root of the tree. */
1282 fmt
->last
= &fmt
->array
;
1283 fmt
->last
->next
= NULL
;
1284 fmt
->avail
= &fmt
->array
.array
[0];
1286 memset (fmt
->avail
, 0, sizeof (*fmt
->avail
));
1287 fmt
->avail
->format
= FMT_LPAREN
;
1288 fmt
->avail
->repeat
= 1;
1291 if (format_lex (fmt
) == FMT_LPAREN
)
1292 fmt
->array
.array
[0].u
.child
= parse_format_list (dtp
, &seen_data_desc
);
1294 fmt
->error
= "Missing initial left parenthesis in format";
1296 if (format_cache_ok
)
1297 save_parsed_format (dtp
);
1299 dtp
->u
.p
.format_not_saved
= 1;
1302 format_error (dtp
, NULL
, fmt
->error
);
1306 /* next_format0()-- Get the next format node without worrying about
1307 * reversion. Returns NULL when we hit the end of the list.
1308 * Parenthesis nodes are incremented after the list has been
1309 * exhausted, other nodes are incremented before they are returned. */
1311 static const fnode
*
1312 next_format0 (fnode
* f
)
1319 if (f
->format
!= FMT_LPAREN
)
1322 if (f
->count
<= f
->repeat
)
1329 /* Deal with a parenthesis node with unlimited format. */
1331 if (f
->repeat
== -2) /* -2 signifies unlimited. */
1334 if (f
->current
== NULL
)
1335 f
->current
= f
->u
.child
;
1337 for (; f
->current
!= NULL
; f
->current
= f
->current
->next
)
1339 r
= next_format0 (f
->current
);
1345 /* Deal with a parenthesis node with specific repeat count. */
1346 for (; f
->count
< f
->repeat
; f
->count
++)
1348 if (f
->current
== NULL
)
1349 f
->current
= f
->u
.child
;
1351 for (; f
->current
!= NULL
; f
->current
= f
->current
->next
)
1353 r
= next_format0 (f
->current
);
1364 /* next_format()-- Return the next format node. If the format list
1365 * ends up being exhausted, we do reversion. Reversion is only
1366 * allowed if we've seen a data descriptor since the
1367 * initialization or the last reversion. We return NULL if there
1368 * are no more data descriptors to return (which is an error
1372 next_format (st_parameter_dt
*dtp
)
1376 format_data
*fmt
= dtp
->u
.p
.fmt
;
1378 if (fmt
->saved_format
!= NULL
)
1379 { /* Deal with a pushed-back format node */
1380 f
= fmt
->saved_format
;
1381 fmt
->saved_format
= NULL
;
1385 f
= next_format0 (&fmt
->array
.array
[0]);
1388 if (!fmt
->reversion_ok
)
1391 fmt
->reversion_ok
= 0;
1394 f
= next_format0 (&fmt
->array
.array
[0]);
1397 format_error (dtp
, NULL
, reversion_error
);
1401 /* Push the first reverted token and return a colon node in case
1402 * there are no more data items. */
1404 fmt
->saved_format
= f
;
1408 /* If this is a data edit descriptor, then reversion has become OK. */
1412 if (!fmt
->reversion_ok
&&
1413 (t
== FMT_I
|| t
== FMT_B
|| t
== FMT_O
|| t
== FMT_Z
|| t
== FMT_F
||
1414 t
== FMT_E
|| t
== FMT_EN
|| t
== FMT_ES
|| t
== FMT_G
|| t
== FMT_L
||
1415 t
== FMT_A
|| t
== FMT_D
))
1416 fmt
->reversion_ok
= 1;
1421 /* unget_format()-- Push the given format back so that it will be
1422 * returned on the next call to next_format() without affecting
1423 * counts. This is necessary when we've encountered a data
1424 * descriptor, but don't know what the data item is yet. The format
1425 * node is pushed back, and we return control to the main program,
1426 * which calls the library back with the data item (or not). */
1429 unget_format (st_parameter_dt
*dtp
, const fnode
*f
)
1431 dtp
->u
.p
.fmt
->saved_format
= f
;