1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 Namelist output contributed by Paul Thomas
5 This file is part of the GNU Fortran 95 runtime library (libgfortran).
7 Libgfortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
21 Libgfortran is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with Libgfortran; see the file COPYING. If not, write to
28 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA. */
37 #define star_fill(p, n) memset(p, '*', n)
41 { SIGN_NONE
, SIGN_MINUS
, SIGN_PLUS
}
46 write_a (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
51 wlen
= f
->u
.string
.length
< 0 ? len
: f
->u
.string
.length
;
54 /* If this is formatted STREAM IO convert any embedded line feed characters
55 to CR_LF on systems that use that sequence for newlines. See F2003
56 Standard sections 10.6.3 and 9.9 for further information. */
57 if (is_stream_io (dtp
))
59 const char crlf
[] = "\r\n";
63 /* Write out any padding if needed. */
66 p
= write_block (dtp
, wlen
- len
);
69 memset (p
, ' ', wlen
- len
);
72 /* Scan the source string looking for '\n' and convert it if found. */
73 for (i
= 0; i
< wlen
; i
++)
75 if (source
[i
] == '\n')
77 /* Write out the previously scanned characters in the string. */
80 p
= write_block (dtp
, bytes
);
83 memcpy (p
, &source
[q
], bytes
);
88 /* Write out the CR_LF sequence. */
90 p
= write_block (dtp
, 2);
99 /* Write out any remaining bytes if no LF was found. */
102 p
= write_block (dtp
, bytes
);
105 memcpy (p
, &source
[q
], bytes
);
111 p
= write_block (dtp
, wlen
);
116 memcpy (p
, source
, wlen
);
119 memset (p
, ' ', wlen
- len
);
120 memcpy (p
+ wlen
- len
, source
, len
);
127 static GFC_INTEGER_LARGEST
128 extract_int (const void *p
, int len
)
130 GFC_INTEGER_LARGEST i
= 0;
140 memcpy ((void *) &tmp
, p
, len
);
147 memcpy ((void *) &tmp
, p
, len
);
154 memcpy ((void *) &tmp
, p
, len
);
161 memcpy ((void *) &tmp
, p
, len
);
165 #ifdef HAVE_GFC_INTEGER_16
169 memcpy ((void *) &tmp
, p
, len
);
175 internal_error (NULL
, "bad integer kind");
181 static GFC_UINTEGER_LARGEST
182 extract_uint (const void *p
, int len
)
184 GFC_UINTEGER_LARGEST i
= 0;
194 memcpy ((void *) &tmp
, p
, len
);
195 i
= (GFC_UINTEGER_1
) tmp
;
201 memcpy ((void *) &tmp
, p
, len
);
202 i
= (GFC_UINTEGER_2
) tmp
;
208 memcpy ((void *) &tmp
, p
, len
);
209 i
= (GFC_UINTEGER_4
) tmp
;
215 memcpy ((void *) &tmp
, p
, len
);
216 i
= (GFC_UINTEGER_8
) tmp
;
219 #ifdef HAVE_GFC_INTEGER_16
223 memcpy ((void *) &tmp
, p
, len
);
224 i
= (GFC_UINTEGER_16
) tmp
;
229 internal_error (NULL
, "bad integer kind");
235 static GFC_REAL_LARGEST
236 extract_real (const void *p
, int len
)
238 GFC_REAL_LARGEST i
= 0;
244 memcpy ((void *) &tmp
, p
, len
);
251 memcpy ((void *) &tmp
, p
, len
);
255 #ifdef HAVE_GFC_REAL_10
259 memcpy ((void *) &tmp
, p
, len
);
264 #ifdef HAVE_GFC_REAL_16
268 memcpy ((void *) &tmp
, p
, len
);
274 internal_error (NULL
, "bad real kind");
280 /* Given a flag that indicate if a value is negative or not, return a
281 sign_t that gives the sign that we need to produce. */
284 calculate_sign (st_parameter_dt
*dtp
, int negative_flag
)
286 sign_t s
= SIGN_NONE
;
291 switch (dtp
->u
.p
.sign_status
)
300 s
= options
.optional_plus
? SIGN_PLUS
: SIGN_NONE
;
308 /* Returns the value of 10**d. */
310 static GFC_REAL_LARGEST
311 calculate_exp (int d
)
314 GFC_REAL_LARGEST r
= 1.0;
316 for (i
= 0; i
< (d
>= 0 ? d
: -d
); i
++)
319 r
= (d
>= 0) ? r
: 1.0 / r
;
325 /* Generate corresponding I/O format for FMT_G output.
326 The rules to translate FMT_G to FMT_E or FMT_F from DEC fortran
327 LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
329 Data Magnitude Equivalent Conversion
330 0< m < 0.1-0.5*10**(-d-1) Ew.d[Ee]
331 m = 0 F(w-n).(d-1), n' '
332 0.1-0.5*10**(-d-1)<= m < 1-0.5*10**(-d) F(w-n).d, n' '
333 1-0.5*10**(-d)<= m < 10-0.5*10**(-d+1) F(w-n).(d-1), n' '
334 10-0.5*10**(-d+1)<= m < 100-0.5*10**(-d+2) F(w-n).(d-2), n' '
335 ................ ..........
336 10**(d-1)-0.5*10**(-1)<= m <10**d-0.5 F(w-n).0,n(' ')
337 m >= 10**d-0.5 Ew.d[Ee]
339 notes: for Gw.d , n' ' means 4 blanks
340 for Gw.dEe, n' ' means e+2 blanks */
343 calculate_G_format (st_parameter_dt
*dtp
, const fnode
*f
,
344 GFC_REAL_LARGEST value
, int *num_blank
)
350 GFC_REAL_LARGEST m
, exp_d
;
354 newf
= get_mem (sizeof (fnode
));
356 /* Absolute value. */
357 m
= (value
> 0.0) ? value
: -value
;
359 /* In case of the two data magnitude ranges,
360 generate E editing, Ew.d[Ee]. */
361 exp_d
= calculate_exp (d
);
362 if ((m
> 0.0 && m
< 0.1 - 0.05 / exp_d
) || (m
>= exp_d
- 0.5 ) ||
363 ((m
== 0.0) && !(compile_options
.allow_std
& GFC_STD_F2003
)))
365 newf
->format
= FMT_E
;
373 /* Use binary search to find the data magnitude range. */
382 GFC_REAL_LARGEST temp
;
383 mid
= (low
+ high
) / 2;
385 /* 0.1 * 10**mid - 0.5 * 10**(mid-d-1) */
386 temp
= 0.1 * calculate_exp (mid
) - 0.5 * calculate_exp (mid
- d
- 1);
391 if (ubound
== lbound
+ 1)
398 if (ubound
== lbound
+ 1)
409 /* Pad with blanks where the exponent would be. */
415 /* Generate the F editing. F(w-n).(-(mid-d-1)), n' '. */
416 newf
->format
= FMT_F
;
417 newf
->u
.real
.w
= f
->u
.real
.w
- *num_blank
;
421 newf
->u
.real
.d
= d
- 1;
423 newf
->u
.real
.d
= - (mid
- d
- 1);
425 /* For F editing, the scale factor is ignored. */
426 dtp
->u
.p
.scale_factor
= 0;
431 /* Output a real number according to its format which is FMT_G free. */
434 output_float (st_parameter_dt
*dtp
, const fnode
*f
, GFC_REAL_LARGEST value
)
436 #if defined(HAVE_GFC_REAL_16) && __LDBL_DIG__ > 18
437 # define MIN_FIELD_WIDTH 46
439 # define MIN_FIELD_WIDTH 31
441 #define STR(x) STR1(x)
443 /* This must be large enough to accurately hold any value. */
444 char buffer
[MIN_FIELD_WIDTH
+1];
454 /* Number of digits before the decimal point. */
456 /* Number of zeros after the decimal point. */
458 /* Number of digits after the decimal point. */
460 /* Number of zeros after the decimal point, whatever the precision. */
475 /* We should always know the field width and precision. */
477 internal_error (&dtp
->common
, "Unspecified precision");
479 /* Use sprintf to print the number in the format +D.DDDDe+ddd
480 For an N digit exponent, this gives us (MIN_FIELD_WIDTH-5)-N digits
481 after the decimal point, plus another one before the decimal point. */
482 sign
= calculate_sign (dtp
, value
< 0.0);
483 sign_bit
= signbit (value
);
487 /* Special case when format specifies no digits after the decimal point. */
488 if (d
== 0 && ft
== FMT_F
)
492 else if (value
< 1.0)
496 /* printf pads blanks for us on the exponent so we just need it big enough
497 to handle the largest number of exponent digits expected. */
500 if (ft
== FMT_F
|| ft
== FMT_EN
501 || ((ft
== FMT_D
|| ft
== FMT_E
) && dtp
->u
.p
.scale_factor
!= 0))
503 /* Always convert at full precision to avoid double rounding. */
504 ndigits
= MIN_FIELD_WIDTH
- 4 - edigits
;
508 /* We know the number of digits, so can let printf do the rounding
514 if (ndigits
> MIN_FIELD_WIDTH
- 4 - edigits
)
515 ndigits
= MIN_FIELD_WIDTH
- 4 - edigits
;
518 /* # The result will always contain a decimal point, even if no
521 * - The converted value is to be left adjusted on the field boundary
523 * + A sign (+ or -) always be placed before a number
525 * MIN_FIELD_WIDTH minimum field width
527 * * (ndigits-1) is used as the precision
529 * e format: [-]d.ddde±dd where there is one digit before the
530 * decimal-point character and the number of digits after it is
531 * equal to the precision. The exponent always contains at least two
532 * digits; if the value is zero, the exponent is 00.
535 snprintf (buffer
, sizeof (buffer
), "%+-#" STR(MIN_FIELD_WIDTH
) ".*"
536 GFC_REAL_LARGEST_FORMAT
"e", ndigits
- 1, value
);
538 sprintf (buffer
, "%+-#" STR(MIN_FIELD_WIDTH
) ".*"
539 GFC_REAL_LARGEST_FORMAT
"e", ndigits
- 1, value
);
542 /* Check the resulting string has punctuation in the correct places. */
543 if (d
!= 0 && (buffer
[2] != '.' || buffer
[ndigits
+ 2] != 'e'))
544 internal_error (&dtp
->common
, "printf is broken");
546 /* Read the exponent back in. */
547 e
= atoi (&buffer
[ndigits
+ 3]) + 1;
549 /* Make sure zero comes out as 0.0e0. */
553 if (compile_options
.sign_zero
== 1)
554 sign
= calculate_sign (dtp
, sign_bit
);
556 sign
= calculate_sign (dtp
, 0);
559 /* Normalize the fractional component. */
560 buffer
[2] = buffer
[1];
563 /* Figure out where to place the decimal point. */
567 nbefore
= e
+ dtp
->u
.p
.scale_factor
;
587 i
= dtp
->u
.p
.scale_factor
;
600 nafter
= (d
- i
) + 1;
616 /* The exponent must be a multiple of three, with 1-3 digits before
617 the decimal point. */
626 nbefore
= 3 - nbefore
;
645 /* Should never happen. */
646 internal_error (&dtp
->common
, "Unexpected format token");
649 /* Round the value. */
650 if (nbefore
+ nafter
== 0)
653 if (nzero_real
== d
&& digits
[0] >= '5')
655 /* We rounded to zero but shouldn't have */
662 else if (nbefore
+ nafter
< ndigits
)
664 ndigits
= nbefore
+ nafter
;
666 if (digits
[i
] >= '5')
668 /* Propagate the carry. */
669 for (i
--; i
>= 0; i
--)
671 if (digits
[i
] != '9')
681 /* The carry overflowed. Fortunately we have some spare space
682 at the start of the buffer. We may discard some digits, but
683 this is ok because we already know they are zero. */
696 else if (ft
== FMT_EN
)
711 /* Calculate the format of the exponent field. */
715 for (i
= abs (e
); i
>= 10; i
/= 10)
720 /* Width not specified. Must be no more than 3 digits. */
721 if (e
> 999 || e
< -999)
726 if (e
> 99 || e
< -99)
732 /* Exponent width specified, check it is wide enough. */
733 if (edigits
> f
->u
.real
.e
)
736 edigits
= f
->u
.real
.e
+ 2;
742 /* Pick a field size if none was specified. */
744 w
= nbefore
+ nzero
+ nafter
+ (sign
!= SIGN_NONE
? 2 : 1);
746 /* Create the ouput buffer. */
747 out
= write_block (dtp
, w
);
751 /* Zero values always output as positive, even if the value was negative
753 for (i
= 0; i
< ndigits
; i
++)
755 if (digits
[i
] != '0')
760 /* The output is zero, so set the sign according to the sign bit unless
761 -fno-sign-zero was specified. */
762 if (compile_options
.sign_zero
== 1)
763 sign
= calculate_sign (dtp
, sign_bit
);
765 sign
= calculate_sign (dtp
, 0);
768 /* Work out how much padding is needed. */
769 nblanks
= w
- (nbefore
+ nzero
+ nafter
+ edigits
+ 1);
770 if (sign
!= SIGN_NONE
)
773 /* Check the value fits in the specified field width. */
774 if (nblanks
< 0 || edigits
== -1)
780 /* See if we have space for a zero before the decimal point. */
781 if (nbefore
== 0 && nblanks
> 0)
789 /* Pad to full field width. */
791 if ( ( nblanks
> 0 ) && !dtp
->u
.p
.no_leading_blank
)
793 memset (out
, ' ', nblanks
);
797 /* Output the initial sign (if any). */
798 if (sign
== SIGN_PLUS
)
800 else if (sign
== SIGN_MINUS
)
803 /* Output an optional leading zero. */
807 /* Output the part before the decimal point, padding with zeros. */
810 if (nbefore
> ndigits
)
813 memcpy (out
, digits
, i
);
821 memcpy (out
, digits
, i
);
828 /* Output the decimal point. */
831 /* Output leading zeros after the decimal point. */
834 for (i
= 0; i
< nzero
; i
++)
838 /* Output digits after the decimal point, padding with zeros. */
841 if (nafter
> ndigits
)
846 memcpy (out
, digits
, i
);
855 /* Output the exponent. */
864 snprintf (buffer
, sizeof (buffer
), "%+0*d", edigits
, e
);
866 sprintf (buffer
, "%+0*d", edigits
, e
);
868 memcpy (out
, buffer
, edigits
);
871 if (dtp
->u
.p
.no_leading_blank
)
874 memset( out
, ' ' , nblanks
);
875 dtp
->u
.p
.no_leading_blank
= 0;
879 #undef MIN_FIELD_WIDTH
884 write_l (st_parameter_dt
*dtp
, const fnode
*f
, char *source
, int len
)
887 GFC_INTEGER_LARGEST n
;
889 p
= write_block (dtp
, f
->u
.w
);
893 memset (p
, ' ', f
->u
.w
- 1);
894 n
= extract_int (source
, len
);
895 p
[f
->u
.w
- 1] = (n
) ? 'T' : 'F';
898 /* Output a real number according to its format. */
901 write_float (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
)
904 int nb
=0, res
, save_scale_factor
;
908 n
= extract_real (source
, len
);
910 if (f
->format
!= FMT_B
&& f
->format
!= FMT_O
&& f
->format
!= FMT_Z
)
917 /* If the field width is zero, the processor must select a width
918 not zero. 4 is chosen to allow output of '-Inf' or '+Inf' */
921 p
= write_block (dtp
, nb
);
937 /* If the sign is negative and the width is 3, there is
938 insufficient room to output '-Inf', so output asterisks */
946 /* The negative sign is mandatory */
952 /* The positive sign is optional, but we output it for
959 /* We have room, so output 'Infinity' */
961 memcpy(p
+ nb
- 8, "Infinity", 8);
964 /* For the case of width equals 8, there is not enough room
965 for the sign and 'Infinity' so we go with 'Inf' */
967 memcpy(p
+ nb
- 3, "Inf", 3);
968 if (nb
< 9 && nb
> 3)
969 p
[nb
- 4] = fin
; /* Put the sign in front of Inf */
971 p
[nb
- 9] = fin
; /* Put the sign in front of Infinity */
974 memcpy(p
+ nb
- 3, "NaN", 3);
979 if (f
->format
!= FMT_G
)
980 output_float (dtp
, f
, n
);
983 save_scale_factor
= dtp
->u
.p
.scale_factor
;
984 f2
= calculate_G_format (dtp
, f
, n
, &nb
);
985 output_float (dtp
, f2
, n
);
986 dtp
->u
.p
.scale_factor
= save_scale_factor
;
992 p
= write_block (dtp
, nb
);
1002 write_int (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
, int len
,
1003 const char *(*conv
) (GFC_UINTEGER_LARGEST
, char *, size_t))
1005 GFC_UINTEGER_LARGEST n
= 0;
1006 int w
, m
, digits
, nzero
, nblank
;
1009 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
1014 n
= extract_uint (source
, len
);
1018 if (m
== 0 && n
== 0)
1023 p
= write_block (dtp
, w
);
1031 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
1032 digits
= strlen (q
);
1034 /* Select a width if none was specified. The idea here is to always
1038 w
= ((digits
< m
) ? m
: digits
);
1040 p
= write_block (dtp
, w
);
1048 /* See if things will work. */
1050 nblank
= w
- (nzero
+ digits
);
1059 if (!dtp
->u
.p
.no_leading_blank
)
1061 memset (p
, ' ', nblank
);
1063 memset (p
, '0', nzero
);
1065 memcpy (p
, q
, digits
);
1069 memset (p
, '0', nzero
);
1071 memcpy (p
, q
, digits
);
1073 memset (p
, ' ', nblank
);
1074 dtp
->u
.p
.no_leading_blank
= 0;
1082 write_decimal (st_parameter_dt
*dtp
, const fnode
*f
, const char *source
,
1084 const char *(*conv
) (GFC_INTEGER_LARGEST
, char *, size_t))
1086 GFC_INTEGER_LARGEST n
= 0;
1087 int w
, m
, digits
, nsign
, nzero
, nblank
;
1091 char itoa_buf
[GFC_BTOA_BUF_SIZE
];
1096 n
= extract_int (source
, len
);
1100 if (m
== 0 && n
== 0)
1105 p
= write_block (dtp
, w
);
1113 sign
= calculate_sign (dtp
, n
< 0);
1117 nsign
= sign
== SIGN_NONE
? 0 : 1;
1118 q
= conv (n
, itoa_buf
, sizeof (itoa_buf
));
1120 digits
= strlen (q
);
1122 /* Select a width if none was specified. The idea here is to always
1126 w
= ((digits
< m
) ? m
: digits
) + nsign
;
1128 p
= write_block (dtp
, w
);
1136 /* See if things will work. */
1138 nblank
= w
- (nsign
+ nzero
+ digits
);
1146 memset (p
, ' ', nblank
);
1161 memset (p
, '0', nzero
);
1164 memcpy (p
, q
, digits
);
1171 /* Convert unsigned octal to ascii. */
1174 otoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
1178 assert (len
>= GFC_OTOA_BUF_SIZE
);
1183 p
= buffer
+ GFC_OTOA_BUF_SIZE
- 1;
1188 *--p
= '0' + (n
& 7);
1196 /* Convert unsigned binary to ascii. */
1199 btoa (GFC_UINTEGER_LARGEST n
, char *buffer
, size_t len
)
1203 assert (len
>= GFC_BTOA_BUF_SIZE
);
1208 p
= buffer
+ GFC_BTOA_BUF_SIZE
- 1;
1213 *--p
= '0' + (n
& 1);
1222 write_i (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1224 write_decimal (dtp
, f
, p
, len
, (void *) gfc_itoa
);
1229 write_b (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1231 write_int (dtp
, f
, p
, len
, btoa
);
1236 write_o (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1238 write_int (dtp
, f
, p
, len
, otoa
);
1242 write_z (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1244 write_int (dtp
, f
, p
, len
, xtoa
);
1249 write_d (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1251 write_float (dtp
, f
, p
, len
);
1256 write_e (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1258 write_float (dtp
, f
, p
, len
);
1263 write_f (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1265 write_float (dtp
, f
, p
, len
);
1270 write_en (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1272 write_float (dtp
, f
, p
, len
);
1277 write_es (st_parameter_dt
*dtp
, const fnode
*f
, const char *p
, int len
)
1279 write_float (dtp
, f
, p
, len
);
1283 /* Take care of the X/TR descriptor. */
1286 write_x (st_parameter_dt
*dtp
, int len
, int nspaces
)
1290 p
= write_block (dtp
, len
);
1295 memset (&p
[len
- nspaces
], ' ', nspaces
);
1299 /* List-directed writing. */
1302 /* Write a single character to the output. Returns nonzero if
1303 something goes wrong. */
1306 write_char (st_parameter_dt
*dtp
, char c
)
1310 p
= write_block (dtp
, 1);
1320 /* Write a list-directed logical value. */
1323 write_logical (st_parameter_dt
*dtp
, const char *source
, int length
)
1325 write_char (dtp
, extract_int (source
, length
) ? 'T' : 'F');
1329 /* Write a list-directed integer value. */
1332 write_integer (st_parameter_dt
*dtp
, const char *source
, int length
)
1338 char itoa_buf
[GFC_ITOA_BUF_SIZE
];
1340 q
= gfc_itoa (extract_int (source
, length
), itoa_buf
, sizeof (itoa_buf
));
1365 digits
= strlen (q
);
1369 p
= write_block (dtp
, width
);
1372 if (dtp
->u
.p
.no_leading_blank
)
1374 memcpy (p
, q
, digits
);
1375 memset (p
+ digits
, ' ', width
- digits
);
1379 memset (p
, ' ', width
- digits
);
1380 memcpy (p
+ width
- digits
, q
, digits
);
1385 /* Write a list-directed string. We have to worry about delimiting
1386 the strings if the file has been opened in that mode. */
1389 write_character (st_parameter_dt
*dtp
, const char *source
, int length
)
1394 switch (dtp
->u
.p
.current_unit
->flags
.delim
)
1396 case DELIM_APOSTROPHE
:
1413 for (i
= 0; i
< length
; i
++)
1418 p
= write_block (dtp
, length
+ extra
);
1423 memcpy (p
, source
, length
);
1428 for (i
= 0; i
< length
; i
++)
1440 /* Output a real number with default format.
1441 This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
1442 1PG28.19E4 for REAL(10) and 1PG43.34E4 for REAL(16). */
1445 write_real (st_parameter_dt
*dtp
, const char *source
, int length
)
1448 int org_scale
= dtp
->u
.p
.scale_factor
;
1450 dtp
->u
.p
.scale_factor
= 1;
1474 internal_error (&dtp
->common
, "bad real kind");
1477 write_float (dtp
, &f
, source
, length
);
1478 dtp
->u
.p
.scale_factor
= org_scale
;
1483 write_complex (st_parameter_dt
*dtp
, const char *source
, int kind
, size_t size
)
1485 if (write_char (dtp
, '('))
1487 write_real (dtp
, source
, kind
);
1489 if (write_char (dtp
, ','))
1491 write_real (dtp
, source
+ size
/ 2, kind
);
1493 write_char (dtp
, ')');
1497 /* Write the separator between items. */
1500 write_separator (st_parameter_dt
*dtp
)
1504 p
= write_block (dtp
, options
.separator_len
);
1508 memcpy (p
, options
.separator
, options
.separator_len
);
1512 /* Write an item with list formatting.
1513 TODO: handle skipping to the next record correctly, particularly
1517 list_formatted_write_scalar (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
1520 if (dtp
->u
.p
.current_unit
== NULL
)
1523 if (dtp
->u
.p
.first_item
)
1525 dtp
->u
.p
.first_item
= 0;
1526 write_char (dtp
, ' ');
1530 if (type
!= BT_CHARACTER
|| !dtp
->u
.p
.char_flag
||
1531 dtp
->u
.p
.current_unit
->flags
.delim
!= DELIM_NONE
)
1532 write_separator (dtp
);
1538 write_integer (dtp
, p
, kind
);
1541 write_logical (dtp
, p
, kind
);
1544 write_character (dtp
, p
, kind
);
1547 write_real (dtp
, p
, kind
);
1550 write_complex (dtp
, p
, kind
, size
);
1553 internal_error (&dtp
->common
, "list_formatted_write(): Bad type");
1556 dtp
->u
.p
.char_flag
= (type
== BT_CHARACTER
);
1561 list_formatted_write (st_parameter_dt
*dtp
, bt type
, void *p
, int kind
,
1562 size_t size
, size_t nelems
)
1569 /* Big loop over all the elements. */
1570 for (elem
= 0; elem
< nelems
; elem
++)
1572 dtp
->u
.p
.item_count
++;
1573 list_formatted_write_scalar (dtp
, type
, tmp
+ size
*elem
, kind
, size
);
1579 nml_write_obj writes a namelist object to the output stream. It is called
1580 recursively for derived type components:
1581 obj = is the namelist_info for the current object.
1582 offset = the offset relative to the address held by the object for
1583 derived type arrays.
1584 base = is the namelist_info of the derived type, when obj is a
1586 base_name = the full name for a derived type, including qualifiers
1588 The returned value is a pointer to the object beyond the last one
1589 accessed, including nested derived types. Notice that the namelist is
1590 a linear linked list of objects, including derived types and their
1591 components. A tree, of sorts, is implied by the compound names of
1592 the derived type components and this is how this function recurses through
1595 /* A generous estimate of the number of characters needed to print
1596 repeat counts and indices, including commas, asterices and brackets. */
1598 #define NML_DIGITS 20
1600 static namelist_info
*
1601 nml_write_obj (st_parameter_dt
*dtp
, namelist_info
* obj
, index_type offset
,
1602 namelist_info
* base
, char * base_name
)
1608 index_type obj_size
;
1612 index_type elem_ctr
;
1613 index_type obj_name_len
;
1618 char rep_buff
[NML_DIGITS
];
1619 namelist_info
* cmp
;
1620 namelist_info
* retval
= obj
->next
;
1621 size_t base_name_len
;
1622 size_t base_var_name_len
;
1625 /* Write namelist variable names in upper case. If a derived type,
1626 nothing is output. If a component, base and base_name are set. */
1628 if (obj
->type
!= GFC_DTYPE_DERIVED
)
1631 write_character (dtp
, "\r\n ", 3);
1633 write_character (dtp
, "\n ", 2);
1638 len
=strlen (base
->var_name
);
1639 for (dim_i
= 0; dim_i
< (index_type
) strlen (base_name
); dim_i
++)
1641 cup
= toupper (base_name
[dim_i
]);
1642 write_character (dtp
, &cup
, 1);
1645 for (dim_i
=len
; dim_i
< (index_type
) strlen (obj
->var_name
); dim_i
++)
1647 cup
= toupper (obj
->var_name
[dim_i
]);
1648 write_character (dtp
, &cup
, 1);
1650 write_character (dtp
, "=", 1);
1653 /* Counts the number of data output on a line, including names. */
1662 case GFC_DTYPE_REAL
:
1663 obj_size
= size_from_real_kind (len
);
1666 case GFC_DTYPE_COMPLEX
:
1667 obj_size
= size_from_complex_kind (len
);
1670 case GFC_DTYPE_CHARACTER
:
1671 obj_size
= obj
->string_length
;
1679 obj_size
= obj
->size
;
1681 /* Set the index vector and count the number of elements. */
1684 for (dim_i
=0; dim_i
< obj
->var_rank
; dim_i
++)
1686 obj
->ls
[dim_i
].idx
= obj
->dim
[dim_i
].lbound
;
1687 nelem
= nelem
* (obj
->dim
[dim_i
].ubound
+ 1 - obj
->dim
[dim_i
].lbound
);
1690 /* Main loop to output the data held in the object. */
1693 for (elem_ctr
= 0; elem_ctr
< nelem
; elem_ctr
++)
1696 /* Build the pointer to the data value. The offset is passed by
1697 recursive calls to this function for arrays of derived types.
1698 Is NULL otherwise. */
1700 p
= (void *)(obj
->mem_pos
+ elem_ctr
* obj_size
);
1703 /* Check for repeat counts of intrinsic types. */
1705 if ((elem_ctr
< (nelem
- 1)) &&
1706 (obj
->type
!= GFC_DTYPE_DERIVED
) &&
1707 !memcmp (p
, (void*)(p
+ obj_size
), obj_size
))
1712 /* Execute a repeated output. Note the flag no_leading_blank that
1713 is used in the functions used to output the intrinsic types. */
1719 sprintf(rep_buff
, " %d*", rep_ctr
);
1720 write_character (dtp
, rep_buff
, strlen (rep_buff
));
1721 dtp
->u
.p
.no_leading_blank
= 1;
1725 /* Output the data, if an intrinsic type, or recurse into this
1726 routine to treat derived types. */
1731 case GFC_DTYPE_INTEGER
:
1732 write_integer (dtp
, p
, len
);
1735 case GFC_DTYPE_LOGICAL
:
1736 write_logical (dtp
, p
, len
);
1739 case GFC_DTYPE_CHARACTER
:
1740 if (dtp
->u
.p
.nml_delim
)
1741 write_character (dtp
, &dtp
->u
.p
.nml_delim
, 1);
1742 write_character (dtp
, p
, obj
->string_length
);
1743 if (dtp
->u
.p
.nml_delim
)
1744 write_character (dtp
, &dtp
->u
.p
.nml_delim
, 1);
1747 case GFC_DTYPE_REAL
:
1748 write_real (dtp
, p
, len
);
1751 case GFC_DTYPE_COMPLEX
:
1752 dtp
->u
.p
.no_leading_blank
= 0;
1754 write_complex (dtp
, p
, len
, obj_size
);
1757 case GFC_DTYPE_DERIVED
:
1759 /* To treat a derived type, we need to build two strings:
1760 ext_name = the name, including qualifiers that prepends
1761 component names in the output - passed to
1763 obj_name = the derived type name with no qualifiers but %
1764 appended. This is used to identify the
1767 /* First ext_name => get length of all possible components */
1769 base_name_len
= base_name
? strlen (base_name
) : 0;
1770 base_var_name_len
= base
? strlen (base
->var_name
) : 0;
1771 ext_name
= (char*)get_mem ( base_name_len
1773 + strlen (obj
->var_name
)
1774 + obj
->var_rank
* NML_DIGITS
1777 memcpy (ext_name
, base_name
, base_name_len
);
1778 clen
= strlen (obj
->var_name
+ base_var_name_len
);
1779 memcpy (ext_name
+ base_name_len
,
1780 obj
->var_name
+ base_var_name_len
, clen
);
1782 /* Append the qualifier. */
1784 tot_len
= base_name_len
+ clen
;
1785 for (dim_i
= 0; dim_i
< obj
->var_rank
; dim_i
++)
1789 ext_name
[tot_len
] = '(';
1792 sprintf (ext_name
+ tot_len
, "%d", (int) obj
->ls
[dim_i
].idx
);
1793 tot_len
+= strlen (ext_name
+ tot_len
);
1794 ext_name
[tot_len
] = (dim_i
== obj
->var_rank
- 1) ? ')' : ',';
1798 ext_name
[tot_len
] = '\0';
1802 obj_name_len
= strlen (obj
->var_name
) + 1;
1803 obj_name
= get_mem (obj_name_len
+1);
1804 memcpy (obj_name
, obj
->var_name
, obj_name_len
-1);
1805 memcpy (obj_name
+ obj_name_len
-1, "%", 2);
1807 /* Now loop over the components. Update the component pointer
1808 with the return value from nml_write_obj => this loop jumps
1809 past nested derived types. */
1811 for (cmp
= obj
->next
;
1812 cmp
&& !strncmp (cmp
->var_name
, obj_name
, obj_name_len
);
1815 retval
= nml_write_obj (dtp
, cmp
,
1816 (index_type
)(p
- obj
->mem_pos
),
1820 free_mem (obj_name
);
1821 free_mem (ext_name
);
1825 internal_error (&dtp
->common
, "Bad type for namelist write");
1828 /* Reset the leading blank suppression, write a comma and, if 5
1829 values have been output, write a newline and advance to column
1830 2. Reset the repeat counter. */
1832 dtp
->u
.p
.no_leading_blank
= 0;
1833 write_character (dtp
, ",", 1);
1838 write_character (dtp
, "\r\n ", 3);
1840 write_character (dtp
, "\n ", 2);
1846 /* Cycle through and increment the index vector. */
1851 for (dim_i
= 0; nml_carry
&& (dim_i
< obj
->var_rank
); dim_i
++)
1853 obj
->ls
[dim_i
].idx
+= nml_carry
;
1855 if (obj
->ls
[dim_i
].idx
> (ssize_t
)obj
->dim
[dim_i
].ubound
)
1857 obj
->ls
[dim_i
].idx
= obj
->dim
[dim_i
].lbound
;
1863 /* Return a pointer beyond the furthest object accessed. */
1868 /* This is the entry function for namelist writes. It outputs the name
1869 of the namelist and iterates through the namelist by calls to
1870 nml_write_obj. The call below has dummys in the arguments used in
1871 the treatment of derived types. */
1874 namelist_write (st_parameter_dt
*dtp
)
1876 namelist_info
* t1
, *t2
, *dummy
= NULL
;
1878 index_type dummy_offset
= 0;
1880 char * dummy_name
= NULL
;
1881 unit_delim tmp_delim
;
1883 /* Set the delimiter for namelist output. */
1885 tmp_delim
= dtp
->u
.p
.current_unit
->flags
.delim
;
1886 dtp
->u
.p
.current_unit
->flags
.delim
= DELIM_NONE
;
1890 dtp
->u
.p
.nml_delim
= '"';
1893 case (DELIM_APOSTROPHE
):
1894 dtp
->u
.p
.nml_delim
= '\'';
1898 dtp
->u
.p
.nml_delim
= '\0';
1902 write_character (dtp
, "&", 1);
1904 /* Write namelist name in upper case - f95 std. */
1906 for (i
= 0 ;i
< dtp
->namelist_name_len
;i
++ )
1908 c
= toupper (dtp
->namelist_name
[i
]);
1909 write_character (dtp
, &c
,1);
1912 if (dtp
->u
.p
.ionml
!= NULL
)
1914 t1
= dtp
->u
.p
.ionml
;
1918 t1
= nml_write_obj (dtp
, t2
, dummy_offset
, dummy
, dummy_name
);
1922 write_character (dtp
, " /\r\n", 5);
1924 write_character (dtp
, " /\n", 4);
1927 /* Recover the original delimiter. */
1929 dtp
->u
.p
.current_unit
->flags
.delim
= tmp_delim
;