1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 Namelist output contributed by Paul Thomas
5 This file is part of the GNU Fortran 95 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 2, or (at your option)
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
21 Libgfortran is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with Libgfortran; see the file COPYING. If not, write to
28 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA. */
37 #define star_fill(p, n) memset(p, '*', n)
39 #include "write_float.def"
42 write_a (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
47 wlen
= f
->u
.string
.length
< 0 ? len
: f
->u
.string
.length
;
50 /* If this is formatted STREAM IO convert any embedded line feed characters
51 to CR_LF on systems that use that sequence for newlines. See F2003
52 Standard sections 10.6.3 and 9.9 for further information. */
53 if (is_stream_io (dtp
))
55 const char crlf
[] = "\r\n";
59 /* Write out any padding if needed. */
62 p
= write_block (dtp
, wlen
- len
);
65 memset (p
, ' ', wlen
- len
);
68 /* Scan the source string looking for '\n' and convert it if found. */
69 for (i
= 0; i
< wlen
; i
++)
71 if (source
[i
] == '\n')
73 /* Write out the previously scanned characters in the string. */
76 p
= write_block (dtp
, bytes
);
79 memcpy (p
, &source
[q
], bytes
);
84 /* Write out the CR_LF sequence. */
86 p
= write_block (dtp
, 2);
95 /* Write out any remaining bytes if no LF was found. */
98 p
= write_block (dtp
, bytes
);
101 memcpy (p
, &source
[q
], bytes
);
107 p
= write_block (dtp
, wlen
);
112 memcpy (p
, source
, wlen
);
115 memset (p
, ' ', wlen
- len
);
116 memcpy (p
+ wlen
- len
, source
, len
);
123 static GFC_INTEGER_LARGEST
124 extract_int (const void *p
, int len
)
126 GFC_INTEGER_LARGEST i
= 0;
136 memcpy ((void *) &tmp
, p
, len
);
143 memcpy ((void *) &tmp
, p
, len
);
150 memcpy ((void *) &tmp
, p
, len
);
157 memcpy ((void *) &tmp
, p
, len
);
161 #ifdef HAVE_GFC_INTEGER_16
165 memcpy ((void *) &tmp
, p
, len
);
171 internal_error (NULL
, "bad integer kind");
177 static GFC_UINTEGER_LARGEST
178 extract_uint (const void *p
, int len
)
180 GFC_UINTEGER_LARGEST i
= 0;
190 memcpy ((void *) &tmp
, p
, len
);
191 i
= (GFC_UINTEGER_1
) tmp
;
197 memcpy ((void *) &tmp
, p
, len
);
198 i
= (GFC_UINTEGER_2
) tmp
;
204 memcpy ((void *) &tmp
, p
, len
);
205 i
= (GFC_UINTEGER_4
) tmp
;
211 memcpy ((void *) &tmp
, p
, len
);
212 i
= (GFC_UINTEGER_8
) tmp
;
215 #ifdef HAVE_GFC_INTEGER_16
219 memcpy ((void *) &tmp
, p
, len
);
220 i
= (GFC_UINTEGER_16
) tmp
;
225 internal_error (NULL
, "bad integer kind");
233 write_l (st_parameter_dt
*dtp
, const fnode
*f
, char *source
, int len
)
236 GFC_INTEGER_LARGEST n
;
238 p
= write_block (dtp
, f
->u
.w
);
242 memset (p
, ' ', f
->u
.w
- 1);
243 n
= extract_int (source
, len
);
244 p
[f
->u
.w
- 1] = (n
) ? 'T' : 'F';
249 write_int (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
,
250 const char *(*conv
) (GFC_UINTEGER_LARGEST
, char *, size_t))
252 GFC_UINTEGER_LARGEST n
= 0;
253 int w
, m
, digits
, nzero
, nblank
;
256 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
261 n
= extract_uint (source
, len
);
265 if (m
== 0 && n
== 0)
270 p
= write_block (dtp
, w
);
278 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
281 /* Select a width if none was specified. The idea here is to always
285 w
= ((digits
< m
) ? m
: digits
);
287 p
= write_block (dtp
, w
);
295 /* See if things will work. */
297 nblank
= w
- (nzero
+ digits
);
306 if (!dtp
->u
.p
.no_leading_blank
)
308 memset (p
, ' ', nblank
);
310 memset (p
, '0', nzero
);
312 memcpy (p
, q
, digits
);
316 memset (p
, '0', nzero
);
318 memcpy (p
, q
, digits
);
320 memset (p
, ' ', nblank
);
321 dtp
->u
.p
.no_leading_blank
= 0;
329 write_decimal (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
,
331 const char *(*conv
) (GFC_INTEGER_LARGEST
, char *, size_t))
333 GFC_INTEGER_LARGEST n
= 0;
334 int w
, m
, digits
, nsign
, nzero
, nblank
;
338 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
343 n
= extract_int (source
, len
);
347 if (m
== 0 && n
== 0)
352 p
= write_block (dtp
, w
);
360 sign
= calculate_sign (dtp
, n
< 0);
364 nsign
= sign
== SIGN_NONE
? 0 : 1;
365 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
369 /* Select a width if none was specified. The idea here is to always
373 w
= ((digits
< m
) ? m
: digits
) + nsign
;
375 p
= write_block (dtp
, w
);
383 /* See if things will work. */
385 nblank
= w
- (nsign
+ nzero
+ digits
);
393 memset (p
, ' ', nblank
);
408 memset (p
, '0', nzero
);
411 memcpy (p
, q
, digits
);
418 /* Convert unsigned octal to ascii. */
421 otoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
425 assert (len
>= GFC_OTOA_BUF_SIZE
);
430 p
= buffer
+ GFC_OTOA_BUF_SIZE
- 1;
435 *--p
= '0' + (n
& 7);
443 /* Convert unsigned binary to ascii. */
446 btoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
450 assert (len
>= GFC_BTOA_BUF_SIZE
);
455 p
= buffer
+ GFC_BTOA_BUF_SIZE
- 1;
460 *--p
= '0' + (n
& 1);
469 write_i (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
471 write_decimal (dtp
, f
, p
, len
, (void *) gfc_itoa
);
476 write_b (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
478 write_int (dtp
, f
, p
, len
, btoa
);
483 write_o (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
485 write_int (dtp
, f
, p
, len
, otoa
);
489 write_z (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
491 write_int (dtp
, f
, p
, len
, xtoa
);
496 write_d (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
498 write_float (dtp
, f
, p
, len
);
503 write_e (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
505 write_float (dtp
, f
, p
, len
);
510 write_f (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
512 write_float (dtp
, f
, p
, len
);
517 write_en (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
519 write_float (dtp
, f
, p
, len
);
524 write_es (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
526 write_float (dtp
, f
, p
, len
);
530 /* Take care of the X/TR descriptor. */
533 write_x (st_parameter_dt
*dtp
, int len
, int nspaces
)
537 p
= write_block (dtp
, len
);
542 memset (&p
[len
- nspaces
], ' ', nspaces
);
546 /* List-directed writing. */
549 /* Write a single character to the output. Returns nonzero if
550 something goes wrong. */
553 write_char (st_parameter_dt
*dtp
, char c
)
557 p
= write_block (dtp
, 1);
567 /* Write a list-directed logical value. */
570 write_logical (st_parameter_dt
*dtp
, const char *source
, int length
)
572 write_char (dtp
, extract_int (source
, length
) ? 'T' : 'F');
576 /* Write a list-directed integer value. */
579 write_integer (st_parameter_dt
*dtp
, const char *source
, int length
)
585 char itoa_buf
[GFC_ITOA_BUF_SIZE
];
587 q
= gfc_itoa (extract_int (source
, length
), itoa_buf
, sizeof (itoa_buf
));
616 p
= write_block (dtp
, width
);
619 if (dtp
->u
.p
.no_leading_blank
)
621 memcpy (p
, q
, digits
);
622 memset (p
+ digits
, ' ', width
- digits
);
626 memset (p
, ' ', width
- digits
);
627 memcpy (p
+ width
- digits
, q
, digits
);
632 /* Write a list-directed string. We have to worry about delimiting
633 the strings if the file has been opened in that mode. */
636 write_character (st_parameter_dt
*dtp
, const char *source
, int length
)
641 switch (dtp
->u
.p
.current_unit
->flags
.delim
)
643 case DELIM_APOSTROPHE
:
660 for (i
= 0; i
< length
; i
++)
665 p
= write_block (dtp
, length
+ extra
);
670 memcpy (p
, source
, length
);
675 for (i
= 0; i
< length
; i
++)
687 /* Output a real number with default format.
688 This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
689 1PG28.19E4 for REAL(10) and 1PG43.34E4 for REAL(16). */
692 write_real (st_parameter_dt
*dtp
, const char *source
, int length
)
695 int org_scale
= dtp
->u
.p
.scale_factor
;
697 dtp
->u
.p
.scale_factor
= 1;
721 internal_error (&dtp
->common
, "bad real kind");
724 write_float (dtp
, &f
, source
, length
);
725 dtp
->u
.p
.scale_factor
= org_scale
;
730 write_complex (st_parameter_dt
*dtp
, const char *source
, int kind
, size_t size
)
732 if (write_char (dtp
, '('))
734 write_real (dtp
, source
, kind
);
736 if (write_char (dtp
, ','))
738 write_real (dtp
, source
+ size
/ 2, kind
);
740 write_char (dtp
, ')');
744 /* Write the separator between items. */
747 write_separator (st_parameter_dt
*dtp
)
751 p
= write_block (dtp
, options
.separator_len
);
755 memcpy (p
, options
.separator
, options
.separator_len
);
759 /* Write an item with list formatting.
760 TODO: handle skipping to the next record correctly, particularly
764 list_formatted_write_scalar (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
767 if (dtp
->u
.p
.current_unit
== NULL
)
770 if (dtp
->u
.p
.first_item
)
772 dtp
->u
.p
.first_item
= 0;
773 write_char (dtp
, ' ');
777 if (type
!= BT_CHARACTER
|| !dtp
->u
.p
.char_flag
||
778 dtp
->u
.p
.current_unit
->flags
.delim
!= DELIM_NONE
)
779 write_separator (dtp
);
785 write_integer (dtp
, p
, kind
);
788 write_logical (dtp
, p
, kind
);
791 write_character (dtp
, p
, kind
);
794 write_real (dtp
, p
, kind
);
797 write_complex (dtp
, p
, kind
, size
);
800 internal_error (&dtp
->common
, "list_formatted_write(): Bad type");
803 dtp
->u
.p
.char_flag
= (type
== BT_CHARACTER
);
808 list_formatted_write (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
809 size_t size
, size_t nelems
)
816 /* Big loop over all the elements. */
817 for (elem
= 0; elem
< nelems
; elem
++)
819 dtp
->u
.p
.item_count
++;
820 list_formatted_write_scalar (dtp
, type
, tmp
+ size
*elem
, kind
, size
);
826 nml_write_obj writes a namelist object to the output stream. It is called
827 recursively for derived type components:
828 obj = is the namelist_info for the current object.
829 offset = the offset relative to the address held by the object for
831 base = is the namelist_info of the derived type, when obj is a
833 base_name = the full name for a derived type, including qualifiers
835 The returned value is a pointer to the object beyond the last one
836 accessed, including nested derived types. Notice that the namelist is
837 a linear linked list of objects, including derived types and their
838 components. A tree, of sorts, is implied by the compound names of
839 the derived type components and this is how this function recurses through
842 /* A generous estimate of the number of characters needed to print
843 repeat counts and indices, including commas, asterices and brackets. */
845 #define NML_DIGITS 20
847 static namelist_info
*
848 nml_write_obj (st_parameter_dt
*dtp
, namelist_info
* obj
, index_type offset
,
849 namelist_info
* base
, char * base_name
)
860 index_type obj_name_len
;
865 char rep_buff
[NML_DIGITS
];
867 namelist_info
* retval
= obj
->next
;
868 size_t base_name_len
;
869 size_t base_var_name_len
;
872 /* Write namelist variable names in upper case. If a derived type,
873 nothing is output. If a component, base and base_name are set. */
875 if (obj
->type
!= GFC_DTYPE_DERIVED
)
878 write_character (dtp
, "\r\n ", 3);
880 write_character (dtp
, "\n ", 2);
885 len
=strlen (base
->var_name
);
886 for (dim_i
= 0; dim_i
< (index_type
) strlen (base_name
); dim_i
++)
888 cup
= toupper (base_name
[dim_i
]);
889 write_character (dtp
, &cup
, 1);
892 for (dim_i
=len
; dim_i
< (index_type
) strlen (obj
->var_name
); dim_i
++)
894 cup
= toupper (obj
->var_name
[dim_i
]);
895 write_character (dtp
, &cup
, 1);
897 write_character (dtp
, "=", 1);
900 /* Counts the number of data output on a line, including names. */
910 obj_size
= size_from_real_kind (len
);
913 case GFC_DTYPE_COMPLEX
:
914 obj_size
= size_from_complex_kind (len
);
917 case GFC_DTYPE_CHARACTER
:
918 obj_size
= obj
->string_length
;
926 obj_size
= obj
->size
;
928 /* Set the index vector and count the number of elements. */
931 for (dim_i
=0; dim_i
< obj
->var_rank
; dim_i
++)
933 obj
->ls
[dim_i
].idx
= obj
->dim
[dim_i
].lbound
;
934 nelem
= nelem
* (obj
->dim
[dim_i
].ubound
+ 1 - obj
->dim
[dim_i
].lbound
);
937 /* Main loop to output the data held in the object. */
940 for (elem_ctr
= 0; elem_ctr
< nelem
; elem_ctr
++)
943 /* Build the pointer to the data value. The offset is passed by
944 recursive calls to this function for arrays of derived types.
945 Is NULL otherwise. */
947 p
= (void *)(obj
->mem_pos
+ elem_ctr
* obj_size
);
950 /* Check for repeat counts of intrinsic types. */
952 if ((elem_ctr
< (nelem
- 1)) &&
953 (obj
->type
!= GFC_DTYPE_DERIVED
) &&
954 !memcmp (p
, (void*)(p
+ obj_size
), obj_size
))
959 /* Execute a repeated output. Note the flag no_leading_blank that
960 is used in the functions used to output the intrinsic types. */
966 sprintf(rep_buff
, " %d*", rep_ctr
);
967 write_character (dtp
, rep_buff
, strlen (rep_buff
));
968 dtp
->u
.p
.no_leading_blank
= 1;
972 /* Output the data, if an intrinsic type, or recurse into this
973 routine to treat derived types. */
978 case GFC_DTYPE_INTEGER
:
979 write_integer (dtp
, p
, len
);
982 case GFC_DTYPE_LOGICAL
:
983 write_logical (dtp
, p
, len
);
986 case GFC_DTYPE_CHARACTER
:
987 if (dtp
->u
.p
.nml_delim
)
988 write_character (dtp
, &dtp
->u
.p
.nml_delim
, 1);
989 write_character (dtp
, p
, obj
->string_length
);
990 if (dtp
->u
.p
.nml_delim
)
991 write_character (dtp
, &dtp
->u
.p
.nml_delim
, 1);
995 write_real (dtp
, p
, len
);
998 case GFC_DTYPE_COMPLEX
:
999 dtp
->u
.p
.no_leading_blank
= 0;
1001 write_complex (dtp
, p
, len
, obj_size
);
1004 case GFC_DTYPE_DERIVED
:
1006 /* To treat a derived type, we need to build two strings:
1007 ext_name = the name, including qualifiers that prepends
1008 component names in the output - passed to
1010 obj_name = the derived type name with no qualifiers but %
1011 appended. This is used to identify the
1014 /* First ext_name => get length of all possible components */
1016 base_name_len
= base_name
? strlen (base_name
) : 0;
1017 base_var_name_len
= base
? strlen (base
->var_name
) : 0;
1018 ext_name
= (char*)get_mem ( base_name_len
1020 + strlen (obj
->var_name
)
1021 + obj
->var_rank
* NML_DIGITS
1024 memcpy (ext_name
, base_name
, base_name_len
);
1025 clen
= strlen (obj
->var_name
+ base_var_name_len
);
1026 memcpy (ext_name
+ base_name_len
,
1027 obj
->var_name
+ base_var_name_len
, clen
);
1029 /* Append the qualifier. */
1031 tot_len
= base_name_len
+ clen
;
1032 for (dim_i
= 0; dim_i
< obj
->var_rank
; dim_i
++)
1036 ext_name
[tot_len
] = '(';
1039 sprintf (ext_name
+ tot_len
, "%d", (int) obj
->ls
[dim_i
].idx
);
1040 tot_len
+= strlen (ext_name
+ tot_len
);
1041 ext_name
[tot_len
] = (dim_i
== obj
->var_rank
- 1) ? ')' : ',';
1045 ext_name
[tot_len
] = '\0';
1049 obj_name_len
= strlen (obj
->var_name
) + 1;
1050 obj_name
= get_mem (obj_name_len
+1);
1051 memcpy (obj_name
, obj
->var_name
, obj_name_len
-1);
1052 memcpy (obj_name
+ obj_name_len
-1, "%", 2);
1054 /* Now loop over the components. Update the component pointer
1055 with the return value from nml_write_obj => this loop jumps
1056 past nested derived types. */
1058 for (cmp
= obj
->next
;
1059 cmp
&& !strncmp (cmp
->var_name
, obj_name
, obj_name_len
);
1062 retval
= nml_write_obj (dtp
, cmp
,
1063 (index_type
)(p
- obj
->mem_pos
),
1067 free_mem (obj_name
);
1068 free_mem (ext_name
);
1072 internal_error (&dtp
->common
, "Bad type for namelist write");
1075 /* Reset the leading blank suppression, write a comma and, if 5
1076 values have been output, write a newline and advance to column
1077 2. Reset the repeat counter. */
1079 dtp
->u
.p
.no_leading_blank
= 0;
1080 write_character (dtp
, ",", 1);
1085 write_character (dtp
, "\r\n ", 3);
1087 write_character (dtp
, "\n ", 2);
1093 /* Cycle through and increment the index vector. */
1098 for (dim_i
= 0; nml_carry
&& (dim_i
< obj
->var_rank
); dim_i
++)
1100 obj
->ls
[dim_i
].idx
+= nml_carry
;
1102 if (obj
->ls
[dim_i
].idx
> (ssize_t
)obj
->dim
[dim_i
].ubound
)
1104 obj
->ls
[dim_i
].idx
= obj
->dim
[dim_i
].lbound
;
1110 /* Return a pointer beyond the furthest object accessed. */
1115 /* This is the entry function for namelist writes. It outputs the name
1116 of the namelist and iterates through the namelist by calls to
1117 nml_write_obj. The call below has dummys in the arguments used in
1118 the treatment of derived types. */
1121 namelist_write (st_parameter_dt
*dtp
)
1123 namelist_info
* t1
, *t2
, *dummy
= NULL
;
1125 index_type dummy_offset
= 0;
1127 char * dummy_name
= NULL
;
1128 unit_delim tmp_delim
;
1130 /* Set the delimiter for namelist output. */
1132 tmp_delim
= dtp
->u
.p
.current_unit
->flags
.delim
;
1133 dtp
->u
.p
.current_unit
->flags
.delim
= DELIM_NONE
;
1137 dtp
->u
.p
.nml_delim
= '"';
1140 case (DELIM_APOSTROPHE
):
1141 dtp
->u
.p
.nml_delim
= '\'';
1145 dtp
->u
.p
.nml_delim
= '\0';
1149 write_character (dtp
, "&", 1);
1151 /* Write namelist name in upper case - f95 std. */
1153 for (i
= 0 ;i
< dtp
->namelist_name_len
;i
++ )
1155 c
= toupper (dtp
->namelist_name
[i
]);
1156 write_character (dtp
, &c
,1);
1159 if (dtp
->u
.p
.ionml
!= NULL
)
1161 t1
= dtp
->u
.p
.ionml
;
1165 t1
= nml_write_obj (dtp
, t2
, dummy_offset
, dummy
, dummy_name
);
1169 write_character (dtp
, " /\r\n", 5);
1171 write_character (dtp
, " /\n", 4);
1174 /* Recover the original delimiter. */
1176 dtp
->u
.p
.current_unit
->flags
.delim
= tmp_delim
;