1 /* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
4 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6 Libgfortran is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Libgfortran; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 /* format.c-- parse a FORMAT string into a binary format suitable for
23 * interpretation during I/O statements */
28 #include "libgfortran.h"
33 /* Number of format nodes that we can store statically before we have
34 * to resort to dynamic allocation. The root node is array[0]. */
36 #define FARRAY_SIZE 200
38 static fnode
*avail
, array
[FARRAY_SIZE
];
40 /* Local variables for checking format strings. The saved_token is
41 * used to back up by a single format token during the parsing process. */
43 static char *format_string
, *string
;
44 static const char *error
;
45 static format_token saved_token
;
46 static int value
, format_string_len
, reversion_ok
;
48 static fnode
*saved_format
, colon_node
= { FMT_COLON
};
52 static char posint_required
[] = "Positive width required in format",
53 period_required
[] = "Period required in format",
54 nonneg_required
[] = "Nonnegative width required in format",
55 unexpected_element
[] = "Unexpected element in format",
56 unexpected_end
[] = "Unexpected end of format string",
57 bad_string
[] = "Unterminated character constant in format",
58 bad_hollerith
[] = "Hollerith constant extends past the end of the format",
59 reversion_error
[] = "Exhausted data descriptors in format";
62 /* next_char()-- Return the next character in the format string.
63 * Returns -1 when the string is done. If the literal flag is set,
64 * spaces are significant, otherwise they are not. */
67 next_char (int literal
)
73 if (format_string_len
== 0)
77 c
= toupper (*format_string
++);
79 while (c
== ' ' && !literal
);
85 /* unget_char()-- Back up one character position. */
87 #define unget_char() { format_string--; format_string_len++; }
90 /* get_fnode()-- Allocate a new format node, inserting it into the
91 * current singly linked list. These are initially allocated from the
95 get_fnode (fnode
** head
, fnode
** tail
, format_token t
)
99 if (avail
- array
>= FARRAY_SIZE
)
100 f
= get_mem (sizeof (fnode
));
104 memset (f
, '\0', sizeof (fnode
));
117 f
->source
= format_string
;
122 /* free_fnode()-- Recursive function to free the given fnode and
123 * everything it points to. We only have to actually free something
124 * if it is outside of the static array. */
127 free_fnode (fnode
* f
)
135 if (f
->format
== FMT_LPAREN
)
136 free_fnode (f
->u
.child
);
137 if (f
< array
|| f
>= array
+ FARRAY_SIZE
)
143 /* free_fnodes()-- Free the current tree of fnodes. We only have to
144 * traverse the tree if some nodes were allocated dynamically. */
150 if (avail
- array
>= FARRAY_SIZE
)
151 free_fnode (&array
[0]);
154 memset(array
, 0, sizeof(avail
[0]) * FARRAY_SIZE
);
158 /* format_lex()-- Simple lexical analyzer for getting the next token
159 * in a FORMAT string. We support a one-level token pushback in the
160 * saved_token variable. */
170 if (saved_token
!= FMT_NONE
)
173 saved_token
= FMT_NONE
;
202 value
= 10 * value
+ c
- '0';
209 token
= FMT_SIGNED_INT
;
230 value
= 10 * value
+ c
- '0';
234 token
= (value
== 0) ? FMT_ZERO
: FMT_POSINT
;
258 switch (next_char (0))
287 switch (next_char (0))
304 switch (next_char (0))
324 string
= format_string
;
325 value
= 0; /* This is the length of the string */
332 token
= FMT_BADSTRING
;
343 token
= FMT_BADSTRING
;
382 switch (next_char (0))
431 /* parse_format_list()-- Parse a format list. Assumes that a left
432 * paren has already been seen. Returns a list representing the
433 * parenthesis node which contains the rest of the list. */
436 parse_format_list (void)
439 format_token t
, u
, t2
;
444 /* Get the next format item */
457 get_fnode (&head
, &tail
, FMT_LPAREN
);
458 tail
->repeat
= repeat
;
459 tail
->u
.child
= parse_format_list ();
466 get_fnode (&head
, &tail
, FMT_SLASH
);
467 tail
->repeat
= repeat
;
471 get_fnode (&head
, &tail
, FMT_X
);
484 get_fnode (&head
, &tail
, FMT_LPAREN
);
486 tail
->u
.child
= parse_format_list ();
492 case FMT_SIGNED_INT
: /* Signed integer can only precede a P format. */
493 case FMT_ZERO
: /* Same for zero. */
497 error
= "Expected P edit descriptor in format";
502 get_fnode (&head
, &tail
, FMT_P
);
507 if (t
== FMT_F
|| t
== FMT_EN
|| t
== FMT_ES
|| t
== FMT_D
508 || t
== FMT_G
|| t
== FMT_E
)
517 case FMT_P
: /* P and X require a prior number */
518 error
= "P descriptor requires leading scale factor";
525 If we would be pedantic in the library, we would have to reject
526 an X descriptor without an integer prefix:
528 error = "X descriptor requires leading space count";
531 However, this is an extension supported by many Fortran compilers,
532 including Cray, HP, AIX, and IRIX. Therefore, we allow it in the
533 runtime library, and make the front end reject it if the compiler
534 is in pedantic mode. The interpretation of 'X' is '1X'.
536 get_fnode (&head
, &tail
, FMT_X
);
542 get_fnode (&head
, &tail
, FMT_STRING
);
544 tail
->u
.string
.p
= string
;
545 tail
->u
.string
.length
= value
;
554 get_fnode (&head
, &tail
, t
);
558 get_fnode (&head
, &tail
, FMT_COLON
);
562 get_fnode (&head
, &tail
, FMT_SLASH
);
568 get_fnode (&head
, &tail
, FMT_DOLLAR
);
575 if (t2
!= FMT_POSINT
)
577 error
= posint_required
;
580 get_fnode (&head
, &tail
, t
);
601 get_fnode (&head
, &tail
, FMT_STRING
);
603 if (format_string_len
< 1)
605 error
= bad_hollerith
;
609 tail
->u
.string
.p
= format_string
;
610 tail
->u
.string
.length
= 1;
619 error
= unexpected_end
;
629 error
= unexpected_element
;
633 /* In this state, t must currently be a data descriptor. Deal with
634 * things that can/must follow the descriptor */
643 error
= "Repeat count cannot follow P descriptor";
648 get_fnode (&head
, &tail
, FMT_P
);
656 error
= posint_required
;
660 get_fnode (&head
, &tail
, FMT_L
);
662 tail
->repeat
= repeat
;
670 value
= -1; /* Width not present */
673 get_fnode (&head
, &tail
, FMT_A
);
674 tail
->repeat
= repeat
;
684 get_fnode (&head
, &tail
, t
);
685 tail
->repeat
= repeat
;
688 if (t
== FMT_F
|| g
.mode
== WRITING
)
690 if (u
!= FMT_POSINT
&& u
!= FMT_ZERO
)
692 error
= nonneg_required
;
700 error
= posint_required
;
705 tail
->u
.real
.w
= value
;
710 error
= period_required
;
715 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
717 error
= nonneg_required
;
721 tail
->u
.real
.d
= value
;
723 if (t
== FMT_D
|| t
== FMT_F
)
728 /* Look for optional exponent */
738 error
= "Positive exponent width required in format";
742 tail
->u
.real
.e
= value
;
748 if (repeat
> format_string_len
)
750 error
= bad_hollerith
;
754 get_fnode (&head
, &tail
, FMT_STRING
);
756 tail
->u
.string
.p
= format_string
;
757 tail
->u
.string
.length
= repeat
;
760 format_string
+= value
;
761 format_string_len
-= repeat
;
769 get_fnode (&head
, &tail
, t
);
770 tail
->repeat
= repeat
;
774 if (g
.mode
== READING
)
778 error
= posint_required
;
784 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
786 error
= nonneg_required
;
791 tail
->u
.integer
.w
= value
;
792 tail
->u
.integer
.m
= -1;
802 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
804 error
= nonneg_required
;
808 tail
->u
.integer
.m
= value
;
811 if (tail
->u
.integer
.w
!= 0 && tail
->u
.integer
.m
> tail
->u
.integer
.w
)
813 error
= "Minimum digits exceeds field width";
820 error
= unexpected_element
;
824 /* Between a descriptor and what comes next */
836 get_fnode (&head
, &tail
, FMT_SLASH
);
845 error
= unexpected_end
;
849 error
= "Missing comma in format";
853 /* Optional comma is a weird between state where we've just finished
854 * reading a colon, slash or P descriptor. */
866 default: /* Assume that we have another format item */
878 /* format_error()-- Generate an error message for a format statement.
879 * If the node that gives the location of the error is NULL, the error
880 * is assumed to happen at parse time, and the current location of the
883 * After freeing any dynamically allocated fnodes, generate a message
884 * showing where the problem is. We take extra care to print only the
885 * relevant part of the format if it is longer than a standard 80
889 format_error (fnode
* f
, const char *message
)
891 int width
, i
, j
, offset
;
892 char *p
, buffer
[300];
895 format_string
= f
->source
;
899 st_sprintf (buffer
, "%s\n", message
);
901 j
= format_string
- ioparm
.format
;
903 offset
= (j
> 60) ? j
- 40 : 0;
906 width
= ioparm
.format_len
- offset
;
911 /* Show the format */
913 p
= strchr (buffer
, '\0');
915 memcpy (p
, ioparm
.format
+ offset
, width
);
920 /* Show where the problem is */
922 for (i
= 1; i
< j
; i
++)
928 generate_error (ERROR_FORMAT
, buffer
);
932 /* parse_format()-- Parse a format string. */
938 format_string
= ioparm
.format
;
939 format_string_len
= ioparm
.format_len
;
941 saved_token
= FMT_NONE
;
944 /* Initialize variables used during traversal of the tree */
947 g
.reversion_flag
= 0;
950 /* Allocate the first format node as the root of the tree */
954 avail
->format
= FMT_LPAREN
;
958 if (format_lex () == FMT_LPAREN
)
959 array
[0].u
.child
= parse_format_list ();
961 error
= "Missing initial left parenthesis in format";
964 format_error (NULL
, error
);
968 /* revert()-- Do reversion of the format. Control reverts to the left
969 * parenthesis that matches the rightmost right parenthesis. From our
970 * tree structure, we are looking for the rightmost parenthesis node
971 * at the second level, the first level always being a single
972 * parenthesis node. If this node doesn't exit, we use the top
980 g
.reversion_flag
= 1;
984 for (f
= array
[0].u
.child
; f
; f
= f
->next
)
985 if (f
->format
== FMT_LPAREN
)
988 /* If r is NULL because no node was found, the whole tree will be used */
990 array
[0].current
= r
;
995 /* next_format0()-- Get the next format node without worrying about
996 * reversion. Returns NULL when we hit the end of the list.
997 * Parenthesis nodes are incremented after the list has been
998 * exhausted, other nodes are incremented before they are returned. */
1001 next_format0 (fnode
* f
)
1008 if (f
->format
!= FMT_LPAREN
)
1011 if (f
->count
<= f
->repeat
)
1018 /* Deal with a parenthesis node */
1020 for (; f
->count
< f
->repeat
; f
->count
++)
1022 if (f
->current
== NULL
)
1023 f
->current
= f
->u
.child
;
1025 for (; f
->current
!= NULL
; f
->current
= f
->current
->next
)
1027 r
= next_format0 (f
->current
);
1038 /* next_format()-- Return the next format node. If the format list
1039 * ends up being exhausted, we do reversion. Reversion is only
1040 * allowed if the we've seen a data descriptor since the
1041 * initialization or the last reversion. We return NULL if the there
1042 * are no more data descriptors to return (which is an error
1051 if (saved_format
!= NULL
)
1052 { /* Deal with a pushed-back format node */
1054 saved_format
= NULL
;
1058 f
= next_format0 (&array
[0]);
1069 f
= next_format0 (&array
[0]);
1072 format_error (NULL
, reversion_error
);
1076 /* Push the first reverted token and return a colon node in case
1077 * there are no more data items. */
1083 /* If this is a data edit descriptor, then reversion has become OK. */
1088 if (!reversion_ok
&&
1089 (t
== FMT_I
|| t
== FMT_B
|| t
== FMT_O
|| t
== FMT_Z
|| t
== FMT_F
||
1090 t
== FMT_E
|| t
== FMT_EN
|| t
== FMT_ES
|| t
== FMT_G
|| t
== FMT_L
||
1091 t
== FMT_A
|| t
== FMT_D
))
1097 /* unget_format()-- Push the given format back so that it will be
1098 * returned on the next call to next_format() without affecting
1099 * counts. This is necessary when we've encountered a data
1100 * descriptor, but don't know what the data item is yet. The format
1101 * node is pushed back, and we return control to the main program,
1102 * which calls the library back with the data item (or not). */
1105 unget_format (fnode
* f
)
1116 static void dump_format1 (fnode
* f
);
1118 /* dump_format0()-- Dump a single format node */
1121 dump_format0 (fnode
* f
)
1132 st_printf (" %d/", f
->u
.r
);
1138 st_printf (" T%d", f
->u
.n
);
1141 st_printf (" TR%d", f
->u
.n
);
1144 st_printf (" TL%d", f
->u
.n
);
1147 st_printf (" %dX", f
->u
.n
);
1163 st_printf (" %d(", f
->repeat
);
1165 dump_format1 (f
->u
.child
);
1172 for (i
= f
->u
.string
.length
; i
> 0; i
--)
1173 st_printf ("%c", *p
++);
1179 st_printf (" %dP", f
->u
.k
);
1182 st_printf (" %dI%d.%d", f
->repeat
, f
->u
.integer
.w
, f
->u
.integer
.m
);
1186 st_printf (" %dB%d.%d", f
->repeat
, f
->u
.integer
.w
, f
->u
.integer
.m
);
1190 st_printf (" %dO%d.%d", f
->repeat
, f
->u
.integer
.w
, f
->u
.integer
.m
);
1194 st_printf (" %dZ%d.%d", f
->repeat
, f
->u
.integer
.w
, f
->u
.integer
.m
);
1204 st_printf (" %dD%d.%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
);
1208 st_printf (" %dEN%d.%dE%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
,
1213 st_printf (" %dES%d.%dE%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
,
1218 st_printf (" %dF%d.%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
);
1222 st_printf (" %dE%d.%dE%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
,
1227 st_printf (" %dG%d.%dE%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
,
1232 st_printf (" %dL%d", f
->repeat
, f
->u
.w
);
1235 st_printf (" %dA%d", f
->repeat
, f
->u
.w
);
1245 /* dump_format1()-- Dump a string of format nodes */
1248 dump_format1 (fnode
* f
)
1251 for (; f
; f
= f
->next
)
1255 /* dump_format()-- Dump the whole format node tree */
1261 st_printf ("format = ");
1262 dump_format0 (&array
[0]);
1273 for (i
= 0; i
< 20; i
++)
1278 st_printf ("No format!\n");