2018-11-13 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgfortran / io / format.c
blobf5d3158d21d8b50f08f966597be22ee09fae0a43
1 /* Copyright (C) 2002-2018 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)
10 any later version.
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. */
30 #include "io.h"
31 #include "format.h"
32 #include <ctype.h>
33 #include <string.h>
36 static const fnode colon_node = { FMT_COLON, 0, NULL, NULL, {{ 0, 0, 0 }}, 0,
37 NULL };
39 /* Error messages. */
41 static const char posint_required[] = "Positive width required in format",
42 period_required[] = "Period required in format",
43 nonneg_required[] = "Nonnegative width required in format",
44 unexpected_element[] = "Unexpected element '%c' in format\n",
45 unexpected_end[] = "Unexpected end of format string",
46 bad_string[] = "Unterminated character constant in format",
47 bad_hollerith[] = "Hollerith constant extends past the end of the format",
48 reversion_error[] = "Exhausted data descriptors in format",
49 zero_width[] = "Zero width in format descriptor";
51 /* The following routines support caching format data from parsed format strings
52 into a hash table. This avoids repeatedly parsing duplicate format strings
53 or format strings in I/O statements that are repeated in loops. */
56 /* Traverse the table and free all data. */
58 void
59 free_format_hash_table (gfc_unit *u)
61 size_t i;
63 /* free_format_data handles any NULL pointers. */
64 for (i = 0; i < FORMAT_HASH_SIZE; i++)
66 if (u->format_hash_table[i].hashed_fmt != NULL)
68 free_format_data (u->format_hash_table[i].hashed_fmt);
69 free (u->format_hash_table[i].key);
71 u->format_hash_table[i].key = NULL;
72 u->format_hash_table[i].key_len = 0;
73 u->format_hash_table[i].hashed_fmt = NULL;
77 /* Traverse the format_data structure and reset the fnode counters. */
79 static void
80 reset_node (fnode *fn)
82 fnode *f;
84 fn->count = 0;
85 fn->current = NULL;
87 if (fn->format != FMT_LPAREN)
88 return;
90 for (f = fn->u.child; f; f = f->next)
92 if (f->format == FMT_RPAREN)
93 break;
94 reset_node (f);
98 static void
99 reset_fnode_counters (st_parameter_dt *dtp)
101 fnode *f;
102 format_data *fmt;
104 fmt = dtp->u.p.fmt;
106 /* Clear this pointer at the head so things start at the right place. */
107 fmt->array.array[0].current = NULL;
109 for (f = fmt->array.array[0].u.child; f; f = f->next)
110 reset_node (f);
114 /* A simple hashing function to generate an index into the hash table. */
116 static uint32_t
117 format_hash (st_parameter_dt *dtp)
119 char *key;
120 gfc_charlen_type key_len;
121 uint32_t hash = 0;
122 gfc_charlen_type i;
124 /* Hash the format string. Super simple, but what the heck! */
125 key = dtp->format;
126 key_len = dtp->format_len;
127 for (i = 0; i < key_len; i++)
128 hash ^= key[i];
129 hash &= (FORMAT_HASH_SIZE - 1);
130 return hash;
134 static void
135 save_parsed_format (st_parameter_dt *dtp)
137 uint32_t hash;
138 gfc_unit *u;
140 hash = format_hash (dtp);
141 u = dtp->u.p.current_unit;
143 /* Index into the hash table. We are simply replacing whatever is there
144 relying on probability. */
145 if (u->format_hash_table[hash].hashed_fmt != NULL)
146 free_format_data (u->format_hash_table[hash].hashed_fmt);
147 u->format_hash_table[hash].hashed_fmt = NULL;
149 free (u->format_hash_table[hash].key);
150 u->format_hash_table[hash].key = dtp->format;
152 u->format_hash_table[hash].key_len = dtp->format_len;
153 u->format_hash_table[hash].hashed_fmt = dtp->u.p.fmt;
157 static format_data *
158 find_parsed_format (st_parameter_dt *dtp)
160 uint32_t hash;
161 gfc_unit *u;
163 hash = format_hash (dtp);
164 u = dtp->u.p.current_unit;
166 if (u->format_hash_table[hash].key != NULL)
168 /* See if it matches. */
169 if (u->format_hash_table[hash].key_len == dtp->format_len)
171 /* So far so good. */
172 if (strncmp (u->format_hash_table[hash].key,
173 dtp->format, dtp->format_len) == 0)
174 return u->format_hash_table[hash].hashed_fmt;
177 return NULL;
181 /* next_char()-- Return the next character in the format string.
182 Returns -1 when the string is done. If the literal flag is set,
183 spaces are significant, otherwise they are not. */
185 static int
186 next_char (format_data *fmt, int literal)
188 int c;
192 if (fmt->format_string_len == 0)
193 return -1;
195 fmt->format_string_len--;
196 c = toupper (*fmt->format_string++);
197 fmt->error_element = c;
199 while ((c == ' ' || c == '\t') && !literal);
201 return c;
205 /* unget_char()-- Back up one character position. */
207 #define unget_char(fmt) \
208 { fmt->format_string--; fmt->format_string_len++; }
211 /* get_fnode()-- Allocate a new format node, inserting it into the
212 current singly linked list. These are initially allocated from the
213 static buffer. */
215 static fnode *
216 get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t)
218 fnode *f;
220 if (fmt->avail == &fmt->last->array[FARRAY_SIZE])
222 fmt->last->next = xmalloc (sizeof (fnode_array));
223 fmt->last = fmt->last->next;
224 fmt->last->next = NULL;
225 fmt->avail = &fmt->last->array[0];
227 f = fmt->avail++;
228 memset (f, '\0', sizeof (fnode));
230 if (*head == NULL)
231 *head = *tail = f;
232 else
234 (*tail)->next = f;
235 *tail = f;
238 f->format = t;
239 f->repeat = -1;
240 f->source = fmt->format_string;
241 return f;
245 /* free_format()-- Free allocated format string. */
246 void
247 free_format (st_parameter_dt *dtp)
249 if ((dtp->common.flags & IOPARM_DT_HAS_FORMAT) && dtp->format)
251 free (dtp->format);
252 dtp->format = NULL;
257 /* free_format_data()-- Free all allocated format data. */
259 void
260 free_format_data (format_data *fmt)
262 fnode_array *fa, *fa_next;
263 fnode *fnp;
265 if (fmt == NULL)
266 return;
268 /* Free vlist descriptors in the fnode_array if one was allocated. */
269 for (fnp = fmt->array.array; fnp < &fmt->array.array[FARRAY_SIZE] &&
270 fnp->format != FMT_NONE; fnp++)
271 if (fnp->format == FMT_DT)
273 if (GFC_DESCRIPTOR_DATA(fnp->u.udf.vlist))
274 free (GFC_DESCRIPTOR_DATA(fnp->u.udf.vlist));
275 free (fnp->u.udf.vlist);
278 for (fa = fmt->array.next; fa; fa = fa_next)
280 fa_next = fa->next;
281 free (fa);
284 free (fmt);
285 fmt = NULL;
289 /* format_lex()-- Simple lexical analyzer for getting the next token
290 in a FORMAT string. We support a one-level token pushback in the
291 fmt->saved_token variable. */
293 static format_token
294 format_lex (format_data *fmt)
296 format_token token;
297 int negative_flag;
298 int c;
299 char delim;
301 if (fmt->saved_token != FMT_NONE)
303 token = fmt->saved_token;
304 fmt->saved_token = FMT_NONE;
305 return token;
308 negative_flag = 0;
309 c = next_char (fmt, 0);
311 switch (c)
313 case '*':
314 token = FMT_STAR;
315 break;
317 case '(':
318 token = FMT_LPAREN;
319 break;
321 case ')':
322 token = FMT_RPAREN;
323 break;
325 case '-':
326 negative_flag = 1;
327 /* Fall Through */
329 case '+':
330 c = next_char (fmt, 0);
331 if (!isdigit (c))
333 token = FMT_UNKNOWN;
334 break;
337 fmt->value = c - '0';
339 for (;;)
341 c = next_char (fmt, 0);
342 if (!isdigit (c))
343 break;
345 fmt->value = 10 * fmt->value + c - '0';
348 unget_char (fmt);
350 if (negative_flag)
351 fmt->value = -fmt->value;
352 token = FMT_SIGNED_INT;
353 break;
355 case '0':
356 case '1':
357 case '2':
358 case '3':
359 case '4':
360 case '5':
361 case '6':
362 case '7':
363 case '8':
364 case '9':
365 fmt->value = c - '0';
367 for (;;)
369 c = next_char (fmt, 0);
370 if (!isdigit (c))
371 break;
373 fmt->value = 10 * fmt->value + c - '0';
376 unget_char (fmt);
377 token = (fmt->value == 0) ? FMT_ZERO : FMT_POSINT;
378 break;
380 case '.':
381 token = FMT_PERIOD;
382 break;
384 case ',':
385 token = FMT_COMMA;
386 break;
388 case ':':
389 token = FMT_COLON;
390 break;
392 case '/':
393 token = FMT_SLASH;
394 break;
396 case '$':
397 token = FMT_DOLLAR;
398 break;
400 case 'T':
401 switch (next_char (fmt, 0))
403 case 'L':
404 token = FMT_TL;
405 break;
406 case 'R':
407 token = FMT_TR;
408 break;
409 default:
410 token = FMT_T;
411 unget_char (fmt);
412 break;
415 break;
417 case 'X':
418 token = FMT_X;
419 break;
421 case 'S':
422 switch (next_char (fmt, 0))
424 case 'S':
425 token = FMT_SS;
426 break;
427 case 'P':
428 token = FMT_SP;
429 break;
430 default:
431 token = FMT_S;
432 unget_char (fmt);
433 break;
436 break;
438 case 'B':
439 switch (next_char (fmt, 0))
441 case 'N':
442 token = FMT_BN;
443 break;
444 case 'Z':
445 token = FMT_BZ;
446 break;
447 default:
448 token = FMT_B;
449 unget_char (fmt);
450 break;
453 break;
455 case '\'':
456 case '"':
457 delim = c;
459 fmt->string = fmt->format_string;
460 fmt->value = 0; /* This is the length of the string */
462 for (;;)
464 c = next_char (fmt, 1);
465 if (c == -1)
467 token = FMT_BADSTRING;
468 fmt->error = bad_string;
469 break;
472 if (c == delim)
474 c = next_char (fmt, 1);
476 if (c == -1)
478 token = FMT_BADSTRING;
479 fmt->error = bad_string;
480 break;
483 if (c != delim)
485 unget_char (fmt);
486 token = FMT_STRING;
487 break;
491 fmt->value++;
494 break;
496 case 'P':
497 token = FMT_P;
498 break;
500 case 'I':
501 token = FMT_I;
502 break;
504 case 'O':
505 token = FMT_O;
506 break;
508 case 'Z':
509 token = FMT_Z;
510 break;
512 case 'F':
513 token = FMT_F;
514 break;
516 case 'E':
517 switch (next_char (fmt, 0))
519 case 'N':
520 token = FMT_EN;
521 break;
522 case 'S':
523 token = FMT_ES;
524 break;
525 default:
526 token = FMT_E;
527 unget_char (fmt);
528 break;
530 break;
532 case 'G':
533 token = FMT_G;
534 break;
536 case 'H':
537 token = FMT_H;
538 break;
540 case 'L':
541 token = FMT_L;
542 break;
544 case 'A':
545 token = FMT_A;
546 break;
548 case 'D':
549 switch (next_char (fmt, 0))
551 case 'P':
552 token = FMT_DP;
553 break;
554 case 'C':
555 token = FMT_DC;
556 break;
557 case 'T':
558 token = FMT_DT;
559 break;
560 default:
561 token = FMT_D;
562 unget_char (fmt);
563 break;
565 break;
567 case 'R':
568 switch (next_char (fmt, 0))
570 case 'C':
571 token = FMT_RC;
572 break;
573 case 'D':
574 token = FMT_RD;
575 break;
576 case 'N':
577 token = FMT_RN;
578 break;
579 case 'P':
580 token = FMT_RP;
581 break;
582 case 'U':
583 token = FMT_RU;
584 break;
585 case 'Z':
586 token = FMT_RZ;
587 break;
588 default:
589 unget_char (fmt);
590 token = FMT_UNKNOWN;
591 break;
593 break;
595 case -1:
596 token = FMT_END;
597 break;
599 default:
600 token = FMT_UNKNOWN;
601 break;
604 return token;
608 /* parse_format_list()-- Parse a format list. Assumes that a left
609 paren has already been seen. Returns a list representing the
610 parenthesis node which contains the rest of the list. */
612 static fnode *
613 parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
615 fnode *head, *tail;
616 format_token t, u, t2;
617 int repeat;
618 format_data *fmt = dtp->u.p.fmt;
619 bool seen_data_desc = false;
621 head = tail = NULL;
623 /* Get the next format item */
624 format_item:
625 t = format_lex (fmt);
626 format_item_1:
627 switch (t)
629 case FMT_STAR:
630 t = format_lex (fmt);
631 if (t != FMT_LPAREN)
633 fmt->error = "Left parenthesis required after '*'";
634 goto finished;
636 get_fnode (fmt, &head, &tail, FMT_LPAREN);
637 tail->repeat = -2; /* Signifies unlimited format. */
638 tail->u.child = parse_format_list (dtp, &seen_data_desc);
639 *seen_dd = seen_data_desc;
640 if (fmt->error != NULL)
641 goto finished;
642 if (!seen_data_desc)
644 fmt->error = "'*' requires at least one associated data descriptor";
645 goto finished;
647 goto between_desc;
649 case FMT_POSINT:
650 repeat = fmt->value;
652 t = format_lex (fmt);
653 switch (t)
655 case FMT_LPAREN:
656 get_fnode (fmt, &head, &tail, FMT_LPAREN);
657 tail->repeat = repeat;
658 tail->u.child = parse_format_list (dtp, &seen_data_desc);
659 *seen_dd = seen_data_desc;
660 if (fmt->error != NULL)
661 goto finished;
663 goto between_desc;
665 case FMT_SLASH:
666 get_fnode (fmt, &head, &tail, FMT_SLASH);
667 tail->repeat = repeat;
668 goto optional_comma;
670 case FMT_X:
671 get_fnode (fmt, &head, &tail, FMT_X);
672 tail->repeat = 1;
673 tail->u.k = fmt->value;
674 goto between_desc;
676 case FMT_P:
677 goto p_descriptor;
679 default:
680 goto data_desc;
683 case FMT_LPAREN:
684 get_fnode (fmt, &head, &tail, FMT_LPAREN);
685 tail->repeat = 1;
686 tail->u.child = parse_format_list (dtp, &seen_data_desc);
687 *seen_dd = seen_data_desc;
688 if (fmt->error != NULL)
689 goto finished;
691 goto between_desc;
693 case FMT_SIGNED_INT: /* Signed integer can only precede a P format. */
694 case FMT_ZERO: /* Same for zero. */
695 t = format_lex (fmt);
696 if (t != FMT_P)
698 fmt->error = "Expected P edit descriptor in format";
699 goto finished;
702 p_descriptor:
703 get_fnode (fmt, &head, &tail, FMT_P);
704 tail->u.k = fmt->value;
705 tail->repeat = 1;
707 t = format_lex (fmt);
708 if (t == FMT_F || t == FMT_EN || t == FMT_ES || t == FMT_D
709 || t == FMT_G || t == FMT_E)
711 repeat = 1;
712 goto data_desc;
715 if (t != FMT_COMMA && t != FMT_RPAREN && t != FMT_SLASH
716 && t != FMT_POSINT)
718 fmt->error = "Comma required after P descriptor";
719 goto finished;
722 fmt->saved_token = t;
723 goto optional_comma;
725 case FMT_P: /* P and X require a prior number */
726 fmt->error = "P descriptor requires leading scale factor";
727 goto finished;
729 case FMT_X:
731 EXTENSION!
733 If we would be pedantic in the library, we would have to reject
734 an X descriptor without an integer prefix:
736 fmt->error = "X descriptor requires leading space count";
737 goto finished;
739 However, this is an extension supported by many Fortran compilers,
740 including Cray, HP, AIX, and IRIX. Therefore, we allow it in the
741 runtime library, and make the front end reject it if the compiler
742 is in pedantic mode. The interpretation of 'X' is '1X'.
744 get_fnode (fmt, &head, &tail, FMT_X);
745 tail->repeat = 1;
746 tail->u.k = 1;
747 goto between_desc;
749 case FMT_STRING:
750 get_fnode (fmt, &head, &tail, FMT_STRING);
751 tail->u.string.p = fmt->string;
752 tail->u.string.length = fmt->value;
753 tail->repeat = 1;
754 goto optional_comma;
756 case FMT_RC:
757 case FMT_RD:
758 case FMT_RN:
759 case FMT_RP:
760 case FMT_RU:
761 case FMT_RZ:
762 notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: Round "
763 "descriptor not allowed");
764 get_fnode (fmt, &head, &tail, t);
765 tail->repeat = 1;
766 goto between_desc;
768 case FMT_DC:
769 case FMT_DP:
770 notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: DC or DP "
771 "descriptor not allowed");
772 /* Fall through. */
773 case FMT_S:
774 case FMT_SS:
775 case FMT_SP:
776 case FMT_BN:
777 case FMT_BZ:
778 get_fnode (fmt, &head, &tail, t);
779 tail->repeat = 1;
780 goto between_desc;
782 case FMT_COLON:
783 get_fnode (fmt, &head, &tail, FMT_COLON);
784 tail->repeat = 1;
785 goto optional_comma;
787 case FMT_SLASH:
788 get_fnode (fmt, &head, &tail, FMT_SLASH);
789 tail->repeat = 1;
790 tail->u.r = 1;
791 goto optional_comma;
793 case FMT_DOLLAR:
794 get_fnode (fmt, &head, &tail, FMT_DOLLAR);
795 tail->repeat = 1;
796 notify_std (&dtp->common, GFC_STD_GNU, "Extension: $ descriptor");
797 goto between_desc;
799 case FMT_T:
800 case FMT_TL:
801 case FMT_TR:
802 t2 = format_lex (fmt);
803 if (t2 != FMT_POSINT)
805 fmt->error = posint_required;
806 goto finished;
808 get_fnode (fmt, &head, &tail, t);
809 tail->u.n = fmt->value;
810 tail->repeat = 1;
811 goto between_desc;
813 case FMT_I:
814 case FMT_B:
815 case FMT_O:
816 case FMT_Z:
817 case FMT_E:
818 case FMT_EN:
819 case FMT_ES:
820 case FMT_D:
821 case FMT_DT:
822 case FMT_L:
823 case FMT_A:
824 case FMT_F:
825 case FMT_G:
826 repeat = 1;
827 *seen_dd = true;
828 goto data_desc;
830 case FMT_H:
831 get_fnode (fmt, &head, &tail, FMT_STRING);
832 if (fmt->format_string_len < 1)
834 fmt->error = bad_hollerith;
835 goto finished;
838 tail->u.string.p = fmt->format_string;
839 tail->u.string.length = 1;
840 tail->repeat = 1;
842 fmt->format_string++;
843 fmt->format_string_len--;
845 goto between_desc;
847 case FMT_END:
848 fmt->error = unexpected_end;
849 goto finished;
851 case FMT_BADSTRING:
852 goto finished;
854 case FMT_RPAREN:
855 goto finished;
857 default:
858 fmt->error = unexpected_element;
859 goto finished;
862 /* In this state, t must currently be a data descriptor. Deal with
863 things that can/must follow the descriptor */
864 data_desc:
866 switch (t)
868 case FMT_L:
869 *seen_dd = true;
870 t = format_lex (fmt);
871 if (t != FMT_POSINT)
873 if (t == FMT_ZERO)
875 if (notification_std(GFC_STD_GNU) == NOTIFICATION_ERROR)
877 fmt->error = "Extension: Zero width after L descriptor";
878 goto finished;
880 else
881 notify_std (&dtp->common, GFC_STD_GNU,
882 "Zero width after L descriptor");
884 else
886 fmt->saved_token = t;
887 notify_std (&dtp->common, GFC_STD_GNU,
888 "Positive width required with L descriptor");
890 fmt->value = 1; /* Default width */
892 get_fnode (fmt, &head, &tail, FMT_L);
893 tail->u.n = fmt->value;
894 tail->repeat = repeat;
895 break;
897 case FMT_A:
898 *seen_dd = true;
899 t = format_lex (fmt);
900 if (t == FMT_ZERO)
902 fmt->error = zero_width;
903 goto finished;
906 if (t != FMT_POSINT)
908 fmt->saved_token = t;
909 fmt->value = -1; /* Width not present */
912 get_fnode (fmt, &head, &tail, FMT_A);
913 tail->repeat = repeat;
914 tail->u.n = fmt->value;
915 break;
917 case FMT_D:
918 case FMT_E:
919 case FMT_F:
920 case FMT_G:
921 case FMT_EN:
922 case FMT_ES:
923 *seen_dd = true;
924 get_fnode (fmt, &head, &tail, t);
925 tail->repeat = repeat;
927 u = format_lex (fmt);
928 if (t == FMT_G && u == FMT_ZERO)
930 *seen_dd = true;
931 if (notification_std (GFC_STD_F2008) == NOTIFICATION_ERROR
932 || dtp->u.p.mode == READING)
934 fmt->error = zero_width;
935 goto finished;
937 tail->u.real.w = 0;
938 u = format_lex (fmt);
939 if (u != FMT_PERIOD)
941 fmt->saved_token = u;
942 break;
945 u = format_lex (fmt);
946 if (u != FMT_POSINT)
948 fmt->error = posint_required;
949 goto finished;
951 tail->u.real.d = fmt->value;
952 break;
954 if (t == FMT_F && dtp->u.p.mode == WRITING)
956 *seen_dd = true;
957 if (u != FMT_POSINT && u != FMT_ZERO)
959 fmt->error = nonneg_required;
960 goto finished;
963 else if (u != FMT_POSINT)
965 fmt->error = posint_required;
966 goto finished;
969 tail->u.real.w = fmt->value;
970 t2 = t;
971 t = format_lex (fmt);
972 if (t != FMT_PERIOD)
974 /* We treat a missing decimal descriptor as 0. Note: This is only
975 allowed if -std=legacy, otherwise an error occurs. */
976 if (compile_options.warn_std != 0)
978 fmt->error = period_required;
979 goto finished;
981 fmt->saved_token = t;
982 tail->u.real.d = 0;
983 tail->u.real.e = -1;
984 break;
987 t = format_lex (fmt);
988 if (t != FMT_ZERO && t != FMT_POSINT)
990 fmt->error = nonneg_required;
991 goto finished;
994 tail->u.real.d = fmt->value;
995 tail->u.real.e = -1;
997 if (t2 == FMT_D || t2 == FMT_F)
999 *seen_dd = true;
1000 break;
1003 /* Look for optional exponent */
1004 t = format_lex (fmt);
1005 if (t != FMT_E)
1006 fmt->saved_token = t;
1007 else
1009 t = format_lex (fmt);
1010 if (t != FMT_POSINT)
1012 fmt->error = "Positive exponent width required in format";
1013 goto finished;
1016 tail->u.real.e = fmt->value;
1019 break;
1020 case FMT_DT:
1021 *seen_dd = true;
1022 get_fnode (fmt, &head, &tail, t);
1023 tail->repeat = repeat;
1025 t = format_lex (fmt);
1027 /* Initialize the vlist to a zero size, rank-one array. */
1028 tail->u.udf.vlist= xmalloc (sizeof(gfc_array_i4)
1029 + sizeof (descriptor_dimension));
1030 GFC_DESCRIPTOR_DATA(tail->u.udf.vlist) = NULL;
1031 GFC_DIMENSION_SET(tail->u.udf.vlist->dim[0],1, 0, 0);
1033 if (t == FMT_STRING)
1035 /* Get pointer to the optional format string. */
1036 tail->u.udf.string = fmt->string;
1037 tail->u.udf.string_len = fmt->value;
1038 t = format_lex (fmt);
1040 if (t == FMT_LPAREN)
1042 /* Temporary buffer to hold the vlist values. */
1043 GFC_INTEGER_4 temp[FARRAY_SIZE];
1044 int i = 0;
1045 loop:
1046 t = format_lex (fmt);
1047 if (t != FMT_POSINT)
1049 fmt->error = posint_required;
1050 goto finished;
1052 /* Save the positive integer value. */
1053 temp[i++] = fmt->value;
1054 t = format_lex (fmt);
1055 if (t == FMT_COMMA)
1056 goto loop;
1057 if (t == FMT_RPAREN)
1059 /* We have parsed the complete vlist so initialize the
1060 array descriptor and save it in the format node. */
1061 gfc_full_array_i4 *vp = tail->u.udf.vlist;
1062 GFC_DESCRIPTOR_DATA(vp) = xmalloc (i * sizeof(GFC_INTEGER_4));
1063 GFC_DIMENSION_SET(vp->dim[0],1, i, 1);
1064 memcpy (GFC_DESCRIPTOR_DATA(vp), temp, i * sizeof(GFC_INTEGER_4));
1065 break;
1067 fmt->error = unexpected_element;
1068 goto finished;
1070 fmt->saved_token = t;
1071 break;
1072 case FMT_H:
1073 if (repeat > fmt->format_string_len)
1075 fmt->error = bad_hollerith;
1076 goto finished;
1079 get_fnode (fmt, &head, &tail, FMT_STRING);
1080 tail->u.string.p = fmt->format_string;
1081 tail->u.string.length = repeat;
1082 tail->repeat = 1;
1084 fmt->format_string += fmt->value;
1085 fmt->format_string_len -= repeat;
1087 break;
1089 case FMT_I:
1090 case FMT_B:
1091 case FMT_O:
1092 case FMT_Z:
1093 *seen_dd = true;
1094 get_fnode (fmt, &head, &tail, t);
1095 tail->repeat = repeat;
1097 t = format_lex (fmt);
1099 if (dtp->u.p.mode == READING)
1101 if (t != FMT_POSINT)
1103 fmt->error = posint_required;
1104 goto finished;
1107 else
1109 if (t != FMT_ZERO && t != FMT_POSINT)
1111 fmt->error = nonneg_required;
1112 goto finished;
1116 tail->u.integer.w = fmt->value;
1117 tail->u.integer.m = -1;
1119 t = format_lex (fmt);
1120 if (t != FMT_PERIOD)
1122 fmt->saved_token = t;
1124 else
1126 t = format_lex (fmt);
1127 if (t != FMT_ZERO && t != FMT_POSINT)
1129 fmt->error = nonneg_required;
1130 goto finished;
1133 tail->u.integer.m = fmt->value;
1136 if (tail->u.integer.w != 0 && tail->u.integer.m > tail->u.integer.w)
1138 fmt->error = "Minimum digits exceeds field width";
1139 goto finished;
1142 break;
1144 default:
1145 fmt->error = unexpected_element;
1146 goto finished;
1149 /* Between a descriptor and what comes next */
1150 between_desc:
1151 t = format_lex (fmt);
1152 switch (t)
1154 case FMT_COMMA:
1155 goto format_item;
1157 case FMT_RPAREN:
1158 goto finished;
1160 case FMT_SLASH:
1161 case FMT_COLON:
1162 get_fnode (fmt, &head, &tail, t);
1163 tail->repeat = 1;
1164 goto optional_comma;
1166 case FMT_END:
1167 fmt->error = unexpected_end;
1168 goto finished;
1170 default:
1171 /* Assume a missing comma, this is a GNU extension */
1172 goto format_item_1;
1175 /* Optional comma is a weird between state where we've just finished
1176 reading a colon, slash or P descriptor. */
1177 optional_comma:
1178 t = format_lex (fmt);
1179 switch (t)
1181 case FMT_COMMA:
1182 break;
1184 case FMT_RPAREN:
1185 goto finished;
1187 default: /* Assume that we have another format item */
1188 fmt->saved_token = t;
1189 break;
1192 goto format_item;
1194 finished:
1196 return head;
1200 /* format_error()-- Generate an error message for a format statement.
1201 If the node that gives the location of the error is NULL, the error
1202 is assumed to happen at parse time, and the current location of the
1203 parser is shown.
1205 We generate a message showing where the problem is. We take extra
1206 care to print only the relevant part of the format if it is longer
1207 than a standard 80 column display. */
1209 void
1210 format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
1212 int width, i, offset;
1213 #define BUFLEN 300
1214 char *p, buffer[BUFLEN];
1215 format_data *fmt = dtp->u.p.fmt;
1217 if (f != NULL)
1218 p = f->source;
1219 else /* This should not happen. */
1220 p = dtp->format;
1222 if (message == unexpected_element)
1223 snprintf (buffer, BUFLEN, message, fmt->error_element);
1224 else
1225 snprintf (buffer, BUFLEN, "%s\n", message);
1227 /* Get the offset into the format string where the error occurred. */
1228 offset = dtp->format_len - (fmt->reversion_ok ?
1229 (int) strlen(p) : fmt->format_string_len);
1231 width = dtp->format_len;
1233 if (width > 80)
1234 width = 80;
1236 /* Show the format */
1238 p = strchr (buffer, '\0');
1240 if (dtp->format)
1241 memcpy (p, dtp->format, width);
1243 p += width;
1244 *p++ = '\n';
1246 /* Show where the problem is */
1248 for (i = 1; i < offset; i++)
1249 *p++ = ' ';
1251 *p++ = '^';
1252 *p = '\0';
1254 generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
1258 /* revert()-- Do reversion of the format. Control reverts to the left
1259 parenthesis that matches the rightmost right parenthesis. From our
1260 tree structure, we are looking for the rightmost parenthesis node
1261 at the second level, the first level always being a single
1262 parenthesis node. If this node doesn't exit, we use the top
1263 level. */
1265 static void
1266 revert (st_parameter_dt *dtp)
1268 fnode *f, *r;
1269 format_data *fmt = dtp->u.p.fmt;
1271 dtp->u.p.reversion_flag = 1;
1273 r = NULL;
1275 for (f = fmt->array.array[0].u.child; f; f = f->next)
1276 if (f->format == FMT_LPAREN)
1277 r = f;
1279 /* If r is NULL because no node was found, the whole tree will be used */
1281 fmt->array.array[0].current = r;
1282 fmt->array.array[0].count = 0;
1285 /* parse_format()-- Parse a format string. */
1287 void
1288 parse_format (st_parameter_dt *dtp)
1290 format_data *fmt;
1291 bool format_cache_ok, seen_data_desc = false;
1293 /* Don't cache for internal units and set an arbitrary limit on the
1294 size of format strings we will cache. (Avoids memory issues.)
1295 Also, the format_hash_table resides in the current_unit, so
1296 child_dtio procedures would overwrite the parent table */
1297 format_cache_ok = !is_internal_unit (dtp)
1298 && (dtp->u.p.current_unit->child_dtio == 0);
1300 /* Lookup format string to see if it has already been parsed. */
1301 if (format_cache_ok)
1303 dtp->u.p.fmt = find_parsed_format (dtp);
1305 if (dtp->u.p.fmt != NULL)
1307 dtp->u.p.fmt->reversion_ok = 0;
1308 dtp->u.p.fmt->saved_token = FMT_NONE;
1309 dtp->u.p.fmt->saved_format = NULL;
1310 reset_fnode_counters (dtp);
1311 return;
1315 /* Not found so proceed as follows. */
1317 char *fmt_string = fc_strdup_notrim (dtp->format, dtp->format_len);
1318 dtp->format = fmt_string;
1320 dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data));
1321 fmt->format_string = dtp->format;
1322 fmt->format_string_len = dtp->format_len;
1324 fmt->string = NULL;
1325 fmt->saved_token = FMT_NONE;
1326 fmt->error = NULL;
1327 fmt->value = 0;
1329 /* Initialize variables used during traversal of the tree. */
1331 fmt->reversion_ok = 0;
1332 fmt->saved_format = NULL;
1334 /* Initialize the fnode_array. */
1336 memset (&(fmt->array), 0, sizeof(fmt->array));
1338 /* Allocate the first format node as the root of the tree. */
1340 fmt->last = &fmt->array;
1341 fmt->last->next = NULL;
1342 fmt->avail = &fmt->array.array[0];
1344 memset (fmt->avail, 0, sizeof (*fmt->avail));
1345 fmt->avail->format = FMT_LPAREN;
1346 fmt->avail->repeat = 1;
1347 fmt->avail++;
1349 if (format_lex (fmt) == FMT_LPAREN)
1350 fmt->array.array[0].u.child = parse_format_list (dtp, &seen_data_desc);
1351 else
1352 fmt->error = "Missing initial left parenthesis in format";
1354 if (format_cache_ok)
1355 save_parsed_format (dtp);
1356 else
1357 dtp->u.p.format_not_saved = 1;
1359 if (fmt->error)
1360 format_error (dtp, NULL, fmt->error);
1364 /* next_format0()-- Get the next format node without worrying about
1365 reversion. Returns NULL when we hit the end of the list.
1366 Parenthesis nodes are incremented after the list has been
1367 exhausted, other nodes are incremented before they are returned. */
1369 static const fnode *
1370 next_format0 (fnode *f)
1372 const fnode *r;
1374 if (f == NULL)
1375 return NULL;
1377 if (f->format != FMT_LPAREN)
1379 f->count++;
1380 if (f->count <= f->repeat)
1381 return f;
1383 f->count = 0;
1384 return NULL;
1387 /* Deal with a parenthesis node with unlimited format. */
1389 if (f->repeat == -2) /* -2 signifies unlimited. */
1390 for (;;)
1392 if (f->current == NULL)
1393 f->current = f->u.child;
1395 for (; f->current != NULL; f->current = f->current->next)
1397 r = next_format0 (f->current);
1398 if (r != NULL)
1399 return r;
1403 /* Deal with a parenthesis node with specific repeat count. */
1404 for (; f->count < f->repeat; f->count++)
1406 if (f->current == NULL)
1407 f->current = f->u.child;
1409 for (; f->current != NULL; f->current = f->current->next)
1411 r = next_format0 (f->current);
1412 if (r != NULL)
1413 return r;
1417 f->count = 0;
1418 return NULL;
1422 /* next_format()-- Return the next format node. If the format list
1423 ends up being exhausted, we do reversion. Reversion is only
1424 allowed if we've seen a data descriptor since the
1425 initialization or the last reversion. We return NULL if there
1426 are no more data descriptors to return (which is an error
1427 condition). */
1429 const fnode *
1430 next_format (st_parameter_dt *dtp)
1432 format_token t;
1433 const fnode *f;
1434 format_data *fmt = dtp->u.p.fmt;
1436 if (fmt->saved_format != NULL)
1437 { /* Deal with a pushed-back format node */
1438 f = fmt->saved_format;
1439 fmt->saved_format = NULL;
1440 goto done;
1443 f = next_format0 (&fmt->array.array[0]);
1444 if (f == NULL)
1446 if (!fmt->reversion_ok)
1447 return NULL;
1449 fmt->reversion_ok = 0;
1450 revert (dtp);
1452 f = next_format0 (&fmt->array.array[0]);
1453 if (f == NULL)
1455 format_error (dtp, NULL, reversion_error);
1456 return NULL;
1459 /* Push the first reverted token and return a colon node in case
1460 there are no more data items. */
1462 fmt->saved_format = f;
1463 return &colon_node;
1466 /* If this is a data edit descriptor, then reversion has become OK. */
1467 done:
1468 t = f->format;
1470 if (!fmt->reversion_ok &&
1471 (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F ||
1472 t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L ||
1473 t == FMT_A || t == FMT_D || t == FMT_DT))
1474 fmt->reversion_ok = 1;
1475 return f;
1479 /* unget_format()-- Push the given format back so that it will be
1480 returned on the next call to next_format() without affecting
1481 counts. This is necessary when we've encountered a data
1482 descriptor, but don't know what the data item is yet. The format
1483 node is pushed back, and we return control to the main program,
1484 which calls the library back with the data item (or not). */
1486 void
1487 unget_format (st_parameter_dt *dtp, const fnode *f)
1489 dtp->u.p.fmt->saved_format = f;