1 /* Copyright (C) 2002-2021 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 Namelist output contributed by Paul Thomas
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)
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/>. */
35 #define star_fill(p, n) memset(p, '*', n)
37 typedef unsigned char uchar
;
39 /* Helper functions for character(kind=4) internal units. These are needed
40 by write_float.def. */
43 memcpy4 (gfc_char4_t
*dest
, const char *source
, int k
)
47 const char *p
= source
;
48 for (j
= 0; j
< k
; j
++)
49 *dest
++ = (gfc_char4_t
) *p
++;
52 /* This include contains the heart and soul of formatted floating point. */
53 #include "write_float.def"
55 /* Write out default char4. */
58 write_default_char4 (st_parameter_dt
*dtp
, const gfc_char4_t
*source
,
59 int src_len
, int w_len
)
66 /* Take care of preceding blanks. */
70 p
= write_block (dtp
, k
);
73 if (is_char4_unit (dtp
))
75 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
82 /* Get ready to handle delimiters if needed. */
83 switch (dtp
->u
.p
.current_unit
->delim_status
)
85 case DELIM_APOSTROPHE
:
96 /* Now process the remaining characters, one at a time. */
97 for (j
= 0; j
< src_len
; j
++)
100 if (is_char4_unit (dtp
))
103 /* Handle delimiters if any. */
104 if (c
== d
&& d
!= ' ')
106 p
= write_block (dtp
, 2);
109 q
= (gfc_char4_t
*) p
;
114 p
= write_block (dtp
, 1);
117 q
= (gfc_char4_t
*) p
;
123 /* Handle delimiters if any. */
124 if (c
== d
&& d
!= ' ')
126 p
= write_block (dtp
, 2);
133 p
= write_block (dtp
, 1);
137 *p
= c
> 255 ? '?' : (uchar
) c
;
143 /* Write out UTF-8 converted from char4. */
146 write_utf8_char4 (st_parameter_dt
*dtp
, gfc_char4_t
*source
,
147 int src_len
, int w_len
)
152 static const uchar masks
[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
153 static const uchar limits
[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
157 /* Take care of preceding blanks. */
161 p
= write_block (dtp
, k
);
167 /* Get ready to handle delimiters if needed. */
168 switch (dtp
->u
.p
.current_unit
->delim_status
)
170 case DELIM_APOSTROPHE
:
181 /* Now process the remaining characters, one at a time. */
182 for (j
= k
; j
< src_len
; j
++)
187 /* Handle the delimiters if any. */
188 if (c
== d
&& d
!= ' ')
190 p
= write_block (dtp
, 2);
197 p
= write_block (dtp
, 1);
205 /* Convert to UTF-8 sequence. */
211 *--q
= ((c
& 0x3F) | 0x80);
215 while (c
>= 0x3F || (c
& limits
[nbytes
-1]));
217 *--q
= (c
| masks
[nbytes
-1]);
219 p
= write_block (dtp
, nbytes
);
230 /* Check the first character in source if we are using CC_FORTRAN
231 and set the cc.type appropriately. The cc.type is used later by write_cc
232 to determine the output start-of-record, and next_record_cc to determine the
233 output end-of-record.
234 This function is called before the output buffer is allocated, so alloc_len
235 is set to the appropriate size to allocate. */
238 write_check_cc (st_parameter_dt
*dtp
, const char **source
, size_t *alloc_len
)
240 /* Only valid for CARRIAGECONTROL=FORTRAN. */
241 if (dtp
->u
.p
.current_unit
->flags
.cc
!= CC_FORTRAN
242 || alloc_len
== NULL
|| source
== NULL
)
245 /* Peek at the first character. */
246 int c
= (*alloc_len
> 0) ? (*source
)[0] : EOF
;
249 /* The start-of-record character which will be printed. */
250 dtp
->u
.p
.cc
.u
.start
= '\n';
251 /* The number of characters to print at the start-of-record.
252 len > 1 means copy the SOR character multiple times.
253 len == 0 means no SOR will be output. */
259 dtp
->u
.p
.cc
.type
= CCF_OVERPRINT
;
263 dtp
->u
.p
.cc
.type
= CCF_ONE_LF
;
267 dtp
->u
.p
.cc
.type
= CCF_TWO_LF
;
271 dtp
->u
.p
.cc
.type
= CCF_PAGE_FEED
;
273 dtp
->u
.p
.cc
.u
.start
= '\f';
276 dtp
->u
.p
.cc
.type
= CCF_PROMPT
;
280 dtp
->u
.p
.cc
.type
= CCF_OVERPRINT_NOA
;
284 /* In the default case we copy ONE_LF. */
285 dtp
->u
.p
.cc
.type
= CCF_DEFAULT
;
290 /* We add n-1 to alloc_len so our write buffer is the right size.
291 We are replacing the first character, and possibly prepending some
292 additional characters. Note for n==0, we actually subtract one from
293 alloc_len, which is correct, since that character is skipped. */
297 *alloc_len
+= dtp
->u
.p
.cc
.len
- 1;
299 /* If we have no input, there is no first character to replace. Make
300 sure we still allocate enough space for the start-of-record string. */
302 *alloc_len
= dtp
->u
.p
.cc
.len
;
307 /* Write the start-of-record character(s) for CC_FORTRAN.
308 Also adjusts the 'cc' struct to contain the end-of-record character
310 The source_len is set to the remaining length to copy from the source,
311 after the start-of-record string was inserted. */
314 write_cc (st_parameter_dt
*dtp
, char *p
, size_t *source_len
)
316 /* Only valid for CARRIAGECONTROL=FORTRAN. */
317 if (dtp
->u
.p
.current_unit
->flags
.cc
!= CC_FORTRAN
|| source_len
== NULL
)
320 /* Write the start-of-record string to the output buffer. Note that len is
321 never more than 2. */
322 if (dtp
->u
.p
.cc
.len
> 0)
324 *(p
++) = dtp
->u
.p
.cc
.u
.start
;
325 if (dtp
->u
.p
.cc
.len
> 1)
326 *(p
++) = dtp
->u
.p
.cc
.u
.start
;
328 /* source_len comes from write_check_cc where it is set to the full
329 allocated length of the output buffer. Therefore we subtract off the
330 length of the SOR string to obtain the remaining source length. */
331 *source_len
-= dtp
->u
.p
.cc
.len
;
336 dtp
->u
.p
.cc
.u
.end
= '\r';
338 /* Update end-of-record character for next_record_w. */
339 switch (dtp
->u
.p
.cc
.type
)
342 case CCF_OVERPRINT_NOA
:
343 /* No end-of-record. */
345 dtp
->u
.p
.cc
.u
.end
= '\0';
353 /* Carriage return. */
355 dtp
->u
.p
.cc
.u
.end
= '\r';
364 write_a (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, size_t len
)
369 wlen
= f
->u
.string
.length
< 0
370 || (f
->format
== FMT_G
&& f
->u
.string
.length
== 0)
371 ? len
: (size_t) f
->u
.string
.length
;
374 /* If this is formatted STREAM IO convert any embedded line feed characters
375 to CR_LF on systems that use that sequence for newlines. See F2003
376 Standard sections 10.6.3 and 9.9 for further information. */
377 if (is_stream_io (dtp
))
379 const char crlf
[] = "\r\n";
383 /* Write out any padding if needed. */
386 p
= write_block (dtp
, wlen
- len
);
389 memset (p
, ' ', wlen
- len
);
392 /* Scan the source string looking for '\n' and convert it if found. */
393 for (size_t i
= 0; i
< wlen
; i
++)
395 if (source
[i
] == '\n')
397 /* Write out the previously scanned characters in the string. */
400 p
= write_block (dtp
, bytes
);
403 memcpy (p
, &source
[q
], bytes
);
408 /* Write out the CR_LF sequence. */
410 p
= write_block (dtp
, 2);
419 /* Write out any remaining bytes if no LF was found. */
422 p
= write_block (dtp
, bytes
);
425 memcpy (p
, &source
[q
], bytes
);
431 if (dtp
->u
.p
.current_unit
->flags
.cc
== CC_FORTRAN
)
432 write_check_cc (dtp
, &source
, &wlen
);
434 p
= write_block (dtp
, wlen
);
438 if (dtp
->u
.p
.current_unit
->flags
.cc
== CC_FORTRAN
)
439 p
= write_cc (dtp
, p
, &wlen
);
441 if (unlikely (is_char4_unit (dtp
)))
443 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
445 memcpy4 (p4
, source
, wlen
);
448 memset4 (p4
, ' ', wlen
- len
);
449 memcpy4 (p4
+ wlen
- len
, source
, len
);
455 memcpy (p
, source
, wlen
);
458 memset (p
, ' ', wlen
- len
);
459 memcpy (p
+ wlen
- len
, source
, len
);
467 /* The primary difference between write_a_char4 and write_a is that we have to
468 deal with writing from the first byte of the 4-byte character and pay
469 attention to the most significant bytes. For ENCODING="default" write the
470 lowest significant byte. If the 3 most significant bytes contain
471 non-zero values, emit a '?'. For ENCODING="utf-8", convert the UCS-32 value
472 to the UTF-8 encoded string before writing out. */
475 write_a_char4 (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, size_t len
)
480 wlen
= f
->u
.string
.length
< 0
481 || (f
->format
== FMT_G
&& f
->u
.string
.length
== 0)
482 ? len
: (size_t) f
->u
.string
.length
;
484 q
= (gfc_char4_t
*) source
;
486 /* If this is formatted STREAM IO convert any embedded line feed characters
487 to CR_LF on systems that use that sequence for newlines. See F2003
488 Standard sections 10.6.3 and 9.9 for further information. */
489 if (is_stream_io (dtp
))
491 const gfc_char4_t crlf
[] = {0x000d,0x000a};
496 /* Write out any padding if needed. */
500 p
= write_block (dtp
, wlen
- len
);
503 memset (p
, ' ', wlen
- len
);
506 /* Scan the source string looking for '\n' and convert it if found. */
507 qq
= (gfc_char4_t
*) source
;
508 for (size_t i
= 0; i
< wlen
; i
++)
512 /* Write out the previously scanned characters in the string. */
515 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
516 write_utf8_char4 (dtp
, q
, bytes
, 0);
518 write_default_char4 (dtp
, q
, bytes
, 0);
522 /* Write out the CR_LF sequence. */
523 write_default_char4 (dtp
, crlf
, 2, 0);
529 /* Write out any remaining bytes if no LF was found. */
532 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
533 write_utf8_char4 (dtp
, q
, bytes
, 0);
535 write_default_char4 (dtp
, q
, bytes
, 0);
541 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
542 write_utf8_char4 (dtp
, q
, len
, wlen
);
544 write_default_char4 (dtp
, q
, len
, wlen
);
551 static GFC_INTEGER_LARGEST
552 extract_int (const void *p
, int len
)
554 GFC_INTEGER_LARGEST i
= 0;
564 memcpy ((void *) &tmp
, p
, len
);
571 memcpy ((void *) &tmp
, p
, len
);
578 memcpy ((void *) &tmp
, p
, len
);
585 memcpy ((void *) &tmp
, p
, len
);
589 #ifdef HAVE_GFC_INTEGER_16
593 memcpy ((void *) &tmp
, p
, len
);
599 internal_error (NULL
, "bad integer kind");
605 static GFC_UINTEGER_LARGEST
606 extract_uint (const void *p
, int len
)
608 GFC_UINTEGER_LARGEST i
= 0;
618 memcpy ((void *) &tmp
, p
, len
);
619 i
= (GFC_UINTEGER_1
) tmp
;
625 memcpy ((void *) &tmp
, p
, len
);
626 i
= (GFC_UINTEGER_2
) tmp
;
632 memcpy ((void *) &tmp
, p
, len
);
633 i
= (GFC_UINTEGER_4
) tmp
;
639 memcpy ((void *) &tmp
, p
, len
);
640 i
= (GFC_UINTEGER_8
) tmp
;
643 #ifdef HAVE_GFC_INTEGER_16
647 GFC_INTEGER_16 tmp
= 0;
648 memcpy ((void *) &tmp
, p
, len
);
649 i
= (GFC_UINTEGER_16
) tmp
;
654 internal_error (NULL
, "bad integer kind");
662 write_l (st_parameter_dt
*dtp
, const fnode
*f
, char *source
, int len
)
666 GFC_INTEGER_LARGEST n
;
668 wlen
= (f
->format
== FMT_G
&& f
->u
.w
== 0) ? 1 : f
->u
.w
;
670 p
= write_block (dtp
, wlen
);
674 n
= extract_int (source
, len
);
676 if (unlikely (is_char4_unit (dtp
)))
678 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
679 memset4 (p4
, ' ', wlen
-1);
680 p4
[wlen
- 1] = (n
) ? 'T' : 'F';
684 memset (p
, ' ', wlen
-1);
685 p
[wlen
- 1] = (n
) ? 'T' : 'F';
689 write_boz (st_parameter_dt
*dtp
, const fnode
*f
, const char *q
, int n
, int len
)
691 int w
, m
, digits
, nzero
, nblank
;
699 if (m
== 0 && n
== 0)
704 p
= write_block (dtp
, w
);
707 if (unlikely (is_char4_unit (dtp
)))
709 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
710 memset4 (p4
, ' ', w
);
719 /* Select a width if none was specified. The idea here is to always
722 if (w
== DEFAULT_WIDTH
)
723 w
= default_width_for_integer (len
);
726 w
= ((digits
< m
) ? m
: digits
);
728 p
= write_block (dtp
, w
);
736 /* See if things will work. */
738 nblank
= w
- (nzero
+ digits
);
740 if (unlikely (is_char4_unit (dtp
)))
742 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
745 memset4 (p4
, '*', w
);
749 if (!dtp
->u
.p
.no_leading_blank
)
751 memset4 (p4
, ' ', nblank
);
753 memset4 (p4
, '0', nzero
);
755 memcpy4 (p4
, q
, digits
);
759 memset4 (p4
, '0', nzero
);
761 memcpy4 (p4
, q
, digits
);
763 memset4 (p4
, ' ', nblank
);
764 dtp
->u
.p
.no_leading_blank
= 0;
775 if (!dtp
->u
.p
.no_leading_blank
)
777 memset (p
, ' ', nblank
);
779 memset (p
, '0', nzero
);
781 memcpy (p
, q
, digits
);
785 memset (p
, '0', nzero
);
787 memcpy (p
, q
, digits
);
789 memset (p
, ' ', nblank
);
790 dtp
->u
.p
.no_leading_blank
= 0;
798 write_decimal (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
,
800 const char *(*conv
) (GFC_INTEGER_LARGEST
, char *, size_t))
802 GFC_INTEGER_LARGEST n
= 0;
803 int w
, m
, digits
, nsign
, nzero
, nblank
;
807 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
810 m
= f
->format
== FMT_G
? -1 : f
->u
.integer
.m
;
812 n
= extract_int (source
, len
);
815 if (m
== 0 && n
== 0)
820 p
= write_block (dtp
, w
);
823 if (unlikely (is_char4_unit (dtp
)))
825 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
826 memset4 (p4
, ' ', w
);
833 sign
= calculate_sign (dtp
, n
< 0);
836 nsign
= sign
== S_NONE
? 0 : 1;
838 /* conv calls itoa which sets the negative sign needed
839 by write_integer. The sign '+' or '-' is set below based on sign
840 calculated above, so we just point past the sign in the string
841 before proceeding to avoid double signs in corner cases.
843 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
849 /* Select a width if none was specified. The idea here is to always
851 if (w
== DEFAULT_WIDTH
)
852 w
= default_width_for_integer (len
);
855 w
= ((digits
< m
) ? m
: digits
) + nsign
;
857 p
= write_block (dtp
, w
);
865 /* See if things will work. */
867 nblank
= w
- (nsign
+ nzero
+ digits
);
869 if (unlikely (is_char4_unit (dtp
)))
871 gfc_char4_t
*p4
= (gfc_char4_t
*)p
;
874 memset4 (p4
, '*', w
);
878 if (!dtp
->u
.p
.namelist_mode
)
880 memset4 (p4
, ' ', nblank
);
896 memset4 (p4
, '0', nzero
);
899 memcpy4 (p4
, q
, digits
);
902 if (dtp
->u
.p
.namelist_mode
)
905 memset4 (p4
, ' ', nblank
);
915 if (!dtp
->u
.p
.namelist_mode
)
917 memset (p
, ' ', nblank
);
933 memset (p
, '0', nzero
);
936 memcpy (p
, q
, digits
);
938 if (dtp
->u
.p
.namelist_mode
)
941 memset (p
, ' ', nblank
);
949 /* Convert unsigned octal to ascii. */
952 otoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
956 assert (len
>= GFC_OTOA_BUF_SIZE
);
961 p
= buffer
+ GFC_OTOA_BUF_SIZE
- 1;
966 *--p
= '0' + (n
& 7);
974 /* Convert unsigned binary to ascii. */
977 btoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
981 assert (len
>= GFC_BTOA_BUF_SIZE
);
986 p
= buffer
+ GFC_BTOA_BUF_SIZE
- 1;
991 *--p
= '0' + (n
& 1);
998 /* The following three functions, btoa_big, otoa_big, and ztoa_big, are needed
999 to convert large reals with kind sizes that exceed the largest integer type
1000 available on certain platforms. In these cases, byte by byte conversion is
1001 performed. Endianess is taken into account. */
1003 /* Conversion to binary. */
1006 btoa_big (const char *s
, char *buffer
, int len
, GFC_UINTEGER_LARGEST
*n
)
1012 if (__BYTE_ORDER__
== __ORDER_BIG_ENDIAN__
)
1015 for (i
= 0; i
< len
; i
++)
1019 /* Test for zero. Needed by write_boz later. */
1023 for (j
= 0; j
< 8; j
++)
1025 *q
++ = (c
& 128) ? '1' : '0';
1033 const char *p
= s
+ len
- 1;
1034 for (i
= 0; i
< len
; i
++)
1038 /* Test for zero. Needed by write_boz later. */
1042 for (j
= 0; j
< 8; j
++)
1044 *q
++ = (c
& 128) ? '1' : '0';
1054 /* Move past any leading zeros. */
1055 while (*buffer
== '0')
1062 /* Conversion to octal. */
1065 otoa_big (const char *s
, char *buffer
, int len
, GFC_UINTEGER_LARGEST
*n
)
1071 q
= buffer
+ GFC_OTOA_BUF_SIZE
- 1;
1075 if (__BYTE_ORDER__
== __ORDER_BIG_ENDIAN__
)
1077 const char *p
= s
+ len
- 1;
1081 /* Test for zero. Needed by write_boz later. */
1085 for (j
= 0; j
< 3 && i
< len
; j
++)
1087 octet
|= (c
& 1) << j
;
1106 /* Test for zero. Needed by write_boz later. */
1110 for (j
= 0; j
< 3 && i
< len
; j
++)
1112 octet
|= (c
& 1) << j
;
1129 /* Move past any leading zeros. */
1136 /* Conversion to hexidecimal. */
1139 ztoa_big (const char *s
, char *buffer
, int len
, GFC_UINTEGER_LARGEST
*n
)
1141 static char a
[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
1142 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
1150 if (__BYTE_ORDER__
== __ORDER_BIG_ENDIAN__
)
1153 for (i
= 0; i
< len
; i
++)
1155 /* Test for zero. Needed by write_boz later. */
1159 h
= (*p
>> 4) & 0x0F;
1167 const char *p
= s
+ len
- 1;
1168 for (i
= 0; i
< len
; i
++)
1170 /* Test for zero. Needed by write_boz later. */
1174 h
= (*p
>> 4) & 0x0F;
1181 /* write_z, which calls ztoa_big, is called from transfer.c,
1182 formatted_transfer_scalar_write. There it is passed the kind as
1183 argument, which means a maximum of 16. The buffer is large
1184 enough, but the compiler does not know that, so shut up the
1186 #pragma GCC diagnostic push
1187 #pragma GCC diagnostic ignored "-Wstringop-overflow"
1189 #pragma GCC diagnostic pop
1194 /* Move past any leading zeros. */
1195 while (*buffer
== '0')
1203 write_i (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1205 write_decimal (dtp
, f
, p
, len
, (void *) gfc_itoa
);
1210 write_b (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
1213 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
1214 GFC_UINTEGER_LARGEST n
= 0;
1216 /* Ensure we end up with a null terminated string. */
1217 memset(itoa_buf
, '\0', GFC_BTOA_BUF_SIZE
);
1219 if (len
> (int) sizeof (GFC_UINTEGER_LARGEST
))
1221 p
= btoa_big (source
, itoa_buf
, len
, &n
);
1222 write_boz (dtp
, f
, p
, n
, len
);
1226 n
= extract_uint (source
, len
);
1227 p
= btoa (n
, itoa_buf
, sizeof (itoa_buf
));
1228 write_boz (dtp
, f
, p
, n
, len
);
1234 write_o (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
1237 char itoa_buf
[GFC_OTOA_BUF_SIZE
];
1238 GFC_UINTEGER_LARGEST n
= 0;
1240 if (len
> (int) sizeof (GFC_UINTEGER_LARGEST
))
1242 p
= otoa_big (source
, itoa_buf
, len
, &n
);
1243 write_boz (dtp
, f
, p
, n
, len
);
1247 n
= extract_uint (source
, len
);
1248 p
= otoa (n
, itoa_buf
, sizeof (itoa_buf
));
1249 write_boz (dtp
, f
, p
, n
, len
);
1254 write_z (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
1257 char itoa_buf
[GFC_XTOA_BUF_SIZE
];
1258 GFC_UINTEGER_LARGEST n
= 0;
1260 if (len
> (int) sizeof (GFC_UINTEGER_LARGEST
))
1262 p
= ztoa_big (source
, itoa_buf
, len
, &n
);
1263 write_boz (dtp
, f
, p
, n
, len
);
1267 n
= extract_uint (source
, len
);
1268 p
= gfc_xtoa (n
, itoa_buf
, sizeof (itoa_buf
));
1269 write_boz (dtp
, f
, p
, n
, len
);
1273 /* Take care of the X/TR descriptor. */
1276 write_x (st_parameter_dt
*dtp
, int len
, int nspaces
)
1280 p
= write_block (dtp
, len
);
1283 if (nspaces
> 0 && len
- nspaces
>= 0)
1285 if (unlikely (is_char4_unit (dtp
)))
1287 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
1288 memset4 (&p4
[len
- nspaces
], ' ', nspaces
);
1291 memset (&p
[len
- nspaces
], ' ', nspaces
);
1296 /* List-directed writing. */
1299 /* Write a single character to the output. Returns nonzero if
1300 something goes wrong. */
1303 write_char (st_parameter_dt
*dtp
, int c
)
1307 p
= write_block (dtp
, 1);
1310 if (unlikely (is_char4_unit (dtp
)))
1312 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
1323 /* Write a list-directed logical value. */
1326 write_logical (st_parameter_dt
*dtp
, const char *source
, int length
)
1328 write_char (dtp
, extract_int (source
, length
) ? 'T' : 'F');
1332 /* Write a list-directed integer value. */
1335 write_integer (st_parameter_dt
*dtp
, const char *source
, int kind
)
1366 f
.u
.integer
.w
= width
;
1368 f
.format
= FMT_NONE
;
1369 write_decimal (dtp
, &f
, source
, kind
, (void *) gfc_itoa
);
1373 /* Write a list-directed string. We have to worry about delimiting
1374 the strings if the file has been opened in that mode. */
1380 write_character (st_parameter_dt
*dtp
, const char *source
, int kind
, size_t length
, int mode
)
1387 switch (dtp
->u
.p
.current_unit
->delim_status
)
1389 case DELIM_APOSTROPHE
:
1411 for (size_t i
= 0; i
< length
; i
++)
1416 p
= write_block (dtp
, length
+ extra
);
1420 if (unlikely (is_char4_unit (dtp
)))
1422 gfc_char4_t d4
= (gfc_char4_t
) d
;
1423 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
1426 memcpy4 (p4
, source
, length
);
1431 for (size_t i
= 0; i
< length
; i
++)
1433 *p4
++ = (gfc_char4_t
) source
[i
];
1444 memcpy (p
, source
, length
);
1449 for (size_t i
= 0; i
< length
; i
++)
1463 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
1464 write_utf8_char4 (dtp
, (gfc_char4_t
*) source
, length
, 0);
1466 write_default_char4 (dtp
, (gfc_char4_t
*) source
, length
, 0);
1470 p
= write_block (dtp
, 1);
1473 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
1474 write_utf8_char4 (dtp
, (gfc_char4_t
*) source
, length
, 0);
1476 write_default_char4 (dtp
, (gfc_char4_t
*) source
, length
, 0);
1478 p
= write_block (dtp
, 1);
1484 /* Floating point helper functions. */
1486 #define BUF_STACK_SZ 384
1489 get_precision (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int kind
)
1491 if (f
->format
!= FMT_EN
)
1492 return determine_precision (dtp
, f
, kind
);
1494 return determine_en_precision (dtp
, f
, source
, kind
);
1497 /* 4932 is the maximum exponent of long double and quad precision, 3
1498 extra characters for the sign, the decimal point, and the
1499 trailing null. Extra digits are added by the calling functions for
1500 requested precision. Likewise for float and double. F0 editing produces
1501 full precision output. */
1503 size_from_kind (st_parameter_dt
*dtp
, const fnode
*f
, int kind
)
1507 if ((f
->format
== FMT_F
&& f
->u
.real
.w
== 0) || f
->u
.real
.w
== DEFAULT_WIDTH
)
1512 size
= 38 + 3; /* These constants shown for clarity. */
1524 internal_error (&dtp
->common
, "bad real kind");
1529 size
= f
->u
.real
.w
+ 1; /* One byte for a NULL character. */
1535 select_buffer (st_parameter_dt
*dtp
, const fnode
*f
, int precision
,
1536 char *buf
, size_t *size
, int kind
)
1540 /* The buffer needs at least one more byte to allow room for
1541 normalizing and 1 to hold null terminator. */
1542 *size
= size_from_kind (dtp
, f
, kind
) + precision
+ 1 + 1;
1544 if (*size
> BUF_STACK_SZ
)
1545 result
= xmalloc (*size
);
1552 select_string (st_parameter_dt
*dtp
, const fnode
*f
, char *buf
, size_t *size
,
1556 *size
= size_from_kind (dtp
, f
, kind
) + f
->u
.real
.d
+ 1;
1557 if (*size
> BUF_STACK_SZ
)
1558 result
= xmalloc (*size
);
1565 write_float_string (st_parameter_dt
*dtp
, char *fstr
, size_t len
)
1567 char *p
= write_block (dtp
, len
);
1571 if (unlikely (is_char4_unit (dtp
)))
1573 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
1574 memcpy4 (p4
, fstr
, len
);
1577 memcpy (p
, fstr
, len
);
1582 write_float_0 (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int kind
)
1584 char buf_stack
[BUF_STACK_SZ
];
1585 char str_buf
[BUF_STACK_SZ
];
1586 char *buffer
, *result
;
1587 size_t buf_size
, res_len
, flt_str_len
;
1589 /* Precision for snprintf call. */
1590 int precision
= get_precision (dtp
, f
, source
, kind
);
1592 /* String buffer to hold final result. */
1593 result
= select_string (dtp
, f
, str_buf
, &res_len
, kind
);
1595 buffer
= select_buffer (dtp
, f
, precision
, buf_stack
, &buf_size
, kind
);
1597 get_float_string (dtp
, f
, source
, kind
, 0, buffer
,
1598 precision
, buf_size
, result
, &flt_str_len
);
1599 write_float_string (dtp
, result
, flt_str_len
);
1601 if (buf_size
> BUF_STACK_SZ
)
1603 if (res_len
> BUF_STACK_SZ
)
1608 write_d (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1610 write_float_0 (dtp
, f
, p
, len
);
1615 write_e (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1617 write_float_0 (dtp
, f
, p
, len
);
1622 write_f (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1624 write_float_0 (dtp
, f
, p
, len
);
1629 write_en (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1631 write_float_0 (dtp
, f
, p
, len
);
1636 write_es (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1638 write_float_0 (dtp
, f
, p
, len
);
1642 /* Set an fnode to default format. */
1645 set_fnode_default (st_parameter_dt
*dtp
, fnode
*f
, int length
)
1666 /* Adjust decimal precision depending on binary precision, 106 or 113. */
1667 #if GFC_REAL_16_DIGITS == 113
1678 internal_error (&dtp
->common
, "bad real kind");
1683 /* Output a real number with default format.
1684 To guarantee that a binary -> decimal -> binary roundtrip conversion
1685 recovers the original value, IEEE 754-2008 requires 9, 17, 21 and 36
1686 significant digits for REAL kinds 4, 8, 10, and 16, respectively.
1687 Thus, we use 1PG16.9E2 for REAL(4), 1PG25.17E3 for REAL(8), 1PG30.21E4
1688 for REAL(10) and 1PG45.36E4 for REAL(16). The exception is that the
1689 Fortran standard requires outputting an extra digit when the scale
1690 factor is 1 and when the magnitude of the value is such that E
1691 editing is used. However, gfortran compensates for this, and thus
1692 for list formatted the same number of significant digits is
1693 generated both when using F and E editing. */
1696 write_real (st_parameter_dt
*dtp
, const char *source
, int kind
)
1699 char buf_stack
[BUF_STACK_SZ
];
1700 char str_buf
[BUF_STACK_SZ
];
1701 char *buffer
, *result
;
1702 size_t buf_size
, res_len
, flt_str_len
;
1703 int orig_scale
= dtp
->u
.p
.scale_factor
;
1704 dtp
->u
.p
.scale_factor
= 1;
1705 set_fnode_default (dtp
, &f
, kind
);
1707 /* Precision for snprintf call. */
1708 int precision
= get_precision (dtp
, &f
, source
, kind
);
1710 /* String buffer to hold final result. */
1711 result
= select_string (dtp
, &f
, str_buf
, &res_len
, kind
);
1713 /* Scratch buffer to hold final result. */
1714 buffer
= select_buffer (dtp
, &f
, precision
, buf_stack
, &buf_size
, kind
);
1716 get_float_string (dtp
, &f
, source
, kind
, 1, buffer
,
1717 precision
, buf_size
, result
, &flt_str_len
);
1718 write_float_string (dtp
, result
, flt_str_len
);
1720 dtp
->u
.p
.scale_factor
= orig_scale
;
1721 if (buf_size
> BUF_STACK_SZ
)
1723 if (res_len
> BUF_STACK_SZ
)
1727 /* Similar to list formatted REAL output, for kPG0 where k > 0 we
1728 compensate for the extra digit. */
1731 write_real_w0 (st_parameter_dt
*dtp
, const char *source
, int kind
,
1735 char buf_stack
[BUF_STACK_SZ
];
1736 char str_buf
[BUF_STACK_SZ
];
1737 char *buffer
, *result
;
1738 size_t buf_size
, res_len
, flt_str_len
;
1741 set_fnode_default (dtp
, &ff
, kind
);
1743 if (f
->u
.real
.d
> 0)
1744 ff
.u
.real
.d
= f
->u
.real
.d
;
1745 ff
.format
= f
->format
;
1747 /* For FMT_G, Compensate for extra digits when using scale factor, d
1748 is not specified, and the magnitude is such that E editing
1750 if (f
->format
== FMT_G
)
1752 if (dtp
->u
.p
.scale_factor
> 0 && f
->u
.real
.d
== 0)
1758 if (f
->u
.real
.e
>= 0)
1759 ff
.u
.real
.e
= f
->u
.real
.e
;
1761 dtp
->u
.p
.g0_no_blanks
= 1;
1763 /* Precision for snprintf call. */
1764 int precision
= get_precision (dtp
, &ff
, source
, kind
);
1766 /* String buffer to hold final result. */
1767 result
= select_string (dtp
, &ff
, str_buf
, &res_len
, kind
);
1769 buffer
= select_buffer (dtp
, &ff
, precision
, buf_stack
, &buf_size
, kind
);
1771 get_float_string (dtp
, &ff
, source
, kind
, comp_d
, buffer
,
1772 precision
, buf_size
, result
, &flt_str_len
);
1773 write_float_string (dtp
, result
, flt_str_len
);
1775 dtp
->u
.p
.g0_no_blanks
= 0;
1776 if (buf_size
> BUF_STACK_SZ
)
1778 if (res_len
> BUF_STACK_SZ
)
1784 write_complex (st_parameter_dt
*dtp
, const char *source
, int kind
, size_t size
)
1787 dtp
->u
.p
.current_unit
->decimal_status
== DECIMAL_POINT
? ',' : ';';
1789 /* Set for no blanks so we get a string result with no leading
1790 blanks. We will pad left later. */
1791 dtp
->u
.p
.g0_no_blanks
= 1;
1794 char buf_stack
[BUF_STACK_SZ
];
1795 char str1_buf
[BUF_STACK_SZ
];
1796 char str2_buf
[BUF_STACK_SZ
];
1797 char *buffer
, *result1
, *result2
;
1798 size_t buf_size
, res_len1
, res_len2
, flt_str_len1
, flt_str_len2
;
1799 int width
, lblanks
, orig_scale
= dtp
->u
.p
.scale_factor
;
1801 dtp
->u
.p
.scale_factor
= 1;
1802 set_fnode_default (dtp
, &f
, kind
);
1804 /* Set width for two values, parenthesis, and comma. */
1805 width
= 2 * f
.u
.real
.w
+ 3;
1807 /* Set for no blanks so we get a string result with no leading
1808 blanks. We will pad left later. */
1809 dtp
->u
.p
.g0_no_blanks
= 1;
1811 /* Precision for snprintf call. */
1812 int precision
= get_precision (dtp
, &f
, source
, kind
);
1814 /* String buffers to hold final result. */
1815 result1
= select_string (dtp
, &f
, str1_buf
, &res_len1
, kind
);
1816 result2
= select_string (dtp
, &f
, str2_buf
, &res_len2
, kind
);
1818 buffer
= select_buffer (dtp
, &f
, precision
, buf_stack
, &buf_size
, kind
);
1820 get_float_string (dtp
, &f
, source
, kind
, 0, buffer
,
1821 precision
, buf_size
, result1
, &flt_str_len1
);
1822 get_float_string (dtp
, &f
, source
+ size
/ 2 , kind
, 0, buffer
,
1823 precision
, buf_size
, result2
, &flt_str_len2
);
1824 if (!dtp
->u
.p
.namelist_mode
)
1826 lblanks
= width
- flt_str_len1
- flt_str_len2
- 3;
1827 write_x (dtp
, lblanks
, lblanks
);
1829 write_char (dtp
, '(');
1830 write_float_string (dtp
, result1
, flt_str_len1
);
1831 write_char (dtp
, semi_comma
);
1832 write_float_string (dtp
, result2
, flt_str_len2
);
1833 write_char (dtp
, ')');
1835 dtp
->u
.p
.scale_factor
= orig_scale
;
1836 dtp
->u
.p
.g0_no_blanks
= 0;
1837 if (buf_size
> BUF_STACK_SZ
)
1839 if (res_len1
> BUF_STACK_SZ
)
1841 if (res_len2
> BUF_STACK_SZ
)
1846 /* Write the separator between items. */
1849 write_separator (st_parameter_dt
*dtp
)
1853 p
= write_block (dtp
, options
.separator_len
);
1856 if (unlikely (is_char4_unit (dtp
)))
1858 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
1859 memcpy4 (p4
, options
.separator
, options
.separator_len
);
1862 memcpy (p
, options
.separator
, options
.separator_len
);
1866 /* Write an item with list formatting.
1867 TODO: handle skipping to the next record correctly, particularly
1871 list_formatted_write_scalar (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
1874 if (dtp
->u
.p
.current_unit
== NULL
)
1877 if (dtp
->u
.p
.first_item
)
1879 dtp
->u
.p
.first_item
= 0;
1880 if (dtp
->u
.p
.current_unit
->flags
.cc
!= CC_FORTRAN
)
1881 write_char (dtp
, ' ');
1885 if (type
!= BT_CHARACTER
|| !dtp
->u
.p
.char_flag
||
1886 (dtp
->u
.p
.current_unit
->delim_status
!= DELIM_NONE
1887 && dtp
->u
.p
.current_unit
->delim_status
!= DELIM_UNSPECIFIED
))
1888 write_separator (dtp
);
1894 write_integer (dtp
, p
, kind
);
1897 write_logical (dtp
, p
, kind
);
1900 write_character (dtp
, p
, kind
, size
, DELIM
);
1903 write_real (dtp
, p
, kind
);
1906 write_complex (dtp
, p
, kind
, size
);
1910 int unit
= dtp
->u
.p
.current_unit
->unit_number
;
1911 char iotype
[] = "LISTDIRECTED";
1912 gfc_charlen_type iotype_len
= 12;
1913 char tmp_iomsg
[IOMSG_LEN
] = "";
1915 gfc_charlen_type child_iomsg_len
;
1917 int *child_iostat
= NULL
;
1918 gfc_full_array_i4 vlist
;
1920 GFC_DESCRIPTOR_DATA(&vlist
) = NULL
;
1921 GFC_DIMENSION_SET(vlist
.dim
[0],1, 0, 0);
1923 /* Set iostat, intent(out). */
1925 child_iostat
= (dtp
->common
.flags
& IOPARM_HAS_IOSTAT
) ?
1926 dtp
->common
.iostat
: &noiostat
;
1928 /* Set iomsge, intent(inout). */
1929 if (dtp
->common
.flags
& IOPARM_HAS_IOMSG
)
1931 child_iomsg
= dtp
->common
.iomsg
;
1932 child_iomsg_len
= dtp
->common
.iomsg_len
;
1936 child_iomsg
= tmp_iomsg
;
1937 child_iomsg_len
= IOMSG_LEN
;
1940 /* Call the user defined formatted WRITE procedure. */
1941 dtp
->u
.p
.current_unit
->child_dtio
++;
1942 dtp
->u
.p
.fdtio_ptr (p
, &unit
, iotype
, &vlist
,
1943 child_iostat
, child_iomsg
,
1944 iotype_len
, child_iomsg_len
);
1945 dtp
->u
.p
.current_unit
->child_dtio
--;
1949 internal_error (&dtp
->common
, "list_formatted_write(): Bad type");
1952 fbuf_flush_list (dtp
->u
.p
.current_unit
, LIST_WRITING
);
1953 dtp
->u
.p
.char_flag
= (type
== BT_CHARACTER
);
1958 list_formatted_write (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
1959 size_t size
, size_t nelems
)
1963 size_t stride
= type
== BT_CHARACTER
?
1964 size
* GFC_SIZE_OF_CHAR_KIND(kind
) : size
;
1968 /* Big loop over all the elements. */
1969 for (elem
= 0; elem
< nelems
; elem
++)
1971 dtp
->u
.p
.item_count
++;
1972 list_formatted_write_scalar (dtp
, type
, tmp
+ elem
* stride
, kind
, size
);
1978 nml_write_obj writes a namelist object to the output stream. It is called
1979 recursively for derived type components:
1980 obj = is the namelist_info for the current object.
1981 offset = the offset relative to the address held by the object for
1982 derived type arrays.
1983 base = is the namelist_info of the derived type, when obj is a
1985 base_name = the full name for a derived type, including qualifiers
1987 The returned value is a pointer to the object beyond the last one
1988 accessed, including nested derived types. Notice that the namelist is
1989 a linear linked list of objects, including derived types and their
1990 components. A tree, of sorts, is implied by the compound names of
1991 the derived type components and this is how this function recurses through
1994 /* A generous estimate of the number of characters needed to print
1995 repeat counts and indices, including commas, asterices and brackets. */
1997 #define NML_DIGITS 20
2000 namelist_write_newline (st_parameter_dt
*dtp
)
2002 if (!is_internal_unit (dtp
))
2005 write_character (dtp
, "\r\n", 1, 2, NODELIM
);
2007 write_character (dtp
, "\n", 1, 1, NODELIM
);
2012 if (is_array_io (dtp
))
2017 int length
= dtp
->u
.p
.current_unit
->bytes_left
;
2019 p
= write_block (dtp
, length
);
2023 if (unlikely (is_char4_unit (dtp
)))
2025 gfc_char4_t
*p4
= (gfc_char4_t
*) p
;
2026 memset4 (p4
, ' ', length
);
2029 memset (p
, ' ', length
);
2031 /* Now that the current record has been padded out,
2032 determine where the next record in the array is. */
2033 record
= next_array_record (dtp
, dtp
->u
.p
.current_unit
->ls
,
2036 dtp
->u
.p
.current_unit
->endfile
= AT_ENDFILE
;
2039 /* Now seek to this record */
2040 record
= record
* dtp
->u
.p
.current_unit
->recl
;
2042 if (sseek (dtp
->u
.p
.current_unit
->s
, record
, SEEK_SET
) < 0)
2044 generate_error (&dtp
->common
, LIBERROR_INTERNAL_UNIT
, NULL
);
2048 dtp
->u
.p
.current_unit
->bytes_left
= dtp
->u
.p
.current_unit
->recl
;
2052 write_character (dtp
, " ", 1, 1, NODELIM
);
2056 static namelist_info
*
2057 nml_write_obj (st_parameter_dt
*dtp
, namelist_info
*obj
, index_type offset
,
2058 namelist_info
*base
, char *base_name
)
2064 index_type obj_size
;
2068 index_type elem_ctr
;
2069 size_t obj_name_len
;
2075 size_t ext_name_len
;
2076 char rep_buff
[NML_DIGITS
];
2078 namelist_info
*retval
= obj
->next
;
2079 size_t base_name_len
;
2080 size_t base_var_name_len
;
2083 /* Set the character to be used to separate values
2084 to a comma or semi-colon. */
2087 dtp
->u
.p
.current_unit
->decimal_status
== DECIMAL_POINT
? ',' : ';';
2089 /* Write namelist variable names in upper case. If a derived type,
2090 nothing is output. If a component, base and base_name are set. */
2092 if (obj
->type
!= BT_DERIVED
|| obj
->dtio_sub
!= NULL
)
2094 namelist_write_newline (dtp
);
2095 write_character (dtp
, " ", 1, 1, NODELIM
);
2100 len
= strlen (base
->var_name
);
2101 base_name_len
= strlen (base_name
);
2102 for (dim_i
= 0; dim_i
< base_name_len
; dim_i
++)
2104 cup
= toupper ((int) base_name
[dim_i
]);
2105 write_character (dtp
, &cup
, 1, 1, NODELIM
);
2108 clen
= strlen (obj
->var_name
);
2109 for (dim_i
= len
; dim_i
< clen
; dim_i
++)
2111 cup
= toupper ((int) obj
->var_name
[dim_i
]);
2114 write_character (dtp
, &cup
, 1, 1, NODELIM
);
2116 write_character (dtp
, "=", 1, 1, NODELIM
);
2119 /* Counts the number of data output on a line, including names. */
2129 obj_size
= size_from_real_kind (len
);
2133 obj_size
= size_from_complex_kind (len
);
2137 obj_size
= obj
->string_length
;
2145 obj_size
= obj
->size
;
2147 /* Set the index vector and count the number of elements. */
2150 for (dim_i
= 0; dim_i
< (size_t) obj
->var_rank
; dim_i
++)
2152 obj
->ls
[dim_i
].idx
= GFC_DESCRIPTOR_LBOUND(obj
, dim_i
);
2153 nelem
= nelem
* GFC_DESCRIPTOR_EXTENT (obj
, dim_i
);
2156 /* Main loop to output the data held in the object. */
2159 for (elem_ctr
= 0; elem_ctr
< nelem
; elem_ctr
++)
2162 /* Build the pointer to the data value. The offset is passed by
2163 recursive calls to this function for arrays of derived types.
2164 Is NULL otherwise. */
2166 p
= (void *)(obj
->mem_pos
+ elem_ctr
* obj_size
);
2169 /* Check for repeat counts of intrinsic types. */
2171 if ((elem_ctr
< (nelem
- 1)) &&
2172 (obj
->type
!= BT_DERIVED
) &&
2173 !memcmp (p
, (void *)(p
+ obj_size
), obj_size
))
2178 /* Execute a repeated output. Note the flag no_leading_blank that
2179 is used in the functions used to output the intrinsic types. */
2185 snprintf(rep_buff
, NML_DIGITS
, " %d*", rep_ctr
);
2186 write_character (dtp
, rep_buff
, 1, strlen (rep_buff
), NODELIM
);
2187 dtp
->u
.p
.no_leading_blank
= 1;
2191 /* Output the data, if an intrinsic type, or recurse into this
2192 routine to treat derived types. */
2198 write_integer (dtp
, p
, len
);
2202 write_logical (dtp
, p
, len
);
2206 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
2207 write_character (dtp
, p
, 4, obj
->string_length
, DELIM
);
2209 write_character (dtp
, p
, 1, obj
->string_length
, DELIM
);
2213 write_real (dtp
, p
, len
);
2217 dtp
->u
.p
.no_leading_blank
= 0;
2219 write_complex (dtp
, p
, len
, obj_size
);
2224 /* To treat a derived type, we need to build two strings:
2225 ext_name = the name, including qualifiers that prepends
2226 component names in the output - passed to
2228 obj_name = the derived type name with no qualifiers but %
2229 appended. This is used to identify the
2232 /* First ext_name => get length of all possible components */
2233 if (obj
->dtio_sub
!= NULL
)
2235 int unit
= dtp
->u
.p
.current_unit
->unit_number
;
2236 char iotype
[] = "NAMELIST";
2237 gfc_charlen_type iotype_len
= 8;
2238 char tmp_iomsg
[IOMSG_LEN
] = "";
2240 gfc_charlen_type child_iomsg_len
;
2242 int *child_iostat
= NULL
;
2243 gfc_full_array_i4 vlist
;
2244 formatted_dtio dtio_ptr
= (formatted_dtio
)obj
->dtio_sub
;
2246 GFC_DIMENSION_SET(vlist
.dim
[0],1, 0, 0);
2248 /* Set iostat, intent(out). */
2250 child_iostat
= (dtp
->common
.flags
& IOPARM_HAS_IOSTAT
) ?
2251 dtp
->common
.iostat
: &noiostat
;
2253 /* Set iomsg, intent(inout). */
2254 if (dtp
->common
.flags
& IOPARM_HAS_IOMSG
)
2256 child_iomsg
= dtp
->common
.iomsg
;
2257 child_iomsg_len
= dtp
->common
.iomsg_len
;
2261 child_iomsg
= tmp_iomsg
;
2262 child_iomsg_len
= IOMSG_LEN
;
2265 /* Call the user defined formatted WRITE procedure. */
2266 dtp
->u
.p
.current_unit
->child_dtio
++;
2267 if (obj
->type
== BT_DERIVED
)
2269 /* Build a class container. */
2272 list_obj
.vptr
= obj
->vtable
;
2274 dtio_ptr ((void *)&list_obj
, &unit
, iotype
, &vlist
,
2275 child_iostat
, child_iomsg
,
2276 iotype_len
, child_iomsg_len
);
2280 dtio_ptr (p
, &unit
, iotype
, &vlist
,
2281 child_iostat
, child_iomsg
,
2282 iotype_len
, child_iomsg_len
);
2284 dtp
->u
.p
.current_unit
->child_dtio
--;
2289 base_name_len
= base_name
? strlen (base_name
) : 0;
2290 base_var_name_len
= base
? strlen (base
->var_name
) : 0;
2291 ext_name_len
= base_name_len
+ base_var_name_len
2292 + strlen (obj
->var_name
) + obj
->var_rank
* NML_DIGITS
+ 1;
2293 ext_name
= xmalloc (ext_name_len
);
2296 memcpy (ext_name
, base_name
, base_name_len
);
2297 clen
= strlen (obj
->var_name
+ base_var_name_len
);
2298 memcpy (ext_name
+ base_name_len
,
2299 obj
->var_name
+ base_var_name_len
, clen
);
2301 /* Append the qualifier. */
2303 tot_len
= base_name_len
+ clen
;
2304 for (dim_i
= 0; dim_i
< (size_t) obj
->var_rank
; dim_i
++)
2308 ext_name
[tot_len
] = '(';
2311 snprintf (ext_name
+ tot_len
, ext_name_len
- tot_len
, "%d",
2312 (int) obj
->ls
[dim_i
].idx
);
2313 tot_len
+= strlen (ext_name
+ tot_len
);
2314 ext_name
[tot_len
] = ((int) dim_i
== obj
->var_rank
- 1) ? ')' : ',';
2318 ext_name
[tot_len
] = '\0';
2319 for (q
= ext_name
; *q
; q
++)
2325 obj_name_len
= strlen (obj
->var_name
) + 1;
2326 obj_name
= xmalloc (obj_name_len
+ 1);
2327 memcpy (obj_name
, obj
->var_name
, obj_name_len
-1);
2328 memcpy (obj_name
+ obj_name_len
-1, "%", 2);
2330 /* Now loop over the components. Update the component pointer
2331 with the return value from nml_write_obj => this loop jumps
2332 past nested derived types. */
2334 for (cmp
= obj
->next
;
2335 cmp
&& !strncmp (cmp
->var_name
, obj_name
, obj_name_len
);
2338 retval
= nml_write_obj (dtp
, cmp
,
2339 (index_type
)(p
- obj
->mem_pos
),
2348 internal_error (&dtp
->common
, "Bad type for namelist write");
2351 /* Reset the leading blank suppression, write a comma (or semi-colon)
2352 and, if 5 values have been output, write a newline and advance
2353 to column 2. Reset the repeat counter. */
2355 dtp
->u
.p
.no_leading_blank
= 0;
2356 if (obj
->type
== BT_CHARACTER
)
2358 if (dtp
->u
.p
.nml_delim
!= '\0')
2359 write_character (dtp
, &semi_comma
, 1, 1, NODELIM
);
2362 write_character (dtp
, &semi_comma
, 1, 1, NODELIM
);
2366 if (dtp
->u
.p
.nml_delim
== '\0')
2367 write_character (dtp
, &semi_comma
, 1, 1, NODELIM
);
2368 namelist_write_newline (dtp
);
2369 write_character (dtp
, " ", 1, 1, NODELIM
);
2374 /* Cycle through and increment the index vector. */
2379 for (dim_i
= 0; nml_carry
&& (dim_i
< (size_t) obj
->var_rank
); dim_i
++)
2381 obj
->ls
[dim_i
].idx
+= nml_carry
;
2383 if (obj
->ls
[dim_i
].idx
> GFC_DESCRIPTOR_UBOUND(obj
,dim_i
))
2385 obj
->ls
[dim_i
].idx
= GFC_DESCRIPTOR_LBOUND(obj
,dim_i
);
2391 /* Return a pointer beyond the furthest object accessed. */
2397 /* This is the entry function for namelist writes. It outputs the name
2398 of the namelist and iterates through the namelist by calls to
2399 nml_write_obj. The call below has dummys in the arguments used in
2400 the treatment of derived types. */
2403 namelist_write (st_parameter_dt
*dtp
)
2405 namelist_info
*t1
, *t2
, *dummy
= NULL
;
2406 index_type dummy_offset
= 0;
2408 char *dummy_name
= NULL
;
2410 /* Set the delimiter for namelist output. */
2411 switch (dtp
->u
.p
.current_unit
->delim_status
)
2413 case DELIM_APOSTROPHE
:
2414 dtp
->u
.p
.nml_delim
= '\'';
2417 case DELIM_UNSPECIFIED
:
2418 dtp
->u
.p
.nml_delim
= '"';
2421 dtp
->u
.p
.nml_delim
= '\0';
2424 write_character (dtp
, "&", 1, 1, NODELIM
);
2426 /* Write namelist name in upper case - f95 std. */
2427 for (gfc_charlen_type i
= 0; i
< dtp
->namelist_name_len
; i
++ )
2429 c
= toupper ((int) dtp
->namelist_name
[i
]);
2430 write_character (dtp
, &c
, 1 ,1, NODELIM
);
2433 if (dtp
->u
.p
.ionml
!= NULL
)
2435 t1
= dtp
->u
.p
.ionml
;
2439 t1
= nml_write_obj (dtp
, t2
, dummy_offset
, dummy
, dummy_name
);
2443 namelist_write_newline (dtp
);
2444 write_character (dtp
, " /", 1, 2, NODELIM
);