1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006 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 #include "libgfortran.h"
40 #define star_fill(p, n) memset(p, '*', n)
44 { SIGN_NONE
, SIGN_MINUS
, SIGN_PLUS
}
49 write_a (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
54 wlen
= f
->u
.string
.length
< 0 ? len
: f
->u
.string
.length
;
57 /* If this is formatted STREAM IO convert any embedded line feed characters
58 to CR_LF on systems that use that sequence for newlines. See F2003
59 Standard sections 10.6.3 and 9.9 for further information. */
60 if (is_stream_io (dtp
))
62 const char crlf
[] = "\r\n";
66 /* Write out any padding if needed. */
69 p
= write_block (dtp
, wlen
- len
);
72 memset (p
, ' ', wlen
- len
);
75 /* Scan the source string looking for '\n' and convert it if found. */
76 for (i
= 0; i
< wlen
; i
++)
78 if (source
[i
] == '\n')
80 /* Write out the previously scanned characters in the string. */
83 p
= write_block (dtp
, bytes
);
86 memcpy (p
, &source
[q
], bytes
);
91 /* Write out the CR_LF sequence. */
93 p
= write_block (dtp
, 2);
102 /* Write out any remaining bytes if no LF was found. */
105 p
= write_block (dtp
, bytes
);
108 memcpy (p
, &source
[q
], bytes
);
114 p
= write_block (dtp
, wlen
);
119 memcpy (p
, source
, wlen
);
122 memset (p
, ' ', wlen
- len
);
123 memcpy (p
+ wlen
- len
, source
, len
);
130 static GFC_INTEGER_LARGEST
131 extract_int (const void *p
, int len
)
133 GFC_INTEGER_LARGEST i
= 0;
143 memcpy ((void *) &tmp
, p
, len
);
150 memcpy ((void *) &tmp
, p
, len
);
157 memcpy ((void *) &tmp
, p
, len
);
164 memcpy ((void *) &tmp
, p
, len
);
168 #ifdef HAVE_GFC_INTEGER_16
172 memcpy ((void *) &tmp
, p
, len
);
178 internal_error (NULL
, "bad integer kind");
184 static GFC_UINTEGER_LARGEST
185 extract_uint (const void *p
, int len
)
187 GFC_UINTEGER_LARGEST i
= 0;
197 memcpy ((void *) &tmp
, p
, len
);
198 i
= (GFC_UINTEGER_1
) tmp
;
204 memcpy ((void *) &tmp
, p
, len
);
205 i
= (GFC_UINTEGER_2
) tmp
;
211 memcpy ((void *) &tmp
, p
, len
);
212 i
= (GFC_UINTEGER_4
) tmp
;
218 memcpy ((void *) &tmp
, p
, len
);
219 i
= (GFC_UINTEGER_8
) tmp
;
222 #ifdef HAVE_GFC_INTEGER_16
226 memcpy ((void *) &tmp
, p
, len
);
227 i
= (GFC_UINTEGER_16
) tmp
;
232 internal_error (NULL
, "bad integer kind");
238 static GFC_REAL_LARGEST
239 extract_real (const void *p
, int len
)
241 GFC_REAL_LARGEST i
= 0;
247 memcpy ((void *) &tmp
, p
, len
);
254 memcpy ((void *) &tmp
, p
, len
);
258 #ifdef HAVE_GFC_REAL_10
262 memcpy ((void *) &tmp
, p
, len
);
267 #ifdef HAVE_GFC_REAL_16
271 memcpy ((void *) &tmp
, p
, len
);
277 internal_error (NULL
, "bad real kind");
283 /* Given a flag that indicate if a value is negative or not, return a
284 sign_t that gives the sign that we need to produce. */
287 calculate_sign (st_parameter_dt
*dtp
, int negative_flag
)
289 sign_t s
= SIGN_NONE
;
294 switch (dtp
->u
.p
.sign_status
)
303 s
= options
.optional_plus
? SIGN_PLUS
: SIGN_NONE
;
311 /* Returns the value of 10**d. */
313 static GFC_REAL_LARGEST
314 calculate_exp (int d
)
317 GFC_REAL_LARGEST r
= 1.0;
319 for (i
= 0; i
< (d
>= 0 ? d
: -d
); i
++)
322 r
= (d
>= 0) ? r
: 1.0 / r
;
328 /* Generate corresponding I/O format for FMT_G output.
329 The rules to translate FMT_G to FMT_E or FMT_F from DEC fortran
330 LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
332 Data Magnitude Equivalent Conversion
333 0< m < 0.1-0.5*10**(-d-1) Ew.d[Ee]
334 m = 0 F(w-n).(d-1), n' '
335 0.1-0.5*10**(-d-1)<= m < 1-0.5*10**(-d) F(w-n).d, n' '
336 1-0.5*10**(-d)<= m < 10-0.5*10**(-d+1) F(w-n).(d-1), n' '
337 10-0.5*10**(-d+1)<= m < 100-0.5*10**(-d+2) F(w-n).(d-2), n' '
338 ................ ..........
339 10**(d-1)-0.5*10**(-1)<= m <10**d-0.5 F(w-n).0,n(' ')
340 m >= 10**d-0.5 Ew.d[Ee]
342 notes: for Gw.d , n' ' means 4 blanks
343 for Gw.dEe, n' ' means e+2 blanks */
346 calculate_G_format (st_parameter_dt
*dtp
, const fnode
*f
,
347 GFC_REAL_LARGEST value
, int *num_blank
)
353 GFC_REAL_LARGEST m
, exp_d
;
357 newf
= get_mem (sizeof (fnode
));
359 /* Absolute value. */
360 m
= (value
> 0.0) ? value
: -value
;
362 /* In case of the two data magnitude ranges,
363 generate E editing, Ew.d[Ee]. */
364 exp_d
= calculate_exp (d
);
365 if ((m
> 0.0 && m
< 0.1 - 0.05 / exp_d
) || (m
>= exp_d
- 0.5 ) ||
366 ((m
== 0.0) && !(compile_options
.allow_std
& GFC_STD_F2003
)))
368 newf
->format
= FMT_E
;
376 /* Use binary search to find the data magnitude range. */
385 GFC_REAL_LARGEST temp
;
386 mid
= (low
+ high
) / 2;
388 /* 0.1 * 10**mid - 0.5 * 10**(mid-d-1) */
389 temp
= 0.1 * calculate_exp (mid
) - 0.5 * calculate_exp (mid
- d
- 1);
394 if (ubound
== lbound
+ 1)
401 if (ubound
== lbound
+ 1)
412 /* Pad with blanks where the exponent would be. */
418 /* Generate the F editing. F(w-n).(-(mid-d-1)), n' '. */
419 newf
->format
= FMT_F
;
420 newf
->u
.real
.w
= f
->u
.real
.w
- *num_blank
;
424 newf
->u
.real
.d
= d
- 1;
426 newf
->u
.real
.d
= - (mid
- d
- 1);
428 /* For F editing, the scale factor is ignored. */
429 dtp
->u
.p
.scale_factor
= 0;
434 /* Output a real number according to its format which is FMT_G free. */
437 output_float (st_parameter_dt
*dtp
, const fnode
*f
, GFC_REAL_LARGEST value
)
439 #if defined(HAVE_GFC_REAL_16) && __LDBL_DIG__ > 18
440 # define MIN_FIELD_WIDTH 46
442 # define MIN_FIELD_WIDTH 31
444 #define STR(x) STR1(x)
446 /* This must be large enough to accurately hold any value. */
447 char buffer
[MIN_FIELD_WIDTH
+1];
457 /* Number of digits before the decimal point. */
459 /* Number of zeros after the decimal point. */
461 /* Number of digits after the decimal point. */
463 /* Number of zeros after the decimal point, whatever the precision. */
478 /* We should always know the field width and precision. */
480 internal_error (&dtp
->common
, "Unspecified precision");
482 /* Use sprintf to print the number in the format +D.DDDDe+ddd
483 For an N digit exponent, this gives us (MIN_FIELD_WIDTH-5)-N digits
484 after the decimal point, plus another one before the decimal point. */
485 sign
= calculate_sign (dtp
, value
< 0.0);
489 /* Special case when format specifies no digits after the decimal point. */
490 if (d
== 0 && ft
== FMT_F
)
494 else if (value
< 1.0)
498 /* Printf always prints at least two exponent digits. */
503 #if defined(HAVE_GFC_REAL_10) || defined(HAVE_GFC_REAL_16)
504 abslog
= fabs((double) log10l(value
));
506 abslog
= fabs(log10(value
));
511 edigits
= 1 + (int) log10(abslog
);
514 if (ft
== FMT_F
|| ft
== FMT_EN
515 || ((ft
== FMT_D
|| ft
== FMT_E
) && dtp
->u
.p
.scale_factor
!= 0))
517 /* Always convert at full precision to avoid double rounding. */
518 ndigits
= MIN_FIELD_WIDTH
- 4 - edigits
;
522 /* We know the number of digits, so can let printf do the rounding
528 if (ndigits
> MIN_FIELD_WIDTH
- 4 - edigits
)
529 ndigits
= MIN_FIELD_WIDTH
- 4 - edigits
;
532 /* # The result will always contain a decimal point, even if no
535 * - The converted value is to be left adjusted on the field boundary
537 * + A sign (+ or -) always be placed before a number
539 * MIN_FIELD_WIDTH minimum field width
541 * * (ndigits-1) is used as the precision
543 * e format: [-]d.ddde±dd where there is one digit before the
544 * decimal-point character and the number of digits after it is
545 * equal to the precision. The exponent always contains at least two
546 * digits; if the value is zero, the exponent is 00.
548 sprintf (buffer
, "%+-#" STR(MIN_FIELD_WIDTH
) ".*"
549 GFC_REAL_LARGEST_FORMAT
"e", ndigits
- 1, value
);
551 /* Check the resulting string has punctuation in the correct places. */
552 if (d
!= 0 && (buffer
[2] != '.' || buffer
[ndigits
+ 2] != 'e'))
553 internal_error (&dtp
->common
, "printf is broken");
555 /* Read the exponent back in. */
556 e
= atoi (&buffer
[ndigits
+ 3]) + 1;
558 /* Make sure zero comes out as 0.0e0. */
562 /* Normalize the fractional component. */
563 buffer
[2] = buffer
[1];
566 /* Figure out where to place the decimal point. */
570 nbefore
= e
+ dtp
->u
.p
.scale_factor
;
590 i
= dtp
->u
.p
.scale_factor
;
603 nafter
= (d
- i
) + 1;
619 /* The exponent must be a multiple of three, with 1-3 digits before
620 the decimal point. */
629 nbefore
= 3 - nbefore
;
648 /* Should never happen. */
649 internal_error (&dtp
->common
, "Unexpected format token");
652 /* Round the value. */
653 if (nbefore
+ nafter
== 0)
656 if (nzero_real
== d
&& digits
[0] >= '5')
658 /* We rounded to zero but shouldn't have */
665 else if (nbefore
+ nafter
< ndigits
)
667 ndigits
= nbefore
+ nafter
;
669 if (digits
[i
] >= '5')
671 /* Propagate the carry. */
672 for (i
--; i
>= 0; i
--)
674 if (digits
[i
] != '9')
684 /* The carry overflowed. Fortunately we have some spare space
685 at the start of the buffer. We may discard some digits, but
686 this is ok because we already know they are zero. */
699 else if (ft
== FMT_EN
)
714 /* Calculate the format of the exponent field. */
718 for (i
= abs (e
); i
>= 10; i
/= 10)
723 /* Width not specified. Must be no more than 3 digits. */
724 if (e
> 999 || e
< -999)
729 if (e
> 99 || e
< -99)
735 /* Exponent width specified, check it is wide enough. */
736 if (edigits
> f
->u
.real
.e
)
739 edigits
= f
->u
.real
.e
+ 2;
745 /* Pick a field size if none was specified. */
747 w
= nbefore
+ nzero
+ nafter
+ (sign
!= SIGN_NONE
? 2 : 1);
749 /* Create the ouput buffer. */
750 out
= write_block (dtp
, w
);
754 /* Zero values always output as positive, even if the value was negative
756 for (i
= 0; i
< ndigits
; i
++)
758 if (digits
[i
] != '0')
762 sign
= calculate_sign (dtp
, 0);
764 /* Work out how much padding is needed. */
765 nblanks
= w
- (nbefore
+ nzero
+ nafter
+ edigits
+ 1);
766 if (sign
!= SIGN_NONE
)
769 /* Check the value fits in the specified field width. */
770 if (nblanks
< 0 || edigits
== -1)
776 /* See if we have space for a zero before the decimal point. */
777 if (nbefore
== 0 && nblanks
> 0)
785 /* Pad to full field width. */
788 if ( ( nblanks
> 0 ) && !dtp
->u
.p
.no_leading_blank
)
790 memset (out
, ' ', nblanks
);
794 /* Output the initial sign (if any). */
795 if (sign
== SIGN_PLUS
)
797 else if (sign
== SIGN_MINUS
)
800 /* Output an optional leading zero. */
804 /* Output the part before the decimal point, padding with zeros. */
807 if (nbefore
> ndigits
)
812 memcpy (out
, digits
, i
);
820 /* Output the decimal point. */
823 /* Output leading zeros after the decimal point. */
826 for (i
= 0; i
< nzero
; i
++)
830 /* Output digits after the decimal point, padding with zeros. */
833 if (nafter
> ndigits
)
838 memcpy (out
, digits
, i
);
847 /* Output the exponent. */
856 snprintf (buffer
, sizeof (buffer
), "%+0*d", edigits
, e
);
858 sprintf (buffer
, "%+0*d", edigits
, e
);
860 memcpy (out
, buffer
, edigits
);
863 if (dtp
->u
.p
.no_leading_blank
)
866 memset( out
, ' ' , nblanks
);
867 dtp
->u
.p
.no_leading_blank
= 0;
871 #undef MIN_FIELD_WIDTH
876 write_l (st_parameter_dt
*dtp
, const fnode
*f
, char *source
, int len
)
879 GFC_INTEGER_LARGEST n
;
881 p
= write_block (dtp
, f
->u
.w
);
885 memset (p
, ' ', f
->u
.w
- 1);
886 n
= extract_int (source
, len
);
887 p
[f
->u
.w
- 1] = (n
) ? 'T' : 'F';
890 /* Output a real number according to its format. */
893 write_float (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
896 int nb
=0, res
, save_scale_factor
;
900 n
= extract_real (source
, len
);
902 if (f
->format
!= FMT_B
&& f
->format
!= FMT_O
&& f
->format
!= FMT_Z
)
909 /* If the field width is zero, the processor must select a width
910 not zero. 4 is chosen to allow output of '-Inf' or '+Inf' */
913 p
= write_block (dtp
, nb
);
929 /* If the sign is negative and the width is 3, there is
930 insufficient room to output '-Inf', so output asterisks */
938 /* The negative sign is mandatory */
944 /* The positive sign is optional, but we output it for
951 /* We have room, so output 'Infinity' */
953 memcpy(p
+ nb
- 8, "Infinity", 8);
956 /* For the case of width equals 8, there is not enough room
957 for the sign and 'Infinity' so we go with 'Inf' */
959 memcpy(p
+ nb
- 3, "Inf", 3);
960 if (nb
< 9 && nb
> 3)
961 p
[nb
- 4] = fin
; /* Put the sign in front of Inf */
963 p
[nb
- 9] = fin
; /* Put the sign in front of Infinity */
966 memcpy(p
+ nb
- 3, "NaN", 3);
971 if (f
->format
!= FMT_G
)
972 output_float (dtp
, f
, n
);
975 save_scale_factor
= dtp
->u
.p
.scale_factor
;
976 f2
= calculate_G_format (dtp
, f
, n
, &nb
);
977 output_float (dtp
, f2
, n
);
978 dtp
->u
.p
.scale_factor
= save_scale_factor
;
984 p
= write_block (dtp
, nb
);
994 write_int (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
,
995 const char *(*conv
) (GFC_UINTEGER_LARGEST
, char *, size_t))
997 GFC_UINTEGER_LARGEST n
= 0;
998 int w
, m
, digits
, nzero
, nblank
;
1001 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
1006 n
= extract_uint (source
, len
);
1010 if (m
== 0 && n
== 0)
1015 p
= write_block (dtp
, w
);
1023 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
1024 digits
= strlen (q
);
1026 /* Select a width if none was specified. The idea here is to always
1030 w
= ((digits
< m
) ? m
: digits
);
1032 p
= write_block (dtp
, w
);
1040 /* See if things will work. */
1042 nblank
= w
- (nzero
+ digits
);
1051 if (!dtp
->u
.p
.no_leading_blank
)
1053 memset (p
, ' ', nblank
);
1055 memset (p
, '0', nzero
);
1057 memcpy (p
, q
, digits
);
1061 memset (p
, '0', nzero
);
1063 memcpy (p
, q
, digits
);
1065 memset (p
, ' ', nblank
);
1066 dtp
->u
.p
.no_leading_blank
= 0;
1074 write_decimal (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
,
1076 const char *(*conv
) (GFC_INTEGER_LARGEST
, char *, size_t))
1078 GFC_INTEGER_LARGEST n
= 0;
1079 int w
, m
, digits
, nsign
, nzero
, nblank
;
1083 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
1088 n
= extract_int (source
, len
);
1092 if (m
== 0 && n
== 0)
1097 p
= write_block (dtp
, w
);
1105 sign
= calculate_sign (dtp
, n
< 0);
1109 nsign
= sign
== SIGN_NONE
? 0 : 1;
1110 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
1112 digits
= strlen (q
);
1114 /* Select a width if none was specified. The idea here is to always
1118 w
= ((digits
< m
) ? m
: digits
) + nsign
;
1120 p
= write_block (dtp
, w
);
1128 /* See if things will work. */
1130 nblank
= w
- (nsign
+ nzero
+ digits
);
1138 memset (p
, ' ', nblank
);
1153 memset (p
, '0', nzero
);
1156 memcpy (p
, q
, digits
);
1163 /* Convert unsigned octal to ascii. */
1166 otoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
1170 assert (len
>= GFC_OTOA_BUF_SIZE
);
1175 p
= buffer
+ GFC_OTOA_BUF_SIZE
- 1;
1180 *--p
= '0' + (n
& 7);
1188 /* Convert unsigned binary to ascii. */
1191 btoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
1195 assert (len
>= GFC_BTOA_BUF_SIZE
);
1200 p
= buffer
+ GFC_BTOA_BUF_SIZE
- 1;
1205 *--p
= '0' + (n
& 1);
1214 write_i (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1216 write_decimal (dtp
, f
, p
, len
, (void *) gfc_itoa
);
1221 write_b (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1223 write_int (dtp
, f
, p
, len
, btoa
);
1228 write_o (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1230 write_int (dtp
, f
, p
, len
, otoa
);
1234 write_z (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1236 write_int (dtp
, f
, p
, len
, xtoa
);
1241 write_d (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1243 write_float (dtp
, f
, p
, len
);
1248 write_e (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1250 write_float (dtp
, f
, p
, len
);
1255 write_f (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1257 write_float (dtp
, f
, p
, len
);
1262 write_en (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1264 write_float (dtp
, f
, p
, len
);
1269 write_es (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1271 write_float (dtp
, f
, p
, len
);
1275 /* Take care of the X/TR descriptor. */
1278 write_x (st_parameter_dt
*dtp
, int len
, int nspaces
)
1282 p
= write_block (dtp
, len
);
1287 memset (&p
[len
- nspaces
], ' ', nspaces
);
1291 /* List-directed writing. */
1294 /* Write a single character to the output. Returns nonzero if
1295 something goes wrong. */
1298 write_char (st_parameter_dt
*dtp
, char c
)
1302 p
= write_block (dtp
, 1);
1312 /* Write a list-directed logical value. */
1315 write_logical (st_parameter_dt
*dtp
, const char *source
, int length
)
1317 write_char (dtp
, extract_int (source
, length
) ? 'T' : 'F');
1321 /* Write a list-directed integer value. */
1324 write_integer (st_parameter_dt
*dtp
, const char *source
, int length
)
1330 char itoa_buf
[GFC_ITOA_BUF_SIZE
];
1332 q
= gfc_itoa (extract_int (source
, length
), itoa_buf
, sizeof (itoa_buf
));
1357 digits
= strlen (q
);
1361 p
= write_block (dtp
, width
);
1364 if (dtp
->u
.p
.no_leading_blank
)
1366 memcpy (p
, q
, digits
);
1367 memset (p
+ digits
, ' ', width
- digits
);
1371 memset (p
, ' ', width
- digits
);
1372 memcpy (p
+ width
- digits
, q
, digits
);
1377 /* Write a list-directed string. We have to worry about delimiting
1378 the strings if the file has been opened in that mode. */
1381 write_character (st_parameter_dt
*dtp
, const char *source
, int length
)
1386 switch (dtp
->u
.p
.current_unit
->flags
.delim
)
1388 case DELIM_APOSTROPHE
:
1405 for (i
= 0; i
< length
; i
++)
1410 p
= write_block (dtp
, length
+ extra
);
1415 memcpy (p
, source
, length
);
1420 for (i
= 0; i
< length
; i
++)
1432 /* Output a real number with default format.
1433 This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
1434 1PG28.19E4 for REAL(10) and 1PG43.34E4 for REAL(16). */
1437 write_real (st_parameter_dt
*dtp
, const char *source
, int length
)
1440 int org_scale
= dtp
->u
.p
.scale_factor
;
1442 dtp
->u
.p
.scale_factor
= 1;
1466 internal_error (&dtp
->common
, "bad real kind");
1469 write_float (dtp
, &f
, source
, length
);
1470 dtp
->u
.p
.scale_factor
= org_scale
;
1475 write_complex (st_parameter_dt
*dtp
, const char *source
, int kind
, size_t size
)
1477 if (write_char (dtp
, '('))
1479 write_real (dtp
, source
, kind
);
1481 if (write_char (dtp
, ','))
1483 write_real (dtp
, source
+ size
/ 2, kind
);
1485 write_char (dtp
, ')');
1489 /* Write the separator between items. */
1492 write_separator (st_parameter_dt
*dtp
)
1496 p
= write_block (dtp
, options
.separator_len
);
1500 memcpy (p
, options
.separator
, options
.separator_len
);
1504 /* Write an item with list formatting.
1505 TODO: handle skipping to the next record correctly, particularly
1509 list_formatted_write_scalar (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
1512 if (dtp
->u
.p
.current_unit
== NULL
)
1515 if (dtp
->u
.p
.first_item
)
1517 dtp
->u
.p
.first_item
= 0;
1518 write_char (dtp
, ' ');
1522 if (type
!= BT_CHARACTER
|| !dtp
->u
.p
.char_flag
||
1523 dtp
->u
.p
.current_unit
->flags
.delim
!= DELIM_NONE
)
1524 write_separator (dtp
);
1530 write_integer (dtp
, p
, kind
);
1533 write_logical (dtp
, p
, kind
);
1536 write_character (dtp
, p
, kind
);
1539 write_real (dtp
, p
, kind
);
1542 write_complex (dtp
, p
, kind
, size
);
1545 internal_error (&dtp
->common
, "list_formatted_write(): Bad type");
1548 dtp
->u
.p
.char_flag
= (type
== BT_CHARACTER
);
1553 list_formatted_write (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
1554 size_t size
, size_t nelems
)
1561 /* Big loop over all the elements. */
1562 for (elem
= 0; elem
< nelems
; elem
++)
1564 dtp
->u
.p
.item_count
++;
1565 list_formatted_write_scalar (dtp
, type
, tmp
+ size
*elem
, kind
, size
);
1571 nml_write_obj writes a namelist object to the output stream. It is called
1572 recursively for derived type components:
1573 obj = is the namelist_info for the current object.
1574 offset = the offset relative to the address held by the object for
1575 derived type arrays.
1576 base = is the namelist_info of the derived type, when obj is a
1578 base_name = the full name for a derived type, including qualifiers
1580 The returned value is a pointer to the object beyond the last one
1581 accessed, including nested derived types. Notice that the namelist is
1582 a linear linked list of objects, including derived types and their
1583 components. A tree, of sorts, is implied by the compound names of
1584 the derived type components and this is how this function recurses through
1587 /* A generous estimate of the number of characters needed to print
1588 repeat counts and indices, including commas, asterices and brackets. */
1590 #define NML_DIGITS 20
1592 static namelist_info
*
1593 nml_write_obj (st_parameter_dt
*dtp
, namelist_info
* obj
, index_type offset
,
1594 namelist_info
* base
, char * base_name
)
1600 index_type obj_size
;
1604 index_type elem_ctr
;
1605 index_type obj_name_len
;
1610 char rep_buff
[NML_DIGITS
];
1611 namelist_info
* cmp
;
1612 namelist_info
* retval
= obj
->next
;
1614 /* Write namelist variable names in upper case. If a derived type,
1615 nothing is output. If a component, base and base_name are set. */
1617 if (obj
->type
!= GFC_DTYPE_DERIVED
)
1620 write_character (dtp
, "\r\n ", 3);
1622 write_character (dtp
, "\n ", 2);
1627 len
=strlen (base
->var_name
);
1628 for (dim_i
= 0; dim_i
< (index_type
) strlen (base_name
); dim_i
++)
1630 cup
= toupper (base_name
[dim_i
]);
1631 write_character (dtp
, &cup
, 1);
1634 for (dim_i
=len
; dim_i
< (index_type
) strlen (obj
->var_name
); dim_i
++)
1636 cup
= toupper (obj
->var_name
[dim_i
]);
1637 write_character (dtp
, &cup
, 1);
1639 write_character (dtp
, "=", 1);
1642 /* Counts the number of data output on a line, including names. */
1651 case GFC_DTYPE_REAL
:
1652 obj_size
= size_from_real_kind (len
);
1655 case GFC_DTYPE_COMPLEX
:
1656 obj_size
= size_from_complex_kind (len
);
1659 case GFC_DTYPE_CHARACTER
:
1660 obj_size
= obj
->string_length
;
1668 obj_size
= obj
->size
;
1670 /* Set the index vector and count the number of elements. */
1673 for (dim_i
=0; dim_i
< obj
->var_rank
; dim_i
++)
1675 obj
->ls
[dim_i
].idx
= obj
->dim
[dim_i
].lbound
;
1676 nelem
= nelem
* (obj
->dim
[dim_i
].ubound
+ 1 - obj
->dim
[dim_i
].lbound
);
1679 /* Main loop to output the data held in the object. */
1682 for (elem_ctr
= 0; elem_ctr
< nelem
; elem_ctr
++)
1685 /* Build the pointer to the data value. The offset is passed by
1686 recursive calls to this function for arrays of derived types.
1687 Is NULL otherwise. */
1689 p
= (void *)(obj
->mem_pos
+ elem_ctr
* obj_size
);
1692 /* Check for repeat counts of intrinsic types. */
1694 if ((elem_ctr
< (nelem
- 1)) &&
1695 (obj
->type
!= GFC_DTYPE_DERIVED
) &&
1696 !memcmp (p
, (void*)(p
+ obj_size
), obj_size
))
1701 /* Execute a repeated output. Note the flag no_leading_blank that
1702 is used in the functions used to output the intrinsic types. */
1708 st_sprintf(rep_buff
, " %d*", rep_ctr
);
1709 write_character (dtp
, rep_buff
, strlen (rep_buff
));
1710 dtp
->u
.p
.no_leading_blank
= 1;
1714 /* Output the data, if an intrinsic type, or recurse into this
1715 routine to treat derived types. */
1720 case GFC_DTYPE_INTEGER
:
1721 write_integer (dtp
, p
, len
);
1724 case GFC_DTYPE_LOGICAL
:
1725 write_logical (dtp
, p
, len
);
1728 case GFC_DTYPE_CHARACTER
:
1729 if (dtp
->u
.p
.nml_delim
)
1730 write_character (dtp
, &dtp
->u
.p
.nml_delim
, 1);
1731 write_character (dtp
, p
, obj
->string_length
);
1732 if (dtp
->u
.p
.nml_delim
)
1733 write_character (dtp
, &dtp
->u
.p
.nml_delim
, 1);
1736 case GFC_DTYPE_REAL
:
1737 write_real (dtp
, p
, len
);
1740 case GFC_DTYPE_COMPLEX
:
1741 dtp
->u
.p
.no_leading_blank
= 0;
1743 write_complex (dtp
, p
, len
, obj_size
);
1746 case GFC_DTYPE_DERIVED
:
1748 /* To treat a derived type, we need to build two strings:
1749 ext_name = the name, including qualifiers that prepends
1750 component names in the output - passed to
1752 obj_name = the derived type name with no qualifiers but %
1753 appended. This is used to identify the
1756 /* First ext_name => get length of all possible components */
1758 ext_name
= (char*)get_mem ( (base_name
? strlen (base_name
) : 0)
1759 + (base
? strlen (base
->var_name
) : 0)
1760 + strlen (obj
->var_name
)
1761 + obj
->var_rank
* NML_DIGITS
1764 strcpy(ext_name
, base_name
? base_name
: "");
1765 clen
= base
? strlen (base
->var_name
) : 0;
1766 strcat (ext_name
, obj
->var_name
+ clen
);
1768 /* Append the qualifier. */
1770 for (dim_i
= 0; dim_i
< obj
->var_rank
; dim_i
++)
1772 strcat (ext_name
, dim_i
? "" : "(");
1773 clen
= strlen (ext_name
);
1774 st_sprintf (ext_name
+ clen
, "%d", (int) obj
->ls
[dim_i
].idx
);
1775 strcat (ext_name
, (dim_i
== obj
->var_rank
- 1) ? ")" : ",");
1780 obj_name_len
= strlen (obj
->var_name
) + 1;
1781 obj_name
= get_mem (obj_name_len
+1);
1782 strcpy (obj_name
, obj
->var_name
);
1783 strcat (obj_name
, "%");
1785 /* Now loop over the components. Update the component pointer
1786 with the return value from nml_write_obj => this loop jumps
1787 past nested derived types. */
1789 for (cmp
= obj
->next
;
1790 cmp
&& !strncmp (cmp
->var_name
, obj_name
, obj_name_len
);
1793 retval
= nml_write_obj (dtp
, cmp
,
1794 (index_type
)(p
- obj
->mem_pos
),
1798 free_mem (obj_name
);
1799 free_mem (ext_name
);
1803 internal_error (&dtp
->common
, "Bad type for namelist write");
1806 /* Reset the leading blank suppression, write a comma and, if 5
1807 values have been output, write a newline and advance to column
1808 2. Reset the repeat counter. */
1810 dtp
->u
.p
.no_leading_blank
= 0;
1811 write_character (dtp
, ",", 1);
1816 write_character (dtp
, "\r\n ", 3);
1818 write_character (dtp
, "\n ", 2);
1824 /* Cycle through and increment the index vector. */
1829 for (dim_i
= 0; nml_carry
&& (dim_i
< obj
->var_rank
); dim_i
++)
1831 obj
->ls
[dim_i
].idx
+= nml_carry
;
1833 if (obj
->ls
[dim_i
].idx
> (ssize_t
)obj
->dim
[dim_i
].ubound
)
1835 obj
->ls
[dim_i
].idx
= obj
->dim
[dim_i
].lbound
;
1841 /* Return a pointer beyond the furthest object accessed. */
1846 /* This is the entry function for namelist writes. It outputs the name
1847 of the namelist and iterates through the namelist by calls to
1848 nml_write_obj. The call below has dummys in the arguments used in
1849 the treatment of derived types. */
1852 namelist_write (st_parameter_dt
*dtp
)
1854 namelist_info
* t1
, *t2
, *dummy
= NULL
;
1856 index_type dummy_offset
= 0;
1858 char * dummy_name
= NULL
;
1859 unit_delim tmp_delim
;
1861 /* Set the delimiter for namelist output. */
1863 tmp_delim
= dtp
->u
.p
.current_unit
->flags
.delim
;
1864 dtp
->u
.p
.current_unit
->flags
.delim
= DELIM_NONE
;
1868 dtp
->u
.p
.nml_delim
= '"';
1871 case (DELIM_APOSTROPHE
):
1872 dtp
->u
.p
.nml_delim
= '\'';
1876 dtp
->u
.p
.nml_delim
= '\0';
1880 write_character (dtp
, "&", 1);
1882 /* Write namelist name in upper case - f95 std. */
1884 for (i
= 0 ;i
< dtp
->namelist_name_len
;i
++ )
1886 c
= toupper (dtp
->namelist_name
[i
]);
1887 write_character (dtp
, &c
,1);
1890 if (dtp
->u
.p
.ionml
!= NULL
)
1892 t1
= dtp
->u
.p
.ionml
;
1896 t1
= nml_write_obj (dtp
, t2
, dummy_offset
, dummy
, dummy_name
);
1900 write_character (dtp
, " /\r\n", 5);
1902 write_character (dtp
, " /\n", 4);
1905 /* Recover the original delimiter. */
1907 dtp
->u
.p
.current_unit
->flags
.delim
= tmp_delim
;