* global.c (global_alloc): Make it static.
[official-gcc.git] / libgfortran / io / format.c
blob23ea3175dc41aa6077d8959b2a1a5fc2c7743181
1 /* Copyright (C) 2002, 2003, 2004, 2005
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
5 This file is part of the GNU Fortran 95 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 2, or (at your option)
10 any later version.
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
19 executable.)
21 Libgfortran is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with Libgfortran; see the file COPYING. If not, write to
28 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA. */
32 /* format.c-- parse a FORMAT string into a binary format suitable for
33 * interpretation during I/O statements */
35 #include "config.h"
36 #include <ctype.h>
37 #include <string.h>
38 #include "libgfortran.h"
39 #include "io.h"
41 #define FARRAY_SIZE 64
43 typedef struct fnode_array
45 struct fnode_array *next;
46 fnode array[FARRAY_SIZE];
48 fnode_array;
50 typedef struct format_data
52 char *format_string, *string;
53 const char *error;
54 format_token saved_token;
55 int value, format_string_len, reversion_ok;
56 fnode *avail;
57 const fnode *saved_format;
58 fnode_array *last;
59 fnode_array array;
61 format_data;
63 static const fnode colon_node = { FMT_COLON, 0, NULL, NULL, {{ 0, 0, 0 }}, 0,
64 NULL };
66 /* Error messages */
68 static const char posint_required[] = "Positive width required in format",
69 period_required[] = "Period required in format",
70 nonneg_required[] = "Nonnegative width required in format",
71 unexpected_element[] = "Unexpected element in format",
72 unexpected_end[] = "Unexpected end of format string",
73 bad_string[] = "Unterminated character constant in format",
74 bad_hollerith[] = "Hollerith constant extends past the end of the format",
75 reversion_error[] = "Exhausted data descriptors in format";
78 /* next_char()-- Return the next character in the format string.
79 * Returns -1 when the string is done. If the literal flag is set,
80 * spaces are significant, otherwise they are not. */
82 static int
83 next_char (format_data *fmt, int literal)
85 int c;
89 if (fmt->format_string_len == 0)
90 return -1;
92 fmt->format_string_len--;
93 c = toupper (*fmt->format_string++);
95 while (c == ' ' && !literal);
97 return c;
101 /* unget_char()-- Back up one character position. */
103 #define unget_char(fmt) \
104 { fmt->format_string--; fmt->format_string_len++; }
107 /* get_fnode()-- Allocate a new format node, inserting it into the
108 * current singly linked list. These are initially allocated from the
109 * static buffer. */
111 static fnode *
112 get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t)
114 fnode *f;
116 if (fmt->avail == &fmt->last->array[FARRAY_SIZE])
118 fmt->last->next = get_mem (sizeof (fnode_array));
119 fmt->last = fmt->last->next;
120 fmt->last->next = NULL;
121 fmt->avail = &fmt->last->array[0];
123 f = fmt->avail++;
124 memset (f, '\0', sizeof (fnode));
126 if (*head == NULL)
127 *head = *tail = f;
128 else
130 (*tail)->next = f;
131 *tail = f;
134 f->format = t;
135 f->repeat = -1;
136 f->source = fmt->format_string;
137 return f;
141 /* free_format_data()-- Free all allocated format data. */
143 void
144 free_format_data (st_parameter_dt *dtp)
146 fnode_array *fa, *fa_next;
147 format_data *fmt = dtp->u.p.fmt;
149 if (fmt == NULL)
150 return;
152 for (fa = fmt->array.next; fa; fa = fa_next)
154 fa_next = fa->next;
155 free_mem (fa);
158 free_mem (fmt);
159 dtp->u.p.fmt = NULL;
163 /* format_lex()-- Simple lexical analyzer for getting the next token
164 * in a FORMAT string. We support a one-level token pushback in the
165 * fmt->saved_token variable. */
167 static format_token
168 format_lex (format_data *fmt)
170 format_token token;
171 int negative_flag;
172 int c;
173 char delim;
175 if (fmt->saved_token != FMT_NONE)
177 token = fmt->saved_token;
178 fmt->saved_token = FMT_NONE;
179 return token;
182 negative_flag = 0;
183 c = next_char (fmt, 0);
185 switch (c)
187 case '-':
188 negative_flag = 1;
189 /* Fall Through */
191 case '+':
192 c = next_char (fmt, 0);
193 if (!isdigit (c))
195 token = FMT_UNKNOWN;
196 break;
199 fmt->value = c - '0';
201 for (;;)
203 c = next_char (fmt, 0);
204 if (!isdigit (c))
205 break;
207 fmt->value = 10 * fmt->value + c - '0';
210 unget_char (fmt);
212 if (negative_flag)
213 fmt->value = -fmt->value;
214 token = FMT_SIGNED_INT;
215 break;
217 case '0':
218 case '1':
219 case '2':
220 case '3':
221 case '4':
222 case '5':
223 case '6':
224 case '7':
225 case '8':
226 case '9':
227 fmt->value = c - '0';
229 for (;;)
231 c = next_char (fmt, 0);
232 if (!isdigit (c))
233 break;
235 fmt->value = 10 * fmt->value + c - '0';
238 unget_char (fmt);
239 token = (fmt->value == 0) ? FMT_ZERO : FMT_POSINT;
240 break;
242 case '.':
243 token = FMT_PERIOD;
244 break;
246 case ',':
247 token = FMT_COMMA;
248 break;
250 case ':':
251 token = FMT_COLON;
252 break;
254 case '/':
255 token = FMT_SLASH;
256 break;
258 case '$':
259 token = FMT_DOLLAR;
260 break;
262 case 'T':
263 switch (next_char (fmt, 0))
265 case 'L':
266 token = FMT_TL;
267 break;
268 case 'R':
269 token = FMT_TR;
270 break;
271 default:
272 token = FMT_T;
273 unget_char (fmt);
274 break;
277 break;
279 case '(':
280 token = FMT_LPAREN;
281 break;
283 case ')':
284 token = FMT_RPAREN;
285 break;
287 case 'X':
288 token = FMT_X;
289 break;
291 case 'S':
292 switch (next_char (fmt, 0))
294 case 'S':
295 token = FMT_SS;
296 break;
297 case 'P':
298 token = FMT_SP;
299 break;
300 default:
301 token = FMT_S;
302 unget_char (fmt);
303 break;
306 break;
308 case 'B':
309 switch (next_char (fmt, 0))
311 case 'N':
312 token = FMT_BN;
313 break;
314 case 'Z':
315 token = FMT_BZ;
316 break;
317 default:
318 token = FMT_B;
319 unget_char (fmt);
320 break;
323 break;
325 case '\'':
326 case '"':
327 delim = c;
329 fmt->string = fmt->format_string;
330 fmt->value = 0; /* This is the length of the string */
332 for (;;)
334 c = next_char (fmt, 1);
335 if (c == -1)
337 token = FMT_BADSTRING;
338 fmt->error = bad_string;
339 break;
342 if (c == delim)
344 c = next_char (fmt, 1);
346 if (c == -1)
348 token = FMT_BADSTRING;
349 fmt->error = bad_string;
350 break;
353 if (c != delim)
355 unget_char (fmt);
356 token = FMT_STRING;
357 break;
361 fmt->value++;
364 break;
366 case 'P':
367 token = FMT_P;
368 break;
370 case 'I':
371 token = FMT_I;
372 break;
374 case 'O':
375 token = FMT_O;
376 break;
378 case 'Z':
379 token = FMT_Z;
380 break;
382 case 'F':
383 token = FMT_F;
384 break;
386 case 'E':
387 switch (next_char (fmt, 0))
389 case 'N':
390 token = FMT_EN;
391 break;
392 case 'S':
393 token = FMT_ES;
394 break;
395 default:
396 token = FMT_E;
397 unget_char (fmt);
398 break;
401 break;
403 case 'G':
404 token = FMT_G;
405 break;
407 case 'H':
408 token = FMT_H;
409 break;
411 case 'L':
412 token = FMT_L;
413 break;
415 case 'A':
416 token = FMT_A;
417 break;
419 case 'D':
420 token = FMT_D;
421 break;
423 case -1:
424 token = FMT_END;
425 break;
427 default:
428 token = FMT_UNKNOWN;
429 break;
432 return token;
436 /* parse_format_list()-- Parse a format list. Assumes that a left
437 * paren has already been seen. Returns a list representing the
438 * parenthesis node which contains the rest of the list. */
440 static fnode *
441 parse_format_list (st_parameter_dt *dtp)
443 fnode *head, *tail;
444 format_token t, u, t2;
445 int repeat;
446 format_data *fmt = dtp->u.p.fmt;
448 head = tail = NULL;
450 /* Get the next format item */
451 format_item:
452 t = format_lex (fmt);
453 format_item_1:
454 switch (t)
456 case FMT_POSINT:
457 repeat = fmt->value;
459 t = format_lex (fmt);
460 switch (t)
462 case FMT_LPAREN:
463 get_fnode (fmt, &head, &tail, FMT_LPAREN);
464 tail->repeat = repeat;
465 tail->u.child = parse_format_list (dtp);
466 if (fmt->error != NULL)
467 goto finished;
469 goto between_desc;
471 case FMT_SLASH:
472 get_fnode (fmt, &head, &tail, FMT_SLASH);
473 tail->repeat = repeat;
474 goto optional_comma;
476 case FMT_X:
477 get_fnode (fmt, &head, &tail, FMT_X);
478 tail->repeat = 1;
479 tail->u.k = fmt->value;
480 goto between_desc;
482 case FMT_P:
483 goto p_descriptor;
485 default:
486 goto data_desc;
489 case FMT_LPAREN:
490 get_fnode (fmt, &head, &tail, FMT_LPAREN);
491 tail->repeat = 1;
492 tail->u.child = parse_format_list (dtp);
493 if (fmt->error != NULL)
494 goto finished;
496 goto between_desc;
498 case FMT_SIGNED_INT: /* Signed integer can only precede a P format. */
499 case FMT_ZERO: /* Same for zero. */
500 t = format_lex (fmt);
501 if (t != FMT_P)
503 fmt->error = "Expected P edit descriptor in format";
504 goto finished;
507 p_descriptor:
508 get_fnode (fmt, &head, &tail, FMT_P);
509 tail->u.k = fmt->value;
510 tail->repeat = 1;
512 t = format_lex (fmt);
513 if (t == FMT_F || t == FMT_EN || t == FMT_ES || t == FMT_D
514 || t == FMT_G || t == FMT_E)
516 repeat = 1;
517 goto data_desc;
520 fmt->saved_token = t;
521 goto optional_comma;
523 case FMT_P: /* P and X require a prior number */
524 fmt->error = "P descriptor requires leading scale factor";
525 goto finished;
527 case FMT_X:
529 EXTENSION!
531 If we would be pedantic in the library, we would have to reject
532 an X descriptor without an integer prefix:
534 fmt->error = "X descriptor requires leading space count";
535 goto finished;
537 However, this is an extension supported by many Fortran compilers,
538 including Cray, HP, AIX, and IRIX. Therefore, we allow it in the
539 runtime library, and make the front end reject it if the compiler
540 is in pedantic mode. The interpretation of 'X' is '1X'.
542 get_fnode (fmt, &head, &tail, FMT_X);
543 tail->repeat = 1;
544 tail->u.k = 1;
545 goto between_desc;
547 case FMT_STRING:
548 get_fnode (fmt, &head, &tail, FMT_STRING);
550 tail->u.string.p = fmt->string;
551 tail->u.string.length = fmt->value;
552 tail->repeat = 1;
553 goto optional_comma;
555 case FMT_S:
556 case FMT_SS:
557 case FMT_SP:
558 case FMT_BN:
559 case FMT_BZ:
560 get_fnode (fmt, &head, &tail, t);
561 tail->repeat = 1;
562 goto between_desc;
564 case FMT_COLON:
565 get_fnode (fmt, &head, &tail, FMT_COLON);
566 tail->repeat = 1;
567 goto optional_comma;
569 case FMT_SLASH:
570 get_fnode (fmt, &head, &tail, FMT_SLASH);
571 tail->repeat = 1;
572 tail->u.r = 1;
573 goto optional_comma;
575 case FMT_DOLLAR:
576 get_fnode (fmt, &head, &tail, FMT_DOLLAR);
577 tail->repeat = 1;
578 notify_std (GFC_STD_GNU, "Extension: $ descriptor");
579 goto between_desc;
581 case FMT_T:
582 case FMT_TL:
583 case FMT_TR:
584 t2 = format_lex (fmt);
585 if (t2 != FMT_POSINT)
587 fmt->error = posint_required;
588 goto finished;
590 get_fnode (fmt, &head, &tail, t);
591 tail->u.n = fmt->value;
592 tail->repeat = 1;
593 goto between_desc;
595 case FMT_I:
596 case FMT_B:
597 case FMT_O:
598 case FMT_Z:
599 case FMT_E:
600 case FMT_EN:
601 case FMT_ES:
602 case FMT_D:
603 case FMT_L:
604 case FMT_A:
605 case FMT_F:
606 case FMT_G:
607 repeat = 1;
608 goto data_desc;
610 case FMT_H:
611 get_fnode (fmt, &head, &tail, FMT_STRING);
613 if (fmt->format_string_len < 1)
615 fmt->error = bad_hollerith;
616 goto finished;
619 tail->u.string.p = fmt->format_string;
620 tail->u.string.length = 1;
621 tail->repeat = 1;
623 fmt->format_string++;
624 fmt->format_string_len--;
626 goto between_desc;
628 case FMT_END:
629 fmt->error = unexpected_end;
630 goto finished;
632 case FMT_BADSTRING:
633 goto finished;
635 case FMT_RPAREN:
636 goto finished;
638 default:
639 fmt->error = unexpected_element;
640 goto finished;
643 /* In this state, t must currently be a data descriptor. Deal with
644 things that can/must follow the descriptor */
645 data_desc:
646 switch (t)
648 case FMT_P:
649 t = format_lex (fmt);
650 if (t == FMT_POSINT)
652 fmt->error = "Repeat count cannot follow P descriptor";
653 goto finished;
656 fmt->saved_token = t;
657 get_fnode (fmt, &head, &tail, FMT_P);
659 goto optional_comma;
661 case FMT_L:
662 t = format_lex (fmt);
663 if (t != FMT_POSINT)
665 fmt->error = posint_required;
666 goto finished;
669 get_fnode (fmt, &head, &tail, FMT_L);
670 tail->u.n = fmt->value;
671 tail->repeat = repeat;
672 break;
674 case FMT_A:
675 t = format_lex (fmt);
676 if (t != FMT_POSINT)
678 fmt->saved_token = t;
679 fmt->value = -1; /* Width not present */
682 get_fnode (fmt, &head, &tail, FMT_A);
683 tail->repeat = repeat;
684 tail->u.n = fmt->value;
685 break;
687 case FMT_D:
688 case FMT_E:
689 case FMT_F:
690 case FMT_G:
691 case FMT_EN:
692 case FMT_ES:
693 get_fnode (fmt, &head, &tail, t);
694 tail->repeat = repeat;
696 u = format_lex (fmt);
697 if (t == FMT_F || dtp->u.p.mode == WRITING)
699 if (u != FMT_POSINT && u != FMT_ZERO)
701 fmt->error = nonneg_required;
702 goto finished;
705 else
707 if (u != FMT_POSINT)
709 fmt->error = posint_required;
710 goto finished;
714 tail->u.real.w = fmt->value;
715 t2 = t;
716 t = format_lex (fmt);
717 if (t != FMT_PERIOD)
719 fmt->error = period_required;
720 goto finished;
723 t = format_lex (fmt);
724 if (t != FMT_ZERO && t != FMT_POSINT)
726 fmt->error = nonneg_required;
727 goto finished;
730 tail->u.real.d = fmt->value;
732 if (t == FMT_D || t == FMT_F)
733 break;
735 tail->u.real.e = -1;
737 /* Look for optional exponent */
738 t = format_lex (fmt);
739 if (t != FMT_E)
740 fmt->saved_token = t;
741 else
743 t = format_lex (fmt);
744 if (t != FMT_POSINT)
746 fmt->error = "Positive exponent width required in format";
747 goto finished;
750 tail->u.real.e = fmt->value;
753 break;
755 case FMT_H:
756 if (repeat > fmt->format_string_len)
758 fmt->error = bad_hollerith;
759 goto finished;
762 get_fnode (fmt, &head, &tail, FMT_STRING);
764 tail->u.string.p = fmt->format_string;
765 tail->u.string.length = repeat;
766 tail->repeat = 1;
768 fmt->format_string += fmt->value;
769 fmt->format_string_len -= repeat;
771 break;
773 case FMT_I:
774 case FMT_B:
775 case FMT_O:
776 case FMT_Z:
777 get_fnode (fmt, &head, &tail, t);
778 tail->repeat = repeat;
780 t = format_lex (fmt);
782 if (dtp->u.p.mode == READING)
784 if (t != FMT_POSINT)
786 fmt->error = posint_required;
787 goto finished;
790 else
792 if (t != FMT_ZERO && t != FMT_POSINT)
794 fmt->error = nonneg_required;
795 goto finished;
799 tail->u.integer.w = fmt->value;
800 tail->u.integer.m = -1;
802 t = format_lex (fmt);
803 if (t != FMT_PERIOD)
805 fmt->saved_token = t;
807 else
809 t = format_lex (fmt);
810 if (t != FMT_ZERO && t != FMT_POSINT)
812 fmt->error = nonneg_required;
813 goto finished;
816 tail->u.integer.m = fmt->value;
819 if (tail->u.integer.w != 0 && tail->u.integer.m > tail->u.integer.w)
821 fmt->error = "Minimum digits exceeds field width";
822 goto finished;
825 break;
827 default:
828 fmt->error = unexpected_element;
829 goto finished;
832 /* Between a descriptor and what comes next */
833 between_desc:
834 t = format_lex (fmt);
835 switch (t)
837 case FMT_COMMA:
838 goto format_item;
840 case FMT_RPAREN:
841 goto finished;
843 case FMT_SLASH:
844 get_fnode (fmt, &head, &tail, FMT_SLASH);
845 tail->repeat = 1;
847 /* Fall Through */
849 case FMT_COLON:
850 goto optional_comma;
852 case FMT_END:
853 fmt->error = unexpected_end;
854 goto finished;
856 default:
857 /* Assume a missing comma, this is a GNU extension */
858 goto format_item_1;
861 /* Optional comma is a weird between state where we've just finished
862 reading a colon, slash or P descriptor. */
863 optional_comma:
864 t = format_lex (fmt);
865 switch (t)
867 case FMT_COMMA:
868 break;
870 case FMT_RPAREN:
871 goto finished;
873 default: /* Assume that we have another format item */
874 fmt->saved_token = t;
875 break;
878 goto format_item;
880 finished:
881 return head;
885 /* format_error()-- Generate an error message for a format statement.
886 * If the node that gives the location of the error is NULL, the error
887 * is assumed to happen at parse time, and the current location of the
888 * parser is shown.
890 * We generate a message showing where the problem is. We take extra
891 * care to print only the relevant part of the format if it is longer
892 * than a standard 80 column display. */
894 void
895 format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
897 int width, i, j, offset;
898 char *p, buffer[300];
899 format_data *fmt = dtp->u.p.fmt;
901 if (f != NULL)
902 fmt->format_string = f->source;
904 st_sprintf (buffer, "%s\n", message);
906 j = fmt->format_string - dtp->format;
908 offset = (j > 60) ? j - 40 : 0;
910 j -= offset;
911 width = dtp->format_len - offset;
913 if (width > 80)
914 width = 80;
916 /* Show the format */
918 p = strchr (buffer, '\0');
920 memcpy (p, dtp->format + offset, width);
922 p += width;
923 *p++ = '\n';
925 /* Show where the problem is */
927 for (i = 1; i < j; i++)
928 *p++ = ' ';
930 *p++ = '^';
931 *p = '\0';
933 generate_error (&dtp->common, ERROR_FORMAT, buffer);
937 /* parse_format()-- Parse a format string. */
939 void
940 parse_format (st_parameter_dt *dtp)
942 format_data *fmt;
944 dtp->u.p.fmt = fmt = get_mem (sizeof (format_data));
945 fmt->format_string = dtp->format;
946 fmt->format_string_len = dtp->format_len;
948 fmt->string = NULL;
949 fmt->saved_token = FMT_NONE;
950 fmt->error = NULL;
951 fmt->value = 0;
953 /* Initialize variables used during traversal of the tree */
955 fmt->reversion_ok = 0;
956 fmt->saved_format = NULL;
958 /* Allocate the first format node as the root of the tree */
960 fmt->last = &fmt->array;
961 fmt->last->next = NULL;
962 fmt->avail = &fmt->array.array[0];
964 memset (fmt->avail, 0, sizeof (*fmt->avail));
965 fmt->avail->format = FMT_LPAREN;
966 fmt->avail->repeat = 1;
967 fmt->avail++;
969 if (format_lex (fmt) == FMT_LPAREN)
970 fmt->array.array[0].u.child = parse_format_list (dtp);
971 else
972 fmt->error = "Missing initial left parenthesis in format";
974 if (fmt->error)
975 format_error (dtp, NULL, fmt->error);
979 /* revert()-- Do reversion of the format. Control reverts to the left
980 * parenthesis that matches the rightmost right parenthesis. From our
981 * tree structure, we are looking for the rightmost parenthesis node
982 * at the second level, the first level always being a single
983 * parenthesis node. If this node doesn't exit, we use the top
984 * level. */
986 static void
987 revert (st_parameter_dt *dtp)
989 fnode *f, *r;
990 format_data *fmt = dtp->u.p.fmt;
992 dtp->u.p.reversion_flag = 1;
994 r = NULL;
996 for (f = fmt->array.array[0].u.child; f; f = f->next)
997 if (f->format == FMT_LPAREN)
998 r = f;
1000 /* If r is NULL because no node was found, the whole tree will be used */
1002 fmt->array.array[0].current = r;
1003 fmt->array.array[0].count = 0;
1007 /* next_format0()-- Get the next format node without worrying about
1008 * reversion. Returns NULL when we hit the end of the list.
1009 * Parenthesis nodes are incremented after the list has been
1010 * exhausted, other nodes are incremented before they are returned. */
1012 static const fnode *
1013 next_format0 (fnode * f)
1015 const fnode *r;
1017 if (f == NULL)
1018 return NULL;
1020 if (f->format != FMT_LPAREN)
1022 f->count++;
1023 if (f->count <= f->repeat)
1024 return f;
1026 f->count = 0;
1027 return NULL;
1030 /* Deal with a parenthesis node */
1032 for (; f->count < f->repeat; f->count++)
1034 if (f->current == NULL)
1035 f->current = f->u.child;
1037 for (; f->current != NULL; f->current = f->current->next)
1039 r = next_format0 (f->current);
1040 if (r != NULL)
1041 return r;
1045 f->count = 0;
1046 return NULL;
1050 /* next_format()-- Return the next format node. If the format list
1051 * ends up being exhausted, we do reversion. Reversion is only
1052 * allowed if the we've seen a data descriptor since the
1053 * initialization or the last reversion. We return NULL if the there
1054 * are no more data descriptors to return (which is an error
1055 * condition). */
1057 const fnode *
1058 next_format (st_parameter_dt *dtp)
1060 format_token t;
1061 const fnode *f;
1062 format_data *fmt = dtp->u.p.fmt;
1064 if (fmt->saved_format != NULL)
1065 { /* Deal with a pushed-back format node */
1066 f = fmt->saved_format;
1067 fmt->saved_format = NULL;
1068 goto done;
1071 f = next_format0 (&fmt->array.array[0]);
1072 if (f == NULL)
1074 if (!fmt->reversion_ok)
1075 return NULL;
1077 fmt->reversion_ok = 0;
1078 revert (dtp);
1080 f = next_format0 (&fmt->array.array[0]);
1081 if (f == NULL)
1083 format_error (dtp, NULL, reversion_error);
1084 return NULL;
1087 /* Push the first reverted token and return a colon node in case
1088 * there are no more data items. */
1090 fmt->saved_format = f;
1091 return &colon_node;
1094 /* If this is a data edit descriptor, then reversion has become OK. */
1095 done:
1096 t = f->format;
1098 if (!fmt->reversion_ok &&
1099 (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F ||
1100 t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L ||
1101 t == FMT_A || t == FMT_D))
1102 fmt->reversion_ok = 1;
1103 return f;
1107 /* unget_format()-- Push the given format back so that it will be
1108 * returned on the next call to next_format() without affecting
1109 * counts. This is necessary when we've encountered a data
1110 * descriptor, but don't know what the data item is yet. The format
1111 * node is pushed back, and we return control to the main program,
1112 * which calls the library back with the data item (or not). */
1114 void
1115 unget_format (st_parameter_dt *dtp, const fnode *f)
1117 dtp->u.p.fmt->saved_format = f;