]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/io/format.c
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
);
559 get_fnode (&head
, &tail
, FMT_COLON
);
563 get_fnode (&head
, &tail
, FMT_SLASH
);
569 get_fnode (&head
, &tail
, FMT_DOLLAR
);
576 if (t2
!= FMT_POSINT
)
578 error
= posint_required
;
581 get_fnode (&head
, &tail
, t
);
602 get_fnode (&head
, &tail
, FMT_STRING
);
604 if (format_string_len
< 1)
606 error
= bad_hollerith
;
610 tail
->u
.string
.p
= format_string
;
611 tail
->u
.string
.length
= 1;
620 error
= unexpected_end
;
630 error
= unexpected_element
;
634 /* In this state, t must currently be a data descriptor. Deal with
635 * things that can/must follow the descriptor */
644 error
= "Repeat count cannot follow P descriptor";
649 get_fnode (&head
, &tail
, FMT_P
);
657 error
= posint_required
;
661 get_fnode (&head
, &tail
, FMT_L
);
663 tail
->repeat
= repeat
;
671 value
= -1; /* Width not present */
674 get_fnode (&head
, &tail
, FMT_A
);
675 tail
->repeat
= repeat
;
685 get_fnode (&head
, &tail
, t
);
686 tail
->repeat
= repeat
;
689 if (t
== FMT_F
|| g
.mode
== WRITING
)
691 if (u
!= FMT_POSINT
&& u
!= FMT_ZERO
)
693 error
= nonneg_required
;
701 error
= posint_required
;
706 tail
->u
.real
.w
= value
;
711 error
= period_required
;
716 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
718 error
= nonneg_required
;
722 tail
->u
.real
.d
= value
;
724 if (t
== FMT_D
|| t
== FMT_F
)
729 /* Look for optional exponent */
739 error
= "Positive exponent width required in format";
743 tail
->u
.real
.e
= value
;
749 if (repeat
> format_string_len
)
751 error
= bad_hollerith
;
755 get_fnode (&head
, &tail
, FMT_STRING
);
757 tail
->u
.string
.p
= format_string
;
758 tail
->u
.string
.length
= repeat
;
761 format_string
+= value
;
762 format_string_len
-= repeat
;
770 get_fnode (&head
, &tail
, t
);
771 tail
->repeat
= repeat
;
775 if (g
.mode
== READING
)
779 error
= posint_required
;
785 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
787 error
= nonneg_required
;
792 tail
->u
.integer
.w
= value
;
793 tail
->u
.integer
.m
= -1;
803 if (t
!= FMT_ZERO
&& t
!= FMT_POSINT
)
805 error
= nonneg_required
;
809 tail
->u
.integer
.m
= value
;
812 if (tail
->u
.integer
.w
!= 0 && tail
->u
.integer
.m
> tail
->u
.integer
.w
)
814 error
= "Minimum digits exceeds field width";
821 error
= unexpected_element
;
825 /* Between a descriptor and what comes next */
837 get_fnode (&head
, &tail
, FMT_SLASH
);
846 error
= unexpected_end
;
850 error
= "Missing comma in format";
854 /* Optional comma is a weird between state where we've just finished
855 * reading a colon, slash or P descriptor. */
867 default: /* Assume that we have another format item */
879 /* format_error()-- Generate an error message for a format statement.
880 * If the node that gives the location of the error is NULL, the error
881 * is assumed to happen at parse time, and the current location of the
884 * After freeing any dynamically allocated fnodes, generate a message
885 * showing where the problem is. We take extra care to print only the
886 * relevant part of the format if it is longer than a standard 80
890 format_error (fnode
* f
, const char *message
)
892 int width
, i
, j
, offset
;
893 char *p
, buffer
[300];
896 format_string
= f
->source
;
900 st_sprintf (buffer
, "%s\n", message
);
902 j
= format_string
- ioparm
.format
;
904 offset
= (j
> 60) ? j
- 40 : 0;
907 width
= ioparm
.format_len
- offset
;
912 /* Show the format */
914 p
= strchr (buffer
, '\0');
916 memcpy (p
, ioparm
.format
+ offset
, width
);
921 /* Show where the problem is */
923 for (i
= 1; i
< j
; i
++)
929 generate_error (ERROR_FORMAT
, buffer
);
933 /* parse_format()-- Parse a format string. */
939 format_string
= ioparm
.format
;
940 format_string_len
= ioparm
.format_len
;
942 saved_token
= FMT_NONE
;
945 /* Initialize variables used during traversal of the tree */
948 g
.reversion_flag
= 0;
951 /* Allocate the first format node as the root of the tree */
955 avail
->format
= FMT_LPAREN
;
959 if (format_lex () == FMT_LPAREN
)
960 array
[0].u
.child
= parse_format_list ();
962 error
= "Missing initial left parenthesis in format";
965 format_error (NULL
, error
);
969 /* revert()-- Do reversion of the format. Control reverts to the left
970 * parenthesis that matches the rightmost right parenthesis. From our
971 * tree structure, we are looking for the rightmost parenthesis node
972 * at the second level, the first level always being a single
973 * parenthesis node. If this node doesn't exit, we use the top
981 g
.reversion_flag
= 1;
985 for (f
= array
[0].u
.child
; f
; f
= f
->next
)
986 if (f
->format
== FMT_LPAREN
)
989 /* If r is NULL because no node was found, the whole tree will be used */
991 array
[0].current
= r
;
996 /* next_format0()-- Get the next format node without worrying about
997 * reversion. Returns NULL when we hit the end of the list.
998 * Parenthesis nodes are incremented after the list has been
999 * exhausted, other nodes are incremented before they are returned. */
1002 next_format0 (fnode
* f
)
1009 if (f
->format
!= FMT_LPAREN
)
1012 if (f
->count
<= f
->repeat
)
1019 /* Deal with a parenthesis node */
1021 for (; f
->count
< f
->repeat
; f
->count
++)
1023 if (f
->current
== NULL
)
1024 f
->current
= f
->u
.child
;
1026 for (; f
->current
!= NULL
; f
->current
= f
->current
->next
)
1028 r
= next_format0 (f
->current
);
1039 /* next_format()-- Return the next format node. If the format list
1040 * ends up being exhausted, we do reversion. Reversion is only
1041 * allowed if the we've seen a data descriptor since the
1042 * initialization or the last reversion. We return NULL if the there
1043 * are no more data descriptors to return (which is an error
1052 if (saved_format
!= NULL
)
1053 { /* Deal with a pushed-back format node */
1055 saved_format
= NULL
;
1059 f
= next_format0 (&array
[0]);
1070 f
= next_format0 (&array
[0]);
1073 format_error (NULL
, reversion_error
);
1077 /* Push the first reverted token and return a colon node in case
1078 * there are no more data items. */
1084 /* If this is a data edit descriptor, then reversion has become OK. */
1089 if (!reversion_ok
&&
1090 (t
== FMT_I
|| t
== FMT_B
|| t
== FMT_O
|| t
== FMT_Z
|| t
== FMT_F
||
1091 t
== FMT_E
|| t
== FMT_EN
|| t
== FMT_ES
|| t
== FMT_G
|| t
== FMT_L
||
1092 t
== FMT_A
|| t
== FMT_D
))
1098 /* unget_format()-- Push the given format back so that it will be
1099 * returned on the next call to next_format() without affecting
1100 * counts. This is necessary when we've encountered a data
1101 * descriptor, but don't know what the data item is yet. The format
1102 * node is pushed back, and we return control to the main program,
1103 * which calls the library back with the data item (or not). */
1106 unget_format (fnode
* f
)
1117 static void dump_format1 (fnode
* f
);
1119 /* dump_format0()-- Dump a single format node */
1122 dump_format0 (fnode
* f
)
1133 st_printf (" %d/", f
->u
.r
);
1139 st_printf (" T%d", f
->u
.n
);
1142 st_printf (" TR%d", f
->u
.n
);
1145 st_printf (" TL%d", f
->u
.n
);
1148 st_printf (" %dX", f
->u
.n
);
1164 st_printf (" %d(", f
->repeat
);
1166 dump_format1 (f
->u
.child
);
1173 for (i
= f
->u
.string
.length
; i
> 0; i
--)
1174 st_printf ("%c", *p
++);
1180 st_printf (" %dP", f
->u
.k
);
1183 st_printf (" %dI%d.%d", f
->repeat
, f
->u
.integer
.w
, f
->u
.integer
.m
);
1187 st_printf (" %dB%d.%d", f
->repeat
, f
->u
.integer
.w
, f
->u
.integer
.m
);
1191 st_printf (" %dO%d.%d", f
->repeat
, f
->u
.integer
.w
, f
->u
.integer
.m
);
1195 st_printf (" %dZ%d.%d", f
->repeat
, f
->u
.integer
.w
, f
->u
.integer
.m
);
1205 st_printf (" %dD%d.%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
);
1209 st_printf (" %dEN%d.%dE%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
,
1214 st_printf (" %dES%d.%dE%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
,
1219 st_printf (" %dF%d.%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
);
1223 st_printf (" %dE%d.%dE%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
,
1228 st_printf (" %dG%d.%dE%d", f
->repeat
, f
->u
.real
.w
, f
->u
.real
.d
,
1233 st_printf (" %dL%d", f
->repeat
, f
->u
.w
);
1236 st_printf (" %dA%d", f
->repeat
, f
->u
.w
);
1246 /* dump_format1()-- Dump a string of format nodes */
1249 dump_format1 (fnode
* f
)
1252 for (; f
; f
= f
->next
)
1256 /* dump_format()-- Dump the whole format node tree */
1262 st_printf ("format = ");
1263 dump_format0 (&array
[0]);
1274 for (i
= 0; i
< 20; i
++)
1279 st_printf ("No format!\n");