1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4 Namelist output contributed by Paul Thomas
5 F2003 I/O support contributed by Jerry DeLisle
7 This file is part of the GNU Fortran 95 runtime library (libgfortran).
9 Libgfortran is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 Libgfortran is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
35 #define star_fill(p, n) memset(p, '*', n)
37 #include "write_float.def"
39 typedef unsigned char uchar
;
41 /* Write out default char4. */
44 write_default_char4 (st_parameter_dt
*dtp
, gfc_char4_t
*source
,
45 int src_len
, int w_len
)
52 /* Take care of preceding blanks. */
56 p
= write_block (dtp
, k
);
62 /* Get ready to handle delimiters if needed. */
63 switch (dtp
->u
.p
.current_unit
->delim_status
)
65 case DELIM_APOSTROPHE
:
76 /* Now process the remaining characters, one at a time. */
77 for (j
= k
; j
< src_len
; j
++)
81 /* Handle delimiters if any. */
82 if (c
== d
&& d
!= ' ')
84 p
= write_block (dtp
, 2);
91 p
= write_block (dtp
, 1);
95 *p
= c
> 255 ? '?' : (uchar
) c
;
100 /* Write out UTF-8 converted from char4. */
103 write_utf8_char4 (st_parameter_dt
*dtp
, gfc_char4_t
*source
,
104 int src_len
, int w_len
)
109 static const uchar masks
[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
110 static const uchar limits
[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
114 /* Take care of preceding blanks. */
118 p
= write_block (dtp
, k
);
124 /* Get ready to handle delimiters if needed. */
125 switch (dtp
->u
.p
.current_unit
->delim_status
)
127 case DELIM_APOSTROPHE
:
138 /* Now process the remaining characters, one at a time. */
139 for (j
= k
; j
< src_len
; j
++)
144 /* Handle the delimiters if any. */
145 if (c
== d
&& d
!= ' ')
147 p
= write_block (dtp
, 2);
154 p
= write_block (dtp
, 1);
162 /* Convert to UTF-8 sequence. */
168 *--q
= ((c
& 0x3F) | 0x80);
172 while (c
>= 0x3F || (c
& limits
[nbytes
-1]));
174 *--q
= (c
| masks
[nbytes
-1]);
176 p
= write_block (dtp
, nbytes
);
188 write_a (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
193 wlen
= f
->u
.string
.length
< 0
194 || (f
->format
== FMT_G
&& f
->u
.string
.length
== 0)
195 ? len
: f
->u
.string
.length
;
198 /* If this is formatted STREAM IO convert any embedded line feed characters
199 to CR_LF on systems that use that sequence for newlines. See F2003
200 Standard sections 10.6.3 and 9.9 for further information. */
201 if (is_stream_io (dtp
))
203 const char crlf
[] = "\r\n";
207 /* Write out any padding if needed. */
210 p
= write_block (dtp
, wlen
- len
);
213 memset (p
, ' ', wlen
- len
);
216 /* Scan the source string looking for '\n' and convert it if found. */
217 for (i
= 0; i
< wlen
; i
++)
219 if (source
[i
] == '\n')
221 /* Write out the previously scanned characters in the string. */
224 p
= write_block (dtp
, bytes
);
227 memcpy (p
, &source
[q
], bytes
);
232 /* Write out the CR_LF sequence. */
234 p
= write_block (dtp
, 2);
243 /* Write out any remaining bytes if no LF was found. */
246 p
= write_block (dtp
, bytes
);
249 memcpy (p
, &source
[q
], bytes
);
255 p
= write_block (dtp
, wlen
);
260 memcpy (p
, source
, wlen
);
263 memset (p
, ' ', wlen
- len
);
264 memcpy (p
+ wlen
- len
, source
, len
);
272 /* The primary difference between write_a_char4 and write_a is that we have to
273 deal with writing from the first byte of the 4-byte character and pay
274 attention to the most significant bytes. For ENCODING="default" write the
275 lowest significant byte. If the 3 most significant bytes contain
276 non-zero values, emit a '?'. For ENCODING="utf-8", convert the UCS-32 value
277 to the UTF-8 encoded string before writing out. */
280 write_a_char4 (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
285 wlen
= f
->u
.string
.length
< 0
286 || (f
->format
== FMT_G
&& f
->u
.string
.length
== 0)
287 ? len
: f
->u
.string
.length
;
289 q
= (gfc_char4_t
*) source
;
291 /* If this is formatted STREAM IO convert any embedded line feed characters
292 to CR_LF on systems that use that sequence for newlines. See F2003
293 Standard sections 10.6.3 and 9.9 for further information. */
294 if (is_stream_io (dtp
))
296 const char crlf
[] = "\r\n";
301 /* Write out any padding if needed. */
305 p
= write_block (dtp
, wlen
- len
);
308 memset (p
, ' ', wlen
- len
);
311 /* Scan the source string looking for '\n' and convert it if found. */
312 qq
= (gfc_char4_t
*) source
;
313 for (i
= 0; i
< wlen
; i
++)
317 /* Write out the previously scanned characters in the string. */
320 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
321 write_utf8_char4 (dtp
, q
, bytes
, 0);
323 write_default_char4 (dtp
, q
, bytes
, 0);
327 /* Write out the CR_LF sequence. */
328 write_default_char4 (dtp
, crlf
, 2, 0);
334 /* Write out any remaining bytes if no LF was found. */
337 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
338 write_utf8_char4 (dtp
, q
, bytes
, 0);
340 write_default_char4 (dtp
, q
, bytes
, 0);
346 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
347 write_utf8_char4 (dtp
, q
, len
, wlen
);
349 write_default_char4 (dtp
, q
, len
, wlen
);
356 static GFC_INTEGER_LARGEST
357 extract_int (const void *p
, int len
)
359 GFC_INTEGER_LARGEST i
= 0;
369 memcpy ((void *) &tmp
, p
, len
);
376 memcpy ((void *) &tmp
, p
, len
);
383 memcpy ((void *) &tmp
, p
, len
);
390 memcpy ((void *) &tmp
, p
, len
);
394 #ifdef HAVE_GFC_INTEGER_16
398 memcpy ((void *) &tmp
, p
, len
);
404 internal_error (NULL
, "bad integer kind");
410 static GFC_UINTEGER_LARGEST
411 extract_uint (const void *p
, int len
)
413 GFC_UINTEGER_LARGEST i
= 0;
423 memcpy ((void *) &tmp
, p
, len
);
424 i
= (GFC_UINTEGER_1
) tmp
;
430 memcpy ((void *) &tmp
, p
, len
);
431 i
= (GFC_UINTEGER_2
) tmp
;
437 memcpy ((void *) &tmp
, p
, len
);
438 i
= (GFC_UINTEGER_4
) tmp
;
444 memcpy ((void *) &tmp
, p
, len
);
445 i
= (GFC_UINTEGER_8
) tmp
;
448 #ifdef HAVE_GFC_INTEGER_16
452 memcpy ((void *) &tmp
, p
, len
);
453 i
= (GFC_UINTEGER_16
) tmp
;
458 internal_error (NULL
, "bad integer kind");
466 write_l (st_parameter_dt
*dtp
, const fnode
*f
, char *source
, int len
)
470 GFC_INTEGER_LARGEST n
;
472 wlen
= (f
->format
== FMT_G
&& f
->u
.w
== 0) ? 1 : f
->u
.w
;
474 p
= write_block (dtp
, wlen
);
478 memset (p
, ' ', wlen
- 1);
479 n
= extract_int (source
, len
);
480 p
[wlen
- 1] = (n
) ? 'T' : 'F';
485 write_int (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
,
486 const char *(*conv
) (GFC_UINTEGER_LARGEST
, char *, size_t))
488 GFC_UINTEGER_LARGEST n
= 0;
489 int w
, m
, digits
, nzero
, nblank
;
492 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
497 n
= extract_uint (source
, len
);
501 if (m
== 0 && n
== 0)
506 p
= write_block (dtp
, w
);
514 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
517 /* Select a width if none was specified. The idea here is to always
521 w
= ((digits
< m
) ? m
: digits
);
523 p
= write_block (dtp
, w
);
531 /* See if things will work. */
533 nblank
= w
- (nzero
+ digits
);
542 if (!dtp
->u
.p
.no_leading_blank
)
544 memset (p
, ' ', nblank
);
546 memset (p
, '0', nzero
);
548 memcpy (p
, q
, digits
);
552 memset (p
, '0', nzero
);
554 memcpy (p
, q
, digits
);
556 memset (p
, ' ', nblank
);
557 dtp
->u
.p
.no_leading_blank
= 0;
565 write_decimal (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
,
567 const char *(*conv
) (GFC_INTEGER_LARGEST
, char *, size_t))
569 GFC_INTEGER_LARGEST n
= 0;
570 int w
, m
, digits
, nsign
, nzero
, nblank
;
574 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
577 m
= f
->format
== FMT_G
? -1 : f
->u
.integer
.m
;
579 n
= extract_int (source
, len
);
582 if (m
== 0 && n
== 0)
587 p
= write_block (dtp
, w
);
595 sign
= calculate_sign (dtp
, n
< 0);
598 nsign
= sign
== S_NONE
? 0 : 1;
600 /* conv calls itoa which sets the negative sign needed
601 by write_integer. The sign '+' or '-' is set below based on sign
602 calculated above, so we just point past the sign in the string
603 before proceeding to avoid double signs in corner cases.
605 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
611 /* Select a width if none was specified. The idea here is to always
615 w
= ((digits
< m
) ? m
: digits
) + nsign
;
617 p
= write_block (dtp
, w
);
625 /* See if things will work. */
627 nblank
= w
- (nsign
+ nzero
+ digits
);
635 memset (p
, ' ', nblank
);
650 memset (p
, '0', nzero
);
653 memcpy (p
, q
, digits
);
660 /* Convert unsigned octal to ascii. */
663 otoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
667 assert (len
>= GFC_OTOA_BUF_SIZE
);
672 p
= buffer
+ GFC_OTOA_BUF_SIZE
- 1;
677 *--p
= '0' + (n
& 7);
685 /* Convert unsigned binary to ascii. */
688 btoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
692 assert (len
>= GFC_BTOA_BUF_SIZE
);
697 p
= buffer
+ GFC_BTOA_BUF_SIZE
- 1;
702 *--p
= '0' + (n
& 1);
710 /* gfc_itoa()-- Integer to decimal conversion.
711 The itoa function is a widespread non-standard extension to standard
712 C, often declared in <stdlib.h>. Even though the itoa defined here
713 is a static function we take care not to conflict with any prior
714 non-static declaration. Hence the 'gfc_' prefix, which is normally
715 reserved for functions with external linkage. */
718 gfc_itoa (GFC_INTEGER_LARGEST n
, char *buffer
, size_t len
)
722 GFC_UINTEGER_LARGEST t
;
724 assert (len
>= GFC_ITOA_BUF_SIZE
);
734 t
= -n
; /*must use unsigned to protect from overflow*/
737 p
= buffer
+ GFC_ITOA_BUF_SIZE
- 1;
742 *--p
= '0' + (t
% 10);
753 write_i (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
755 write_decimal (dtp
, f
, p
, len
, (void *) gfc_itoa
);
760 write_b (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
762 write_int (dtp
, f
, p
, len
, btoa
);
767 write_o (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
769 write_int (dtp
, f
, p
, len
, otoa
);
773 write_z (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
775 write_int (dtp
, f
, p
, len
, gfc_xtoa
);
780 write_d (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
782 write_float (dtp
, f
, p
, len
);
787 write_e (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
789 write_float (dtp
, f
, p
, len
);
794 write_f (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
796 write_float (dtp
, f
, p
, len
);
801 write_en (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
803 write_float (dtp
, f
, p
, len
);
808 write_es (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
810 write_float (dtp
, f
, p
, len
);
814 /* Take care of the X/TR descriptor. */
817 write_x (st_parameter_dt
*dtp
, int len
, int nspaces
)
821 p
= write_block (dtp
, len
);
824 if (nspaces
> 0 && len
- nspaces
>= 0)
825 memset (&p
[len
- nspaces
], ' ', nspaces
);
829 /* List-directed writing. */
832 /* Write a single character to the output. Returns nonzero if
833 something goes wrong. */
836 write_char (st_parameter_dt
*dtp
, char c
)
840 p
= write_block (dtp
, 1);
850 /* Write a list-directed logical value. */
853 write_logical (st_parameter_dt
*dtp
, const char *source
, int length
)
855 write_char (dtp
, extract_int (source
, length
) ? 'T' : 'F');
859 /* Write a list-directed integer value. */
862 write_integer (st_parameter_dt
*dtp
, const char *source
, int length
)
868 char itoa_buf
[GFC_ITOA_BUF_SIZE
];
870 q
= gfc_itoa (extract_int (source
, length
), itoa_buf
, sizeof (itoa_buf
));
899 p
= write_block (dtp
, width
);
902 if (dtp
->u
.p
.no_leading_blank
)
904 memcpy (p
, q
, digits
);
905 memset (p
+ digits
, ' ', width
- digits
);
909 memset (p
, ' ', width
- digits
);
910 memcpy (p
+ width
- digits
, q
, digits
);
915 /* Write a list-directed string. We have to worry about delimiting
916 the strings if the file has been opened in that mode. */
919 write_character (st_parameter_dt
*dtp
, const char *source
, int kind
, int length
)
924 switch (dtp
->u
.p
.current_unit
->delim_status
)
926 case DELIM_APOSTROPHE
:
945 for (i
= 0; i
< length
; i
++)
950 p
= write_block (dtp
, length
+ extra
);
955 memcpy (p
, source
, length
);
960 for (i
= 0; i
< length
; i
++)
974 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
975 write_utf8_char4 (dtp
, (gfc_char4_t
*) source
, length
, 0);
977 write_default_char4 (dtp
, (gfc_char4_t
*) source
, length
, 0);
981 p
= write_block (dtp
, 1);
984 if (dtp
->u
.p
.current_unit
->flags
.encoding
== ENCODING_UTF8
)
985 write_utf8_char4 (dtp
, (gfc_char4_t
*) source
, length
, 0);
987 write_default_char4 (dtp
, (gfc_char4_t
*) source
, length
, 0);
989 p
= write_block (dtp
, 1);
996 /* Set an fnode to default format. */
999 set_fnode_default (st_parameter_dt
*dtp
, fnode
*f
, int length
)
1025 internal_error (&dtp
->common
, "bad real kind");
1029 /* Output a real number with default format.
1030 This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
1031 1PG28.19E4 for REAL(10) and 1PG43.34E4 for REAL(16). */
1034 write_real (st_parameter_dt
*dtp
, const char *source
, int length
)
1037 int org_scale
= dtp
->u
.p
.scale_factor
;
1038 dtp
->u
.p
.scale_factor
= 1;
1039 set_fnode_default (dtp
, &f
, length
);
1040 write_float (dtp
, &f
, source
, length
);
1041 dtp
->u
.p
.scale_factor
= org_scale
;
1046 write_real_g0 (st_parameter_dt
*dtp
, const char *source
, int length
, int d
)
1049 set_fnode_default (dtp
, &f
, length
);
1052 dtp
->u
.p
.g0_no_blanks
= 1;
1053 write_float (dtp
, &f
, source
, length
);
1054 dtp
->u
.p
.g0_no_blanks
= 0;
1059 write_complex (st_parameter_dt
*dtp
, const char *source
, int kind
, size_t size
)
1062 dtp
->u
.p
.current_unit
->decimal_status
== DECIMAL_POINT
? ',' : ';';
1064 if (write_char (dtp
, '('))
1066 write_real (dtp
, source
, kind
);
1068 if (write_char (dtp
, semi_comma
))
1070 write_real (dtp
, source
+ size
/ 2, kind
);
1072 write_char (dtp
, ')');
1076 /* Write the separator between items. */
1079 write_separator (st_parameter_dt
*dtp
)
1083 p
= write_block (dtp
, options
.separator_len
);
1087 memcpy (p
, options
.separator
, options
.separator_len
);
1091 /* Write an item with list formatting.
1092 TODO: handle skipping to the next record correctly, particularly
1096 list_formatted_write_scalar (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
1099 if (dtp
->u
.p
.current_unit
== NULL
)
1102 if (dtp
->u
.p
.first_item
)
1104 dtp
->u
.p
.first_item
= 0;
1105 write_char (dtp
, ' ');
1109 if (type
!= BT_CHARACTER
|| !dtp
->u
.p
.char_flag
||
1110 dtp
->u
.p
.current_unit
->delim_status
!= DELIM_NONE
)
1111 write_separator (dtp
);
1117 write_integer (dtp
, p
, kind
);
1120 write_logical (dtp
, p
, kind
);
1123 write_character (dtp
, p
, kind
, size
);
1126 write_real (dtp
, p
, kind
);
1129 write_complex (dtp
, p
, kind
, size
);
1132 internal_error (&dtp
->common
, "list_formatted_write(): Bad type");
1135 dtp
->u
.p
.char_flag
= (type
== BT_CHARACTER
);
1140 list_formatted_write (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
1141 size_t size
, size_t nelems
)
1145 size_t stride
= type
== BT_CHARACTER
?
1146 size
* GFC_SIZE_OF_CHAR_KIND(kind
) : size
;
1150 /* Big loop over all the elements. */
1151 for (elem
= 0; elem
< nelems
; elem
++)
1153 dtp
->u
.p
.item_count
++;
1154 list_formatted_write_scalar (dtp
, type
, tmp
+ elem
* stride
, kind
, size
);
1160 nml_write_obj writes a namelist object to the output stream. It is called
1161 recursively for derived type components:
1162 obj = is the namelist_info for the current object.
1163 offset = the offset relative to the address held by the object for
1164 derived type arrays.
1165 base = is the namelist_info of the derived type, when obj is a
1167 base_name = the full name for a derived type, including qualifiers
1169 The returned value is a pointer to the object beyond the last one
1170 accessed, including nested derived types. Notice that the namelist is
1171 a linear linked list of objects, including derived types and their
1172 components. A tree, of sorts, is implied by the compound names of
1173 the derived type components and this is how this function recurses through
1176 /* A generous estimate of the number of characters needed to print
1177 repeat counts and indices, including commas, asterices and brackets. */
1179 #define NML_DIGITS 20
1182 namelist_write_newline (st_parameter_dt
*dtp
)
1184 if (!is_internal_unit (dtp
))
1187 write_character (dtp
, "\r\n", 1, 2);
1189 write_character (dtp
, "\n", 1, 1);
1194 if (is_array_io (dtp
))
1197 int finished
, length
;
1199 length
= (int) dtp
->u
.p
.current_unit
->bytes_left
;
1201 /* Now that the current record has been padded out,
1202 determine where the next record in the array is. */
1203 record
= next_array_record (dtp
, dtp
->u
.p
.current_unit
->ls
,
1206 dtp
->u
.p
.current_unit
->endfile
= AT_ENDFILE
;
1209 /* Now seek to this record */
1210 record
= record
* dtp
->u
.p
.current_unit
->recl
;
1212 if (sseek (dtp
->u
.p
.current_unit
->s
, record
, SEEK_SET
) < 0)
1214 generate_error (&dtp
->common
, LIBERROR_INTERNAL_UNIT
, NULL
);
1218 dtp
->u
.p
.current_unit
->bytes_left
= dtp
->u
.p
.current_unit
->recl
;
1222 write_character (dtp
, " ", 1, 1);
1226 static namelist_info
*
1227 nml_write_obj (st_parameter_dt
*dtp
, namelist_info
* obj
, index_type offset
,
1228 namelist_info
* base
, char * base_name
)
1234 index_type obj_size
;
1238 index_type elem_ctr
;
1239 size_t obj_name_len
;
1244 char rep_buff
[NML_DIGITS
];
1245 namelist_info
* cmp
;
1246 namelist_info
* retval
= obj
->next
;
1247 size_t base_name_len
;
1248 size_t base_var_name_len
;
1250 unit_delim tmp_delim
;
1252 /* Set the character to be used to separate values
1253 to a comma or semi-colon. */
1256 dtp
->u
.p
.current_unit
->decimal_status
== DECIMAL_POINT
? ',' : ';';
1258 /* Write namelist variable names in upper case. If a derived type,
1259 nothing is output. If a component, base and base_name are set. */
1261 if (obj
->type
!= GFC_DTYPE_DERIVED
)
1263 namelist_write_newline (dtp
);
1264 write_character (dtp
, " ", 1, 1);
1269 len
= strlen (base
->var_name
);
1270 base_name_len
= strlen (base_name
);
1271 for (dim_i
= 0; dim_i
< base_name_len
; dim_i
++)
1273 cup
= toupper (base_name
[dim_i
]);
1274 write_character (dtp
, &cup
, 1, 1);
1277 clen
= strlen (obj
->var_name
);
1278 for (dim_i
= len
; dim_i
< clen
; dim_i
++)
1280 cup
= toupper (obj
->var_name
[dim_i
]);
1281 write_character (dtp
, &cup
, 1, 1);
1283 write_character (dtp
, "=", 1, 1);
1286 /* Counts the number of data output on a line, including names. */
1295 case GFC_DTYPE_REAL
:
1296 obj_size
= size_from_real_kind (len
);
1299 case GFC_DTYPE_COMPLEX
:
1300 obj_size
= size_from_complex_kind (len
);
1303 case GFC_DTYPE_CHARACTER
:
1304 obj_size
= obj
->string_length
;
1312 obj_size
= obj
->size
;
1314 /* Set the index vector and count the number of elements. */
1317 for (dim_i
= 0; dim_i
< (size_t) obj
->var_rank
; dim_i
++)
1319 obj
->ls
[dim_i
].idx
= GFC_DESCRIPTOR_LBOUND(obj
, dim_i
);
1320 nelem
= nelem
* GFC_DESCRIPTOR_EXTENT (obj
, dim_i
);
1323 /* Main loop to output the data held in the object. */
1326 for (elem_ctr
= 0; elem_ctr
< nelem
; elem_ctr
++)
1329 /* Build the pointer to the data value. The offset is passed by
1330 recursive calls to this function for arrays of derived types.
1331 Is NULL otherwise. */
1333 p
= (void *)(obj
->mem_pos
+ elem_ctr
* obj_size
);
1336 /* Check for repeat counts of intrinsic types. */
1338 if ((elem_ctr
< (nelem
- 1)) &&
1339 (obj
->type
!= GFC_DTYPE_DERIVED
) &&
1340 !memcmp (p
, (void*)(p
+ obj_size
), obj_size
))
1345 /* Execute a repeated output. Note the flag no_leading_blank that
1346 is used in the functions used to output the intrinsic types. */
1352 sprintf(rep_buff
, " %d*", rep_ctr
);
1353 write_character (dtp
, rep_buff
, 1, strlen (rep_buff
));
1354 dtp
->u
.p
.no_leading_blank
= 1;
1358 /* Output the data, if an intrinsic type, or recurse into this
1359 routine to treat derived types. */
1364 case GFC_DTYPE_INTEGER
:
1365 write_integer (dtp
, p
, len
);
1368 case GFC_DTYPE_LOGICAL
:
1369 write_logical (dtp
, p
, len
);
1372 case GFC_DTYPE_CHARACTER
:
1373 tmp_delim
= dtp
->u
.p
.current_unit
->delim_status
;
1374 if (dtp
->u
.p
.nml_delim
== '"')
1375 dtp
->u
.p
.current_unit
->delim_status
= DELIM_QUOTE
;
1376 if (dtp
->u
.p
.nml_delim
== '\'')
1377 dtp
->u
.p
.current_unit
->delim_status
= DELIM_APOSTROPHE
;
1378 write_character (dtp
, p
, 1, obj
->string_length
);
1379 dtp
->u
.p
.current_unit
->delim_status
= tmp_delim
;
1382 case GFC_DTYPE_REAL
:
1383 write_real (dtp
, p
, len
);
1386 case GFC_DTYPE_COMPLEX
:
1387 dtp
->u
.p
.no_leading_blank
= 0;
1389 write_complex (dtp
, p
, len
, obj_size
);
1392 case GFC_DTYPE_DERIVED
:
1394 /* To treat a derived type, we need to build two strings:
1395 ext_name = the name, including qualifiers that prepends
1396 component names in the output - passed to
1398 obj_name = the derived type name with no qualifiers but %
1399 appended. This is used to identify the
1402 /* First ext_name => get length of all possible components */
1404 base_name_len
= base_name
? strlen (base_name
) : 0;
1405 base_var_name_len
= base
? strlen (base
->var_name
) : 0;
1406 ext_name
= (char*)get_mem ( base_name_len
1408 + strlen (obj
->var_name
)
1409 + obj
->var_rank
* NML_DIGITS
1412 memcpy (ext_name
, base_name
, base_name_len
);
1413 clen
= strlen (obj
->var_name
+ base_var_name_len
);
1414 memcpy (ext_name
+ base_name_len
,
1415 obj
->var_name
+ base_var_name_len
, clen
);
1417 /* Append the qualifier. */
1419 tot_len
= base_name_len
+ clen
;
1420 for (dim_i
= 0; dim_i
< (size_t) obj
->var_rank
; dim_i
++)
1424 ext_name
[tot_len
] = '(';
1427 sprintf (ext_name
+ tot_len
, "%d", (int) obj
->ls
[dim_i
].idx
);
1428 tot_len
+= strlen (ext_name
+ tot_len
);
1429 ext_name
[tot_len
] = ((int) dim_i
== obj
->var_rank
- 1) ? ')' : ',';
1433 ext_name
[tot_len
] = '\0';
1437 obj_name_len
= strlen (obj
->var_name
) + 1;
1438 obj_name
= get_mem (obj_name_len
+1);
1439 memcpy (obj_name
, obj
->var_name
, obj_name_len
-1);
1440 memcpy (obj_name
+ obj_name_len
-1, "%", 2);
1442 /* Now loop over the components. Update the component pointer
1443 with the return value from nml_write_obj => this loop jumps
1444 past nested derived types. */
1446 for (cmp
= obj
->next
;
1447 cmp
&& !strncmp (cmp
->var_name
, obj_name
, obj_name_len
);
1450 retval
= nml_write_obj (dtp
, cmp
,
1451 (index_type
)(p
- obj
->mem_pos
),
1455 free_mem (obj_name
);
1456 free_mem (ext_name
);
1460 internal_error (&dtp
->common
, "Bad type for namelist write");
1463 /* Reset the leading blank suppression, write a comma (or semi-colon)
1464 and, if 5 values have been output, write a newline and advance
1465 to column 2. Reset the repeat counter. */
1467 dtp
->u
.p
.no_leading_blank
= 0;
1468 write_character (dtp
, &semi_comma
, 1, 1);
1472 namelist_write_newline (dtp
);
1473 write_character (dtp
, " ", 1, 1);
1478 /* Cycle through and increment the index vector. */
1483 for (dim_i
= 0; nml_carry
&& (dim_i
< (size_t) obj
->var_rank
); dim_i
++)
1485 obj
->ls
[dim_i
].idx
+= nml_carry
;
1487 if (obj
->ls
[dim_i
].idx
> (ssize_t
) GFC_DESCRIPTOR_UBOUND(obj
,dim_i
))
1489 obj
->ls
[dim_i
].idx
= GFC_DESCRIPTOR_LBOUND(obj
,dim_i
);
1495 /* Return a pointer beyond the furthest object accessed. */
1501 /* This is the entry function for namelist writes. It outputs the name
1502 of the namelist and iterates through the namelist by calls to
1503 nml_write_obj. The call below has dummys in the arguments used in
1504 the treatment of derived types. */
1507 namelist_write (st_parameter_dt
*dtp
)
1509 namelist_info
* t1
, *t2
, *dummy
= NULL
;
1511 index_type dummy_offset
= 0;
1513 char * dummy_name
= NULL
;
1514 unit_delim tmp_delim
= DELIM_UNSPECIFIED
;
1516 /* Set the delimiter for namelist output. */
1517 tmp_delim
= dtp
->u
.p
.current_unit
->delim_status
;
1519 dtp
->u
.p
.nml_delim
= tmp_delim
== DELIM_APOSTROPHE
? '\'' : '"';
1521 /* Temporarily disable namelist delimters. */
1522 dtp
->u
.p
.current_unit
->delim_status
= DELIM_NONE
;
1524 write_character (dtp
, "&", 1, 1);
1526 /* Write namelist name in upper case - f95 std. */
1527 for (i
= 0 ;i
< dtp
->namelist_name_len
;i
++ )
1529 c
= toupper (dtp
->namelist_name
[i
]);
1530 write_character (dtp
, &c
, 1 ,1);
1533 if (dtp
->u
.p
.ionml
!= NULL
)
1535 t1
= dtp
->u
.p
.ionml
;
1539 t1
= nml_write_obj (dtp
, t2
, dummy_offset
, dummy
, dummy_name
);
1543 namelist_write_newline (dtp
);
1544 write_character (dtp
, " /", 1, 2);
1545 /* Restore the original delimiter. */
1546 dtp
->u
.p
.current_unit
->delim_status
= tmp_delim
;