i386: Adjust rtx cost for imulq and imulw [PR115749]
[official-gcc.git] / libgfortran / io / format.c
blobf39d6ecc65b0ccb520e66c2592e448029950c0e3
1 /* Copyright (C) 2002-2024 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 <string.h>
35 static const fnode colon_node = { FMT_COLON, FMT_NONE, 0, NULL, NULL, {{ 0, 0, 0 }}, 0,
36 NULL };
38 /* Error messages. */
40 static const char posint_required[] = "Positive integer required in format",
41 period_required[] = "Period required in format",
42 nonneg_required[] = "Nonnegative width required in format",
43 unexpected_element[] = "Unexpected element '%c' in format\n",
44 unexpected_end[] = "Unexpected end of format string",
45 bad_string[] = "Unterminated character constant in format",
46 bad_hollerith[] = "Hollerith constant extends past the end of the format",
47 reversion_error[] = "Exhausted data descriptors in format",
48 zero_width[] = "Zero width in format descriptor";
50 /* The following routines support caching format data from parsed format strings
51 into a hash table. This avoids repeatedly parsing duplicate format strings
52 or format strings in I/O statements that are repeated in loops. */
55 /* Traverse the table and free all data. */
57 void
58 free_format_hash_table (gfc_unit *u)
60 size_t i;
62 /* free_format_data handles any NULL pointers. */
63 for (i = 0; i < FORMAT_HASH_SIZE; i++)
65 if (u->format_hash_table[i].hashed_fmt != NULL)
67 free_format_data (u->format_hash_table[i].hashed_fmt);
68 free (u->format_hash_table[i].key);
70 u->format_hash_table[i].key = NULL;
71 u->format_hash_table[i].key_len = 0;
72 u->format_hash_table[i].hashed_fmt = NULL;
76 /* Traverse the format_data structure and reset the fnode counters. */
78 static void
79 reset_node (fnode *fn)
81 fnode *f;
83 fn->count = 0;
84 fn->current = NULL;
86 if (fn->format != FMT_LPAREN)
87 return;
89 for (f = fn->u.child; f; f = f->next)
91 if (f->format == FMT_RPAREN)
92 break;
93 reset_node (f);
97 static void
98 reset_fnode_counters (st_parameter_dt *dtp)
100 fnode *f;
101 format_data *fmt;
103 fmt = dtp->u.p.fmt;
105 /* Clear this pointer at the head so things start at the right place. */
106 fmt->array.array[0].current = NULL;
108 for (f = fmt->array.array[0].u.child; f; f = f->next)
109 reset_node (f);
113 /* A simple hashing function to generate an index into the hash table. */
115 static uint32_t
116 format_hash (st_parameter_dt *dtp)
118 char *key;
119 gfc_charlen_type key_len;
120 uint32_t hash = 0;
121 gfc_charlen_type i;
123 /* Hash the format string. Super simple, but what the heck! */
124 key = dtp->format;
125 key_len = dtp->format_len;
126 for (i = 0; i < key_len; i++)
127 hash ^= key[i];
128 hash &= (FORMAT_HASH_SIZE - 1);
129 return hash;
133 static void
134 save_parsed_format (st_parameter_dt *dtp)
136 uint32_t hash;
137 gfc_unit *u;
139 hash = format_hash (dtp);
140 u = dtp->u.p.current_unit;
142 /* Index into the hash table. We are simply replacing whatever is there
143 relying on probability. */
144 if (u->format_hash_table[hash].hashed_fmt != NULL)
145 free_format_data (u->format_hash_table[hash].hashed_fmt);
146 u->format_hash_table[hash].hashed_fmt = NULL;
148 free (u->format_hash_table[hash].key);
149 u->format_hash_table[hash].key = dtp->format;
151 u->format_hash_table[hash].key_len = dtp->format_len;
152 u->format_hash_table[hash].hashed_fmt = dtp->u.p.fmt;
156 static format_data *
157 find_parsed_format (st_parameter_dt *dtp)
159 uint32_t hash;
160 gfc_unit *u;
162 hash = format_hash (dtp);
163 u = dtp->u.p.current_unit;
165 if (u->format_hash_table[hash].key != NULL)
167 /* See if it matches. */
168 if (u->format_hash_table[hash].key_len == dtp->format_len)
170 /* So far so good. */
171 if (strncmp (u->format_hash_table[hash].key,
172 dtp->format, dtp->format_len) == 0)
173 return u->format_hash_table[hash].hashed_fmt;
176 return NULL;
180 /* next_char()-- Return the next character in the format string.
181 Returns -1 when the string is done. If the literal flag is set,
182 spaces are significant, otherwise they are not. */
184 static int
185 next_char (format_data *fmt, int literal)
187 int c;
191 if (fmt->format_string_len == 0)
192 return -1;
194 fmt->format_string_len--;
195 c = safe_toupper (*fmt->format_string++);
196 fmt->error_element = c;
198 while ((c == ' ' || c == '\t') && !literal);
200 return c;
204 /* unget_char()-- Back up one character position. */
206 #define unget_char(fmt) \
207 { fmt->format_string--; fmt->format_string_len++; }
210 /* get_fnode()-- Allocate a new format node, inserting it into the
211 current singly linked list. These are initially allocated from the
212 static buffer. */
214 static fnode *
215 get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t)
217 fnode *f;
219 if (fmt->avail == &fmt->last->array[FARRAY_SIZE])
221 fmt->last->next = xmalloc (sizeof (fnode_array));
222 fmt->last = fmt->last->next;
223 fmt->last->next = NULL;
224 fmt->avail = &fmt->last->array[0];
226 f = fmt->avail++;
227 memset (f, '\0', sizeof (fnode));
228 f->pushed = FMT_NONE;
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 free (GFC_DESCRIPTOR_DATA(fnp->u.udf.vlist));
274 free (fnp->u.udf.vlist);
277 for (fa = fmt->array.next; fa; fa = fa_next)
279 fa_next = fa->next;
280 free (fa);
283 free (fmt);
284 fmt = NULL;
288 /* format_lex()-- Simple lexical analyzer for getting the next token
289 in a FORMAT string. We support a one-level token pushback in the
290 fmt->saved_token variable. */
292 static format_token
293 format_lex (format_data *fmt)
295 format_token token;
296 int negative_flag;
297 int c;
298 char delim;
300 if (fmt->saved_token != FMT_NONE)
302 token = fmt->saved_token;
303 fmt->saved_token = FMT_NONE;
304 return token;
307 negative_flag = 0;
308 c = next_char (fmt, 0);
310 switch (c)
312 case '*':
313 token = FMT_STAR;
314 break;
316 case '(':
317 token = FMT_LPAREN;
318 break;
320 case ')':
321 token = FMT_RPAREN;
322 break;
324 case '-':
325 negative_flag = 1;
326 /* Fall Through */
328 case '+':
329 c = next_char (fmt, 0);
330 if (!safe_isdigit (c))
332 token = FMT_UNKNOWN;
333 break;
336 fmt->value = c - '0';
338 for (;;)
340 c = next_char (fmt, 0);
341 if (!safe_isdigit (c))
342 break;
344 fmt->value = 10 * fmt->value + c - '0';
347 unget_char (fmt);
349 if (negative_flag)
350 fmt->value = -fmt->value;
351 token = FMT_SIGNED_INT;
352 break;
354 case '0':
355 case '1':
356 case '2':
357 case '3':
358 case '4':
359 case '5':
360 case '6':
361 case '7':
362 case '8':
363 case '9':
364 fmt->value = c - '0';
366 for (;;)
368 c = next_char (fmt, 0);
369 if (!safe_isdigit (c))
370 break;
372 fmt->value = 10 * fmt->value + c - '0';
375 unget_char (fmt);
376 token = (fmt->value == 0) ? FMT_ZERO : FMT_POSINT;
377 break;
379 case '.':
380 token = FMT_PERIOD;
381 break;
383 case ',':
384 token = FMT_COMMA;
385 break;
387 case ':':
388 token = FMT_COLON;
389 break;
391 case '/':
392 token = FMT_SLASH;
393 break;
395 case '$':
396 token = FMT_DOLLAR;
397 break;
399 case 'T':
400 switch (next_char (fmt, 0))
402 case 'L':
403 token = FMT_TL;
404 break;
405 case 'R':
406 token = FMT_TR;
407 break;
408 default:
409 token = FMT_T;
410 unget_char (fmt);
411 break;
414 break;
416 case 'X':
417 token = FMT_X;
418 break;
420 case 'S':
421 switch (next_char (fmt, 0))
423 case 'S':
424 token = FMT_SS;
425 break;
426 case 'P':
427 token = FMT_SP;
428 break;
429 default:
430 token = FMT_S;
431 unget_char (fmt);
432 break;
435 break;
437 case 'B':
438 switch (next_char (fmt, 0))
440 case 'N':
441 token = FMT_BN;
442 break;
443 case 'Z':
444 token = FMT_BZ;
445 break;
446 default:
447 token = FMT_B;
448 unget_char (fmt);
449 break;
452 break;
454 case '\'':
455 case '"':
456 delim = c;
458 fmt->string = fmt->format_string;
459 fmt->value = 0; /* This is the length of the string */
461 for (;;)
463 c = next_char (fmt, 1);
464 if (c == -1)
466 token = FMT_BADSTRING;
467 fmt->error = bad_string;
468 break;
471 if (c == delim)
473 c = next_char (fmt, 1);
475 if (c == -1)
477 token = FMT_BADSTRING;
478 fmt->error = bad_string;
479 break;
482 if (c != delim)
484 unget_char (fmt);
485 token = FMT_STRING;
486 break;
490 fmt->value++;
493 break;
495 case 'P':
496 token = FMT_P;
497 break;
499 case 'I':
500 token = FMT_I;
501 break;
503 case 'O':
504 token = FMT_O;
505 break;
507 case 'Z':
508 token = FMT_Z;
509 break;
511 case 'F':
512 token = FMT_F;
513 break;
515 case 'E':
516 switch (next_char (fmt, 0))
518 case 'N':
519 token = FMT_EN;
520 break;
521 case 'S':
522 token = FMT_ES;
523 break;
524 default:
525 token = FMT_E;
526 unget_char (fmt);
527 break;
529 break;
531 case 'G':
532 token = FMT_G;
533 break;
535 case 'H':
536 token = FMT_H;
537 break;
539 case 'L':
540 token = FMT_L;
541 break;
543 case 'A':
544 token = FMT_A;
545 break;
547 case 'D':
548 switch (next_char (fmt, 0))
550 case 'P':
551 token = FMT_DP;
552 break;
553 case 'C':
554 token = FMT_DC;
555 break;
556 case 'T':
557 token = FMT_DT;
558 break;
559 default:
560 token = FMT_D;
561 unget_char (fmt);
562 break;
564 break;
566 case 'R':
567 switch (next_char (fmt, 0))
569 case 'C':
570 token = FMT_RC;
571 break;
572 case 'D':
573 token = FMT_RD;
574 break;
575 case 'N':
576 token = FMT_RN;
577 break;
578 case 'P':
579 token = FMT_RP;
580 break;
581 case 'U':
582 token = FMT_RU;
583 break;
584 case 'Z':
585 token = FMT_RZ;
586 break;
587 default:
588 unget_char (fmt);
589 token = FMT_UNKNOWN;
590 break;
592 break;
594 case -1:
595 token = FMT_END;
596 break;
598 default:
599 token = FMT_UNKNOWN;
600 break;
603 return token;
607 /* parse_format_list()-- Parse a format list. Assumes that a left
608 paren has already been seen. Returns a list representing the
609 parenthesis node which contains the rest of the list. */
611 static fnode *
612 parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
614 fnode *head, *tail;
615 format_token t, u, t2;
616 int repeat;
617 format_data *fmt = dtp->u.p.fmt;
618 bool seen_data_desc = false;
619 int standard;
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;
926 tail->pushed = FMT_NONE;
928 u = format_lex (fmt);
930 /* Processing for zero width formats. */
931 if (u == FMT_ZERO)
933 if (t == FMT_F)
934 standard = GFC_STD_F95;
935 else if (t == FMT_G)
936 standard = GFC_STD_F2008;
937 else
938 standard = GFC_STD_F2018;
940 if (notification_std (standard) == NOTIFICATION_ERROR
941 || dtp->u.p.mode == READING)
943 fmt->error = zero_width;
944 goto finished;
946 tail->u.real.w = 0;
948 /* Look for the dot seperator. */
949 u = format_lex (fmt);
950 if (u != FMT_PERIOD)
952 fmt->saved_token = u;
953 break;
956 /* Look for the precision. */
957 u = format_lex (fmt);
958 if (u != FMT_ZERO && u != FMT_POSINT)
960 fmt->error = nonneg_required;
961 goto finished;
963 tail->u.real.d = fmt->value;
965 /* Look for optional exponent, not allowed for FMT_D */
966 if (t == FMT_D)
967 break;
968 u = format_lex (fmt);
969 if (u != FMT_E)
970 fmt->saved_token = u;
971 else
973 u = format_lex (fmt);
974 if (u != FMT_POSINT)
976 if (u == FMT_ZERO)
978 notify_std (&dtp->common, GFC_STD_F2018,
979 "Positive exponent width required");
981 else
983 fmt->error = "Positive exponent width required in "
984 "format string at %L";
985 goto finished;
988 tail->u.real.e = fmt->value;
990 break;
993 /* Processing for positive width formats. */
994 if (u == FMT_POSINT)
996 tail->u.real.w = fmt->value;
998 /* Look for the dot separator. Because of legacy behaviors
999 we do some look ahead for missing things. */
1000 t2 = t;
1001 t = format_lex (fmt);
1002 if (t != FMT_PERIOD)
1004 /* We treat a missing decimal descriptor as 0. Note: This is only
1005 allowed if -std=legacy, otherwise an error occurs. */
1006 if (compile_options.warn_std != 0)
1008 fmt->error = period_required;
1009 goto finished;
1011 fmt->saved_token = t;
1012 tail->u.real.d = 0;
1013 tail->u.real.e = -1;
1014 break;
1017 /* If we made it here, we should have the dot so look for the
1018 precision. */
1019 t = format_lex (fmt);
1020 if (t != FMT_ZERO && t != FMT_POSINT)
1022 fmt->error = nonneg_required;
1023 goto finished;
1025 tail->u.real.d = fmt->value;
1026 tail->u.real.e = -1;
1028 /* Done with D and F formats. */
1029 if (t2 == FMT_D || t2 == FMT_F)
1031 *seen_dd = true;
1032 break;
1035 /* Look for optional exponent */
1036 u = format_lex (fmt);
1037 if (u != FMT_E)
1038 fmt->saved_token = u;
1039 else
1041 u = format_lex (fmt);
1042 if (u != FMT_POSINT)
1044 if (u == FMT_ZERO)
1046 notify_std (&dtp->common, GFC_STD_F2018,
1047 "Positive exponent width required");
1049 else
1051 fmt->error = "Positive exponent width required in "
1052 "format string at %L";
1053 goto finished;
1056 tail->u.real.e = fmt->value;
1058 break;
1061 /* Old DEC codes may not have width or precision specified. */
1062 if (dtp->u.p.mode == WRITING && (dtp->common.flags & IOPARM_DT_DEC_EXT))
1064 tail->u.real.w = DEFAULT_WIDTH;
1065 tail->u.real.d = 0;
1066 tail->u.real.e = -1;
1067 fmt->saved_token = u;
1069 break;
1071 case FMT_DT:
1072 *seen_dd = true;
1073 get_fnode (fmt, &head, &tail, t);
1074 tail->repeat = repeat;
1076 t = format_lex (fmt);
1078 /* Initialize the vlist to a zero size, rank-one array. */
1079 tail->u.udf.vlist= xmalloc (sizeof(gfc_array_i4)
1080 + sizeof (descriptor_dimension));
1081 GFC_DESCRIPTOR_DATA(tail->u.udf.vlist) = NULL;
1082 GFC_DIMENSION_SET(tail->u.udf.vlist->dim[0],1, 0, 0);
1084 if (t == FMT_STRING)
1086 /* Get pointer to the optional format string. */
1087 tail->u.udf.string = fmt->string;
1088 tail->u.udf.string_len = fmt->value;
1089 t = format_lex (fmt);
1091 if (t == FMT_LPAREN)
1093 /* Temporary buffer to hold the vlist values. */
1094 GFC_INTEGER_4 temp[FARRAY_SIZE];
1095 int i = 0;
1096 loop:
1097 t = format_lex (fmt);
1098 if (t != FMT_POSINT)
1100 fmt->error = posint_required;
1101 goto finished;
1103 /* Save the positive integer value. */
1104 temp[i++] = fmt->value;
1105 t = format_lex (fmt);
1106 if (t == FMT_COMMA)
1107 goto loop;
1108 if (t == FMT_RPAREN)
1110 /* We have parsed the complete vlist so initialize the
1111 array descriptor and save it in the format node. */
1112 gfc_full_array_i4 *vp = tail->u.udf.vlist;
1113 GFC_DESCRIPTOR_DATA(vp) = xmalloc (i * sizeof(GFC_INTEGER_4));
1114 GFC_DIMENSION_SET(vp->dim[0],1, i, 1);
1115 memcpy (GFC_DESCRIPTOR_DATA(vp), temp, i * sizeof(GFC_INTEGER_4));
1116 break;
1118 fmt->error = unexpected_element;
1119 goto finished;
1121 fmt->saved_token = t;
1122 break;
1123 case FMT_H:
1124 if (repeat > fmt->format_string_len)
1126 fmt->error = bad_hollerith;
1127 goto finished;
1130 get_fnode (fmt, &head, &tail, FMT_STRING);
1131 tail->u.string.p = fmt->format_string;
1132 tail->u.string.length = repeat;
1133 tail->repeat = 1;
1135 fmt->format_string += fmt->value;
1136 fmt->format_string_len -= repeat;
1138 break;
1140 case FMT_I:
1141 case FMT_B:
1142 case FMT_O:
1143 case FMT_Z:
1144 *seen_dd = true;
1145 get_fnode (fmt, &head, &tail, t);
1146 tail->repeat = repeat;
1148 t = format_lex (fmt);
1150 if (dtp->u.p.mode == READING)
1152 if (t != FMT_POSINT)
1154 if (dtp->common.flags & IOPARM_DT_DEC_EXT)
1156 tail->u.integer.w = DEFAULT_WIDTH;
1157 tail->u.integer.m = -1;
1158 fmt->saved_token = t;
1159 break;
1161 fmt->error = posint_required;
1162 goto finished;
1165 else
1167 if (t != FMT_ZERO && t != FMT_POSINT)
1169 if (dtp->common.flags & IOPARM_DT_DEC_EXT)
1171 tail->u.integer.w = DEFAULT_WIDTH;
1172 tail->u.integer.m = -1;
1173 fmt->saved_token = t;
1174 break;
1176 fmt->error = nonneg_required;
1177 goto finished;
1181 tail->u.integer.w = fmt->value;
1182 tail->u.integer.m = -1;
1184 t = format_lex (fmt);
1185 if (t != FMT_PERIOD)
1187 fmt->saved_token = t;
1189 else
1191 t = format_lex (fmt);
1192 if (t != FMT_ZERO && t != FMT_POSINT)
1194 fmt->error = nonneg_required;
1195 goto finished;
1198 tail->u.integer.m = fmt->value;
1201 if (tail->u.integer.w != 0 && tail->u.integer.m > tail->u.integer.w)
1203 fmt->error = "Minimum digits exceeds field width";
1204 goto finished;
1207 break;
1209 default:
1210 fmt->error = unexpected_element;
1211 goto finished;
1214 /* Between a descriptor and what comes next */
1215 between_desc:
1216 t = format_lex (fmt);
1217 switch (t)
1219 case FMT_COMMA:
1220 goto format_item;
1222 case FMT_RPAREN:
1223 goto finished;
1225 case FMT_SLASH:
1226 case FMT_COLON:
1227 get_fnode (fmt, &head, &tail, t);
1228 tail->repeat = 1;
1229 goto optional_comma;
1231 case FMT_END:
1232 fmt->error = unexpected_end;
1233 goto finished;
1235 default:
1236 /* Assume a missing comma, this is a GNU extension */
1237 goto format_item_1;
1240 /* Optional comma is a weird between state where we've just finished
1241 reading a colon, slash or P descriptor. */
1242 optional_comma:
1243 t = format_lex (fmt);
1244 switch (t)
1246 case FMT_COMMA:
1247 break;
1249 case FMT_RPAREN:
1250 goto finished;
1252 default: /* Assume that we have another format item */
1253 fmt->saved_token = t;
1254 break;
1257 goto format_item;
1259 finished:
1261 return head;
1265 /* format_error()-- Generate an error message for a format statement.
1266 If the node that gives the location of the error is NULL, the error
1267 is assumed to happen at parse time, and the current location of the
1268 parser is shown.
1270 We generate a message showing where the problem is. We take extra
1271 care to print only the relevant part of the format if it is longer
1272 than a standard 80 column display. */
1274 void
1275 format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
1277 int width, i, offset;
1278 #define BUFLEN 300
1279 char *p, buffer[BUFLEN];
1280 format_data *fmt = dtp->u.p.fmt;
1282 if (f != NULL)
1283 p = f->source;
1284 else /* This should not happen. */
1285 p = dtp->format;
1287 if (message == unexpected_element)
1288 snprintf (buffer, BUFLEN, message, fmt->error_element);
1289 else
1290 snprintf (buffer, BUFLEN, "%s\n", message);
1292 /* Get the offset into the format string where the error occurred. */
1293 offset = dtp->format_len - (fmt->reversion_ok ?
1294 (int) strlen(p) : fmt->format_string_len);
1296 width = dtp->format_len;
1298 if (width > 80)
1299 width = 80;
1301 /* Show the format */
1303 p = strchr (buffer, '\0');
1305 if (dtp->format)
1306 memcpy (p, dtp->format, width);
1308 p += width;
1309 *p++ = '\n';
1311 /* Show where the problem is */
1313 for (i = 1; i < offset; i++)
1314 *p++ = ' ';
1316 *p++ = '^';
1317 *p = '\0';
1319 generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
1323 /* revert()-- Do reversion of the format. Control reverts to the left
1324 parenthesis that matches the rightmost right parenthesis. From our
1325 tree structure, we are looking for the rightmost parenthesis node
1326 at the second level, the first level always being a single
1327 parenthesis node. If this node doesn't exit, we use the top
1328 level. */
1330 static void
1331 revert (st_parameter_dt *dtp)
1333 fnode *f, *r;
1334 format_data *fmt = dtp->u.p.fmt;
1336 dtp->u.p.reversion_flag = 1;
1338 r = NULL;
1340 for (f = fmt->array.array[0].u.child; f; f = f->next)
1341 if (f->format == FMT_LPAREN)
1342 r = f;
1344 /* If r is NULL because no node was found, the whole tree will be used */
1346 fmt->array.array[0].current = r;
1347 fmt->array.array[0].count = 0;
1350 /* parse_format()-- Parse a format string. */
1352 void
1353 parse_format (st_parameter_dt *dtp)
1355 format_data *fmt;
1356 bool format_cache_ok, seen_data_desc = false;
1358 /* Don't cache for internal units and set an arbitrary limit on the
1359 size of format strings we will cache. (Avoids memory issues.)
1360 Also, the format_hash_table resides in the current_unit, so
1361 child_dtio procedures would overwrite the parent table */
1362 format_cache_ok = !is_internal_unit (dtp)
1363 && (dtp->u.p.current_unit->child_dtio == 0);
1365 /* Lookup format string to see if it has already been parsed. */
1366 if (format_cache_ok)
1368 dtp->u.p.fmt = find_parsed_format (dtp);
1370 if (dtp->u.p.fmt != NULL)
1372 dtp->u.p.fmt->reversion_ok = 0;
1373 dtp->u.p.fmt->saved_token = FMT_NONE;
1374 dtp->u.p.fmt->saved_format = NULL;
1375 reset_fnode_counters (dtp);
1376 return;
1380 /* Not found so proceed as follows. */
1382 char *fmt_string = fc_strdup_notrim (dtp->format, dtp->format_len);
1383 dtp->format = fmt_string;
1385 dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data));
1386 fmt->format_string = dtp->format;
1387 fmt->format_string_len = dtp->format_len;
1389 fmt->string = NULL;
1390 fmt->saved_token = FMT_NONE;
1391 fmt->error = NULL;
1392 fmt->value = 0;
1394 /* Initialize variables used during traversal of the tree. */
1396 fmt->reversion_ok = 0;
1397 fmt->saved_format = NULL;
1399 /* Initialize the fnode_array. */
1401 memset (&(fmt->array), 0, sizeof(fmt->array));
1403 /* Allocate the first format node as the root of the tree. */
1405 fmt->last = &fmt->array;
1406 fmt->last->next = NULL;
1407 fmt->avail = &fmt->array.array[0];
1409 memset (fmt->avail, 0, sizeof (*fmt->avail));
1410 fmt->avail->format = FMT_LPAREN;
1411 fmt->avail->repeat = 1;
1412 fmt->avail++;
1414 if (format_lex (fmt) == FMT_LPAREN)
1415 fmt->array.array[0].u.child = parse_format_list (dtp, &seen_data_desc);
1416 else
1417 fmt->error = "Missing initial left parenthesis in format";
1419 if (format_cache_ok)
1420 save_parsed_format (dtp);
1421 else
1422 dtp->u.p.format_not_saved = 1;
1424 if (fmt->error)
1425 format_error (dtp, NULL, fmt->error);
1429 /* next_format0()-- Get the next format node without worrying about
1430 reversion. Returns NULL when we hit the end of the list.
1431 Parenthesis nodes are incremented after the list has been
1432 exhausted, other nodes are incremented before they are returned. */
1434 static const fnode *
1435 next_format0 (fnode *f)
1437 const fnode *r;
1439 if (f == NULL)
1440 return NULL;
1442 if (f->format != FMT_LPAREN)
1444 f->count++;
1445 if (f->count <= f->repeat)
1446 return f;
1448 f->count = 0;
1449 return NULL;
1452 /* Deal with a parenthesis node with unlimited format. */
1454 if (f->repeat == -2) /* -2 signifies unlimited. */
1455 for (;;)
1457 if (f->current == NULL)
1458 f->current = f->u.child;
1460 for (; f->current != NULL; f->current = f->current->next)
1462 r = next_format0 (f->current);
1463 if (r != NULL)
1464 return r;
1468 /* Deal with a parenthesis node with specific repeat count. */
1469 for (; f->count < f->repeat; f->count++)
1471 if (f->current == NULL)
1472 f->current = f->u.child;
1474 for (; f->current != NULL; f->current = f->current->next)
1476 r = next_format0 (f->current);
1477 if (r != NULL)
1478 return r;
1482 f->count = 0;
1483 return NULL;
1487 /* next_format()-- Return the next format node. If the format list
1488 ends up being exhausted, we do reversion. Reversion is only
1489 allowed if we've seen a data descriptor since the
1490 initialization or the last reversion. We return NULL if there
1491 are no more data descriptors to return (which is an error
1492 condition). */
1494 const fnode *
1495 next_format (st_parameter_dt *dtp)
1497 format_token t;
1498 const fnode *f;
1499 format_data *fmt = dtp->u.p.fmt;
1501 if (fmt->saved_format != NULL)
1502 { /* Deal with a pushed-back format node */
1503 f = fmt->saved_format;
1504 fmt->saved_format = NULL;
1505 goto done;
1508 f = next_format0 (&fmt->array.array[0]);
1509 if (f == NULL)
1511 if (!fmt->reversion_ok)
1512 return NULL;
1514 fmt->reversion_ok = 0;
1515 revert (dtp);
1517 f = next_format0 (&fmt->array.array[0]);
1518 if (f == NULL)
1520 format_error (dtp, NULL, reversion_error);
1521 return NULL;
1524 /* Push the first reverted token and return a colon node in case
1525 there are no more data items. */
1527 fmt->saved_format = f;
1528 return &colon_node;
1531 /* If this is a data edit descriptor, then reversion has become OK. */
1532 done:
1533 t = f->format;
1535 if (!fmt->reversion_ok &&
1536 (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F ||
1537 t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L ||
1538 t == FMT_A || t == FMT_D || t == FMT_DT))
1539 fmt->reversion_ok = 1;
1540 return f;
1544 /* unget_format()-- Push the given format back so that it will be
1545 returned on the next call to next_format() without affecting
1546 counts. This is necessary when we've encountered a data
1547 descriptor, but don't know what the data item is yet. The format
1548 node is pushed back, and we return control to the main program,
1549 which calls the library back with the data item (or not). */
1551 void
1552 unget_format (st_parameter_dt *dtp, const fnode *f)
1554 dtp->u.p.fmt->saved_format = f;