Let the compiler decide whether to inline.
[official-gcc.git] / libgfortran / io / format.c
blob1711a75dd0a5f492282ab3481e051a57cd40c2cf
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 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>
36 #include <stdlib.h>
39 static const fnode colon_node = { FMT_COLON, 0, NULL, NULL, {{ 0, 0, 0 }}, 0,
40 NULL };
42 /* Error messages. */
44 static const char posint_required[] = "Positive width required in format",
45 period_required[] = "Period required in format",
46 nonneg_required[] = "Nonnegative width required in format",
47 unexpected_element[] = "Unexpected element '%c' in format\n",
48 unexpected_end[] = "Unexpected end of format string",
49 bad_string[] = "Unterminated character constant in format",
50 bad_hollerith[] = "Hollerith constant extends past the end of the format",
51 reversion_error[] = "Exhausted data descriptors in format",
52 zero_width[] = "Zero width in format descriptor";
54 /* The following routines support caching format data from parsed format strings
55 into a hash table. This avoids repeatedly parsing duplicate format strings
56 or format strings in I/O statements that are repeated in loops. */
59 /* Traverse the table and free all data. */
61 void
62 free_format_hash_table (gfc_unit *u)
64 size_t i;
66 /* free_format_data handles any NULL pointers. */
67 for (i = 0; i < FORMAT_HASH_SIZE; i++)
69 if (u->format_hash_table[i].hashed_fmt != NULL)
71 free_format_data (u->format_hash_table[i].hashed_fmt);
72 free (u->format_hash_table[i].key);
74 u->format_hash_table[i].key = NULL;
75 u->format_hash_table[i].key_len = 0;
76 u->format_hash_table[i].hashed_fmt = NULL;
80 /* Traverse the format_data structure and reset the fnode counters. */
82 static void
83 reset_node (fnode *fn)
85 fnode *f;
87 fn->count = 0;
88 fn->current = NULL;
90 if (fn->format != FMT_LPAREN)
91 return;
93 for (f = fn->u.child; f; f = f->next)
95 if (f->format == FMT_RPAREN)
96 break;
97 reset_node (f);
101 static void
102 reset_fnode_counters (st_parameter_dt *dtp)
104 fnode *f;
105 format_data *fmt;
107 fmt = dtp->u.p.fmt;
109 /* Clear this pointer at the head so things start at the right place. */
110 fmt->array.array[0].current = NULL;
112 for (f = fmt->array.array[0].u.child; f; f = f->next)
113 reset_node (f);
117 /* A simple hashing function to generate an index into the hash table. */
119 static uint32_t
120 format_hash (st_parameter_dt *dtp)
122 char *key;
123 gfc_charlen_type key_len;
124 uint32_t hash = 0;
125 gfc_charlen_type i;
127 /* Hash the format string. Super simple, but what the heck! */
128 key = dtp->format;
129 key_len = dtp->format_len;
130 for (i = 0; i < key_len; i++)
131 hash ^= key[i];
132 hash &= (FORMAT_HASH_SIZE - 1);
133 return hash;
137 static void
138 save_parsed_format (st_parameter_dt *dtp)
140 uint32_t hash;
141 gfc_unit *u;
143 hash = format_hash (dtp);
144 u = dtp->u.p.current_unit;
146 /* Index into the hash table. We are simply replacing whatever is there
147 relying on probability. */
148 if (u->format_hash_table[hash].hashed_fmt != NULL)
149 free_format_data (u->format_hash_table[hash].hashed_fmt);
150 u->format_hash_table[hash].hashed_fmt = NULL;
152 free (u->format_hash_table[hash].key);
153 u->format_hash_table[hash].key = get_mem (dtp->format_len);
154 memcpy (u->format_hash_table[hash].key, dtp->format, dtp->format_len);
156 u->format_hash_table[hash].key_len = dtp->format_len;
157 u->format_hash_table[hash].hashed_fmt = dtp->u.p.fmt;
161 static format_data *
162 find_parsed_format (st_parameter_dt *dtp)
164 uint32_t hash;
165 gfc_unit *u;
167 hash = format_hash (dtp);
168 u = dtp->u.p.current_unit;
170 if (u->format_hash_table[hash].key != NULL)
172 /* See if it matches. */
173 if (u->format_hash_table[hash].key_len == dtp->format_len)
175 /* So far so good. */
176 if (strncmp (u->format_hash_table[hash].key,
177 dtp->format, dtp->format_len) == 0)
178 return u->format_hash_table[hash].hashed_fmt;
181 return NULL;
185 /* next_char()-- Return the next character in the format string.
186 * Returns -1 when the string is done. If the literal flag is set,
187 * spaces are significant, otherwise they are not. */
189 static int
190 next_char (format_data *fmt, int literal)
192 int c;
196 if (fmt->format_string_len == 0)
197 return -1;
199 fmt->format_string_len--;
200 c = toupper (*fmt->format_string++);
201 fmt->error_element = c;
203 while ((c == ' ' || c == '\t') && !literal);
205 return c;
209 /* unget_char()-- Back up one character position. */
211 #define unget_char(fmt) \
212 { fmt->format_string--; fmt->format_string_len++; }
215 /* get_fnode()-- Allocate a new format node, inserting it into the
216 * current singly linked list. These are initially allocated from the
217 * static buffer. */
219 static fnode *
220 get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t)
222 fnode *f;
224 if (fmt->avail == &fmt->last->array[FARRAY_SIZE])
226 fmt->last->next = get_mem (sizeof (fnode_array));
227 fmt->last = fmt->last->next;
228 fmt->last->next = NULL;
229 fmt->avail = &fmt->last->array[0];
231 f = fmt->avail++;
232 memset (f, '\0', sizeof (fnode));
234 if (*head == NULL)
235 *head = *tail = f;
236 else
238 (*tail)->next = f;
239 *tail = f;
242 f->format = t;
243 f->repeat = -1;
244 f->source = fmt->format_string;
245 return f;
249 /* free_format_data()-- Free all allocated format data. */
251 void
252 free_format_data (format_data *fmt)
254 fnode_array *fa, *fa_next;
257 if (fmt == NULL)
258 return;
260 for (fa = fmt->array.next; fa; fa = fa_next)
262 fa_next = fa->next;
263 free (fa);
266 free (fmt);
267 fmt = NULL;
271 /* format_lex()-- Simple lexical analyzer for getting the next token
272 * in a FORMAT string. We support a one-level token pushback in the
273 * fmt->saved_token variable. */
275 static format_token
276 format_lex (format_data *fmt)
278 format_token token;
279 int negative_flag;
280 int c;
281 char delim;
283 if (fmt->saved_token != FMT_NONE)
285 token = fmt->saved_token;
286 fmt->saved_token = FMT_NONE;
287 return token;
290 negative_flag = 0;
291 c = next_char (fmt, 0);
293 switch (c)
295 case '*':
296 token = FMT_STAR;
297 break;
299 case '(':
300 token = FMT_LPAREN;
301 break;
303 case ')':
304 token = FMT_RPAREN;
305 break;
307 case '-':
308 negative_flag = 1;
309 /* Fall Through */
311 case '+':
312 c = next_char (fmt, 0);
313 if (!isdigit (c))
315 token = FMT_UNKNOWN;
316 break;
319 fmt->value = c - '0';
321 for (;;)
323 c = next_char (fmt, 0);
324 if (!isdigit (c))
325 break;
327 fmt->value = 10 * fmt->value + c - '0';
330 unget_char (fmt);
332 if (negative_flag)
333 fmt->value = -fmt->value;
334 token = FMT_SIGNED_INT;
335 break;
337 case '0':
338 case '1':
339 case '2':
340 case '3':
341 case '4':
342 case '5':
343 case '6':
344 case '7':
345 case '8':
346 case '9':
347 fmt->value = c - '0';
349 for (;;)
351 c = next_char (fmt, 0);
352 if (!isdigit (c))
353 break;
355 fmt->value = 10 * fmt->value + c - '0';
358 unget_char (fmt);
359 token = (fmt->value == 0) ? FMT_ZERO : FMT_POSINT;
360 break;
362 case '.':
363 token = FMT_PERIOD;
364 break;
366 case ',':
367 token = FMT_COMMA;
368 break;
370 case ':':
371 token = FMT_COLON;
372 break;
374 case '/':
375 token = FMT_SLASH;
376 break;
378 case '$':
379 token = FMT_DOLLAR;
380 break;
382 case 'T':
383 switch (next_char (fmt, 0))
385 case 'L':
386 token = FMT_TL;
387 break;
388 case 'R':
389 token = FMT_TR;
390 break;
391 default:
392 token = FMT_T;
393 unget_char (fmt);
394 break;
397 break;
399 case 'X':
400 token = FMT_X;
401 break;
403 case 'S':
404 switch (next_char (fmt, 0))
406 case 'S':
407 token = FMT_SS;
408 break;
409 case 'P':
410 token = FMT_SP;
411 break;
412 default:
413 token = FMT_S;
414 unget_char (fmt);
415 break;
418 break;
420 case 'B':
421 switch (next_char (fmt, 0))
423 case 'N':
424 token = FMT_BN;
425 break;
426 case 'Z':
427 token = FMT_BZ;
428 break;
429 default:
430 token = FMT_B;
431 unget_char (fmt);
432 break;
435 break;
437 case '\'':
438 case '"':
439 delim = c;
441 fmt->string = fmt->format_string;
442 fmt->value = 0; /* This is the length of the string */
444 for (;;)
446 c = next_char (fmt, 1);
447 if (c == -1)
449 token = FMT_BADSTRING;
450 fmt->error = bad_string;
451 break;
454 if (c == delim)
456 c = next_char (fmt, 1);
458 if (c == -1)
460 token = FMT_BADSTRING;
461 fmt->error = bad_string;
462 break;
465 if (c != delim)
467 unget_char (fmt);
468 token = FMT_STRING;
469 break;
473 fmt->value++;
476 break;
478 case 'P':
479 token = FMT_P;
480 break;
482 case 'I':
483 token = FMT_I;
484 break;
486 case 'O':
487 token = FMT_O;
488 break;
490 case 'Z':
491 token = FMT_Z;
492 break;
494 case 'F':
495 token = FMT_F;
496 break;
498 case 'E':
499 switch (next_char (fmt, 0))
501 case 'N':
502 token = FMT_EN;
503 break;
504 case 'S':
505 token = FMT_ES;
506 break;
507 default:
508 token = FMT_E;
509 unget_char (fmt);
510 break;
512 break;
514 case 'G':
515 token = FMT_G;
516 break;
518 case 'H':
519 token = FMT_H;
520 break;
522 case 'L':
523 token = FMT_L;
524 break;
526 case 'A':
527 token = FMT_A;
528 break;
530 case 'D':
531 switch (next_char (fmt, 0))
533 case 'P':
534 token = FMT_DP;
535 break;
536 case 'C':
537 token = FMT_DC;
538 break;
539 default:
540 token = FMT_D;
541 unget_char (fmt);
542 break;
544 break;
546 case 'R':
547 switch (next_char (fmt, 0))
549 case 'C':
550 token = FMT_RC;
551 break;
552 case 'D':
553 token = FMT_RD;
554 break;
555 case 'N':
556 token = FMT_RN;
557 break;
558 case 'P':
559 token = FMT_RP;
560 break;
561 case 'U':
562 token = FMT_RU;
563 break;
564 case 'Z':
565 token = FMT_RZ;
566 break;
567 default:
568 unget_char (fmt);
569 token = FMT_UNKNOWN;
570 break;
572 break;
574 case -1:
575 token = FMT_END;
576 break;
578 default:
579 token = FMT_UNKNOWN;
580 break;
583 return token;
587 /* parse_format_list()-- Parse a format list. Assumes that a left
588 * paren has already been seen. Returns a list representing the
589 * parenthesis node which contains the rest of the list. */
591 static fnode *
592 parse_format_list (st_parameter_dt *dtp, bool *save_ok, bool *seen_dd)
594 fnode *head, *tail;
595 format_token t, u, t2;
596 int repeat;
597 format_data *fmt = dtp->u.p.fmt;
598 bool saveit, seen_data_desc = false;
600 head = tail = NULL;
601 saveit = *save_ok;
603 /* Get the next format item */
604 format_item:
605 t = format_lex (fmt);
606 format_item_1:
607 switch (t)
609 case FMT_STAR:
610 t = format_lex (fmt);
611 if (t != FMT_LPAREN)
613 fmt->error = "Left parenthesis required after '*'";
614 goto finished;
616 get_fnode (fmt, &head, &tail, FMT_LPAREN);
617 tail->repeat = -2; /* Signifies unlimited format. */
618 tail->u.child = parse_format_list (dtp, &saveit, &seen_data_desc);
619 if (fmt->error != NULL)
620 goto finished;
621 if (!seen_data_desc)
623 fmt->error = "'*' requires at least one associated data descriptor";
624 goto finished;
626 goto between_desc;
628 case FMT_POSINT:
629 repeat = fmt->value;
631 t = format_lex (fmt);
632 switch (t)
634 case FMT_LPAREN:
635 get_fnode (fmt, &head, &tail, FMT_LPAREN);
636 tail->repeat = repeat;
637 tail->u.child = parse_format_list (dtp, &saveit, &seen_data_desc);
638 *seen_dd = seen_data_desc;
639 if (fmt->error != NULL)
640 goto finished;
642 goto between_desc;
644 case FMT_SLASH:
645 get_fnode (fmt, &head, &tail, FMT_SLASH);
646 tail->repeat = repeat;
647 goto optional_comma;
649 case FMT_X:
650 get_fnode (fmt, &head, &tail, FMT_X);
651 tail->repeat = 1;
652 tail->u.k = fmt->value;
653 goto between_desc;
655 case FMT_P:
656 goto p_descriptor;
658 default:
659 goto data_desc;
662 case FMT_LPAREN:
663 get_fnode (fmt, &head, &tail, FMT_LPAREN);
664 tail->repeat = 1;
665 tail->u.child = parse_format_list (dtp, &saveit, &seen_data_desc);
666 *seen_dd = seen_data_desc;
667 if (fmt->error != NULL)
668 goto finished;
670 goto between_desc;
672 case FMT_SIGNED_INT: /* Signed integer can only precede a P format. */
673 case FMT_ZERO: /* Same for zero. */
674 t = format_lex (fmt);
675 if (t != FMT_P)
677 fmt->error = "Expected P edit descriptor in format";
678 goto finished;
681 p_descriptor:
682 get_fnode (fmt, &head, &tail, FMT_P);
683 tail->u.k = fmt->value;
684 tail->repeat = 1;
686 t = format_lex (fmt);
687 if (t == FMT_F || t == FMT_EN || t == FMT_ES || t == FMT_D
688 || t == FMT_G || t == FMT_E)
690 repeat = 1;
691 goto data_desc;
694 if (t != FMT_COMMA && t != FMT_RPAREN && t != FMT_SLASH
695 && t != FMT_POSINT)
697 fmt->error = "Comma required after P descriptor";
698 goto finished;
701 fmt->saved_token = t;
702 goto optional_comma;
704 case FMT_P: /* P and X require a prior number */
705 fmt->error = "P descriptor requires leading scale factor";
706 goto finished;
708 case FMT_X:
710 EXTENSION!
712 If we would be pedantic in the library, we would have to reject
713 an X descriptor without an integer prefix:
715 fmt->error = "X descriptor requires leading space count";
716 goto finished;
718 However, this is an extension supported by many Fortran compilers,
719 including Cray, HP, AIX, and IRIX. Therefore, we allow it in the
720 runtime library, and make the front end reject it if the compiler
721 is in pedantic mode. The interpretation of 'X' is '1X'.
723 get_fnode (fmt, &head, &tail, FMT_X);
724 tail->repeat = 1;
725 tail->u.k = 1;
726 goto between_desc;
728 case FMT_STRING:
729 /* TODO: Find out why it is necessary to turn off format caching. */
730 saveit = false;
731 get_fnode (fmt, &head, &tail, FMT_STRING);
732 tail->u.string.p = fmt->string;
733 tail->u.string.length = fmt->value;
734 tail->repeat = 1;
735 goto optional_comma;
737 case FMT_RC:
738 case FMT_RD:
739 case FMT_RN:
740 case FMT_RP:
741 case FMT_RU:
742 case FMT_RZ:
743 notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: Round "
744 "descriptor not allowed");
745 get_fnode (fmt, &head, &tail, t);
746 tail->repeat = 1;
747 goto between_desc;
749 case FMT_DC:
750 case FMT_DP:
751 notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: DC or DP "
752 "descriptor not allowed");
753 /* Fall through. */
754 case FMT_S:
755 case FMT_SS:
756 case FMT_SP:
757 case FMT_BN:
758 case FMT_BZ:
759 get_fnode (fmt, &head, &tail, t);
760 tail->repeat = 1;
761 goto between_desc;
763 case FMT_COLON:
764 get_fnode (fmt, &head, &tail, FMT_COLON);
765 tail->repeat = 1;
766 goto optional_comma;
768 case FMT_SLASH:
769 get_fnode (fmt, &head, &tail, FMT_SLASH);
770 tail->repeat = 1;
771 tail->u.r = 1;
772 goto optional_comma;
774 case FMT_DOLLAR:
775 get_fnode (fmt, &head, &tail, FMT_DOLLAR);
776 tail->repeat = 1;
777 notify_std (&dtp->common, GFC_STD_GNU, "Extension: $ descriptor");
778 goto between_desc;
780 case FMT_T:
781 case FMT_TL:
782 case FMT_TR:
783 t2 = format_lex (fmt);
784 if (t2 != FMT_POSINT)
786 fmt->error = posint_required;
787 goto finished;
789 get_fnode (fmt, &head, &tail, t);
790 tail->u.n = fmt->value;
791 tail->repeat = 1;
792 goto between_desc;
794 case FMT_I:
795 case FMT_B:
796 case FMT_O:
797 case FMT_Z:
798 case FMT_E:
799 case FMT_EN:
800 case FMT_ES:
801 case FMT_D:
802 case FMT_L:
803 case FMT_A:
804 case FMT_F:
805 case FMT_G:
806 repeat = 1;
807 *seen_dd = true;
808 goto data_desc;
810 case FMT_H:
811 get_fnode (fmt, &head, &tail, FMT_STRING);
812 if (fmt->format_string_len < 1)
814 fmt->error = bad_hollerith;
815 goto finished;
818 tail->u.string.p = fmt->format_string;
819 tail->u.string.length = 1;
820 tail->repeat = 1;
822 fmt->format_string++;
823 fmt->format_string_len--;
825 goto between_desc;
827 case FMT_END:
828 fmt->error = unexpected_end;
829 goto finished;
831 case FMT_BADSTRING:
832 goto finished;
834 case FMT_RPAREN:
835 goto finished;
837 default:
838 fmt->error = unexpected_element;
839 goto finished;
842 /* In this state, t must currently be a data descriptor. Deal with
843 things that can/must follow the descriptor */
844 data_desc:
845 switch (t)
847 case FMT_L:
848 t = format_lex (fmt);
849 if (t != FMT_POSINT)
851 if (notification_std(GFC_STD_GNU) == NOTIFICATION_ERROR)
853 fmt->error = posint_required;
854 goto finished;
856 else
858 fmt->saved_token = t;
859 fmt->value = 1; /* Default width */
860 notify_std (&dtp->common, GFC_STD_GNU, posint_required);
864 get_fnode (fmt, &head, &tail, FMT_L);
865 tail->u.n = fmt->value;
866 tail->repeat = repeat;
867 break;
869 case FMT_A:
870 t = format_lex (fmt);
871 if (t == FMT_ZERO)
873 fmt->error = zero_width;
874 goto finished;
877 if (t != FMT_POSINT)
879 fmt->saved_token = t;
880 fmt->value = -1; /* Width not present */
883 get_fnode (fmt, &head, &tail, FMT_A);
884 tail->repeat = repeat;
885 tail->u.n = fmt->value;
886 break;
888 case FMT_D:
889 case FMT_E:
890 case FMT_F:
891 case FMT_G:
892 case FMT_EN:
893 case FMT_ES:
894 get_fnode (fmt, &head, &tail, t);
895 tail->repeat = repeat;
897 u = format_lex (fmt);
898 if (t == FMT_G && u == FMT_ZERO)
900 if (notification_std (GFC_STD_F2008) == NOTIFICATION_ERROR
901 || dtp->u.p.mode == READING)
903 fmt->error = zero_width;
904 goto finished;
906 tail->u.real.w = 0;
907 u = format_lex (fmt);
908 if (u != FMT_PERIOD)
910 fmt->saved_token = u;
911 break;
914 u = format_lex (fmt);
915 if (u != FMT_POSINT)
917 fmt->error = posint_required;
918 goto finished;
920 tail->u.real.d = fmt->value;
921 break;
923 if (t == FMT_F && dtp->u.p.mode == WRITING)
925 if (u != FMT_POSINT && u != FMT_ZERO)
927 fmt->error = nonneg_required;
928 goto finished;
931 else if (u != FMT_POSINT)
933 fmt->error = posint_required;
934 goto finished;
937 tail->u.real.w = fmt->value;
938 t2 = t;
939 t = format_lex (fmt);
940 if (t != FMT_PERIOD)
942 /* We treat a missing decimal descriptor as 0. Note: This is only
943 allowed if -std=legacy, otherwise an error occurs. */
944 if (compile_options.warn_std != 0)
946 fmt->error = period_required;
947 goto finished;
949 fmt->saved_token = t;
950 tail->u.real.d = 0;
951 tail->u.real.e = -1;
952 break;
955 t = format_lex (fmt);
956 if (t != FMT_ZERO && t != FMT_POSINT)
958 fmt->error = nonneg_required;
959 goto finished;
962 tail->u.real.d = fmt->value;
963 tail->u.real.e = -1;
965 if (t2 == FMT_D || t2 == FMT_F)
966 break;
969 /* Look for optional exponent */
970 t = format_lex (fmt);
971 if (t != FMT_E)
972 fmt->saved_token = t;
973 else
975 t = format_lex (fmt);
976 if (t != FMT_POSINT)
978 fmt->error = "Positive exponent width required in format";
979 goto finished;
982 tail->u.real.e = fmt->value;
985 break;
987 case FMT_H:
988 if (repeat > fmt->format_string_len)
990 fmt->error = bad_hollerith;
991 goto finished;
994 get_fnode (fmt, &head, &tail, FMT_STRING);
995 tail->u.string.p = fmt->format_string;
996 tail->u.string.length = repeat;
997 tail->repeat = 1;
999 fmt->format_string += fmt->value;
1000 fmt->format_string_len -= repeat;
1002 break;
1004 case FMT_I:
1005 case FMT_B:
1006 case FMT_O:
1007 case FMT_Z:
1008 get_fnode (fmt, &head, &tail, t);
1009 tail->repeat = repeat;
1011 t = format_lex (fmt);
1013 if (dtp->u.p.mode == READING)
1015 if (t != FMT_POSINT)
1017 fmt->error = posint_required;
1018 goto finished;
1021 else
1023 if (t != FMT_ZERO && t != FMT_POSINT)
1025 fmt->error = nonneg_required;
1026 goto finished;
1030 tail->u.integer.w = fmt->value;
1031 tail->u.integer.m = -1;
1033 t = format_lex (fmt);
1034 if (t != FMT_PERIOD)
1036 fmt->saved_token = t;
1038 else
1040 t = format_lex (fmt);
1041 if (t != FMT_ZERO && t != FMT_POSINT)
1043 fmt->error = nonneg_required;
1044 goto finished;
1047 tail->u.integer.m = fmt->value;
1050 if (tail->u.integer.w != 0 && tail->u.integer.m > tail->u.integer.w)
1052 fmt->error = "Minimum digits exceeds field width";
1053 goto finished;
1056 break;
1058 default:
1059 fmt->error = unexpected_element;
1060 goto finished;
1063 /* Between a descriptor and what comes next */
1064 between_desc:
1065 t = format_lex (fmt);
1066 switch (t)
1068 case FMT_COMMA:
1069 goto format_item;
1071 case FMT_RPAREN:
1072 goto finished;
1074 case FMT_SLASH:
1075 case FMT_COLON:
1076 get_fnode (fmt, &head, &tail, t);
1077 tail->repeat = 1;
1078 goto optional_comma;
1080 case FMT_END:
1081 fmt->error = unexpected_end;
1082 goto finished;
1084 default:
1085 /* Assume a missing comma, this is a GNU extension */
1086 goto format_item_1;
1089 /* Optional comma is a weird between state where we've just finished
1090 reading a colon, slash or P descriptor. */
1091 optional_comma:
1092 t = format_lex (fmt);
1093 switch (t)
1095 case FMT_COMMA:
1096 break;
1098 case FMT_RPAREN:
1099 goto finished;
1101 default: /* Assume that we have another format item */
1102 fmt->saved_token = t;
1103 break;
1106 goto format_item;
1108 finished:
1110 *save_ok = saveit;
1112 return head;
1116 /* format_error()-- Generate an error message for a format statement.
1117 * If the node that gives the location of the error is NULL, the error
1118 * is assumed to happen at parse time, and the current location of the
1119 * parser is shown.
1121 * We generate a message showing where the problem is. We take extra
1122 * care to print only the relevant part of the format if it is longer
1123 * than a standard 80 column display. */
1125 void
1126 format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
1128 int width, i, j, offset;
1129 #define BUFLEN 300
1130 char *p, buffer[BUFLEN];
1131 format_data *fmt = dtp->u.p.fmt;
1133 if (f != NULL)
1134 fmt->format_string = f->source;
1136 if (message == unexpected_element)
1137 snprintf (buffer, BUFLEN, message, fmt->error_element);
1138 else
1139 snprintf (buffer, BUFLEN, "%s\n", message);
1141 j = fmt->format_string - dtp->format;
1143 offset = (j > 60) ? j - 40 : 0;
1145 j -= offset;
1146 width = dtp->format_len - offset;
1148 if (width > 80)
1149 width = 80;
1151 /* Show the format */
1153 p = strchr (buffer, '\0');
1155 memcpy (p, dtp->format + offset, width);
1157 p += width;
1158 *p++ = '\n';
1160 /* Show where the problem is */
1162 for (i = 1; i < j; i++)
1163 *p++ = ' ';
1165 *p++ = '^';
1166 *p = '\0';
1168 generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
1172 /* revert()-- Do reversion of the format. Control reverts to the left
1173 * parenthesis that matches the rightmost right parenthesis. From our
1174 * tree structure, we are looking for the rightmost parenthesis node
1175 * at the second level, the first level always being a single
1176 * parenthesis node. If this node doesn't exit, we use the top
1177 * level. */
1179 static void
1180 revert (st_parameter_dt *dtp)
1182 fnode *f, *r;
1183 format_data *fmt = dtp->u.p.fmt;
1185 dtp->u.p.reversion_flag = 1;
1187 r = NULL;
1189 for (f = fmt->array.array[0].u.child; f; f = f->next)
1190 if (f->format == FMT_LPAREN)
1191 r = f;
1193 /* If r is NULL because no node was found, the whole tree will be used */
1195 fmt->array.array[0].current = r;
1196 fmt->array.array[0].count = 0;
1199 /* parse_format()-- Parse a format string. */
1201 void
1202 parse_format (st_parameter_dt *dtp)
1204 format_data *fmt;
1205 bool format_cache_ok, seen_data_desc = false;
1207 /* Don't cache for internal units and set an arbitrary limit on the size of
1208 format strings we will cache. (Avoids memory issues.) */
1209 format_cache_ok = !is_internal_unit (dtp);
1211 /* Lookup format string to see if it has already been parsed. */
1212 if (format_cache_ok)
1214 dtp->u.p.fmt = find_parsed_format (dtp);
1216 if (dtp->u.p.fmt != NULL)
1218 dtp->u.p.fmt->reversion_ok = 0;
1219 dtp->u.p.fmt->saved_token = FMT_NONE;
1220 dtp->u.p.fmt->saved_format = NULL;
1221 reset_fnode_counters (dtp);
1222 return;
1226 /* Not found so proceed as follows. */
1228 dtp->u.p.fmt = fmt = get_mem (sizeof (format_data));
1229 fmt->format_string = dtp->format;
1230 fmt->format_string_len = dtp->format_len;
1232 fmt->string = NULL;
1233 fmt->saved_token = FMT_NONE;
1234 fmt->error = NULL;
1235 fmt->value = 0;
1237 /* Initialize variables used during traversal of the tree. */
1239 fmt->reversion_ok = 0;
1240 fmt->saved_format = NULL;
1242 /* Allocate the first format node as the root of the tree. */
1244 fmt->last = &fmt->array;
1245 fmt->last->next = NULL;
1246 fmt->avail = &fmt->array.array[0];
1248 memset (fmt->avail, 0, sizeof (*fmt->avail));
1249 fmt->avail->format = FMT_LPAREN;
1250 fmt->avail->repeat = 1;
1251 fmt->avail++;
1253 if (format_lex (fmt) == FMT_LPAREN)
1254 fmt->array.array[0].u.child = parse_format_list (dtp, &format_cache_ok,
1255 &seen_data_desc);
1256 else
1257 fmt->error = "Missing initial left parenthesis in format";
1259 if (fmt->error)
1261 format_error (dtp, NULL, fmt->error);
1262 free_format_hash_table (dtp->u.p.current_unit);
1263 return;
1266 if (format_cache_ok)
1267 save_parsed_format (dtp);
1268 else
1269 dtp->u.p.format_not_saved = 1;
1273 /* next_format0()-- Get the next format node without worrying about
1274 * reversion. Returns NULL when we hit the end of the list.
1275 * Parenthesis nodes are incremented after the list has been
1276 * exhausted, other nodes are incremented before they are returned. */
1278 static const fnode *
1279 next_format0 (fnode * f)
1281 const fnode *r;
1283 if (f == NULL)
1284 return NULL;
1286 if (f->format != FMT_LPAREN)
1288 f->count++;
1289 if (f->count <= f->repeat)
1290 return f;
1292 f->count = 0;
1293 return NULL;
1296 /* Deal with a parenthesis node with unlimited format. */
1298 if (f->repeat == -2) /* -2 signifies unlimited. */
1299 for (;;)
1301 if (f->current == NULL)
1302 f->current = f->u.child;
1304 for (; f->current != NULL; f->current = f->current->next)
1306 r = next_format0 (f->current);
1307 if (r != NULL)
1308 return r;
1312 /* Deal with a parenthesis node with specific repeat count. */
1313 for (; f->count < f->repeat; f->count++)
1315 if (f->current == NULL)
1316 f->current = f->u.child;
1318 for (; f->current != NULL; f->current = f->current->next)
1320 r = next_format0 (f->current);
1321 if (r != NULL)
1322 return r;
1326 f->count = 0;
1327 return NULL;
1331 /* next_format()-- Return the next format node. If the format list
1332 * ends up being exhausted, we do reversion. Reversion is only
1333 * allowed if we've seen a data descriptor since the
1334 * initialization or the last reversion. We return NULL if there
1335 * are no more data descriptors to return (which is an error
1336 * condition). */
1338 const fnode *
1339 next_format (st_parameter_dt *dtp)
1341 format_token t;
1342 const fnode *f;
1343 format_data *fmt = dtp->u.p.fmt;
1345 if (fmt->saved_format != NULL)
1346 { /* Deal with a pushed-back format node */
1347 f = fmt->saved_format;
1348 fmt->saved_format = NULL;
1349 goto done;
1352 f = next_format0 (&fmt->array.array[0]);
1353 if (f == NULL)
1355 if (!fmt->reversion_ok)
1356 return NULL;
1358 fmt->reversion_ok = 0;
1359 revert (dtp);
1361 f = next_format0 (&fmt->array.array[0]);
1362 if (f == NULL)
1364 format_error (dtp, NULL, reversion_error);
1365 return NULL;
1368 /* Push the first reverted token and return a colon node in case
1369 * there are no more data items. */
1371 fmt->saved_format = f;
1372 return &colon_node;
1375 /* If this is a data edit descriptor, then reversion has become OK. */
1376 done:
1377 t = f->format;
1379 if (!fmt->reversion_ok &&
1380 (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F ||
1381 t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L ||
1382 t == FMT_A || t == FMT_D))
1383 fmt->reversion_ok = 1;
1384 return f;
1388 /* unget_format()-- Push the given format back so that it will be
1389 * returned on the next call to next_format() without affecting
1390 * counts. This is necessary when we've encountered a data
1391 * descriptor, but don't know what the data item is yet. The format
1392 * node is pushed back, and we return control to the main program,
1393 * which calls the library back with the data item (or not). */
1395 void
1396 unget_format (st_parameter_dt *dtp, const fnode *f)
1398 dtp->u.p.fmt->saved_format = f;