PR lto/42531
[official-gcc.git] / libgfortran / io / format.c
blobcafea8732e46367d83e2011c063ade38bcbb3d04
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4 F2003 I/O support contributed by Jerry DeLisle
6 This file is part of the GNU Fortran 95 runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
28 /* format.c-- parse a FORMAT string into a binary format suitable for
29 * interpretation during I/O statements */
31 #include "io.h"
32 #include "format.h"
33 #include <ctype.h>
34 #include <string.h>
35 #include <stdbool.h>
37 #define FARRAY_SIZE 64
39 typedef struct fnode_array
41 struct fnode_array *next;
42 fnode array[FARRAY_SIZE];
44 fnode_array;
46 typedef struct format_data
48 char *format_string, *string;
49 const char *error;
50 char error_element;
51 format_token saved_token;
52 int value, format_string_len, reversion_ok;
53 fnode *avail;
54 const fnode *saved_format;
55 fnode_array *last;
56 fnode_array array;
58 format_data;
60 static const fnode colon_node = { FMT_COLON, 0, NULL, NULL, {{ 0, 0, 0 }}, 0,
61 NULL };
63 /* Error messages. */
65 static const char posint_required[] = "Positive width required in format",
66 period_required[] = "Period required in format",
67 nonneg_required[] = "Nonnegative width required in format",
68 unexpected_element[] = "Unexpected element '%c' in format\n",
69 unexpected_end[] = "Unexpected end of format string",
70 bad_string[] = "Unterminated character constant in format",
71 bad_hollerith[] = "Hollerith constant extends past the end of the format",
72 reversion_error[] = "Exhausted data descriptors in format",
73 zero_width[] = "Zero width in format descriptor";
75 /* The following routines support caching format data from parsed format strings
76 into a hash table. This avoids repeatedly parsing duplicate format strings
77 or format strings in I/O statements that are repeated in loops. */
80 /* Traverse the table and free all data. */
82 void
83 free_format_hash_table (gfc_unit *u)
85 size_t i;
87 /* free_format_data handles any NULL pointers. */
88 for (i = 0; i < FORMAT_HASH_SIZE; i++)
90 if (u->format_hash_table[i].hashed_fmt != NULL)
92 free_format_data (u->format_hash_table[i].hashed_fmt);
93 free_mem (u->format_hash_table[i].key);
95 u->format_hash_table[i].key = NULL;
96 u->format_hash_table[i].key_len = 0;
97 u->format_hash_table[i].hashed_fmt = NULL;
101 /* Traverse the format_data structure and reset the fnode counters. */
103 static void
104 reset_node (fnode *fn)
106 fnode *f;
108 fn->count = 0;
109 fn->current = NULL;
111 if (fn->format != FMT_LPAREN)
112 return;
114 for (f = fn->u.child; f; f = f->next)
116 if (f->format == FMT_RPAREN)
117 break;
118 reset_node (f);
122 static void
123 reset_fnode_counters (st_parameter_dt *dtp)
125 fnode *f;
126 format_data *fmt;
128 fmt = dtp->u.p.fmt;
130 /* Clear this pointer at the head so things start at the right place. */
131 fmt->array.array[0].current = NULL;
133 for (f = fmt->last->array[0].u.child; f; f = f->next)
134 reset_node (f);
138 /* A simple hashing function to generate an index into the hash table. */
140 static inline
141 uint32_t format_hash (st_parameter_dt *dtp)
143 char *key;
144 gfc_charlen_type key_len;
145 uint32_t hash = 0;
146 gfc_charlen_type i;
148 /* Hash the format string. Super simple, but what the heck! */
149 key = dtp->format;
150 key_len = dtp->format_len;
151 for (i = 0; i < key_len; i++)
152 hash ^= key[i];
153 hash &= (FORMAT_HASH_SIZE - 1);
154 return hash;
158 static void
159 save_parsed_format (st_parameter_dt *dtp)
161 uint32_t hash;
162 gfc_unit *u;
164 hash = format_hash (dtp);
165 u = dtp->u.p.current_unit;
167 /* Index into the hash table. We are simply replacing whatever is there
168 relying on probability. */
169 if (u->format_hash_table[hash].hashed_fmt != NULL)
170 free_format_data (u->format_hash_table[hash].hashed_fmt);
171 u->format_hash_table[hash].hashed_fmt = NULL;
173 if (u->format_hash_table[hash].key != NULL)
174 free_mem (u->format_hash_table[hash].key);
175 u->format_hash_table[hash].key = get_mem (dtp->format_len);
176 memcpy (u->format_hash_table[hash].key, dtp->format, dtp->format_len);
178 u->format_hash_table[hash].key_len = dtp->format_len;
179 u->format_hash_table[hash].hashed_fmt = dtp->u.p.fmt;
183 static format_data *
184 find_parsed_format (st_parameter_dt *dtp)
186 uint32_t hash;
187 gfc_unit *u;
189 hash = format_hash (dtp);
190 u = dtp->u.p.current_unit;
192 if (u->format_hash_table[hash].key != NULL)
194 /* See if it matches. */
195 if (u->format_hash_table[hash].key_len == dtp->format_len)
197 /* So far so good. */
198 if (strncmp (u->format_hash_table[hash].key,
199 dtp->format, dtp->format_len) == 0)
200 return u->format_hash_table[hash].hashed_fmt;
203 return NULL;
207 /* next_char()-- Return the next character in the format string.
208 * Returns -1 when the string is done. If the literal flag is set,
209 * spaces are significant, otherwise they are not. */
211 static int
212 next_char (format_data *fmt, int literal)
214 int c;
218 if (fmt->format_string_len == 0)
219 return -1;
221 fmt->format_string_len--;
222 c = toupper (*fmt->format_string++);
223 fmt->error_element = c;
225 while ((c == ' ' || c == '\t') && !literal);
227 return c;
231 /* unget_char()-- Back up one character position. */
233 #define unget_char(fmt) \
234 { fmt->format_string--; fmt->format_string_len++; }
237 /* get_fnode()-- Allocate a new format node, inserting it into the
238 * current singly linked list. These are initially allocated from the
239 * static buffer. */
241 static fnode *
242 get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t)
244 fnode *f;
246 if (fmt->avail == &fmt->last->array[FARRAY_SIZE])
248 fmt->last->next = get_mem (sizeof (fnode_array));
249 fmt->last = fmt->last->next;
250 fmt->last->next = NULL;
251 fmt->avail = &fmt->last->array[0];
253 f = fmt->avail++;
254 memset (f, '\0', sizeof (fnode));
256 if (*head == NULL)
257 *head = *tail = f;
258 else
260 (*tail)->next = f;
261 *tail = f;
264 f->format = t;
265 f->repeat = -1;
266 f->source = fmt->format_string;
267 return f;
271 /* free_format_data()-- Free all allocated format data. */
273 void
274 free_format_data (format_data *fmt)
276 fnode_array *fa, *fa_next;
279 if (fmt == NULL)
280 return;
282 for (fa = fmt->array.next; fa; fa = fa_next)
284 fa_next = fa->next;
285 free_mem (fa);
288 free_mem (fmt);
289 fmt = NULL;
293 /* format_lex()-- Simple lexical analyzer for getting the next token
294 * in a FORMAT string. We support a one-level token pushback in the
295 * fmt->saved_token variable. */
297 static format_token
298 format_lex (format_data *fmt)
300 format_token token;
301 int negative_flag;
302 int c;
303 char delim;
305 if (fmt->saved_token != FMT_NONE)
307 token = fmt->saved_token;
308 fmt->saved_token = FMT_NONE;
309 return token;
312 negative_flag = 0;
313 c = next_char (fmt, 0);
315 switch (c)
317 case '*':
318 token = FMT_STAR;
319 break;
321 case '(':
322 token = FMT_LPAREN;
323 break;
325 case ')':
326 token = FMT_RPAREN;
327 break;
329 case '-':
330 negative_flag = 1;
331 /* Fall Through */
333 case '+':
334 c = next_char (fmt, 0);
335 if (!isdigit (c))
337 token = FMT_UNKNOWN;
338 break;
341 fmt->value = c - '0';
343 for (;;)
345 c = next_char (fmt, 0);
346 if (!isdigit (c))
347 break;
349 fmt->value = 10 * fmt->value + c - '0';
352 unget_char (fmt);
354 if (negative_flag)
355 fmt->value = -fmt->value;
356 token = FMT_SIGNED_INT;
357 break;
359 case '0':
360 case '1':
361 case '2':
362 case '3':
363 case '4':
364 case '5':
365 case '6':
366 case '7':
367 case '8':
368 case '9':
369 fmt->value = c - '0';
371 for (;;)
373 c = next_char (fmt, 0);
374 if (!isdigit (c))
375 break;
377 fmt->value = 10 * fmt->value + c - '0';
380 unget_char (fmt);
381 token = (fmt->value == 0) ? FMT_ZERO : FMT_POSINT;
382 break;
384 case '.':
385 token = FMT_PERIOD;
386 break;
388 case ',':
389 token = FMT_COMMA;
390 break;
392 case ':':
393 token = FMT_COLON;
394 break;
396 case '/':
397 token = FMT_SLASH;
398 break;
400 case '$':
401 token = FMT_DOLLAR;
402 break;
404 case 'T':
405 switch (next_char (fmt, 0))
407 case 'L':
408 token = FMT_TL;
409 break;
410 case 'R':
411 token = FMT_TR;
412 break;
413 default:
414 token = FMT_T;
415 unget_char (fmt);
416 break;
419 break;
421 case 'X':
422 token = FMT_X;
423 break;
425 case 'S':
426 switch (next_char (fmt, 0))
428 case 'S':
429 token = FMT_SS;
430 break;
431 case 'P':
432 token = FMT_SP;
433 break;
434 default:
435 token = FMT_S;
436 unget_char (fmt);
437 break;
440 break;
442 case 'B':
443 switch (next_char (fmt, 0))
445 case 'N':
446 token = FMT_BN;
447 break;
448 case 'Z':
449 token = FMT_BZ;
450 break;
451 default:
452 token = FMT_B;
453 unget_char (fmt);
454 break;
457 break;
459 case '\'':
460 case '"':
461 delim = c;
463 fmt->string = fmt->format_string;
464 fmt->value = 0; /* This is the length of the string */
466 for (;;)
468 c = next_char (fmt, 1);
469 if (c == -1)
471 token = FMT_BADSTRING;
472 fmt->error = bad_string;
473 break;
476 if (c == delim)
478 c = next_char (fmt, 1);
480 if (c == -1)
482 token = FMT_BADSTRING;
483 fmt->error = bad_string;
484 break;
487 if (c != delim)
489 unget_char (fmt);
490 token = FMT_STRING;
491 break;
495 fmt->value++;
498 break;
500 case 'P':
501 token = FMT_P;
502 break;
504 case 'I':
505 token = FMT_I;
506 break;
508 case 'O':
509 token = FMT_O;
510 break;
512 case 'Z':
513 token = FMT_Z;
514 break;
516 case 'F':
517 token = FMT_F;
518 break;
520 case 'E':
521 switch (next_char (fmt, 0))
523 case 'N':
524 token = FMT_EN;
525 break;
526 case 'S':
527 token = FMT_ES;
528 break;
529 default:
530 token = FMT_E;
531 unget_char (fmt);
532 break;
534 break;
536 case 'G':
537 token = FMT_G;
538 break;
540 case 'H':
541 token = FMT_H;
542 break;
544 case 'L':
545 token = FMT_L;
546 break;
548 case 'A':
549 token = FMT_A;
550 break;
552 case 'D':
553 switch (next_char (fmt, 0))
555 case 'P':
556 token = FMT_DP;
557 break;
558 case 'C':
559 token = FMT_DC;
560 break;
561 default:
562 token = FMT_D;
563 unget_char (fmt);
564 break;
566 break;
568 case 'R':
569 switch (next_char (fmt, 0))
571 case 'C':
572 token = FMT_RC;
573 break;
574 case 'D':
575 token = FMT_RD;
576 break;
577 case 'N':
578 token = FMT_RN;
579 break;
580 case 'P':
581 token = FMT_RP;
582 break;
583 case 'U':
584 token = FMT_RU;
585 break;
586 case 'Z':
587 token = FMT_RZ;
588 break;
589 default:
590 unget_char (fmt);
591 token = FMT_UNKNOWN;
592 break;
594 break;
596 case -1:
597 token = FMT_END;
598 break;
600 default:
601 token = FMT_UNKNOWN;
602 break;
605 return token;
609 /* parse_format_list()-- Parse a format list. Assumes that a left
610 * paren has already been seen. Returns a list representing the
611 * parenthesis node which contains the rest of the list. */
613 static fnode *
614 parse_format_list (st_parameter_dt *dtp, bool *save_ok)
616 fnode *head, *tail;
617 format_token t, u, t2;
618 int repeat;
619 format_data *fmt = dtp->u.p.fmt;
620 bool saveit;
622 head = tail = NULL;
623 saveit = *save_ok;
625 /* Get the next format item */
626 format_item:
627 t = format_lex (fmt);
628 format_item_1:
629 switch (t)
631 case FMT_STAR:
632 t = format_lex (fmt);
633 if (t != FMT_LPAREN)
635 fmt->error = "Left parenthesis required after '*'";
636 goto finished;
638 get_fnode (fmt, &head, &tail, FMT_LPAREN);
639 tail->repeat = -2; /* Signifies unlimited format. */
640 tail->u.child = parse_format_list (dtp, &saveit);
641 if (fmt->error != NULL)
642 goto finished;
644 goto between_desc;
646 case FMT_POSINT:
647 repeat = fmt->value;
649 t = format_lex (fmt);
650 switch (t)
652 case FMT_LPAREN:
653 get_fnode (fmt, &head, &tail, FMT_LPAREN);
654 tail->repeat = repeat;
655 tail->u.child = parse_format_list (dtp, &saveit);
656 if (fmt->error != NULL)
657 goto finished;
659 goto between_desc;
661 case FMT_SLASH:
662 get_fnode (fmt, &head, &tail, FMT_SLASH);
663 tail->repeat = repeat;
664 goto optional_comma;
666 case FMT_X:
667 get_fnode (fmt, &head, &tail, FMT_X);
668 tail->repeat = 1;
669 tail->u.k = fmt->value;
670 goto between_desc;
672 case FMT_P:
673 goto p_descriptor;
675 default:
676 goto data_desc;
679 case FMT_LPAREN:
680 get_fnode (fmt, &head, &tail, FMT_LPAREN);
681 tail->repeat = 1;
682 tail->u.child = parse_format_list (dtp, &saveit);
683 if (fmt->error != NULL)
684 goto finished;
686 goto between_desc;
688 case FMT_SIGNED_INT: /* Signed integer can only precede a P format. */
689 case FMT_ZERO: /* Same for zero. */
690 t = format_lex (fmt);
691 if (t != FMT_P)
693 fmt->error = "Expected P edit descriptor in format";
694 goto finished;
697 p_descriptor:
698 get_fnode (fmt, &head, &tail, FMT_P);
699 tail->u.k = fmt->value;
700 tail->repeat = 1;
702 t = format_lex (fmt);
703 if (t == FMT_F || t == FMT_EN || t == FMT_ES || t == FMT_D
704 || t == FMT_G || t == FMT_E)
706 repeat = 1;
707 goto data_desc;
710 if (t != FMT_COMMA && t != FMT_RPAREN && t != FMT_SLASH
711 && t != FMT_POSINT)
713 fmt->error = "Comma required after P descriptor";
714 goto finished;
717 fmt->saved_token = t;
718 goto optional_comma;
720 case FMT_P: /* P and X require a prior number */
721 fmt->error = "P descriptor requires leading scale factor";
722 goto finished;
724 case FMT_X:
726 EXTENSION!
728 If we would be pedantic in the library, we would have to reject
729 an X descriptor without an integer prefix:
731 fmt->error = "X descriptor requires leading space count";
732 goto finished;
734 However, this is an extension supported by many Fortran compilers,
735 including Cray, HP, AIX, and IRIX. Therefore, we allow it in the
736 runtime library, and make the front end reject it if the compiler
737 is in pedantic mode. The interpretation of 'X' is '1X'.
739 get_fnode (fmt, &head, &tail, FMT_X);
740 tail->repeat = 1;
741 tail->u.k = 1;
742 goto between_desc;
744 case FMT_STRING:
745 /* TODO: Find out why it is necessary to turn off format caching. */
746 saveit = false;
747 get_fnode (fmt, &head, &tail, FMT_STRING);
748 tail->u.string.p = fmt->string;
749 tail->u.string.length = fmt->value;
750 tail->repeat = 1;
751 goto optional_comma;
753 case FMT_RC:
754 case FMT_RD:
755 case FMT_RN:
756 case FMT_RP:
757 case FMT_RU:
758 case FMT_RZ:
759 notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: Round "
760 "descriptor not allowed");
761 get_fnode (fmt, &head, &tail, t);
762 tail->repeat = 1;
763 goto between_desc;
765 case FMT_DC:
766 case FMT_DP:
767 notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: DC or DP "
768 "descriptor not allowed");
769 /* Fall through. */
770 case FMT_S:
771 case FMT_SS:
772 case FMT_SP:
773 case FMT_BN:
774 case FMT_BZ:
775 get_fnode (fmt, &head, &tail, t);
776 tail->repeat = 1;
777 goto between_desc;
779 case FMT_COLON:
780 get_fnode (fmt, &head, &tail, FMT_COLON);
781 tail->repeat = 1;
782 goto optional_comma;
784 case FMT_SLASH:
785 get_fnode (fmt, &head, &tail, FMT_SLASH);
786 tail->repeat = 1;
787 tail->u.r = 1;
788 goto optional_comma;
790 case FMT_DOLLAR:
791 get_fnode (fmt, &head, &tail, FMT_DOLLAR);
792 tail->repeat = 1;
793 notify_std (&dtp->common, GFC_STD_GNU, "Extension: $ descriptor");
794 goto between_desc;
796 case FMT_T:
797 case FMT_TL:
798 case FMT_TR:
799 t2 = format_lex (fmt);
800 if (t2 != FMT_POSINT)
802 fmt->error = posint_required;
803 goto finished;
805 get_fnode (fmt, &head, &tail, t);
806 tail->u.n = fmt->value;
807 tail->repeat = 1;
808 goto between_desc;
810 case FMT_I:
811 case FMT_B:
812 case FMT_O:
813 case FMT_Z:
814 case FMT_E:
815 case FMT_EN:
816 case FMT_ES:
817 case FMT_D:
818 case FMT_L:
819 case FMT_A:
820 case FMT_F:
821 case FMT_G:
822 repeat = 1;
823 goto data_desc;
825 case FMT_H:
826 get_fnode (fmt, &head, &tail, FMT_STRING);
827 if (fmt->format_string_len < 1)
829 fmt->error = bad_hollerith;
830 goto finished;
833 tail->u.string.p = fmt->format_string;
834 tail->u.string.length = 1;
835 tail->repeat = 1;
837 fmt->format_string++;
838 fmt->format_string_len--;
840 goto between_desc;
842 case FMT_END:
843 fmt->error = unexpected_end;
844 goto finished;
846 case FMT_BADSTRING:
847 goto finished;
849 case FMT_RPAREN:
850 goto finished;
852 default:
853 fmt->error = unexpected_element;
854 goto finished;
857 /* In this state, t must currently be a data descriptor. Deal with
858 things that can/must follow the descriptor */
859 data_desc:
860 switch (t)
862 case FMT_L:
863 t = format_lex (fmt);
864 if (t != FMT_POSINT)
866 if (notification_std(GFC_STD_GNU) == ERROR)
868 fmt->error = posint_required;
869 goto finished;
871 else
873 fmt->saved_token = t;
874 fmt->value = 1; /* Default width */
875 notify_std (&dtp->common, GFC_STD_GNU, posint_required);
879 get_fnode (fmt, &head, &tail, FMT_L);
880 tail->u.n = fmt->value;
881 tail->repeat = repeat;
882 break;
884 case FMT_A:
885 t = format_lex (fmt);
886 if (t == FMT_ZERO)
888 fmt->error = zero_width;
889 goto finished;
892 if (t != FMT_POSINT)
894 fmt->saved_token = t;
895 fmt->value = -1; /* Width not present */
898 get_fnode (fmt, &head, &tail, FMT_A);
899 tail->repeat = repeat;
900 tail->u.n = fmt->value;
901 break;
903 case FMT_D:
904 case FMT_E:
905 case FMT_F:
906 case FMT_G:
907 case FMT_EN:
908 case FMT_ES:
909 get_fnode (fmt, &head, &tail, t);
910 tail->repeat = repeat;
912 u = format_lex (fmt);
913 if (t == FMT_G && u == FMT_ZERO)
915 if (notification_std (GFC_STD_F2008) == ERROR
916 || dtp->u.p.mode == READING)
918 fmt->error = zero_width;
919 goto finished;
921 tail->u.real.w = 0;
922 u = format_lex (fmt);
923 if (u != FMT_PERIOD)
925 fmt->saved_token = u;
926 break;
929 u = format_lex (fmt);
930 if (u != FMT_POSINT)
932 fmt->error = posint_required;
933 goto finished;
935 tail->u.real.d = fmt->value;
936 break;
938 if (t == FMT_F && dtp->u.p.mode == WRITING)
940 if (u != FMT_POSINT && u != FMT_ZERO)
942 fmt->error = nonneg_required;
943 goto finished;
946 else if (u != FMT_POSINT)
948 fmt->error = posint_required;
949 goto finished;
952 tail->u.real.w = fmt->value;
953 t2 = t;
954 t = format_lex (fmt);
955 if (t != FMT_PERIOD)
957 /* We treat a missing decimal descriptor as 0. Note: This is only
958 allowed if -std=legacy, otherwise an error occurs. */
959 if (compile_options.warn_std != 0)
961 fmt->error = period_required;
962 goto finished;
964 fmt->saved_token = t;
965 tail->u.real.d = 0;
966 tail->u.real.e = -1;
967 break;
970 t = format_lex (fmt);
971 if (t != FMT_ZERO && t != FMT_POSINT)
973 fmt->error = nonneg_required;
974 goto finished;
977 tail->u.real.d = fmt->value;
978 tail->u.real.e = -1;
980 if (t2 == FMT_D || t2 == FMT_F)
981 break;
984 /* Look for optional exponent */
985 t = format_lex (fmt);
986 if (t != FMT_E)
987 fmt->saved_token = t;
988 else
990 t = format_lex (fmt);
991 if (t != FMT_POSINT)
993 fmt->error = "Positive exponent width required in format";
994 goto finished;
997 tail->u.real.e = fmt->value;
1000 break;
1002 case FMT_H:
1003 if (repeat > fmt->format_string_len)
1005 fmt->error = bad_hollerith;
1006 goto finished;
1009 get_fnode (fmt, &head, &tail, FMT_STRING);
1010 tail->u.string.p = fmt->format_string;
1011 tail->u.string.length = repeat;
1012 tail->repeat = 1;
1014 fmt->format_string += fmt->value;
1015 fmt->format_string_len -= repeat;
1017 break;
1019 case FMT_I:
1020 case FMT_B:
1021 case FMT_O:
1022 case FMT_Z:
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;
1033 goto finished;
1036 else
1038 if (t != FMT_ZERO && t != FMT_POSINT)
1040 fmt->error = nonneg_required;
1041 goto finished;
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;
1053 else
1055 t = format_lex (fmt);
1056 if (t != FMT_ZERO && t != FMT_POSINT)
1058 fmt->error = nonneg_required;
1059 goto finished;
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";
1068 goto finished;
1071 break;
1073 default:
1074 fmt->error = unexpected_element;
1075 goto finished;
1078 /* Between a descriptor and what comes next */
1079 between_desc:
1080 t = format_lex (fmt);
1081 switch (t)
1083 case FMT_COMMA:
1084 goto format_item;
1086 case FMT_RPAREN:
1087 goto finished;
1089 case FMT_SLASH:
1090 case FMT_COLON:
1091 get_fnode (fmt, &head, &tail, t);
1092 tail->repeat = 1;
1093 goto optional_comma;
1095 case FMT_END:
1096 fmt->error = unexpected_end;
1097 goto finished;
1099 default:
1100 /* Assume a missing comma, this is a GNU extension */
1101 goto format_item_1;
1104 /* Optional comma is a weird between state where we've just finished
1105 reading a colon, slash or P descriptor. */
1106 optional_comma:
1107 t = format_lex (fmt);
1108 switch (t)
1110 case FMT_COMMA:
1111 break;
1113 case FMT_RPAREN:
1114 goto finished;
1116 default: /* Assume that we have another format item */
1117 fmt->saved_token = t;
1118 break;
1121 goto format_item;
1123 finished:
1125 *save_ok = saveit;
1127 return head;
1131 /* format_error()-- Generate an error message for a format statement.
1132 * If the node that gives the location of the error is NULL, the error
1133 * is assumed to happen at parse time, and the current location of the
1134 * parser is shown.
1136 * We generate a message showing where the problem is. We take extra
1137 * care to print only the relevant part of the format if it is longer
1138 * than a standard 80 column display. */
1140 void
1141 format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
1143 int width, i, j, offset;
1144 char *p, buffer[300];
1145 format_data *fmt = dtp->u.p.fmt;
1147 if (f != NULL)
1148 fmt->format_string = f->source;
1150 if (message == unexpected_element)
1151 sprintf (buffer, message, fmt->error_element);
1152 else
1153 sprintf (buffer, "%s\n", message);
1155 j = fmt->format_string - dtp->format;
1157 offset = (j > 60) ? j - 40 : 0;
1159 j -= offset;
1160 width = dtp->format_len - offset;
1162 if (width > 80)
1163 width = 80;
1165 /* Show the format */
1167 p = strchr (buffer, '\0');
1169 memcpy (p, dtp->format + offset, width);
1171 p += width;
1172 *p++ = '\n';
1174 /* Show where the problem is */
1176 for (i = 1; i < j; i++)
1177 *p++ = ' ';
1179 *p++ = '^';
1180 *p = '\0';
1182 generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
1186 /* revert()-- Do reversion of the format. Control reverts to the left
1187 * parenthesis that matches the rightmost right parenthesis. From our
1188 * tree structure, we are looking for the rightmost parenthesis node
1189 * at the second level, the first level always being a single
1190 * parenthesis node. If this node doesn't exit, we use the top
1191 * level. */
1193 static void
1194 revert (st_parameter_dt *dtp)
1196 fnode *f, *r;
1197 format_data *fmt = dtp->u.p.fmt;
1199 dtp->u.p.reversion_flag = 1;
1201 r = NULL;
1203 for (f = fmt->array.array[0].u.child; f; f = f->next)
1204 if (f->format == FMT_LPAREN)
1205 r = f;
1207 /* If r is NULL because no node was found, the whole tree will be used */
1209 fmt->array.array[0].current = r;
1210 fmt->array.array[0].count = 0;
1213 /* parse_format()-- Parse a format string. */
1215 void
1216 parse_format (st_parameter_dt *dtp)
1218 format_data *fmt;
1219 bool format_cache_ok;
1221 format_cache_ok = !is_internal_unit (dtp);
1223 /* Lookup format string to see if it has already been parsed. */
1224 if (format_cache_ok)
1226 dtp->u.p.fmt = find_parsed_format (dtp);
1228 if (dtp->u.p.fmt != NULL)
1230 dtp->u.p.fmt->reversion_ok = 0;
1231 dtp->u.p.fmt->saved_token = FMT_NONE;
1232 dtp->u.p.fmt->saved_format = NULL;
1233 reset_fnode_counters (dtp);
1234 return;
1238 /* Not found so proceed as follows. */
1240 dtp->u.p.fmt = fmt = get_mem (sizeof (format_data));
1241 fmt->format_string = dtp->format;
1242 fmt->format_string_len = dtp->format_len;
1244 fmt->string = NULL;
1245 fmt->saved_token = FMT_NONE;
1246 fmt->error = NULL;
1247 fmt->value = 0;
1249 /* Initialize variables used during traversal of the tree. */
1251 fmt->reversion_ok = 0;
1252 fmt->saved_format = NULL;
1254 /* Allocate the first format node as the root of the tree. */
1256 fmt->last = &fmt->array;
1257 fmt->last->next = NULL;
1258 fmt->avail = &fmt->array.array[0];
1260 memset (fmt->avail, 0, sizeof (*fmt->avail));
1261 fmt->avail->format = FMT_LPAREN;
1262 fmt->avail->repeat = 1;
1263 fmt->avail++;
1265 if (format_lex (fmt) == FMT_LPAREN)
1266 fmt->array.array[0].u.child = parse_format_list (dtp, &format_cache_ok);
1267 else
1268 fmt->error = "Missing initial left parenthesis in format";
1270 if (fmt->error)
1272 format_error (dtp, NULL, fmt->error);
1273 free_format_hash_table (dtp->u.p.current_unit);
1274 return;
1277 if (format_cache_ok)
1278 save_parsed_format (dtp);
1279 else
1280 dtp->u.p.format_not_saved = 1;
1284 /* next_format0()-- Get the next format node without worrying about
1285 * reversion. Returns NULL when we hit the end of the list.
1286 * Parenthesis nodes are incremented after the list has been
1287 * exhausted, other nodes are incremented before they are returned. */
1289 static const fnode *
1290 next_format0 (fnode * f)
1292 const fnode *r;
1294 if (f == NULL)
1295 return NULL;
1297 if (f->format != FMT_LPAREN)
1299 f->count++;
1300 if (f->count <= f->repeat)
1301 return f;
1303 f->count = 0;
1304 return NULL;
1307 /* Deal with a parenthesis node with unlimited format. */
1309 if (f->repeat == -2) /* -2 signifies unlimited. */
1310 for (;;)
1312 if (f->current == NULL)
1313 f->current = f->u.child;
1315 for (; f->current != NULL; f->current = f->current->next)
1317 r = next_format0 (f->current);
1318 if (r != NULL)
1319 return r;
1323 /* Deal with a parenthesis node with specific repeat count. */
1324 for (; f->count < f->repeat; f->count++)
1326 if (f->current == NULL)
1327 f->current = f->u.child;
1329 for (; f->current != NULL; f->current = f->current->next)
1331 r = next_format0 (f->current);
1332 if (r != NULL)
1333 return r;
1337 f->count = 0;
1338 return NULL;
1342 /* next_format()-- Return the next format node. If the format list
1343 * ends up being exhausted, we do reversion. Reversion is only
1344 * allowed if we've seen a data descriptor since the
1345 * initialization or the last reversion. We return NULL if there
1346 * are no more data descriptors to return (which is an error
1347 * condition). */
1349 const fnode *
1350 next_format (st_parameter_dt *dtp)
1352 format_token t;
1353 const fnode *f;
1354 format_data *fmt = dtp->u.p.fmt;
1356 if (fmt->saved_format != NULL)
1357 { /* Deal with a pushed-back format node */
1358 f = fmt->saved_format;
1359 fmt->saved_format = NULL;
1360 goto done;
1363 f = next_format0 (&fmt->array.array[0]);
1364 if (f == NULL)
1366 if (!fmt->reversion_ok)
1367 return NULL;
1369 fmt->reversion_ok = 0;
1370 revert (dtp);
1372 f = next_format0 (&fmt->array.array[0]);
1373 if (f == NULL)
1375 format_error (dtp, NULL, reversion_error);
1376 return NULL;
1379 /* Push the first reverted token and return a colon node in case
1380 * there are no more data items. */
1382 fmt->saved_format = f;
1383 return &colon_node;
1386 /* If this is a data edit descriptor, then reversion has become OK. */
1387 done:
1388 t = f->format;
1390 if (!fmt->reversion_ok &&
1391 (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F ||
1392 t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L ||
1393 t == FMT_A || t == FMT_D))
1394 fmt->reversion_ok = 1;
1395 return f;
1399 /* unget_format()-- Push the given format back so that it will be
1400 * returned on the next call to next_format() without affecting
1401 * counts. This is necessary when we've encountered a data
1402 * descriptor, but don't know what the data item is yet. The format
1403 * node is pushed back, and we return control to the main program,
1404 * which calls the library back with the data item (or not). */
1406 void
1407 unget_format (st_parameter_dt *dtp, const fnode *f)
1409 dtp->u.p.fmt->saved_format = f;